import re, os txt = open(r"C:\Users\29452\AppData\Local\Temp\opencode\decoded\Fonts.dat.txt", encoding="latin1").read() # tokenize blocks def parse_block(s, i): # s[i] should be at '{' assert s[i] == '{' i += 1 entries = [] # (name, value, childidx) children = [] cur_name = None while i < len(s): # skip whitespace while i < len(s) and s[i] in ' \t\r\n': i += 1 if i >= len(s): break if s[i] == '}': return entries, i+1 # read a name m = re.match(r'[A-Za-z_#][A-Za-z0-9_#]*', s[i:]) if m: name = m.group(0) i += len(name) while i < len(s) and s[i] in ' \t\r\n': i += 1 if i < len(s) and s[i] == '=': i += 1 while i < len(s) and s[i] in ' \t\r\n': i += 1 if i < len(s) and s[i] == '"': j = i+1 while j < len(s) and s[j] != '"': j += 1 val = s[i+1:j] i = j+1 else: m2 = re.match(r'[^\s{}]+', s[i:]) val = m2.group(0) if m2 else '' i += len(val) entries.append((name, val)) elif i < len(s) and s[i] == '{': sub, i = parse_block(s, i) children.append((name, sub)) entries.append((name, sub)) else: entries.append((name, '')) else: i += 1 return entries, i # find top-level Font blocks blocks = [] for m in re.finditer(r'\bFont\b\s*\{', txt): start = txt.index('{', m.start()) ent, _ = parse_block(txt, start) blocks.append(ent) print("num Font blocks:", len(blocks)) for b in blocks: d = dict((k, v) for k, v in b if k in ('Name','Language','Texture','#Texture','SpaceWidth','LineDistance','CharDistance')) langs = [v for k, v in b if k == 'Language'] texs = [v for k, v in b if k in ('Texture', '#Texture')] chars = [c for k, c in b if k == 'Char'] print("Font Name=%s langs=%s textures=%s #char=%d" % (d.get('Name'), langs, texs, len(chars))) # print rect for 'e' in first block def charmap(block): cm = {} for k, c in block: if k == 'Char': cd = dict((k2, v2) for k2, v2 in c) cm[cd.get('Code')] = (int(cd.get('X1',0)), int(cd.get('Y1',0)), int(cd.get('X2',0)), int(cd.get('Y2',0))) return cm for bi, b in enumerate(blocks): cm = charmap(b) for ch in ['e','a','o','A',' ']: if ch in cm: print(f"block{bi} '{ch}' -> {cm[ch]}")