6 from copy import deepcopy
8 class MassageLink(etree.XSLTExtension):
9 def execute(self, context, self_node, input_node, output_parent):
10 link = etree.Element("a")
12 ref = input_node.attrib["ref"]
13 term = re.match("^[^#. ]+", ref).group(0)
14 if input_node.text == "ce mot":
15 link.text = term.lower()
17 link.text = input_node.text.lower()
18 link.attrib["style"] = "font-variant: small-caps"
19 link.attrib["href"] = f"q://d?&{term.upper()}"
20 output_parent.append(link)
22 xslt_entree = etree.XSLT(etree.parse("XMLittre-entree.xslt"),
23 extensions={("xmlittre", "massagelink"): MassageLink()})
29 def parse_file(self, fname):
30 fxml = etree.parse(fname)
32 for entree in root.getchildren():
33 assert entree.tag == "entree"
34 terme = entree.attrib["terme"]
35 termes, sous_titre = massage_terme(terme)
37 entree_html = xslt_entree(entree)
38 entree_text = str(entree_html)
39 # entree_text = entree_text.replace("\n", "")
40 entree_text = re.sub(r"\s+|\n", " ", entree_text)
41 assert entree_text.startswith("<div>") and entree_text.endswith("</div>")
42 entree_text = entree_text[5:]
43 entree_text = entree_text[:-6]
45 if termes not in self.entrees:
46 self.entrees[termes] = []
48 self.entrees[termes].append((sous_titre, entree_text))
50 def writeout(self, fname):
51 with open(fname, "w") as f:
52 for termes in self.entrees:
53 f.write(", ".join(termes))
55 if len(self.entrees[termes]) > 1:
56 for i, (sous_titre, entree) in enumerate(self.entrees[termes]):
58 f.write(f"<h2>{i+1}. {sous_titre}</h2>")
60 f.write(f"<h2>{i+1}. {','.join(termes)}</h2>")
63 sous_titre, entree = self.entrees[termes][0]
65 f.write(f"<h2>{sous_titre}</h2>")
69 def massage_terme(terme):
70 vedettes = re.split(r"[ ,](?:[A-Z]?[a-zéêèàç-]+[ ,']*)+", terme)
71 vedettes = list(filter(None, vedettes))
77 m = re.match(r"^(.*) \((.*)\)$", v)
79 if m.group(2)[-1] == "'":
83 v = f"{m.group(2)}{space}{m.group(1)}"
85 sous_terme = sous_terme.replace(m.group(0), v)
91 return (tuple(retval), sous_terme)
93 def test_massage_terme():
94 assert massage_terme("ÉTANCHE") == (("ÉTANCHE",), None)
95 assert massage_terme("ÉREINTÉ, ÉE") == (("ÉREINTÉ",), "ÉREINTÉ, ÉE")
96 assert massage_terme("CLÉ ou CLEF") == (("CLÉ", "CLEF"), "CLÉ ou CLEF")
97 assert massage_terme("HÉMORRAGIE, suivant le dictionnaire de l'Académie, mais mieux HÉMORRHAGIE") == \
98 (("HÉMORRAGIE", "HÉMORRHAGIE"), "HÉMORRAGIE, suivant le dictionnaire de l'Académie, mais mieux HÉMORRHAGIE")
99 assert massage_terme("QUINDÉCEMVIRS ou mieux QUINDÉCIMVIRS puisque le latin est quindecimviri") \
100 == (("QUINDÉCEMVIRS", "QUINDÉCIMVIRS"), "QUINDÉCEMVIRS ou mieux QUINDÉCIMVIRS puisque le latin est quindecimviri")
101 assert massage_terme("DÉVOUEMENT, ou comme quelques-uns écrivent, dit l'Académie, DÉVOÛMENT") == (("DÉVOUEMENT", "DÉVOÛMENT"), "DÉVOUEMENT, ou comme quelques-uns écrivent, dit l'Académie, DÉVOÛMENT")
102 assert massage_terme("HÉMA- ou HÉMO- ou HÉMATO-") == (("HÉMA-", "HÉMO-", "HÉMATO-"), "HÉMA- ou HÉMO- ou HÉMATO-")
103 assert massage_terme("DIVINIS (A)") == (("A DIVINIS",), None)
104 assert massage_terme("BORDEAUX (VIN DE) ou vulgairement et en termes de commerce BORDEAUX") == \
105 (("VIN DE BORDEAUX", "BORDEAUX"), "VIN DE BORDEAUX ou vulgairement et en termes de commerce BORDEAUX")
109 for fname in sorted(glob("../xmlittre-data/?.xml")):
110 print(f"Running on {fname}")
112 p.writeout("XMLittre.tab_separated")
114 if __name__ == "__main__":