#!/usr/bin/env python3 import re, argparse from os import path prog_name = "Zittrigsubersetzer (ZUS)" prog_version = "0.1.0" class Rule: def __init__(self, pre, post, lc): self.pre = pre self.post = post self.lc = lc def sub(self, text): try: return re.sub(self.pre, self.post, text, \ flags=re.IGNORECASE) except: print(f"error: messed up rule on line {self.lc}") print(f"\t pre: {self.pre}\n\tpost: {self.post}") raise class RuleSet: def __init__(self): self.rules = list() def add_rule(self, pre, post, lc): self.rules.append(Rule(pre, post, lc)) def load(self, fd): for i, line in enumerate(fd): line = re.sub("#.*$", "", line) # strip comments line = line.strip() # strip whitespace if not line: continue try: (pre, post) = line.split("//") pre = pre.strip() post = post.strip() except ValueError: print(f"error: shit on line {i + 1}") raise # raise raise zittrigmann self.add_rule(pre, post, i + 1) return ruleset def translate(self, text): text = text.upper() for rule in self.rules: text = rule.sub(text) return text def translate_debug(self, text): text = text.upper() print(text) for i, rule in enumerate(self.rules): before = text after = rule.sub(before) if before == after: continue else: print(f"(rule {i:2d}: s/{rule.pre}/{rule.post}/)") print(after) text = after return text def mode_normal(args, ruleset): while True: try: text = input() if args.debug: print(ruleset.translate_debug(text)) else: print(ruleset.translate(text)) except (EOFError, KeyboardInterrupt): exit(0) def mode_test(args, ruleset): longest_input = 3 table = list() with open(args.tests, "r", encoding="UTF-8") as fd: for test in fd: test = re.sub("#.*$", "", test) test = test.strip() if not test: continue if len(test) > longest_input: longest_input = len(test) output = ruleset.translate(test) table.append((test, output)) for (input, output) in table: input = input.ljust(longest_input, " ") print(f"{input} {output}") if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument("-v", "--version", action="store_true", help="print version") parser.add_argument("-D", "--debug", action="store_true", \ help="be more verbose (for debugging)") parser.add_argument("-R", "--ruleset", \ help="path to file with the rules") parser.add_argument("-T", "--tests", help="path to the tests file") args = parser.parse_args() if args.version: print(f"{prog_name} {prog_version}") exit(0) if not args.ruleset: dirname = path.dirname(path.realpath(__file__)) args.ruleset = path.join(dirname, "rules.txt") ruleset = RuleSet() with open(args.ruleset, "r", encoding="UTF-8") as fd: ruleset.load(fd) if args.tests: mode_test(args, ruleset) else: mode_normal(args, ruleset)