Download code/src/preprocessing/build_mzl_abz_map.py from savastakan/hitit-cuneiform-ocr: direct link, hf CLI and curl.
- Browser
- Download file 3.9 kB
-
https://huggingface.co/savastakan/hitit-cuneiform-ocr/resolve/main/code/src/preprocessing/build_mzl_abz_map.py
- Command line
-
hf download hf://savastakan/hitit-cuneiform-ocr/code/src/preprocessing/build_mzl_abz_map.py
-
curl -L -o build_mzl_abz_map.py https://huggingface.co/savastakan/hitit-cuneiform-ocr/resolve/main/code/src/preprocessing/build_mzl_abz_map.py
3.9 kB
| #!/usr/bin/env python3 | |
| """Build MZL ↔ ABZ mapping from Oracc OSL (osl.asl). | |
| Input: /tmp/osl/00lib/osl.asl (Oracc Global Sign List, CC0) | |
| Output: JSON with: | |
| - mzl_to_abz: MZL_num → ABZ_num | |
| - mzl_to_sign: MZL_num → canonical sign name | |
| - abz_to_sign: ABZ_num → canonical sign name | |
| - sign_to_mzl: sign → MZL_num | |
| - sign_to_abz: sign → ABZ_num | |
| """ | |
| import json, re, argparse | |
| from pathlib import Path | |
| def parse_asl(path): | |
| """Parse @sign ... @end sign blocks from osl.asl.""" | |
| blocks = [] | |
| cur = None | |
| with open(path) as f: | |
| for line in f: | |
| line = line.rstrip() | |
| if line.startswith('@sign '): | |
| name = line[6:].strip() | |
| cur = {'sign': name, 'lists': {}, 'uname': None, 'ucun': None} | |
| elif line.startswith('@sign- '): | |
| cur = None # skip deprecated signs | |
| elif cur is not None and line.startswith('@list\t'): | |
| token = line[6:].strip() | |
| # token format: "MZL001" or "ABZ123" or "ABZ123v" etc | |
| m = re.match(r'^([A-Z]+)(\S+)$', token) | |
| if m: | |
| lst, num = m.group(1), m.group(2) | |
| # Prefer first occurrence per list | |
| if lst not in cur['lists']: | |
| cur['lists'][lst] = num | |
| elif cur is not None and line.startswith('@uname\t'): | |
| cur['uname'] = line[7:].strip() | |
| elif cur is not None and line.startswith('@ucun\t'): | |
| cur['ucun'] = line[6:].strip() | |
| elif line.startswith('@end sign'): | |
| if cur and cur['sign']: | |
| blocks.append(cur) | |
| cur = None | |
| return blocks | |
| def main(): | |
| ap = argparse.ArgumentParser() | |
| ap.add_argument('--osl', default='/tmp/osl/00lib/osl.asl') | |
| ap.add_argument('--output', required=True) | |
| args = ap.parse_args() | |
| blocks = parse_asl(args.osl) | |
| print(f"Parsed {len(blocks)} signs") | |
| mzl_to_abz = {} | |
| mzl_to_sign = {} | |
| abz_to_sign = {} | |
| sign_to_mzl = {} | |
| sign_to_abz = {} | |
| for b in blocks: | |
| sign = b['sign'] | |
| mzl = b['lists'].get('MZL') | |
| # In Oracc OSL the Borger list appears as ABZL (Assyrisch-Babylonische | |
| # Zeichenliste); our codebase historically calls it "ABZ", so treat | |
| # ABZL as the ABZ source. | |
| abz = b['lists'].get('ABZL') or b['lists'].get('ABZ') | |
| if mzl: | |
| # MZL numbers may have leading zeros and optional 'a','b','v' suffixes | |
| # strip leading zeros of pure-numeric prefix | |
| mzl_clean = re.sub(r'^0+', '', mzl) or '0' | |
| mzl_to_sign[mzl] = sign | |
| mzl_to_sign[mzl_clean] = sign # also with stripped | |
| sign_to_mzl[sign] = mzl | |
| if abz: | |
| abz_clean = re.sub(r'^0+', '', abz) or '0' | |
| mzl_to_abz[mzl] = abz | |
| mzl_to_abz[mzl_clean] = abz | |
| if abz: | |
| abz_to_sign[abz] = sign | |
| abz_to_sign[re.sub(r'^0+', '', abz) or '0'] = sign | |
| sign_to_abz[sign] = abz | |
| print(f"MZL entries: {len(sign_to_mzl)}") | |
| print(f"ABZ entries: {len(sign_to_abz)}") | |
| print(f"MZL→ABZ mappings: {len(mzl_to_abz)}") | |
| # Report a few examples | |
| for mzl in ['MZL001', 'MZL839', 'MZL252', 'MZL090']: | |
| if mzl in mzl_to_sign: | |
| print(f" {mzl} = {mzl_to_sign[mzl]} (ABZ: {mzl_to_abz.get(mzl, '?')})") | |
| out = { | |
| 'mzl_to_abz': mzl_to_abz, | |
| 'mzl_to_sign': mzl_to_sign, | |
| 'abz_to_sign': abz_to_sign, | |
| 'sign_to_mzl': sign_to_mzl, | |
| 'sign_to_abz': sign_to_abz, | |
| 'n_signs_total': len(blocks), | |
| } | |
| Path(args.output).parent.mkdir(parents=True, exist_ok=True) | |
| with open(args.output, 'w') as f: | |
| json.dump(out, f, indent=1, ensure_ascii=False) | |
| print(f"Saved → {args.output}") | |
| if __name__ == '__main__': | |
| main() | |