From 9d38c4022e376158e57a7ba070cfaf45f8a8f1c2 Mon Sep 17 00:00:00 2001 From: Empiriker Date: Tue, 19 Sep 2023 21:15:24 +0200 Subject: [PATCH 1/7] Add languages.json and its generator script for the German Wiktionary. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is no authorative list of languages in the German Wiktionary within the dump file itself. The list of languages is generated from the page "Hilfe:Sprachkürzel" and is probably incomplete. Until another source is found, this is the best we can do. The list will then need to be manually completed. --- usertools/de_language_data.py | 72 +++++ wiktextract/data/de/languages.json | 490 +++++++++++++++++++++++++++++ 2 files changed, 562 insertions(+) create mode 100644 usertools/de_language_data.py create mode 100644 wiktextract/data/de/languages.json diff --git a/usertools/de_language_data.py b/usertools/de_language_data.py new file mode 100644 index 00000000..40dd2cbb --- /dev/null +++ b/usertools/de_language_data.py @@ -0,0 +1,72 @@ +# Export German Wiktionary language data to JSON. +# +# Usage: +# +# python language_data.py de dewiktionary_dump_file [--languages languages_output_file] + +import argparse +from wikitextprocessor import Wtp +from wiktextract.config import WiktionaryConfig +from wiktextract.wxr_context import WiktextractContext +from wiktextract.page import clean_node +from wikitextprocessor.dumpparser import process_dump +from wikitextprocessor import NodeKind, WikiNode + +import json + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description="Export Wiktionary language data to JSON" + ) + parser.add_argument("lang_code", type=str, help="Dump file language code") + parser.add_argument("dump", type=str, help="Wiktionary xml dump file path") + parser.add_argument( + "--languages", + type=str, + default="languages.json", + help="Language data output file path", + ) + args = parser.parse_args() + wxr = WiktextractContext(Wtp(lang_code=args.lang_code), WiktionaryConfig()) + + wxr = WiktextractContext( + Wtp( + lang_code=args.lang_code, db_path="wikt-db_de_language_data_temp.db" + ), + WiktionaryConfig(), + ) + help_ns_id = wxr.wtp.NAMESPACE_DATA["Help"]["id"] + template_ns_id = wxr.wtp.NAMESPACE_DATA["Template"]["id"] + process_dump(wxr.wtp, args.dump, {help_ns_id, template_ns_id}) + + # The page 'Hilfe:Sprachkürzel seems to be the only central collection of + # language codes and their German expansions. We will use this until we find + # perhaps a more authoritative source. + sprachkuerzel = wxr.wtp.get_page("Hilfe:Sprachkürzel") + + wxr.config.word = sprachkuerzel.title + wxr.wtp.start_page(sprachkuerzel.title) + tree = wxr.wtp.parse( + sprachkuerzel.body, + pre_expand=True, + ) + + languages = {} + for node in filter(lambda n: isinstance(n, WikiNode), tree.children): + if node.kind != NodeKind.LEVEL3: + continue + + for table_row in node.find_child_recursively(NodeKind.TABLE_ROW): + third_row_content = table_row.children[2].children[0] + if ( + isinstance(third_row_content, str) + or third_row_content.kind != NodeKind.TEMPLATE + ): + continue + lang_code = third_row_content.template_name + + languages[lang_code] = [clean_node(wxr, None, third_row_content)] + + with open(args.languages, "w", encoding="utf-8") as fout: + json.dump(languages, fout, indent=2, ensure_ascii=False, sort_keys=True) diff --git a/wiktextract/data/de/languages.json b/wiktextract/data/de/languages.json new file mode 100644 index 00000000..bc0151f2 --- /dev/null +++ b/wiktextract/data/de/languages.json @@ -0,0 +1,490 @@ +{ + "MHA": ["modernes Hocharabisch"], + "aa": ["Afar"], + "aae": ["Arbëresh"], + "ab": ["Abchasisch"], + "abe": ["West-Abenaki"], + "abq": ["Abasinisch"], + "ace": ["Acehnesisch"], + "acf": ["Antillen-Kreolisch"], + "acw": ["Hijazi-Arabisch"], + "ady": ["Adygeisch"], + "ae": ["Avestisch"], + "af": ["Afrikaans"], + "agf": ["Arguni"], + "agj": ["Argobba"], + "aie": ["Amara"], + "ain": ["Ainu"], + "ak": ["Akan"], + "akg": ["Anakalangu"], + "akk": ["Akkadisch"], + "akz": ["Alabama"], + "ale": ["Aleutisch"], + "aln": ["Gegisch"], + "alp": ["Alune"], + "alq": ["Algonkin"], + "als": ["Alemannisch"], + "alt": ["Altaisch"], + "am": ["Amharisch"], + "amk": ["Ambai"], + "amu": ["Amuzgo"], + "an": ["Aragonesisch"], + "ang": ["Altenglisch"], + "apc": ["Levantinisches Arabisch"], + "apw": ["West-Apache"], + "ar": ["Arabisch"], + "arc": ["Aramäisch"], + "ari": ["Arikara"], + "arn": ["Mapudungun"], + "arw": ["Arawak"], + "ary": ["Marokkanisch-Arabisch"], + "arz": ["Ägyptisch-Arabisch"], + "as": ["Assamesisch"], + "asb": ["Assiniboine"], + "ast": ["Asturisch"], + "atv": ["Nordaltaisch"], + "aua": ["Asumboa"], + "aud": ["Anutisch"], + "av": ["Awarisch"], + "ay": ["Aymara"], + "az": ["Aserbaidschanisch"], + "azb": ["Südaserbaidschanisch"], + "azd": ["Östliches Durango-Nahuatl"], + "azj": ["Nordaserbaidschanisch"], + "ba": ["Baschkirisch"], + "baa": ["Babatana"], + "bal": ["Belutschi"], + "ban": ["Balinesisch"], + "bar": ["Bairisch"], + "bat": ["Altpreußisch"], + "bbc": ["Batak Toba"], + "bci": ["Baule"], + "bcl": ["Zentral-Bikolano"], + "bcm": ["Banoni"], + "bde": ["Bade"], + "be": ["Weißrussisch"], + "bem": ["Bemba"], + "ber": ["Berbersprache"], + "bg": ["Bulgarisch"], + "bh": ["Bihari"], + "bhw": ["Biak"], + "bi": ["Bislama"], + "bjn": ["Banjar"], + "bla": ["Blackfoot"], + "bm": ["Bambara"], + "bmg": ["Bangi"], + "bn": ["Bengalisch"], + "bnd": ["Banda"], + "bo": ["Tibetisch"], + "bpy": ["Bishnupriya"], + "br": ["Bretonisch"], + "bs": ["Bosnisch"], + "bty": ["Bobot"], + "bua": ["Burjatisch"], + "bug": ["Buginesisch"], + "bxr": ["Russisches Burjatisch"], + "bzg": ["Babuza"], + "ca": ["Katalanisch"], + "ccc": ["Chamicuro"], + "ce": ["Tschetschenisch"], + "ceb": ["Cebuano"], + "cel": ["Keltisch"], + "ch": ["Chamorro"], + "chc": ["Catawba"], + "chm": ["Mari"], + "cho": ["Choctaw"], + "chp": ["Chipewyan"], + "chr": ["Cherokee"], + "chy": ["Cheyenne"], + "ciw": ["Chippewa"], + "ckb": ["Sorani"], + "ckt": ["Tschuktschisch"], + "co": ["Korsisch"], + "com": ["Comanche"], + "cr": ["Cree"], + "crh": ["Krimtatarisch"], + "cri": ["Saotomensisches Kreol"], + "cro": ["Crow"], + "crs": ["Seselwa"], + "cs": ["Tschechisch"], + "csb": ["Kaschubisch"], + "ctu": ["Tumbalá-Chol"], + "cu": ["Altkirchenslawisch"], + "cv": ["Tschuwaschisch"], + "cy": ["Walisisch"], + "da": ["Dänisch"], + "dag": ["Dagbani"], + "dak": ["Dakota"], + "ddn": ["Dendi"], + "de": ["Deutsch"], + "dhv": ["Dehu"], + "diq": ["Dimli"], + "dlm": ["Dalmatisch"], + "dng": ["Dunganisch"], + "dob": ["Dobu"], + "dsb": ["Niedersorbisch"], + "dum": ["Mittelniederländisch"], + "dv": ["Maledivisch"], + "dz": ["Dzongkha"], + "ee": ["Ewe"], + "egl": ["Emilianisch"], + "egy": ["Ägyptisch"], + "el": ["Griechisch (Neu-)"], + "ems": ["Alutiiq"], + "en": ["Englisch"], + "enm": ["Mittelenglisch"], + "eo": ["Esperanto"], + "es": ["Spanisch"], + "ess": ["Sibirisch-Yupik"], + "esu": ["Zentral-Alaska-Yupik"], + "et": ["Estnisch"], + "eu": ["Baskisch"], + "ext": ["Extremadurisch"], + "fa": ["Persisch"], + "fan": ["Fang"], + "ff": ["Fulfulde"], + "fi": ["Finnisch"], + "fj": ["Fidschi"], + "fng": ["Fanagalo"], + "fo": ["Färöisch"], + "fon": ["Fon"], + "fr": ["Französisch"], + "frk": ["Altfränkisch"], + "fro": ["Altfranzösisch"], + "frp": ["Frankoprovenzalisch"], + "frr": ["Nordfriesisch"], + "fud": ["Futunisch"], + "fur": ["Friaulisch"], + "fy": ["Westfriesisch"], + "ga": ["Irisch"], + "gag": ["Gagausisch"], + "gan": ["Gan"], + "gay": ["Gayo"], + "gcf": ["Guadeloupe-Kreolisch"], + "gd": ["Schottisch-Gälisch"], + "gem": ["Urgermanisch"], + "gez": ["Ge’ez"], + "gha": ["Ghadames"], + "gil": ["Gilbertesisch"], + "gl": ["Galicisch"], + "glk": ["Gilaki"], + "gmh": ["Mittelhochdeutsch"], + "gml": ["Mittelniederdeutsch"], + "gn": ["Guaraní"], + "gnc": ["Guanche"], + "goh": ["Althochdeutsch"], + "got": ["Gotisch"], + "grc": ["Altgriechisch"], + "gsw": ["Schweizerdeutsch"], + "gu": ["Gujarati"], + "gv": ["Manx"], + "ha": ["Hausa"], + "hac": ["Gorani"], + "hak": ["Hakka"], + "haw": ["Hawaiianisch"], + "he": ["Hebräisch"], + "hi": ["Hindi"], + "hid": ["Hidatsa"], + "hif": ["Fiji Hindi"], + "hil": ["Hiligaynon"], + "hit": ["Hethitisch"], + "ho": ["Hiri Motu"], + "hr": ["Kroatisch"], + "hsb": ["Obersorbisch"], + "ht": ["Haitianisch"], + "hu": ["Ungarisch"], + "hy": ["Armenisch"], + "hz": ["Otjiherero"], + "ia": ["Interlingua"], + "iba": ["Iban"], + "id": ["Indonesisch"], + "ie": ["Interlingue"], + "ig": ["Igbo"], + "ik": ["Inupiaq"], + "ikt": ["Inuinnaqtun"], + "ilo": ["Ilokano"], + "inh": ["Inguschisch"], + "io": ["Ido"], + "is": ["Isländisch"], + "it": ["Italienisch"], + "iu": ["Inuktitut"], + "ja": ["Japanisch"], + "jbo": ["Lojban"], + "jv": ["Javanisch"], + "ka": ["Georgisch"], + "kaa": ["Karakalpakisch"], + "kab": ["Kabylisch"], + "kai": ["Karekare"], + "kaw": ["Kawi"], + "kbd": ["Kabardinisch"], + "kca": ["Chantisch"], + "kdr": ["Karaimisch"], + "kea": ["Kapverdisches Kreol"], + "kg": ["Kikongo"], + "khw": ["Khowar"], + "ki": ["Kikuyu"], + "kic": ["Kickapoo"], + "kj": ["Kuanyama"], + "kjh": ["Chakassisch"], + "kjj": ["Chinalugisch"], + "kk": ["Kasachisch"], + "kl": ["Grönländisch"], + "km": ["Kambodschanisch"], + "kmr": ["Kurmandschi"], + "kn": ["Kannada"], + "ko": ["Koreanisch"], + "koi": ["Komi-Permjakisch"], + "kok": ["Konkani"], + "kos": ["Kosraeanisch"], + "krc": ["Karatschai-Balkarisch"], + "krl": ["Karelisch"], + "ks": ["Kashmiri"], + "ksh": ["Kölsch"], + "ksk": ["Kansa"], + "ku": ["Kurdisch"], + "kum": ["Kumükisch"], + "kv": ["Komi"], + "kw": ["Kornisch"], + "ky": ["Kirgisisch"], + "kyh": ["Karok"], + "la": ["Latein"], + "lad": ["Ladino"], + "lb": ["Luxemburgisch"], + "lep": ["Lepcha"], + "lg": ["Luganda"], + "li": ["Limburgisch"], + "lij": ["Ligurisch"], + "liv": ["Livisch"], + "lkt": ["Lakota"], + "lld": ["Ladinisch"], + "lmo": ["Lombardisch"], + "ln": ["Lingala"], + "lo": ["Laotisch"], + "lt": ["Litauisch"], + "lv": ["Lettisch"], + "lzz": ["Lasisch"], + "mad": ["Maduresisch"], + "mak": ["Makassar"], + "mas": ["Maa"], + "mdf": ["Mokscha"], + "mg": ["Madagassisch"], + "mga": ["Mittelirisch"], + "mh": ["Marshallesisch"], + "mi": ["Maori"], + "mia": ["Miami-Illinois"], + "mic": ["Micmac"], + "min": ["Minangkabau"], + "mjy": ["Mohican"], + "mk": ["Mazedonisch"], + "ml": ["Malayalam"], + "mn": ["Mongolisch"], + "mnc": ["Mandschurisch"], + "mns": ["Mansisch"], + "moh": ["Mohawk"], + "mr": ["Marathi"], + "ms": ["Malaiisch"], + "mt": ["Maltesisch"], + "mus": ["Creek"], + "mxi": ["Mozarabisch"], + "my": ["Birmanisch"], + "myv": ["Ersja"], + "na": ["Nauruisch"], + "nah": ["Nahuatl"], + "nan": ["Min Nan"], + "nap": ["Neapolitanisch"], + "naq": ["Nama"], + "nb": ["Bokmål"], + "nch": ["Huastekisches Zentral-Nahuatl"], + "nci": ["Klassisches Nahuatl"], + "nd": ["Nord-Ndebele"], + "nds": ["Niederdeutsch"], + "ne": ["Nepalesisch"], + "new": ["Newari"], + "ng": ["Ndonga"], + "ngo": ["Ngoni"], + "nic": ["Dogon"], + "nl": ["Niederländisch"], + "nld": ["Flämisch"], + "nmn": ["ǃXóõ"], + "nn": ["Nynorsk"], + "no": ["Norwegisch"], + "nog": ["Nogaisch"], + "non": ["Altnordisch"], + "nov": ["Novial"], + "nqo": ["N'Ko"], + "nr": ["Süd-Ndebele"], + "nrf": ["Altnormannisch"], + "nso": ["Nord-Sotho"], + "nup": ["Nupe"], + "nv": ["Navajo"], + "ny": ["Chichewa"], + "obt": ["Altbretonisch"], + "oc": ["Okzitanisch"], + "oco": ["Altkornisch"], + "ofs": ["Altfriesisch"], + "oge": ["Altgeorgisch"], + "oj": ["Ojibwe"], + "om": ["Oromo"], + "omr": ["Altmarathi"], + "or": ["Oriya"], + "orv": ["Altostslawisch"], + "os": ["Ossetisch"], + "osa": ["Osage"], + "osx": ["Altsächsisch"], + "otk": ["Alttürkisch"], + "otw": ["Ottawa"], + "owl": ["Altwalisisch"], + "pa": ["Pandschabi"], + "pam": ["Kapampangan"], + "pap": ["Papiamentu"], + "pau": ["Palauisch"], + "paw": ["Pawnee"], + "pdc": ["Pennsylvaniadeutsch"], + "pdt": ["Plautdietsch"], + "peo": ["Altpersisch"], + "pi": ["Pali"], + "pih": ["Pitkern"], + "pis": ["Pijin"], + "pl": ["Polnisch"], + "pms": ["Piemontesisch"], + "pov": ["Guineabissauisches Kreol"], + "pox": ["Polabisch"], + "pqm": ["Malecite-Passamaquoddy"], + "pre": ["Principensisches Kreol"], + "prg": ["Prußisch"], + "pro": ["Altprovenzalisch/Altokzitanisch"], + "prs": ["Dari"], + "ps": ["Paschtu"], + "pt": ["Portugiesisch"], + "qka": ["Erzgebirgisch"], + "qu": ["Quechua"], + "qua": ["Quapaw"], + "quz": ["Cusco-Quechua"], + "raj": ["Rajasthani"], + "rap": ["Rapanui"], + "rm": ["Rätoromanisch"], + "rmq": ["Caló"], + "rmy": ["Vlax"], + "rn": ["Kirundi"], + "ro": ["Rumänisch"], + "rom": ["Romani"], + "ru": ["Russisch"], + "ruo": ["Istrorumänisch"], + "rup": ["Aromunisch"], + "ruq": ["Meglenorumänisch"], + "rw": ["Kinyarwanda"], + "ryu": ["Zentral-Okinawa"], + "sa": ["Sanskrit"], + "sac": ["Fox"], + "sah": ["Jakutisch"], + "sc": ["Sardisch"], + "scn": ["Sizilianisch"], + "sco": ["Scots"], + "sd": ["Sindhi"], + "se": ["Nordsamisch"], + "sg": ["Sango"], + "sga": ["Altirisch"], + "sgs": ["Schemaitisch"], + "sgw": ["Gurage"], + "sh": ["Serbokroatisch"], + "si": ["Singhalesisch"], + "sjd": ["Kildinsamisch"], + "sjn": ["Sindarin"], + "sjw": ["Shawnee"], + "sk": ["Slowakisch"], + "sl": ["Slowenisch"], + "sm": ["Samoanisch"], + "smi": ["Sami"], + "smn": ["Inarisamisch"], + "sn": ["Shona"], + "so": ["Somalisch"], + "sq": ["Albanisch"], + "sr": ["Serbisch"], + "srn": ["Sranantongo"], + "ss": ["Siswati"], + "st": ["Sesotho"], + "stq": ["Saterfriesisch"], + "su": ["Sundanesisch"], + "sux": ["Sumerisch"], + "sv": ["Schwedisch"], + "sva": ["Swanisch"], + "sw": ["Suaheli"], + "swb": ["Komorisch"], + "swg": ["Schwäbisch"], + "syr": ["Syrisch"], + "szl": ["Schlesisch (Polnisch)"], + "ta": ["Tamil"], + "tay": ["Atayal"], + "te": ["Telugu"], + "tet": ["Tetum"], + "tg": ["Tadschikisch"], + "tgw": ["Tagwana"], + "th": ["Thai"], + "ti": ["Tigrinya"], + "tk": ["Turkmenisch"], + "tl": ["Tagalog"], + "tlh": ["Klingonisch"], + "tli": ["Tlingit"], + "tn": ["Setswana"], + "to": ["Tongaisch"], + "tok": ["Toki Pona"], + "tpi": ["Tok Pisin"], + "tpn": ["Tupinambá"], + "tpw": ["Tupí"], + "tr": ["Türkisch"], + "trv": ["Taroko"], + "trw": ["Torwali"], + "ts": ["Xitsonga"], + "tsi": ["Tsimshian"], + "tt": ["Tatarisch"], + "tvl": ["Tuvaluisch"], + "ty": ["Tahitianisch"], + "tyv": ["Tuwinisch"], + "udm": ["Udmurtisch"], + "ug": ["Uigurisch"], + "uk": ["Ukrainisch"], + "umu": ["Munsee"], + "unm": ["Unami"], + "ur": ["Urdu"], + "uz": ["Usbekisch"], + "ve": ["Tshivenda"], + "vec": ["Venezianisch"], + "vep": ["Wepsisch"], + "vi": ["Vietnamesisch"], + "vls": ["Westflämisch"], + "vo": ["Volapük"], + "vot": ["Wotisch"], + "vro": ["Võro"], + "wa": ["Wallonisch"], + "war": ["Waray"], + "wen": ["Sorbisch"], + "wlc": ["shiMwali"], + "wni": ["shiNdzuani"], + "wo": ["Wolof"], + "xal": ["Kalmückisch"], + "xcl": ["Altarmenisch"], + "xfa": ["Faliskisch"], + "xga": ["Galatisch"], + "xh": ["isiXhosa"], + "xhu": ["Hurritisch"], + "xld": ["Lydisch"], + "xlu": ["Luwisch"], + "xno": ["Anglonormannisch"], + "xpq": ["Mohegan-Pequot"], + "xtg": ["Gallisch"], + "xur": ["Urartäisch"], + "xve": ["Venetisch"], + "yak": ["Yakima"], + "yi": ["Jiddisch"], + "yo": ["Yoruba"], + "yua": ["Mayathan"], + "yue": ["Kantonesisch"], + "za": ["Zhuang"], + "zdj": ["shiNgazidja"], + "zea": ["Seeländisch"], + "zh": ["Chinesisch"], + "zh-cn": ["Chinesisch (vereinfacht)"], + "zh-tw": ["Chinesisch (traditionell)"], + "zu": ["isiZulu"], + "zza": ["Zazaki"] +} From 180a67eb7b16d7d81ce4999d062bb6b087b2f9b0 Mon Sep 17 00:00:00 2001 From: Empiriker Date: Tue, 19 Sep 2023 22:53:12 +0200 Subject: [PATCH 2/7] Add pos_subtitles.json for German extractor The POS subtitles have been collected from the occurrences of the {{Wortart|...}} template in the German Wiktionary. The ones referring to actual POS are listed here and mapped to the POS tags used by the en and fr extractors. --- wiktextract/data/de/pos_subtitles.json | 91 ++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 wiktextract/data/de/pos_subtitles.json diff --git a/wiktextract/data/de/pos_subtitles.json b/wiktextract/data/de/pos_subtitles.json new file mode 100644 index 00000000..63d5b984 --- /dev/null +++ b/wiktextract/data/de/pos_subtitles.json @@ -0,0 +1,91 @@ +{ + "Abkürzung (Deutsch)": { "pos": "abbrev" }, + "Abkürzung": { "pos": "abbrev" }, + "Abtönungspartikel": { "pos": "particle" }, + "Adjektiv ": { "pos": "adj" }, + "Adjektiv": { "pos": "adj" }, + "Adverb ": { "pos": "adv" }, + "Adverb": { "pos": "adv" }, + "Affix": { "pos": "affix" }, + "Antwortpartikel": { "pos": "particle" }, + "Artikel": { "pos": "det" }, + "Bruchzahlwort": { "pos": "num" }, + "Buchstabe": { "pos": "character" }, + "Demonstrativpronomen": { "pos": "pron" }, + "Eigenname ": { "pos": "name" }, + "Eigenname": { "pos": "name" }, + "Enklitikon": { "pos": "suffix" }, + "Fokuspartikel": { "pos": "particle" }, + "Formel": { "pos": "phrase" }, + "Gebundenes Lexem": { "pos": "lexeme" }, + "Geflügeltes Wort": { "pos": "phrase" }, + "Gentilname": { "pos": "name" }, + "Gradpartikel": { "pos": "particle" }, + "Grußformel": { "pos": "phrase" }, + "Hilfsverb": { "pos": "aux" }, + "Hiragana": { "pos": "character" }, + "Indefinitpronomen": { "pos": "pron" }, + "Infinitiv ": { "pos": "verb" }, + "Infinitiv": { "pos": "verb" }, + "Infix": { "pos": "infix" }, + "Interfix": { "pos": "interfix" }, + "Interjektion": { "pos": "intj" }, + "Interrogativadverb": { "pos": "adv" }, + "Interrogativpronomen": { "pos": "pron" }, + "Kardinalzahl": { "pos": "num" }, + "Kausaladverb": { "pos": "adv" }, + "Kognomen": { "pos": "nomen" }, + "Konjunktion": { "pos": "conj" }, + "Konjunktionaladverb": { "pos": "adv" }, + "Kontraktion": { "pos": "abbrev" }, + "Lokaladverb": { "pos": "adv" }, + "Merkspruch": { "pos": "phrase" }, + "Modaladverb": { "pos": "adv" }, + "Modalpartikel": { "pos": "particle" }, + "Nachname": { "pos": "name" }, + "Negationspartikel": { "pos": "particle" }, + "Numerale": { "pos": "num" }, + "Onomatopoetikum": { "pos": "intj" }, + "Ortsnamengrundwort": { "pos": "name" }, + "Ordinalzahl": { "pos": "num" }, + "Partikel": { "pos": "particle" }, + "Partikelverb": { "pos": "verb" }, + "Patronym": { "pos": "name" }, + "Personalpronomen ": { "pos": "pron" }, + "Personalpronomen": { "pos": "pron" }, + "Possessivpronomen ": { "pos": "pron" }, + "Possessivpronomen": { "pos": "pron" }, + "Postposition": { "pos": "postp" }, + "Präfix": { "pos": "prefix" }, + "Präfixoid": { "pos": "prefix" }, + "Präposition ": { "pos": "prep" }, + "Präposition": { "pos": "prep" }, + "Pronomen": { "pos": "pron" }, + "Pronominaladverb": { "pos": "adv" }, + "Redewendung": { "pos": "phrase" }, + "Reflexives Personalpronomen": { "pos": "pron" }, + "Reflexivpronomen": { "pos": "pron" }, + "Relativpronomen": { "pos": "pron" }, + "Reziprokpronomen": { "pos": "pron" }, + "Schriftzeichen": { "pos": "character" }, + "Sprichwort": { "pos": "phrase" }, + "Straßenname": { "pos": "name" }, + "Subjunktion": { "pos": "conj" }, + "Substantiv": { "pos": "noun" }, + "Suffix": { "pos": "suffix" }, + "Suffixoid": { "pos": "suffix" }, + "Symbol": { "pos": "symbol" }, + "Temporaladverb": { "pos": "adv" }, + "Temporaldverb": { "pos": "adv" }, + "Toponym": { "pos": "name" }, + "Verb": { "pos": "verb" }, + "Vergleichspartikel": { "pos": "particle" }, + "Vervielfältigungszahlwort": { "pos": "num" }, + "Vorname": { "pos": "name" }, + "Wiederholungszahlwort": { "pos": "num" }, + "Wortverbindung": { "pos": "phrase" }, + "Zahlklassifikator": { "pos": "noun" }, + "Zahlzeichen": { "pos": "num" }, + "Zirkumfix": { "pos": "circumfix" }, + "Zirkumposition": { "pos": "circumpos" } +} From 6b97e906e9e472760d5387f646d32de201a5c155 Mon Sep 17 00:00:00 2001 From: Empiriker Date: Tue, 19 Sep 2023 22:57:05 +0200 Subject: [PATCH 3/7] Add other_subtitles.json for German extractor --- wiktextract/data/de/other_subtitles.json | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 wiktextract/data/de/other_subtitles.json diff --git a/wiktextract/data/de/other_subtitles.json b/wiktextract/data/de/other_subtitles.json new file mode 100644 index 00000000..22a657a7 --- /dev/null +++ b/wiktextract/data/de/other_subtitles.json @@ -0,0 +1,4 @@ +{ + "etymology": ["Herkunft"], + "pronunciation": ["Aussprache"] +} From fcb19c70cae7b56e5071d442e80b50eeadb4fd90 Mon Sep 17 00:00:00 2001 From: Empiriker Date: Wed, 20 Sep 2023 08:36:30 +0200 Subject: [PATCH 4/7] Add page and gloss module for German extractor The page module parses a page from the German Wiktionary and extracts the language of each language entry, the pos of each pos section and fixes the subsection hierarchy therein. The gloss module extracts the glosses from the relevant section. It's still quite crude and doesn't capture all subtleties of gloss entries. --- tests/test_de_gloss.py | 46 +++ tests/test_de_page.py | 194 ++++++++++++ wiktextract/extractor/de/gloss.py | 61 ++++ wiktextract/extractor/de/page.py | 508 ++++++++++++++++++++++++++++++ 4 files changed, 809 insertions(+) create mode 100644 tests/test_de_gloss.py create mode 100644 tests/test_de_page.py create mode 100644 wiktextract/extractor/de/gloss.py create mode 100644 wiktextract/extractor/de/page.py diff --git a/tests/test_de_gloss.py b/tests/test_de_gloss.py new file mode 100644 index 00000000..3d19861b --- /dev/null +++ b/tests/test_de_gloss.py @@ -0,0 +1,46 @@ +import unittest +from collections import defaultdict + +from wikitextprocessor import Wtp + +from wiktextract.config import WiktionaryConfig +from wiktextract.extractor.de.gloss import extract_glosses +from wiktextract.thesaurus import close_thesaurus_db +from wiktextract.wxr_context import WiktextractContext + + +class TestGlossList(unittest.TestCase): + def setUp(self) -> None: + self.wxr = WiktextractContext( + Wtp(lang_code="de"), WiktionaryConfig(dump_file_lang_code="de") + ) + + def tearDown(self) -> None: + self.wxr.wtp.close_db_conn() + close_thesaurus_db( + self.wxr.thesaurus_db_path, self.wxr.thesaurus_db_conn + ) + + def test_de_extract_glosses(self): + self.wxr.wtp.start_page("") + root = self.wxr.wtp.parse(":[1] gloss1 \n:[2] gloss2") + + page_data = [defaultdict(list)] + + extract_glosses(self.wxr, page_data, root.children[0]) + + self.assertEqual( + page_data, + [ + { + "senses": [ + { + "glosses": ["gloss1"], + }, + { + "glosses": ["gloss2"], + }, + ] + } + ], + ) diff --git a/tests/test_de_page.py b/tests/test_de_page.py new file mode 100644 index 00000000..c08c9f8c --- /dev/null +++ b/tests/test_de_page.py @@ -0,0 +1,194 @@ +# Tests for parsing a page from the German Wiktionary + +import unittest +from unittest.mock import patch + +from collections import defaultdict + +from wikitextprocessor import Wtp + +from wiktextract.config import WiktionaryConfig +from wiktextract.extractor.de.page import ( + parse_page, + parse_section, + fix_level_hierarchy_of_subsections, +) +from wiktextract.thesaurus import close_thesaurus_db +from wiktextract.wxr_context import WiktextractContext + + +class DePageTests(unittest.TestCase): + def setUp(self): + conf1 = WiktionaryConfig( + dump_file_lang_code="de", + # capture_language_codes=None, + # capture_translations=True, + # capture_pronunciation=True, + # capture_linkages=True, + # capture_compounds=True, + # capture_redirects=True, + # capture_examples=True, + ) + self.wxr = WiktextractContext(Wtp(lang_code="de"), conf1) + + def tearDown(self) -> None: + self.wxr.wtp.close_db_conn() + close_thesaurus_db( + self.wxr.thesaurus_db_path, self.wxr.thesaurus_db_conn + ) + + def test_de_parse_page(self): + self.wxr.wtp.add_page("Vorlage:Sprache", 10, "") + lst = parse_page( + self.wxr, + "Beispiel", + """ +== Beispiel ({{Sprache|Deutsch}}) == +""", + ) + self.assertEqual( + lst, + [ + { + "lang": "Deutsch", + "lang_code": "de", + "word": "Beispiel", + } + ], + ) + + def test_de_parse_page_skipping_head_templates(self): + self.wxr.wtp.add_page("Vorlage:Wort der Woche", 10, "") + self.wxr.wtp.add_page("Vorlage:Siehe auch", 10, "") + self.wxr.wtp.add_page("Vorlage:Sprache", 10, "") + lst = parse_page( + self.wxr, + "Beispiel", + """ +{{Wort der Woche|46|2020}} +{{Siehe auch|[[cát]]}} +== Beispiel ({{Sprache|Deutsch}}) == +""", + ) + self.assertEqual( + lst, + [ + { + "lang": "Deutsch", + "lang_code": "de", + "word": "Beispiel", + } + ], + ) + + def mock_append_base_data_side_effects( + self, page_data, field: str, value, base_data + ) -> None: + import copy + + if page_data[-1].get(field) is not None: + if len(page_data[-1]["senses"]) > 0: + # append new dictionary if the last dictionary has sense data and + # also has the same key + page_data.append(copy.deepcopy(base_data)) + elif isinstance(page_data[-1].get(field), list): + page_data[-1][field] += value + else: + page_data.append(copy.deepcopy(base_data)) + + else: + page_data[-1][field] = value + + @patch("wiktextract.extractor.de.page.append_base_data") + def test_de_parse_section(self, mock_append_base_data): + mock_append_base_data.side_effect = ( + self.mock_append_base_data_side_effects + ) + + self.wxr.wtp.add_page("Vorlage:Wortart", 10, "") + page_text = """ +=== {{Wortart|Adjektiv|Englisch}}, {{Wortart|Adverb|Englisch}} === +=== {{Wortart|Verb|Englisch}} === +=== {{Wortart|Substantiv|Englisch}} === +""" + self.wxr.wtp.start_page("") + root = self.wxr.wtp.parse( + page_text, + pre_expand=True, + ) + + base_data = defaultdict(list, {"lang_code": "de"}) + page_data = [defaultdict(list, {"lang_code": "de"})] + parse_section(self.wxr, page_data, base_data, root.children) + + self.assertEqual( + page_data, + [ + {"lang_code": "de", "pos": "adj", "senses": []}, + {"lang_code": "de", "pos": "adv", "senses": []}, + {"lang_code": "de", "pos": "verb", "senses": []}, + {"lang_code": "de", "pos": "noun"}, + ], + ) + + def test_de_fix_level_hierarchy_of_subsections(self): + self.wxr.wtp.add_page("Vorlage:Englisch Substantiv Übersicht", 10, "") + self.wxr.wtp.add_page("Vorlage:Worttrennung", 10, "") + self.wxr.wtp.add_page("Vorlage:Aussprache", 10, "") + self.wxr.wtp.add_page("Vorlage:Übersetzungen", 10, "") + self.wxr.wtp.add_page("Vorlage:Ü-Tabelle", 10, "") + self.wxr.wtp.add_page("Vorlage:Referenzen", 10, "") + + page_text = """ +{{Englisch Substantiv Übersicht +|args=args}} + +{{Worttrennung}} +:item + +{{Aussprache}} +:item + +==== {{Übersetzungen}} ==== +{{Ü-Tabelle|1|G=arg|Ü-Liste= +:item +}} + +{{Referenzen}} +:item +""" + self.wxr.wtp.start_page("") + root = self.wxr.wtp.parse( + page_text, + pre_expand=True, + ) + + subsections = fix_level_hierarchy_of_subsections( + self.wxr, root.children + ) + + target_page_text = """==== {{Englisch Substantiv Übersicht\n|args=args}} ==== + +==== {{Worttrennung}} ==== +:item + +==== {{Aussprache}} ==== +:item + +==== {{Übersetzungen}} ==== +{{Ü-Tabelle|1|G=arg|Ü-Liste= +:item +}} + +==== {{Referenzen}} ==== +:item +""" + root = self.wxr.wtp.parse( + target_page_text, + pre_expand=True, + ) + + self.assertEqual( + [str(s) for s in subsections], + [str(t) for t in root.children], + ) diff --git a/wiktextract/extractor/de/gloss.py b/wiktextract/extractor/de/gloss.py new file mode 100644 index 00000000..b209f455 --- /dev/null +++ b/wiktextract/extractor/de/gloss.py @@ -0,0 +1,61 @@ +from collections import defaultdict +from typing import Dict, List + +import re + +from wikitextprocessor import NodeKind, WikiNode + +from wiktextract.page import clean_node +from wiktextract.wxr_context import WiktextractContext + + +def extract_glosses( + wxr: WiktextractContext, + page_data: List[Dict], + list_node: WikiNode, +) -> None: + for list_item_node in list_node.find_child(NodeKind.LIST_ITEM): + item_type = list_item_node.sarg + if item_type == "*": + wxr.wtp.debug( + f"Skipped a sense modifier in gloss list: {list_item_node}", + sortid="extractor/de/glosses/extract_glosses/19", + ) + # XXX: We should extract the modifier. However, it seems to affect + # multiple glosses. Needs investigation. + pass + elif item_type == ":": + gloss_data = defaultdict(list) + for sub_list_node in list_item_node.find_child(NodeKind.LIST): + wxr.wtp.debug( + f"Skipped a sub-list in gloss list: {sub_list_node}", + sortid="extractor/de/glosses/extract_glosses/27", + ) + # XXX: We should extract the subglosses as subsenses. + pass + + gloss_text = clean_node(wxr, gloss_data, list_item_node.children) + + match = re.match(r"\[(\d+[a-z]?)\]", gloss_text) + if match: + sense_number = match.group(1) + gloss_text = gloss_text[match.end() :].strip() + else: + sense_number = None + + if not sense_number: + wxr.wtp.debug( + f"Failed to extract sense number from gloss: {gloss_text}", + sortid="extractor/de/glosses/extract_glosses/28", + ) + + gloss_data["glosses"] = [gloss_text] + + page_data[-1]["senses"].append(gloss_data) + + else: + wxr.wtp.debug( + f"Unexpected list item in glosses: {list_item_node}", + sortid="extractor/de/glosses/extract_glosses/29", + ) + continue diff --git a/wiktextract/extractor/de/page.py b/wiktextract/extractor/de/page.py new file mode 100644 index 00000000..a9643072 --- /dev/null +++ b/wiktextract/extractor/de/page.py @@ -0,0 +1,508 @@ +import copy +import logging + +from collections import defaultdict +from typing import Dict, List, Union + +from wikitextprocessor import NodeKind, WikiNode + +from wikitextprocessor.parser import LevelNode + +from wiktextract.datautils import append_base_data +from wiktextract.wxr_context import WiktextractContext + +from .gloss import extract_glosses + +# Templates that are used to form panels on pages and that should be ignored in +# various positions +PANEL_TEMPLATES = set() + +# Template name prefixes used for language-specific panel templates (i.e., +# templates that create side boxes or notice boxes or that should generally +# be ignored). +PANEL_PREFIXES = set() + +# Additional templates to be expanded in the pre-expand phase +ADDITIONAL_EXPAND_TEMPLATES = set() + +FORM_TABLE_TEMPLATES = { + "Deutsch Substantiv Übersicht", + "Deutsch Substantiv Übersicht -sch", + "Deutsch Toponym Übersicht", + "Deutsch adjektivisch Übersicht", + "Deutsch Eigenname Übersicht", + "Deutsch Name Übersicht", + "Deutsch Vorname Übersicht m", + "Deutsch Vorname Übersicht f", + "Deutsch Vorname Übersicht n", + "Deutsch Verb Übersicht", + "Deutsch Adjektiv Übersicht", + "Pronomina-Tabelle", + "Afrikaans Substantiv Übersicht", + "Albanisch Verb Übersicht", + "Altgriechisch Adjektiv Übersicht", + "Altgriechisch Substantiv Übersicht", + "Altirisch Substantiv Übersicht", + "Altnordisch Substantiv Übersicht", + "Aserbaidschanisch Substantiv Übersicht", + "Asturisch Substantiv Übersicht", + "Baschkirisch Substantiv Übersicht", + "Baskisch Substantiv Übersicht", + "Bosnisch Substantiv Übersicht", + "Bretonisch Substantiv Übersicht", + "Bulgarisch Verb Übersicht", + "Dänisch Adjektiv Übersicht", + "Dänisch Possessivpronomen Übersicht", + "Dänisch Substantiv Übersicht", + "Dänisch Verb Übersicht", + "Englisch Adjektiv Übersicht", + "Englisch Substantiv Übersicht", + "Englisch Verb Übersicht", + "Esperanto Substantiv Übersicht", + "Färöisch Substantiv Übersicht", + "Färöisch Verb Übersicht", + "Finnisch Substantiv Übersicht", + "Finnisch Verb Übersicht", + "Französisch Adjektiv Übersicht", + "Französisch Substantiv Übersicht", + "Französisch Verb Übersicht", + "Galicisch Substantiv Übersicht", + "Hausa Adjektiv Übersicht", + "Hausa Possessiv Übersicht", + "Hausa Substantiv Übersicht", + "Hebräisch Substantiv Übersicht", + "Ido Substantiv Übersicht", + "Irisch Adjektiv Übersicht", + "Irisch Substantiv Übersicht", + "Isländisch Name Übersicht", + "Isländisch Substantiv Übersicht", + "Isländisch Verb Übersicht", + "Italienisch Adjektiv Übersicht", + "Italienisch Substantiv Übersicht", + "Italienisch Verb Übersicht", + "Katalanisch Adjektiv Übersicht", + "Katalanisch Substantiv Übersicht", + "Katalanisch Verb Übersicht", + "Keilschrift Übersicht", + "Korsisch Substantiv Übersicht", + "Kroatisch Adjektiv Übersicht", + "Kroatisch Substantiv Übersicht", + "Kurdisch Substantiv Übersicht", + "Latein Adjektiv Übersicht", + "Latein Adverb Übersicht", + "Latein Substantiv Übersicht", + "Lettisch Substantiv Übersicht", + "Lettisch Verb Übersicht", + "Mazedonisch Substantiv Übersicht", + "Nahuatl Substantiv Übersicht", + "Neugriechisch Substantiv Übersicht", + "Niederdeutsch Adjektiv Übersicht", + "Niederländisch Adjektiv Übersicht" "Niederländisch Substantiv Übersicht", + "Niedersorbisch Substantiv Übersicht", + "Norwegisch Adjektiv Übersicht", + "Norwegisch Eigenname Übersicht", + "Norwegisch Substantiv Übersicht", + "Norwegisch Verb Übersicht", + "Okzitanisch Substantiv Übersicht", + "Okzitanisch Verb Übersicht", + "Papiamentu Substantiv Übersicht", + "Polnisch Grundzahl Übersicht", + "Polnisch Substantiv Übersicht", + "Portugiesisch Substantiv Übersicht", + "Rumänisch Numerale Übersicht", + "Rumänisch Personalpronomen Übersicht", + "Rumänisch Substantiv Übersicht", + "Rumänisch Verb Übersicht", + "Russisch Substantiv Übersicht", + "Sardisch Substantiv Übersicht", + "Schwedisch Adjektiv Übersicht", + "Schwedisch Adverb Übersicht", + "Schwedisch Eigenname Übersicht", + "Schwedisch Pronomen Übersicht", + "Schwedisch Verb Übersicht", + "Scots Substantiv Übersicht", + "Serbisch Substantiv Übersicht", + "Sesotho Substantiv Übersicht", + "Slowakisch Adjektiv Übersicht", + "Slowenisch Substantiv Übersicht", + "Spanisch Adjektiv Übersicht", + "Spanisch Substantiv Übersicht", + "Spanisch Verb Übersicht", + "Suaheli Substantiv Übersicht", + "Suaheli Verb Übersicht", + "Symbol Übersicht", + "Tschechisch universal Übersicht", + "Türkisch Substantiv Übersicht", + "Ukrainisch Substantiv Übersicht", + "Umbrisch Substantiv Übersicht", + "Ungarisch Adjektiv Übersicht", + "Ungarisch Substantiv Übersicht", + "Ungarisch Verb Übersicht", + "Usbekisch Substantiv Übersicht", + "Venezianisch Substantiv Übersicht", + "Walisisch Substantiv Übersicht", + "Westflämisch Substantiv Übersicht", +} + +# Templates that should not be pre-expanded +DO_NOT_PRE_EXPAND_TEMPLATES = { + "Ü-Tabelle", # Translation table + "Quellen", # Can be ignored since we have the tags in the tree +} + +DO_NOT_PRE_EXPAND_TEMPLATES.update(FORM_TABLE_TEMPLATES) + + +def fix_level_hierarchy_of_subsections( + wxr: WiktextractContext, tree: List[WikiNode] +) -> List[WikiNode]: + """ + This function introduces level hierarchy to subsections and their content. + + The German Wiktionary does generally not use level 4 headings but instead + uses templates to define the subsections. These templates are usually + followed by a list of content that belongs to the subsection. Yet, in the + tree the content is on the same level as the subsection template. In Gernman + wiktionary, for cosmetic reasons, a level 4 heading is used to introduce the + translation subsection that then also contains other subsections not related + to translations. + + See: + https://de.wiktionary.org/wiki/Hilfe:Formatvorlage#Der_%E2%80%9EEndteil%E2%80%9C + """ + level_nodes: List[WikiNode] = [] + for node in tree: + if isinstance(node, WikiNode): + # A level 4 heading is used to introduce the translation + # section. + if node.kind == NodeKind.LEVEL4: + # Find the index of the first template after the Ü-Tabelle + # template + split_idx = len(node.children) + for idx, child in enumerate(node.children): + if split_idx < len(node.children): + if ( + isinstance(child, WikiNode) + and child.kind == NodeKind.TEMPLATE + ): + break + else: + split_idx = idx + 1 + if ( + isinstance(child, WikiNode) + and child.kind == NodeKind.TEMPLATE + and child.template_name == "Ü-Tabelle" + ): + split_idx = idx + 1 + + children_until_translation_table = node.children[:split_idx] + + children_after_translation_table = node.children[split_idx:] + + node.children = children_until_translation_table + level_nodes.append(node) + + level_nodes.extend( + fix_level_hierarchy_of_subsections( + wxr, children_after_translation_table + ) + ) + + elif node.kind == NodeKind.TEMPLATE: + level_node = LevelNode(NodeKind.LEVEL4, node.loc) + level_node.largs = [[node]] + level_nodes.append(level_node) + + elif node.kind == NodeKind.LIST: + if len(level_nodes) > 0: + level_nodes[-1].children.append(node) + else: + wxr.wtp.debug( + f"Unexpected list while introducing level hierarchy: {node}", + sortid="extractor/de/page/introduce_level_hierarchy/52", + ) + continue + + # Sometimes links are used outside of a section to link the whole + # entry to a category. We treat them here as level 4 headings, + # without any children. + elif node.kind == NodeKind.LINK: + level_node = LevelNode(NodeKind.LEVEL4, node.loc) + level_node.largs = [[node]] + level_nodes.append(level_node) + + # ignore
tags + elif node.kind == NodeKind.HTML and node.sarg == "br": + pass + else: + wxr.wtp.debug( + f"Unexpected WikiNode while introducing level hierarchy: {node}", + sortid="extractor/de/page/introduce_level_hierarchy/55", + ) + else: + if not len(level_nodes): + if not isinstance(node, str) or not node.strip() == "": + wxr.wtp.debug( + f"Unexpected string while introducing level hierarchy: {node}", + sortid="extractor/de/page/introduce_level_hierarchy/61", + ) + continue + level_nodes[-1].children.append(node) + return level_nodes + + +def parse_section( + wxr: WiktextractContext, + page_data: List[Dict], + base_data: Dict, + level_node: Union[WikiNode, List[Union[WikiNode, str]]], +) -> None: + # Page structure: https://de.wiktionary.org/wiki/Hilfe:Formatvorlage + + if isinstance(level_node, list): + for x in level_node: + parse_section(wxr, page_data, base_data, x) + return + + elif not isinstance(level_node, WikiNode): + if not isinstance(level_node, str) or not level_node.strip() == "": + wxr.wtp.debug( + f"Unexpected node type in parse_section: {level_node}", + sortid="extractor/de/page/parse_section/31", + ) + return + + # Level 3 headings are used to start POS sections like + # === {{Wortart|Verb|Deutsch}} === + elif level_node.kind == NodeKind.LEVEL3: + for template_node in level_node.find_content(NodeKind.TEMPLATE): + # German Wiktionary uses a `Wortart` template to define the POS + if template_node.template_name == "Wortart": + process_pos_section( + wxr, page_data, base_data, level_node, template_node + ) + return + + # Level 4 headings were introduced by fix_level_hierarchy_of_subsections() + # for subsections that are introduced by templates. + elif level_node.kind == NodeKind.LEVEL4: + for template_node in level_node.find_content(NodeKind.TEMPLATE): + section_name = template_node.template_name + wxr.wtp.start_subsection(section_name) + if section_name == "Bedeutungen": + for list_node in level_node.find_child(NodeKind.LIST): + extract_glosses(wxr, page_data, list_node) + + +FORM_POS = { + "Konjugierte Form", + "Deklinierte Form", + "Dekliniertes Gerundivum", + "Komparativ", + "Superlativ", + "Supinum", + "Partizip", + "Partizip I", + "Partizip II", + "Erweiterter Infinitiv", + "Adverbialpartizip", + "Exzessiv", + "Gerundium", +} + +IGNORE_POS = {"Albanisch", "Pseudopartizip", "Ajami"} + + +def process_pos_section( + wxr: WiktextractContext, + page_data: List[Dict], + base_data: Dict, + level_node: LevelNode, + pos_template_node: WikiNode, +) -> None: + # Extract the POS + pos_argument = pos_template_node.template_parameters.get(1) + if pos_argument in FORM_POS.union(IGNORE_POS): + # XXX: Extract forms from form sections + return + pos_type = wxr.config.POS_SUBTITLES.get(pos_argument) + + if pos_type is None: + wxr.wtp.debug( + f"Unknown POS type: {pos_argument}", + sortid="extractor/de/page/process_pos_section/55", + ) + return + pos = pos_type["pos"] + + wxr.wtp.start_section(page_data[-1]["lang_code"] + "_" + pos) + + base_data["pos"] = pos + append_base_data(page_data, "pos", pos, base_data) + + # There might be other templates in the level node that define grammatical + # features other than the POS. Extract them here. + for template_node in level_node.find_content(NodeKind.TEMPLATE): + template_name = template_node.template_name + + GENDER_TAGS_TEMPLATES = { + "m", + "f", + "f ", + "n", + "n ", + "mf", + "mn.", + "fn", + "fm", + "nf", + "nm", + "mfn", + "u", + "un", + "Geschlecht", # placeholder template + } + + VERB_TAGS_TEMPLATES = { + "unreg.", + "intrans.", + "trans.", + "refl.", + } + + ARAB_VERB_STEM_TEMPLATES = { + "Grundstamm", + "I", + "II", + "III", + "IV", + "V", + "VI", + "VII", + "VIII", + } + + NOUN_TAGS_TEMPLATES = { + "adjektivische Deklination", + "kPl.", + "Pl.", + "mPl.", + "fPl.", + "nPl.", + "Sachklasse", + "Personenklasse", + "indekl.", + "Suaheli Klassen", + } + + if template_name == "Wortart": + continue + + elif template_name in GENDER_TAGS_TEMPLATES.union( + ARAB_VERB_STEM_TEMPLATES + ).union(NOUN_TAGS_TEMPLATES).union(VERB_TAGS_TEMPLATES): + # XXX: de: Extract additional grammatical markers + pass + + else: + wxr.wtp.debug( + f"Unexpected template in POS section heading: {template_node}", + sortid="extractor/de/page/process_pos_section/31", + ) + + subsections = fix_level_hierarchy_of_subsections(wxr, level_node.children) + + for subsection in subsections: + parse_section(wxr, page_data, base_data, subsection) + return + + +def parse_page( + wxr: WiktextractContext, page_title: str, page_text: str +) -> List[Dict[str, str]]: + if wxr.config.verbose: + logging.info(f"Parsing page: {page_title}") + + wxr.config.word = page_title + wxr.wtp.start_page(page_title) + + # Parse the page, pre-expanding those templates that are likely to + # influence parsing + tree = wxr.wtp.parse( + page_text, + pre_expand=True, + additional_expand=ADDITIONAL_EXPAND_TEMPLATES, + do_not_pre_expand=DO_NOT_PRE_EXPAND_TEMPLATES, + ) + + page_data = [] + for node in filter(lambda n: isinstance(n, WikiNode), tree.children): + # ignore certain top level templates + if node.kind == NodeKind.TEMPLATE: + template_name = node.template_name + + # Mostly meta-templates at the top of the page that do not carry + # any semantic information + IGNORE_TOP_LEVEL_TEMPLATES = { + "Wort der Woche", + "Siehe auch", + "erweitern", + "Abschnitte fehlen", + "überarbeiten", + "Zeichen", + "Wortart fehlt", + "TOC limit", + "Neuer Eintrag", + "Löschantrag/Vorlage", + "keine Belegstelle/Vorlage", + "Anmerkung Keilschrift", + "In Arbeit", + "Halbgeschützte Seite", + "anpassen", + } + + if template_name in IGNORE_TOP_LEVEL_TEMPLATES: + continue + + # ignore certain top level magic words + if node.kind == NodeKind.MAGIC_WORD and node.sarg in { + "__TOC__", + "__NOTOC__", + "__NOEDITSECTION__", + }: + continue + + if node.kind != NodeKind.LEVEL2: + wxr.wtp.warning( + f"Unexpected top-level node: {node}", + sortid="extractor/de/page/parse_page/61", + ) + continue + + for subtitle_template in node.find_content(NodeKind.TEMPLATE): + # The language sections are marked with + # == ({{Sprache|<lang_name>}}) == + # where <title> is the title of the page and <lang_name> is the + # German name of the language of the section. + if subtitle_template.template_name == "Sprache": + lang_name = subtitle_template.template_parameters.get(1) + lang_code = wxr.config.LANGUAGES_BY_NAME.get(lang_name) + if not lang_code: + wxr.wtp.warning( + f"Unknown language: {lang_name}", + sortid="extractor/de/page/parse_page/76", + ) + continue + + base_data = defaultdict( + list, + { + "lang": lang_name, + "lang_code": lang_code, + "word": wxr.wtp.title, + }, + ) + page_data.append(copy.deepcopy(base_data)) + parse_section(wxr, page_data, base_data, node.children) + + return page_data From 41d3ce6e04a82f54016486d42976822a8e6dbb85 Mon Sep 17 00:00:00 2001 From: Empiriker <till.ueberfries@gmail.com> Date: Sun, 1 Oct 2023 22:11:40 +0300 Subject: [PATCH 5/7] Move list of German form tables to separate file --- wiktextract/config.py | 6 ++ wiktextract/data/de/form_tables.json | 119 ++++++++++++++++++++++++ wiktextract/extractor/de/page.py | 132 ++------------------------- 3 files changed, 134 insertions(+), 123 deletions(-) create mode 100644 wiktextract/data/de/form_tables.json diff --git a/wiktextract/config.py b/wiktextract/config.py index 07fd12c1..ac9cc53d 100644 --- a/wiktextract/config.py +++ b/wiktextract/config.py @@ -56,6 +56,8 @@ class WiktionaryConfig: "POS_TYPES", "OTHER_SUBTITLES", "ZH_PRON_TAGS", + "FR_FORM_TABLES", + "DE_FORM_TABLES", "LANGUAGES_BY_NAME", "LANGUAGES_BY_CODE", "FORM_OF_TEMPLATES", @@ -123,6 +125,10 @@ def __init__( self.set_attr_from_json( "FORM_OF_TEMPLATES", "form_of_templates.json" ) + if dump_file_lang_code == "fr": + self.set_attr_from_json("FR_FORM_TABLES", "form_tables.json") + if dump_file_lang_code == "de": + self.set_attr_from_json("DE_FORM_TABLES", "form_templates.json") def to_kwargs(self): return { diff --git a/wiktextract/data/de/form_tables.json b/wiktextract/data/de/form_tables.json new file mode 100644 index 00000000..939a2674 --- /dev/null +++ b/wiktextract/data/de/form_tables.json @@ -0,0 +1,119 @@ +[ + "Deutsch Substantiv Übersicht", + "Deutsch Substantiv Übersicht -sch", + "Deutsch Toponym Übersicht", + "Deutsch adjektivisch Übersicht", + "Deutsch Eigenname Übersicht", + "Deutsch Name Übersicht", + "Deutsch Vorname Übersicht m", + "Deutsch Vorname Übersicht f", + "Deutsch Vorname Übersicht n", + "Deutsch Verb Übersicht", + "Deutsch Adjektiv Übersicht", + "Pronomina-Tabelle", + "Afrikaans Substantiv Übersicht", + "Albanisch Verb Übersicht", + "Altgriechisch Adjektiv Übersicht", + "Altgriechisch Substantiv Übersicht", + "Altirisch Substantiv Übersicht", + "Altnordisch Substantiv Übersicht", + "Aserbaidschanisch Substantiv Übersicht", + "Asturisch Substantiv Übersicht", + "Baschkirisch Substantiv Übersicht", + "Baskisch Substantiv Übersicht", + "Bosnisch Substantiv Übersicht", + "Bretonisch Substantiv Übersicht", + "Bulgarisch Verb Übersicht", + "Dänisch Adjektiv Übersicht", + "Dänisch Possessivpronomen Übersicht", + "Dänisch Substantiv Übersicht", + "Dänisch Verb Übersicht", + "Englisch Adjektiv Übersicht", + "Englisch Substantiv Übersicht", + "Englisch Verb Übersicht", + "Esperanto Substantiv Übersicht", + "Färöisch Substantiv Übersicht", + "Färöisch Verb Übersicht", + "Finnisch Substantiv Übersicht", + "Finnisch Verb Übersicht", + "Französisch Adjektiv Übersicht", + "Französisch Substantiv Übersicht", + "Französisch Verb Übersicht", + "Galicisch Substantiv Übersicht", + "Hausa Adjektiv Übersicht", + "Hausa Possessiv Übersicht", + "Hausa Substantiv Übersicht", + "Hebräisch Substantiv Übersicht", + "Ido Substantiv Übersicht", + "Irisch Adjektiv Übersicht", + "Irisch Substantiv Übersicht", + "Isländisch Name Übersicht", + "Isländisch Substantiv Übersicht", + "Isländisch Verb Übersicht", + "Italienisch Adjektiv Übersicht", + "Italienisch Substantiv Übersicht", + "Italienisch Verb Übersicht", + "Katalanisch Adjektiv Übersicht", + "Katalanisch Substantiv Übersicht", + "Katalanisch Verb Übersicht", + "Keilschrift Übersicht", + "Korsisch Substantiv Übersicht", + "Kroatisch Adjektiv Übersicht", + "Kroatisch Substantiv Übersicht", + "Kurdisch Substantiv Übersicht", + "Latein Adjektiv Übersicht", + "Latein Adverb Übersicht", + "Latein Substantiv Übersicht", + "Lettisch Substantiv Übersicht", + "Lettisch Verb Übersicht", + "Mazedonisch Substantiv Übersicht", + "Nahuatl Substantiv Übersicht", + "Neugriechisch Substantiv Übersicht", + "Niederdeutsch Adjektiv Übersicht", + "Niederländisch Adjektiv Übersicht", + "Niederländisch Substantiv Übersicht", + "Niedersorbisch Substantiv Übersicht", + "Norwegisch Adjektiv Übersicht", + "Norwegisch Eigenname Übersicht", + "Norwegisch Substantiv Übersicht", + "Norwegisch Verb Übersicht", + "Okzitanisch Substantiv Übersicht", + "Okzitanisch Verb Übersicht", + "Papiamentu Substantiv Übersicht", + "Polnisch Grundzahl Übersicht", + "Polnisch Substantiv Übersicht", + "Portugiesisch Substantiv Übersicht", + "Rumänisch Numerale Übersicht", + "Rumänisch Personalpronomen Übersicht", + "Rumänisch Substantiv Übersicht", + "Rumänisch Verb Übersicht", + "Russisch Substantiv Übersicht", + "Sardisch Substantiv Übersicht", + "Schwedisch Adjektiv Übersicht", + "Schwedisch Adverb Übersicht", + "Schwedisch Eigenname Übersicht", + "Schwedisch Pronomen Übersicht", + "Schwedisch Verb Übersicht", + "Scots Substantiv Übersicht", + "Serbisch Substantiv Übersicht", + "Sesotho Substantiv Übersicht", + "Slowakisch Adjektiv Übersicht", + "Slowenisch Substantiv Übersicht", + "Spanisch Adjektiv Übersicht", + "Spanisch Substantiv Übersicht", + "Spanisch Verb Übersicht", + "Suaheli Substantiv Übersicht", + "Suaheli Verb Übersicht", + "Symbol Übersicht", + "Tschechisch universal Übersicht", + "Türkisch Substantiv Übersicht", + "Ukrainisch Substantiv Übersicht", + "Umbrisch Substantiv Übersicht", + "Ungarisch Adjektiv Übersicht", + "Ungarisch Substantiv Übersicht", + "Ungarisch Verb Übersicht", + "Usbekisch Substantiv Übersicht", + "Venezianisch Substantiv Übersicht", + "Walisisch Substantiv Übersicht", + "Westflämisch Substantiv Übersicht" +] diff --git a/wiktextract/extractor/de/page.py b/wiktextract/extractor/de/page.py index a9643072..57537790 100644 --- a/wiktextract/extractor/de/page.py +++ b/wiktextract/extractor/de/page.py @@ -25,124 +25,6 @@ # Additional templates to be expanded in the pre-expand phase ADDITIONAL_EXPAND_TEMPLATES = set() -FORM_TABLE_TEMPLATES = { - "Deutsch Substantiv Übersicht", - "Deutsch Substantiv Übersicht -sch", - "Deutsch Toponym Übersicht", - "Deutsch adjektivisch Übersicht", - "Deutsch Eigenname Übersicht", - "Deutsch Name Übersicht", - "Deutsch Vorname Übersicht m", - "Deutsch Vorname Übersicht f", - "Deutsch Vorname Übersicht n", - "Deutsch Verb Übersicht", - "Deutsch Adjektiv Übersicht", - "Pronomina-Tabelle", - "Afrikaans Substantiv Übersicht", - "Albanisch Verb Übersicht", - "Altgriechisch Adjektiv Übersicht", - "Altgriechisch Substantiv Übersicht", - "Altirisch Substantiv Übersicht", - "Altnordisch Substantiv Übersicht", - "Aserbaidschanisch Substantiv Übersicht", - "Asturisch Substantiv Übersicht", - "Baschkirisch Substantiv Übersicht", - "Baskisch Substantiv Übersicht", - "Bosnisch Substantiv Übersicht", - "Bretonisch Substantiv Übersicht", - "Bulgarisch Verb Übersicht", - "Dänisch Adjektiv Übersicht", - "Dänisch Possessivpronomen Übersicht", - "Dänisch Substantiv Übersicht", - "Dänisch Verb Übersicht", - "Englisch Adjektiv Übersicht", - "Englisch Substantiv Übersicht", - "Englisch Verb Übersicht", - "Esperanto Substantiv Übersicht", - "Färöisch Substantiv Übersicht", - "Färöisch Verb Übersicht", - "Finnisch Substantiv Übersicht", - "Finnisch Verb Übersicht", - "Französisch Adjektiv Übersicht", - "Französisch Substantiv Übersicht", - "Französisch Verb Übersicht", - "Galicisch Substantiv Übersicht", - "Hausa Adjektiv Übersicht", - "Hausa Possessiv Übersicht", - "Hausa Substantiv Übersicht", - "Hebräisch Substantiv Übersicht", - "Ido Substantiv Übersicht", - "Irisch Adjektiv Übersicht", - "Irisch Substantiv Übersicht", - "Isländisch Name Übersicht", - "Isländisch Substantiv Übersicht", - "Isländisch Verb Übersicht", - "Italienisch Adjektiv Übersicht", - "Italienisch Substantiv Übersicht", - "Italienisch Verb Übersicht", - "Katalanisch Adjektiv Übersicht", - "Katalanisch Substantiv Übersicht", - "Katalanisch Verb Übersicht", - "Keilschrift Übersicht", - "Korsisch Substantiv Übersicht", - "Kroatisch Adjektiv Übersicht", - "Kroatisch Substantiv Übersicht", - "Kurdisch Substantiv Übersicht", - "Latein Adjektiv Übersicht", - "Latein Adverb Übersicht", - "Latein Substantiv Übersicht", - "Lettisch Substantiv Übersicht", - "Lettisch Verb Übersicht", - "Mazedonisch Substantiv Übersicht", - "Nahuatl Substantiv Übersicht", - "Neugriechisch Substantiv Übersicht", - "Niederdeutsch Adjektiv Übersicht", - "Niederländisch Adjektiv Übersicht" "Niederländisch Substantiv Übersicht", - "Niedersorbisch Substantiv Übersicht", - "Norwegisch Adjektiv Übersicht", - "Norwegisch Eigenname Übersicht", - "Norwegisch Substantiv Übersicht", - "Norwegisch Verb Übersicht", - "Okzitanisch Substantiv Übersicht", - "Okzitanisch Verb Übersicht", - "Papiamentu Substantiv Übersicht", - "Polnisch Grundzahl Übersicht", - "Polnisch Substantiv Übersicht", - "Portugiesisch Substantiv Übersicht", - "Rumänisch Numerale Übersicht", - "Rumänisch Personalpronomen Übersicht", - "Rumänisch Substantiv Übersicht", - "Rumänisch Verb Übersicht", - "Russisch Substantiv Übersicht", - "Sardisch Substantiv Übersicht", - "Schwedisch Adjektiv Übersicht", - "Schwedisch Adverb Übersicht", - "Schwedisch Eigenname Übersicht", - "Schwedisch Pronomen Übersicht", - "Schwedisch Verb Übersicht", - "Scots Substantiv Übersicht", - "Serbisch Substantiv Übersicht", - "Sesotho Substantiv Übersicht", - "Slowakisch Adjektiv Übersicht", - "Slowenisch Substantiv Übersicht", - "Spanisch Adjektiv Übersicht", - "Spanisch Substantiv Übersicht", - "Spanisch Verb Übersicht", - "Suaheli Substantiv Übersicht", - "Suaheli Verb Übersicht", - "Symbol Übersicht", - "Tschechisch universal Übersicht", - "Türkisch Substantiv Übersicht", - "Ukrainisch Substantiv Übersicht", - "Umbrisch Substantiv Übersicht", - "Ungarisch Adjektiv Übersicht", - "Ungarisch Substantiv Übersicht", - "Ungarisch Verb Übersicht", - "Usbekisch Substantiv Übersicht", - "Venezianisch Substantiv Übersicht", - "Walisisch Substantiv Übersicht", - "Westflämisch Substantiv Übersicht", -} # Templates that should not be pre-expanded DO_NOT_PRE_EXPAND_TEMPLATES = { @@ -150,8 +32,6 @@ "Quellen", # Can be ignored since we have the <ref> tags in the tree } -DO_NOT_PRE_EXPAND_TEMPLATES.update(FORM_TABLE_TEMPLATES) - def fix_level_hierarchy_of_subsections( wxr: WiktextractContext, tree: List[WikiNode] @@ -322,9 +202,13 @@ def process_pos_section( ) -> None: # Extract the POS pos_argument = pos_template_node.template_parameters.get(1) - if pos_argument in FORM_POS.union(IGNORE_POS): - # XXX: Extract forms from form sections + if pos_argument in IGNORE_POS: return + if pos_argument in FORM_POS: + # XXX: Extract form from form pages. Investigate first if this is needed + # at all or redundant with form tables. + return + pos_type = wxr.config.POS_SUBTITLES.get(pos_argument) if pos_type is None: @@ -432,7 +316,9 @@ def parse_page( page_text, pre_expand=True, additional_expand=ADDITIONAL_EXPAND_TEMPLATES, - do_not_pre_expand=DO_NOT_PRE_EXPAND_TEMPLATES, + do_not_pre_expand=DO_NOT_PRE_EXPAND_TEMPLATES.update( + wxr.config.DE_FORM_TABLES + ), ) page_data = [] From e6d3bfa00d3d8657864ac080fea33db346216c43 Mon Sep 17 00:00:00 2001 From: Empiriker <till.ueberfries@gmail.com> Date: Sun, 1 Oct 2023 22:37:22 +0300 Subject: [PATCH 6/7] Add temporarily different variants of test_de_parse_section --- tests/test_de_page.py | 98 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 97 insertions(+), 1 deletion(-) diff --git a/tests/test_de_page.py b/tests/test_de_page.py index c08c9f8c..0de6e4d9 100644 --- a/tests/test_de_page.py +++ b/tests/test_de_page.py @@ -100,7 +100,7 @@ def mock_append_base_data_side_effects( page_data[-1][field] = value @patch("wiktextract.extractor.de.page.append_base_data") - def test_de_parse_section(self, mock_append_base_data): + def test_de_parse_section_with_mock(self, mock_append_base_data): mock_append_base_data.side_effect = ( self.mock_append_base_data_side_effects ) @@ -131,6 +131,102 @@ def test_de_parse_section(self, mock_append_base_data): ], ) + def test_de_parse_section_with_senses(self): + self.wxr.wtp.add_page("Vorlage:Wortart", 10, "") + self.wxr.wtp.add_page("Vorlage:Bedeutungen", 10, "") + page_text = """ +=== {{Wortart|Adjektiv|Englisch}}, {{Wortart|Adverb|Englisch}} === +{{Bedeutungen}} +:[1] gloss1 +=== {{Wortart|Verb|Englisch}} === +{{Bedeutungen}} +:[1] gloss1 +=== {{Wortart|Substantiv|Englisch}} === +{{Bedeutungen}} +:[1] gloss1 + +""" + self.wxr.wtp.start_page("") + root = self.wxr.wtp.parse( + page_text, + pre_expand=True, + ) + + base_data = defaultdict(list, {"lang_code": "de"}) + page_data = [defaultdict(list, {"lang_code": "de"})] + parse_section(self.wxr, page_data, base_data, root.children) + + self.assertEqual( + page_data, + [ + { + "lang_code": "de", + "pos": "adj", + "senses": [ + { + "glosses": ["gloss1"], + }, + ], + }, + { + "lang_code": "de", + "pos": "adv", + "senses": [ + { + "glosses": ["gloss1"], + }, + ], + }, + { + "lang_code": "de", + "pos": "verb", + "senses": [ + { + "glosses": ["gloss1"], + }, + ], + }, + { + "lang_code": "de", + "pos": "noun", + "senses": [ + { + "glosses": ["gloss1"], + }, + ], + }, + ], + ) + + def test_de_parse_section_without_mock(self): + self.wxr.wtp.add_page("Vorlage:Wortart", 10, "") + page_text = """ +=== {{Wortart|Adjektiv|Englisch}}, {{Wortart|Adverb|Englisch}} === +=== {{Wortart|Verb|Englisch}} === +=== {{Wortart|Substantiv|Englisch}} === +""" + self.wxr.wtp.start_page("") + root = self.wxr.wtp.parse( + page_text, + pre_expand=True, + ) + + base_data = defaultdict(list, {"lang_code": "de"}) + page_data = [defaultdict(list, {"lang_code": "de"})] + parse_section(self.wxr, page_data, base_data, root.children) + + self.assertEqual( + page_data, + [ + {"lang_code": "de", "pos": "adj", "senses": []}, + {"lang_code": "de", "pos": "adv", "senses": []}, + {"lang_code": "de", "pos": "verb", "senses": []}, + {"lang_code": "de", "pos": "noun"}, + ], + ) + # Assertion fails. The resulting page_data is just: + # [{'lang_code': 'de', 'pos': 'adj', 'senses': []}] + def test_de_fix_level_hierarchy_of_subsections(self): self.wxr.wtp.add_page("Vorlage:Englisch Substantiv Übersicht", 10, "") self.wxr.wtp.add_page("Vorlage:Worttrennung", 10, "") From e3af868a3b7dd1d190b6a4eb58e9e9c331d05f5a Mon Sep 17 00:00:00 2001 From: Empiriker <till.ueberfries@gmail.com> Date: Thu, 5 Oct 2023 09:45:11 +0300 Subject: [PATCH 7/7] Test German parse_section() with at least some sense data --- tests/test_de_page.py | 93 ++++--------------------------------------- 1 file changed, 8 insertions(+), 85 deletions(-) diff --git a/tests/test_de_page.py b/tests/test_de_page.py index 0de6e4d9..4451898c 100644 --- a/tests/test_de_page.py +++ b/tests/test_de_page.py @@ -1,7 +1,6 @@ # Tests for parsing a page from the German Wiktionary import unittest -from unittest.mock import patch from collections import defaultdict @@ -81,57 +80,10 @@ def test_de_parse_page_skipping_head_templates(self): ], ) - def mock_append_base_data_side_effects( - self, page_data, field: str, value, base_data - ) -> None: - import copy - - if page_data[-1].get(field) is not None: - if len(page_data[-1]["senses"]) > 0: - # append new dictionary if the last dictionary has sense data and - # also has the same key - page_data.append(copy.deepcopy(base_data)) - elif isinstance(page_data[-1].get(field), list): - page_data[-1][field] += value - else: - page_data.append(copy.deepcopy(base_data)) - - else: - page_data[-1][field] = value - - @patch("wiktextract.extractor.de.page.append_base_data") - def test_de_parse_section_with_mock(self, mock_append_base_data): - mock_append_base_data.side_effect = ( - self.mock_append_base_data_side_effects - ) - - self.wxr.wtp.add_page("Vorlage:Wortart", 10, "") - page_text = """ -=== {{Wortart|Adjektiv|Englisch}}, {{Wortart|Adverb|Englisch}} === -=== {{Wortart|Verb|Englisch}} === -=== {{Wortart|Substantiv|Englisch}} === -""" - self.wxr.wtp.start_page("") - root = self.wxr.wtp.parse( - page_text, - pre_expand=True, - ) - - base_data = defaultdict(list, {"lang_code": "de"}) - page_data = [defaultdict(list, {"lang_code": "de"})] - parse_section(self.wxr, page_data, base_data, root.children) - - self.assertEqual( - page_data, - [ - {"lang_code": "de", "pos": "adj", "senses": []}, - {"lang_code": "de", "pos": "adv", "senses": []}, - {"lang_code": "de", "pos": "verb", "senses": []}, - {"lang_code": "de", "pos": "noun"}, - ], - ) - - def test_de_parse_section_with_senses(self): + # The way append_base_data() works requires the presence of a sense + # dictionary before starting a new pos section. Therefore, we need to add + # at least one sense data point to the test case. + def test_de_parse_section(self): self.wxr.wtp.add_page("Vorlage:Wortart", 10, "") self.wxr.wtp.add_page("Vorlage:Bedeutungen", 10, "") page_text = """ @@ -140,10 +92,10 @@ def test_de_parse_section_with_senses(self): :[1] gloss1 === {{Wortart|Verb|Englisch}} === {{Bedeutungen}} -:[1] gloss1 +:[1] gloss2 === {{Wortart|Substantiv|Englisch}} === {{Bedeutungen}} -:[1] gloss1 +:[1] gloss3 """ self.wxr.wtp.start_page("") @@ -182,7 +134,7 @@ def test_de_parse_section_with_senses(self): "pos": "verb", "senses": [ { - "glosses": ["gloss1"], + "glosses": ["gloss2"], }, ], }, @@ -191,42 +143,13 @@ def test_de_parse_section_with_senses(self): "pos": "noun", "senses": [ { - "glosses": ["gloss1"], + "glosses": ["gloss3"], }, ], }, ], ) - def test_de_parse_section_without_mock(self): - self.wxr.wtp.add_page("Vorlage:Wortart", 10, "") - page_text = """ -=== {{Wortart|Adjektiv|Englisch}}, {{Wortart|Adverb|Englisch}} === -=== {{Wortart|Verb|Englisch}} === -=== {{Wortart|Substantiv|Englisch}} === -""" - self.wxr.wtp.start_page("") - root = self.wxr.wtp.parse( - page_text, - pre_expand=True, - ) - - base_data = defaultdict(list, {"lang_code": "de"}) - page_data = [defaultdict(list, {"lang_code": "de"})] - parse_section(self.wxr, page_data, base_data, root.children) - - self.assertEqual( - page_data, - [ - {"lang_code": "de", "pos": "adj", "senses": []}, - {"lang_code": "de", "pos": "adv", "senses": []}, - {"lang_code": "de", "pos": "verb", "senses": []}, - {"lang_code": "de", "pos": "noun"}, - ], - ) - # Assertion fails. The resulting page_data is just: - # [{'lang_code': 'de', 'pos': 'adj', 'senses': []}] - def test_de_fix_level_hierarchy_of_subsections(self): self.wxr.wtp.add_page("Vorlage:Englisch Substantiv Übersicht", 10, "") self.wxr.wtp.add_page("Vorlage:Worttrennung", 10, "")