import os import re from .tree import load_json, dump_json def load_md(p): with open(p, 'r', encoding='utf-8') as f: return f.read() def dump_md(p, str): with open(p, 'w', encoding='utf-8') as f: return f.write(str) class MathWalker: def __init__(self, root) -> None: self.root = root def walk(self): for base, dirs, files in os.walk(self.root): config_path = os.path.join(base, 'config.json') if os.path.exists(config_path): config = load_json(config_path) if config.get('export') is not None: self.parse_math(base, config) def parse_math(self, base, config): for export in config['export']: export_path = os.path.join(base, export) export_obj = load_json(export_path) source_origin = export_obj['source'] if source_origin.find('.md.md') >= 0: source_origin = source_origin[:len(source_origin)-3] source_path = os.path.join(base, source_origin) md = load_md(source_path) new_md = [] math_ctx = { "enter": False, "chars": [] } count = len(md) i = 0 has_enter_math = False while i < count: c = md[i] if c == '$': if math_ctx['enter']: j = 0 chars = math_ctx['chars'] length = len(chars) while j < length: cc = chars[j] if cc == '_': next_c = chars[j+1] if next_c == '{': subs = [] cursor = 2 next_c = chars[j+cursor] while next_c != '}': subs.append(next_c) cursor += 1 next_c = chars[j+cursor] sub = ''.join(subs) new_md.append(f'{sub}') j += cursor else: new_md.append(f'{next_c}') j += 1 elif cc == '^': next_c = chars[j+1] if next_c == '{': subs = [] cursor = 2 next_c = chars[j+cursor] while next_c != '}': subs.append(next_c) cursor += 1 next_c = chars[j+cursor] sub = ''.join(subs) new_md.append(f'{sub}') j += cursor else: new_md.append(f'{next_c}') j += 1 else: new_md.append(cc) j += 1 math_ctx['enter'] = False math_ctx['chars'] = [] else: math_ctx['enter'] = True math_ctx['chars'] = [] has_enter_math = True else: if math_ctx['enter']: math_ctx['chars'].append(c) else: new_md.append(c) i += 1 source_new_relative = source_origin+".md" source_path_new = os.path.join(base, source_new_relative) if has_enter_math: dump_md(source_path_new, ''.join(new_md)) export_obj['source'] = source_new_relative dump_json(export_path, export_obj, True, True)