herolib_python/lib/core/texttools/texttools.py
2025-08-05 15:48:18 +02:00

142 lines
4.6 KiB
Python

import re
def name_fix(name: str) -> str:
# VLang's name_fix converts '-' to '_' and cleans up special chars.
# Python's re.sub can handle this.
name = re.sub(r'[^a-zA-Z0-9_ ]', '', name.replace('-', '_'))
return name.strip()
def expand(txt: str, length: int, expand_with: str) -> str:
# Pads the string to the specified length.
return txt.ljust(length, expand_with)
def dedent(text: str) -> str:
# Removes common leading whitespace from every line.
# This is a simplified version of textwrap.dedent
lines = text.splitlines()
if not lines:
return ""
# Find the minimum indentation of non-empty lines
min_indent = float('inf')
for line in lines:
if line.strip():
indent = len(line) - len(line.lstrip())
min_indent = min(min_indent, indent)
if min_indent == float('inf'): # All lines are empty or just whitespace
return "\n".join([line.strip() for line in lines])
dedented_lines = [line[min_indent:] for line in lines]
return "\n".join(dedented_lines)
def remove_empty_lines(text: str) -> str:
lines = text.splitlines()
return "\n".join([line for line in lines if line.strip()])
def remove_double_lines(text: str) -> str:
lines = text.splitlines()
cleaned_lines = []
prev_empty = False
for line in lines:
is_empty = not line.strip()
if is_empty and prev_empty:
continue
cleaned_lines.append(line)
prev_empty = is_empty
return "\n".join(cleaned_lines)
def ascii_clean(r: str) -> str:
return r.encode('ascii', 'ignore').decode('ascii')
def name_clean(r: str) -> str:
return re.sub(r'[^a-zA-Z0-9]', '', r)
def name_fix_keepspace(name_: str) -> str:
# Similar to name_fix but keeps spaces.
return re.sub(r'[^a-zA-Z0-9 ]', '', name_.replace('-', '_')).strip()
def name_fix_no_ext(name_: str) -> str:
return os.path.splitext(name_)[0]
def name_fix_snake_to_pascal(name: str) -> str:
return ''.join(word.capitalize() for word in name.split('_'))
def snake_case(name: str) -> str:
s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name)
return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower()
def name_split(name: str) -> tuple[str, str]:
parts = name.split('.')
if len(parts) > 1:
return parts[0], '.'.join(parts[1:])
return name, ""
def cmd_line_args_parser(text: str) -> list[str]:
# A simple parser, might need more robust solution for complex cases
import shlex
return shlex.split(text)
def text_remove_quotes(text: str) -> str:
return re.sub(r'["\'].*?["\']', '', text)
def check_exists_outside_quotes(text: str, items: list[str]) -> bool:
# This is a simplified implementation. A full implementation would require
# more complex parsing to correctly identify text outside quotes.
cleaned_text = text_remove_quotes(text)
for item in items:
if item in cleaned_text:
return True
return False
def is_int(text: str) -> bool:
return text.isdigit()
def is_upper_text(text: str) -> bool:
return text.isupper() and text.isalpha()
def multiline_to_single(text: str) -> str:
return text.replace('\n', '\\n').replace('\r', '')
def split_smart(t: str, delimiter_: str) -> list[str]:
# This is a placeholder, a smart split would need to handle quotes and escapes
return t.split(delimiter_)
def version(text_: str) -> int:
# Converts version strings like "v0.4.36" to 4036 or "v1.4.36" to 1004036
match = re.match(r'v?(\d+)\.(\d+)\.(\d+)', text_)
if match:
major, minor, patch = int(match.group(1)), int(match.group(2)), int(match.group(3))
if major == 0:
return minor * 100 + patch
else:
return major * 1000000 + minor * 100 + patch
return 0
def format_rfc1123(dt: datetime) -> str:
return dt.strftime('%a, %d %b %Y %H:%M:%S GMT')
def to_array(r: str) -> list[str]:
if ',' in r:
return [item.strip() for item in r.split(',')]
return [item.strip() for item in r.splitlines() if item.strip()]
def to_array_int(r: str) -> list[int]:
return [int(item) for item in to_array(r) if item.isdigit()]
def to_map(mapstring: str, line: str, delimiter_: str = ' ') -> dict[str, str]:
# This is a simplified implementation. The VLang version is more complex.
# It assumes a space delimiter for now.
keys = [k.strip() for k in mapstring.split(',')]
values = line.split(delimiter_)
result = {}
val_idx = 0
for key in keys:
if key == '-':
val_idx += 1
continue
if val_idx < len(values):
result[key] = values[val_idx]
val_idx += 1
return result