#! /usr/bin/python3 # Last edited on 2026-06-30 01:56:55 by stolfi # -*- coding: utf-8 -*- # Reads from stdin a transcriptionon of the SBJ in simplified hanzi, # with one recipe per line. Removes form each recipe the fields that # seem to have been systematically omitted from the Starred Parags # section of the VMS. # # Assumes that each field to be omitted has tags surrounded in # ideographic brackets '[]' and is terminated by ideographic # period '。'. Allows and preerves a locus ID in "<...>" at the # beginning of each line. # # For now, these fields are the [Flavor], [Other name], and [Provenance]. # # Also replaces 主治 by just 主. # # Also removes all #-comments and blank lines, but adds a line "# -*- # coding: utf-8 -*-" and a warning to not edit this file. import sys, re from sys import stdout as out, stderr as err, stdin as inp from error_funcs import file_line_error def main(): inp.reconfigure(encoding='utf-8') out.reconfigure(encoding='utf-8') nread = 0 out.write("# -*- coding: utf-8 -*-\n") out.write("# Generated by {remove_vms_omitted_fields_from_sbj.py}\n") out.write("# Edit the source, not this file.\n") for line in inp: nread += 1 process_line(nread, line) out.flush() return # ---------------------------------------------------------------------- def process_line(nread, line): def data_error(msg): nonlocal nread; file_line_error("stdin", nread, msg, line) # :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: def excise(name, pat, max_length, tx): # Removes from {tx} any substring that matches {pat}. # Fails if the substring is too long. # The removed stibstrings are written out as #-comments. # Returns the cleaned text. while ( m:= re.search(pat, tx) ) is not None: field = m.group(0) if len(field) > max_length: data_error(f"[{name}] field {field!r} is too long") if field[-1] != '。': data_error(f"[{name}] field {field!r} is missing the period") i0 = m.start(0); i1 = m.end(0) tx = tx[0:i0] + tx[i1:] out.write(f"# {name} = {field!r}\n") return tx # :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: # Remove end-of-line, leading and trailing blanks: line = line.strip() # Discard comments and blank lines: if re.match(r"[ ]*([#]|$)", line): return # Separate recipe ID, if any: if ( m := re.fullmatch(r" *<([^<>]*)> *(.*)", line) ) is not None: loc = m.group(1); text = m.group(2) else: loc = None; text = line # # Remove Chinese punctuation: # text = re.sub(r"[:[]()、,。; ]", "", text) # Add a final Chinese period to simplify matching: text += "。" # Normalize the "mainly for" keyword: text = re.sub(r"主治", "主", text) # Locate and remove the "Flavor" fields: text = excise("Flavor", r"[[]味[^主。]*[。]?", 10, text) # Locate and remove the "Provenance" fields: text = excise("Provenance", r"[[]生[^主。]*[。]?", 12, text) # Locate and remove the "Other name" fields: # Note: there is one alias that has 主 that is not a keyword. text = excise("Alias", r"[[]一名[^生。]*[。]?", 10, text) if loc is not None: out.write(f"<{loc}> ") out.write(text) out.write("\n") return # ---------------------------------------------------------------------- main()