3 # :Copyright: © 2011 Günter Milde.
4 # Released without warranty under the terms of the
5 # GNU General Public License (v. 2 or later)
8 # Versuche Trennstellen neuer Wörter aus vorhandenen zu ermitteln
9 # ===============================================================
11 # Übertragen von kategorisierten Trennstellen vorhandener Wörter
12 # auf neu aufzunehmende, ungetrennte Wörter.
14 # Erwartet eine Datei mit 1 Wort/Zeile.
15 # Pfad/Dateiname im Abschnitt Konfiguration anpassen!
17 # Schreibt eine Liste von Einträgen für die Wörter, welche durch Abgleich
18 # mit der Datenbasis getrennt werden konnten auf stdout.
20 # Die Liste kann nach ``neu.todo`` gespeichert und (nach Durchsicht) mit
21 # ``prepare_patch.py neu`` in die Wortliste eingepflegt werden.
26 from collections
import defaultdict
# Wörterbuch mit Default
27 from werkzeug
import WordFile
, WordEntry
, join_word
, toggle_case
, sortkey_duden
28 from expand_teilwoerter
import expand_wordfile
33 # Pfad zur Datei mit den neu einzutragenden Wörtern::
35 # neuwortdatei = "spell/zusatz-de-1996-aspell-compact"
36 neuwortdatei
= "spell/dehyph-exptl-MV-KorrekturenA-Z.txt"
37 # neuwortdatei = "spell/DDR.txt"
39 # Vorhandene identische Einträge aus Neueinträgen aussortieren::
46 # Übertrag von Praefixen auf Wörter ohne Präfix::
48 def praefixabgleich(key
, praefix
, grossklein
=False):
51 praefix
= praefix
.title()
53 if not key
.startswith(join_word(praefix
)):
56 altkey
= key
[len(join_word(praefix
)):]
59 altkey
= toggle_case(altkey
)
62 altentry
= words
[altkey
]
66 entry
= WordEntry(key
)
67 # print "fundum", key, unicode(entry)
68 for wort
in altentry
[1:]:
69 if not wort
.startswith(u
'-'):
71 wort
= u
'<'.join([praefix
, wort
])
391 # Nach Länge sortieren, damit spezifischere zuerst Probiert werden:
392 praefixe
.sort(key
= len)
396 # Übertrag von Einträgen auf Wörter mit anderer Endung::
398 def endungsabgleich(key
, alt
, neu
, grossklein
=False):
400 if not key
.endswith(join_word(neu
)):
403 altkey
= key
[:-len(join_word(neu
))] + join_word(alt
)
405 altkey
= toggle_case(altkey
)
408 altentry
= words
[altkey
]
412 entry
= WordEntry(key
)
413 # print "fundum", key, unicode(entry)
414 for wort
in altentry
[1:]:
415 if not wort
.startswith(u
'-'):
417 wort
= wort
[:-len(alt
)]
420 wort
= toggle_case(wort
)
421 if join_word(wort
) != key
:
425 print u
"# Übertragungsproblem: %s -> %s (%s,%s) %s" % (
426 altkey
, key
, alt
, neu
, unicode(entry
))
429 entry
.regelaenderungen()
435 # ``(<alt>, <neu>)`` Paare von Endungen::
480 (u
'-en', u
'>bar>keit'),
496 (u
'-sten', u
's-mus'),
518 (u
'e-ren', u
'-ti-on'),
549 (u
'isch', u
'i-sche'),
572 (u
'on', u
'o-nis-mus'),
589 (u
'ph', u
'-phis-mus'),
653 # Zerlege einen String mit von vorn bis hinten wandernder Bruchstelle::
655 # >>> from abgleich_neueintraege import zerlege
656 # >>> list(zerlege(u'wolle'))
657 # [(u'w', u'olle'), (u'wo', u'lle'), (u'wol', u'le'), (u'woll', u'e')]
662 for i
in range(1, len(s
)):
666 # Zerlege String, wenn die Teile in der Wortliste vorhanden sind, setze
667 # sie neu zusammen und übernehme die Trennmarkierer:
670 def trenne_key(key
, grossklein
= False):
673 for k1
, k2
in zerlege(key
):
681 e2
= words
.get(toggle_case(k2
))
683 if len(e1
) != len(e2
):
685 e1
= [e1
[1]] * len(e2
)
687 e2
= [e2
[1]] * len(e1
)
690 entry
= WordEntry(key
)
691 for w1
, w2
in zip(e1
,e2
)[1:]:
692 if w1
.startswith(u
'-'):
694 elif w2
.startswith(u
'-'):
701 while (level
*sep
in w1
) or (level
*sep
in w2
):
703 wort
= (level
*sep
).join([w1
, w2
])
705 entry
.conflate_fields()
706 entries
.append(entry
)
710 def filter_neuliste(neuwortdatei
, words
):
712 for line
in open(neuwortdatei
):
713 line
= line
.decode('utf8').strip()
714 if line
.startswith('#'):
717 neueintrag
= WordEntry(line
)
718 alteintrag
= words
.get(neueintrag
[0])
719 if len(neueintrag
) == 1 or neueintrag
== alteintrag
:
720 print 'vorhanden:', line
726 if __name__
== '__main__':
728 # sys.stdout mit UTF8 encoding.
729 sys
.stdout
= codecs
.getwriter('UTF-8')(sys
.stdout
)
734 words
= WordFile('../../wortliste').asdict()
735 for line
in filter_neuliste(neuwortdatei
, words
):
739 # `Wortliste` einlesen::
741 wordfile
= WordFile('../../wortliste')
742 words
= expand_wordfile(wordfile
)
744 for alt
, neu
in endungen
:
745 words
.pop(join_word(neu
), None)
747 for unwort
in [u
'Em']:
748 words
.pop(unwort
, None)
750 # # schon expandierte Liste:
751 # wordfile = WordFile('wortliste-expandiert') # + Teilwort-Entries
752 # words = wordfile.asdict()
758 # Erstellen der neuen Einträge::
760 newentries
= [WordEntry(line
.decode('utf8').strip())
761 for line
in open(neuwortdatei
)
762 if not line
.startswith('#')]
764 for newentry
in newentries
:
767 # print key, unicode(newentry)
770 # Test auf vorhandene (Teil-) Wörter:
772 entry
= words
.get(key
)
777 entry
= words
.get(key
.lower())
779 neue_grossklein
.append(entry
)
782 entry
= words
.get(key
.title())
784 neue_grossklein
.append(entry
)
789 for alt
, neu
in endungen
:
790 entry
= endungsabgleich(key
, alt
, neu
, grossklein
=False)
792 entry
.comment
= newentry
.comment
799 for alt
, neu
in endungen
:
800 entry
= endungsabgleich(key
, alt
, neu
, grossklein
=True)
802 entry
.comment
= newentry
.comment
803 neue_grossklein
.append(entry
)
811 for praefix
in praefixe
:
812 entry
= praefixabgleich(key
, praefix
, grossklein
=False)
814 entry
.comment
= newentry
.comment
818 entry
= praefixabgleich(key
, praefix
, grossklein
=True)
820 entry
.comment
= newentry
.comment
821 neue_grossklein
.append(entry
)
827 # Zerlegen und test auf Fugen::
829 entries
= trenne_key(key
, grossklein
=False)
833 entries
= trenne_key(key
, grossklein
=True)
835 neue_grossklein
.extend(entries
)
838 # Nicht gefundene Wörter::
840 rest
.append(newentry
)
842 # Mehrdeutige aussortieren::
846 doppelkeys_gleich
= defaultdict(int)
848 # doppelte keys finden:
849 for entry
in neue
+ neue_grossklein
:
850 key
= entry
[0].lower()
851 if key
in alle_neuen
:
852 if entry
== alle_neuen
[key
]:
853 doppelkeys_gleich
[key
] += 1
856 alle_neuen
[key
] = entry
858 # doppelte Einträge "verlegen":
860 eindeutige_grossklein
= []
864 key
= entry
[0].lower()
865 if key
in doppelkeys
:
866 doppelte
.append(entry
)
867 elif doppelkeys_gleich
[key
] > 0:
868 doppelkeys_gleich
[key
] -= 1
870 eindeutige
.append(entry
)
872 for entry
in neue_grossklein
:
873 key
= entry
[0].lower()
874 if key
in doppelkeys
:
875 doppelte
.append(entry
)
876 elif doppelkeys_gleich
[key
] > 0:
877 doppelkeys_gleich
[key
] -= 1
879 eindeutige_grossklein
.append(entry
)
882 # Vergleich mit Original::
885 for entry
in newentries
:
886 altentry
= alle_neuen
.get(entry
[0].lower())
887 if entry
== altentry
:
888 identische
[key
] = entry
890 alle_neuen
.get(key
).comment
+= u
'WL:' + u
';'.join(entry
[1:])
894 print u
'\n# identisch rekonstruiert:'
895 for entry
in sorted(identische
.values(), key
=sortkey_duden
):
898 print u
'\n# eindeutig abgeleitet'
899 for entry
in eindeutige
:
900 if entry
[0].lower() not in identische
:
903 print u
'\n# eindeutig abgeleitet (andere Großschreibung)'
904 for entry
in eindeutige_grossklein
:
905 if entry
[0].lower() not in identische
:
908 print u
'\n# mehrdeutig abgeleitet'
909 for entry
in doppelte
: