Files
PythonLib/pythonlib/formats/rebirth/text_util.py
2024-12-05 19:49:39 -05:00

134 lines
3.2 KiB
Python

import re
import string
NAMES = {
"Veigue": 1,
"Mao": 2,
"Eugene": 3,
"Annie": 4,
"Tytree": 5,
"Hilda": 6,
"Claire": 7,
"Agarte": 8,
"Annie (NPC)": 9,
"Leader": 0x1FFF,
}
COLORS = {
"Blue": 1,
"Red": 2,
"Purple": 3,
"Green": 4,
"Cyan": 5,
"Yellow": 6,
"White": 7,
"Grey": 8,
"Black": 9,
}
ITALICS = {
"/Italic": 0,
"Italic": 10,
}
TAGS = {
"nl": 0x1,
"cr": 0x2,
"var": 0x4,
"color": 0x5,
"scale": 0x6,
"speed": 0x7,
"italic": 0x8,
"nmb": 0x9,
"ptr": 0xA,
"name": 0xB,
"item": 0xC,
"icon": 0xD,
"font": 0xE,
"voice": 0xF,
"unk13": 0x13,
"unk14": 0x14,
"unk15": 0x15,
"unk16": 0x16,
"unk17": 0x17,
"unk18": 0x18,
"unk19": 0x19,
"unk1A": 0x1A,
}
FRIENDLY_TAGS = dict()
FRIENDLY_TAGS.update(NAMES)
FRIENDLY_TAGS.update(COLORS)
FRIENDLY_TAGS.update(ITALICS)
INDENT_CHAR = " "
COMMON_TAG = r"(<[\w/]+:?\w+>)"
HEX_TAG = r"(\{[0-9A-F]{2}\})"
PRINTABLE_CHARS = "".join(
(string.digits, string.ascii_letters, string.punctuation, " ")
)
def indent_lines(lines: list[str], level: int) -> list[str]:
new_lines = list()
for line in lines:
new_lines.append(f"{INDENT_CHAR * level}{line}")
return new_lines
def indent_line(line: str, level: int) -> str:
return f"{INDENT_CHAR * level}{line}"
def text_to_cstr(text: str, is_name: bool = False) -> str:
output = ""
multi_regex = HEX_TAG + "|" + COMMON_TAG + r"|(\n)" + r"|(ー)"
tokens = [sh for sh in re.split(multi_regex, text) if sh]
for token in tokens:
# Hex literals
if re.match(HEX_TAG, token):
output += f" \\x{int(token[1:3], 16):02X}"
# Tags
elif re.match(COMMON_TAG, token):
tag, param, *_ = token[1:-1].split(":") + [None]
# (In)Sanity check
if "unk" in tag.lower():
raise ValueError(
f"Don't use sce tags, makes no sense!\nProblem text -> {text}"
)
if param is not None:
param_bytes = int(param, 16).to_bytes(4, byteorder="little")
raw = ",".join([f"{b:02X}" for b in param_bytes])
output += f" {tag.upper()}({raw}) "
else:
if is_name and tag in NAMES:
ntag = tag.replace("(", "").replace(")", "")
output += f" NAME({ntag.upper()}) "
elif tag in TAGS:
output += f'"\\x{TAGS[tag]:02X}"'
elif tag in FRIENDLY_TAGS:
if tag == "/Italic":
output += " NO_ITALIC "
else:
output += f" {tag.upper()} "
elif token == "\n":
output += " NL\n"
elif token == "":
output += " EM_DASH "
else:
if is_name:
if token == "&":
output += '" and "'
else:
names = [f'NAME("{x}")' for x in token.split("&")]
output += '" and "'.join(names)
else:
output += f'"{token}"'
return output.strip()