]> gitweb.fperrin.net Git - gen-quickdic.git/blob - XMLittre_to_tab_separated
GCIDE conversion
[gen-quickdic.git] / XMLittre_to_tab_separated
1 #!/usr/bin/python3
2
3 from glob import glob
4 from lxml import etree
5 import re
6 from copy import deepcopy
7
8 class MassageLink(etree.XSLTExtension):
9     def execute(self, context, self_node, input_node, output_parent):
10         link = etree.Element("a")
11
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()
16         else:
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)
21
22 xslt_entree = etree.XSLT(etree.parse("XMLittre-entree.xslt"),
23                          extensions={("xmlittre", "massagelink"): MassageLink()})
24
25 class Parser:
26     def __init__(self):
27         self.entrees = {}
28
29     def parse_file(self, fname):
30         fxml = etree.parse(fname)
31         root = fxml.getroot()
32         for entree in root.getchildren():
33             assert entree.tag == "entree"
34             terme = entree.attrib["terme"]
35             termes, sous_titre = massage_terme(terme)
36
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]
44
45             if termes not in self.entrees:
46                 self.entrees[termes] = []
47
48             self.entrees[termes].append((sous_titre, entree_text))
49
50     def writeout(self, fname):
51         with open(fname, "w") as f:
52             for termes in self.entrees:
53                 f.write(", ".join(termes))
54                 f.write("\t")
55                 if len(self.entrees[termes]) > 1:
56                     for i, (sous_titre, entree) in enumerate(self.entrees[termes]):
57                         if sous_titre:
58                             f.write(f"<h2>{i+1}. {sous_titre}</h2>")
59                         else:
60                             f.write(f"<h2>{i+1}. {','.join(termes)}</h2>")
61                         f.write(entree)
62                 else:
63                     sous_titre, entree = self.entrees[termes][0]
64                     if sous_titre:
65                         f.write(f"<h2>{sous_titre}</h2>")
66                     f.write(entree)
67                 f.write("\n")
68
69 def massage_terme(terme):
70     vedettes = re.split(r"[ ,](?:[A-Z]?[a-zéêèàç-]+[ ,']*)+", terme)
71     vedettes = list(filter(None, vedettes))
72     sous_terme = None
73     if len(vedettes) > 1:
74         sous_terme = terme
75     retval = []
76     for v in vedettes:
77         m = re.match(r"^(.*) \((.*)\)$", v)
78         if m:
79             if m.group(2)[-1] == "'":
80                 space = ""
81             else:
82                 space = " "
83             v = f"{m.group(2)}{space}{m.group(1)}"
84             if sous_terme:
85                 sous_terme = sous_terme.replace(m.group(0), v)
86         formes = v.split(",")
87         if len(formes) > 1:
88             v = formes[0]
89             sous_terme = terme
90         retval.append(v)
91     return (tuple(retval), sous_terme)
92
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")
106
107 def main():
108     p = Parser()
109     for fname in sorted(glob("../xmlittre-data/?.xml")):
110         print(f"Running on {fname}")
111         p.parse_file(fname)
112     p.writeout("XMLittre.tab_separated")
113
114 if __name__ == "__main__":
115     main()