3 # :Copyright: © 2012 Günter Milde.
4 # :Licence: This work may be distributed and/or modified under
5 # the conditions of the `LaTeX Project Public License`,
6 # either version 1.3 of this license or (at your option)
8 # :Version: 0.1 (2012-02-07)
15 """Hilfsmittel für die Arbeit mit der `Wortliste`"""
19 # Die hier versammelten Funktionen und Klassen dienen der Arbeit an und
20 # mit der freien `Wortliste der deutschsprachigen Trennmustermannschaft`_
21 # ("Lembergsche Liste")
34 # Klasse zum Lesen und Schreiben der `Wortliste`::
48 # Die spezielle Funktion `__iter__` wird aufgerufen wenn über eine
49 # Klasseninstanz iteriert wird.
51 # Liefer einen Iterator über die "geparsten" Zeilen (Datenfelder)::
54 line
= self
.readline().rstrip().decode(self
.encoding
)
57 line
= self
.readline().rstrip().decode(self
.encoding
)
62 # Lies Datei und trage die Zeilen mit ungetrenntem Wort
63 # als `key` und den Datenfeldern als `value` in ein `dictionary`
64 # (assoziatives Array) ein::
69 words
[entry
[0]] = entry
75 # Schreibe eine Liste von `unicode` Strings (Zeilen ohne Zeilenendezeichen)
76 # in die Datei `destination`::
78 def writelines(self
, lines
, destination
, encoding
=None):
79 outfile
= codecs
.open(destination
, 'w',
80 encoding
=(encoding
or self
.encoding
))
81 outfile
.write(u
'\n'.join(lines
))
87 # Schreibe eine Liste von Datenfeldern (geparste Zeilen) in die Datei
90 def write_entry(self
, wortliste
, destination
, encoding
=None):
91 lines
= [unicode(entry
) for entry
in wortliste
]
92 self
.writelines(lines
, destination
, encoding
)
98 # Klasse für Einträge (Zeilen) der Wortliste
102 # >>> from werkzeug import WordEntry
104 # >>> aalbestand = WordEntry(u'Aalbestand;Aal=be<stand # Test')
105 # >>> print aalbestand
106 # Aalbestand;Aal=be<stand # Test
110 class WordEntry(list):
115 # Kommentare (aktualisiert, wenn Kommentar vorhanden)::
122 # 2. Wort mit Trennungen, falls für alle Varianten identisch,
124 # 3. falls Feld 2 leer, Trennung nach traditioneller Rechtschreibung
125 # 4. falls Feld 2 leer, Trennung nach reformierter Rechtschreibung (2006)
126 # 5. falls Feld 2 leer, Trennung für Wortform, die entweder in
127 # der Schweiz oder mit Großbuchstaben oder Kapitälchen benutzt wird
128 # und für traditionelle und reformierte Rechtschreibung identisch ist
129 # 6. falls Feld 5 leer, Trennung für Wortform, die entweder in
130 # der Schweiz oder mit Großbuchstaben oder Kapitälchen benutzt wird,
131 # traditionelle Rechtschreibung
132 # 7. falls Feld 5 leer, Trennung für Wortform, die entweder in
133 # der Schweiz oder mit Großbuchstaben oder Kapitälchen benutzt wird,
134 # reformierte Rechtschreibung (2006)
135 # 8. falls Feld 5 leer, Trennung nach (deutsch)schweizerischer
136 # Rechtschreibung; insbesondere Wörter mit "sss" gefolgt von
137 # einem Vokal, die wie andere Dreifachkonsonanten gehandhabt wurden
138 # (also anders, als der Duden früher vorgeschrieben hat), z.B.
141 # Sprachvarianten (Tags nach [BCP47]_) (Die Zählung der Indizes beginn in
145 'de': 1, # Deutsch, allgemeingültig
146 'de-1901': 2, # "traditionell" (nach Rechtschreibreform 1901)
147 'de-1996': 3, # reformierte Reformschreibung (1996)
148 'de-x-GROSS': 4, # ohne ß (Schweiz oder GROSS) allgemein
149 'de-1901-x-GROSS': 5, # ohne ß (Schweiz oder GROSS) "traditionell"
150 'de-1996-x-GROSS': 6, # ohne ß (Schweiz oder GROSS) "reformiert"
151 # 'de-CH-1996': 6, # Alias für 'de-1996-x-GROSS'
152 'de-CH-1901': 7, # ohne ß (Schweiz) "traditionell" ("süssauer")
158 def __init__(self
, line
, delimiter
=';'):
159 self
.delimiter
= delimiter
161 # eventuell vorhandenen Kommentar abtrennen und speichern::
164 line
, self
.comment
= line
.split('#')
167 # Zerlegen in Datenfelder, in Liste eintragen::
169 list.__init
__(self
, line
.split(delimiter
))
172 # Rückverwandlung in String
173 # -----------------------------------
175 # Erzeugen eines Eintrag-Strings (Zeile) aus der Liste der Datenfelder und
178 # >>> unicode(aalbestand)
179 # u'Aalbestand;Aal=be<stand # Test'
183 def __unicode__(self
):
184 line
= ';'.join(self
)
185 if self
.comment
is not None:
186 line
+= ' #' + self
.comment
191 return unicode(self
).encode('utf8')
196 # Index des zur Sprachvariante gehörenden Datenfeldes:
198 # >>> aalbestand.lang_index('de')
200 # >>> aalbestand.lang_index('de-1901')
202 # >>> aalbestand.lang_index('de-1996')
204 # >>> abbeissen = WordEntry(
205 # ... u'abbeissen;-2-;-3-;-4-;-5-;ab<bei-ssen;ab<beis-sen;ab<beis-sen')
206 # >>> print abbeissen.lang_index('de')
208 # >>> print abbeissen.lang_index('de-x-GROSS')
210 # >>> abbeissen.lang_index('de-CH-1901')
215 def lang_index(self
, sprachvariante
):
217 assert sprachvariante
in self
.sprachvarianten
, \
218 'Sprachvariante nicht in ' + str(self
.sprachvarianten
.keys())
220 # Einfacher Fall: eine allgemeine Schreibweise::
225 # Spezielle Schreibung::
228 i
= self
.sprachvarianten
[sprachvariante
]
231 if i
> 4 and len(self
) == 5:
232 return 4 # Allgemeine Schweiz/GROSS Schreibung:
233 return None # Feld nicht vorhanden
235 if feld
.startswith('-'): # '-1-', '-2-', ...
236 return None # leeres Feld
240 # Trennmuster für Sprachvariante ausgeben
242 # >>> aalbestand.get('de')
244 # >>> aalbestand.get('de-1901')
246 # >>> aalbestand.get('de-1996')
248 # >>> aalbestand.get('de-x-GROSS')
250 # >>> aalbestand.get('de-1901-x-GROSS')
252 # >>> aalbestand.get('de-1996-x-GROSS')
254 # >>> aalbestand.get('de-CH-1901')
257 # >>> print abbeissen.get('de')
259 # >>> print abbeissen.get('de-x-GROSS')
261 # >>> abbeissen.get('de-1901-x-GROSS')
263 # >>> abbeissen.get('de-CH-1901')
268 def get(self
, sprachvariante
):
270 return self
[self
.lang_index(sprachvariante
)]
271 except TypeError: # Muster in `sprachvariante` nicht vorhanden
274 # Trennmuster für Sprachvariante setzen
276 # >>> abbeissen.set('test', 'de-1901-x-GROSS')
277 # >>> print abbeissen
278 # abbeissen;-2-;-3-;-4-;-5-;test;ab<beis-sen;ab<beis-sen
280 # >>> abbeissen.set('test', 'de-1901')
281 # Traceback (most recent call last):
283 # IndexError: kann kein leeres Feld setzen
287 def set(self
, wort
, sprachvariante
):
288 i
= self
.lang_index(sprachvariante
)
290 raise IndexError, "kann kein leeres Feld setzen"
293 # Felder für alle Sprachvarianten ausfüllen
295 # >>> print str(aalbestand), len(aalbestand)
296 # Aalbestand;Aal=be<stand # Test 2
297 # >>> aalbestand.expand_fields()
298 # >>> print len(aalbestand)
300 # >>> auffrass = WordEntry('auffrass;-2-;-3-;-4-;auf-frass')
301 # >>> auffrass.expand_fields()
303 # auffrass;-2-;-3-;-4-;auf-frass;auf-frass;auf-frass;auf-frass
307 def expand_fields(self
):
308 fields
= [self
.get(sv
) or '-%d-' % (self
.sprachvarianten
[sv
] + 1)
309 for sv
in sorted(self
.sprachvarianten
.keys(),
310 key
=self
.sprachvarianten
.get
)]
312 for i
, field
in enumerate(fields
):
314 self
[i
+1] = field
# Feld 1 ist "key" (ungetrennt)
319 # Felder für Sprachvarianten zusammenfassen
321 # >>> aalbestand.conflate_fields()
322 # >>> print aalbestand
323 # Aalbestand;Aal=be<stand # Test
324 # >>> auffrass.conflate_fields()
326 # auffrass;-2-;-3-;-4-;auf-frass
328 # Aber nicht, wenn die Trennstellen sich unterscheiden:
330 # >>> abenddienste = WordEntry(
331 # ... u'Abenddienste;-2-;Abend=dien-ste;Abend=diens-te')
332 # >>> abenddienste.conflate_fields()
333 # >>> print abenddienste
334 # Abenddienste;-2-;Abend=dien-ste;Abend=diens-te
338 def conflate_fields(self
):
340 if self
[7] == self
[6] == self
[5]:
341 self
[4] = self
[5] # umschreiben auf GROSS-allgemein
346 if self
[4] == self
[2]: # de-x-GROSS == de-1901
351 if self
[3] == self
[2]: # de-1996 == de-1901
352 self
[1] = self
[2] # Umschreiben auf de (allgemein)
364 # Trennzeichen entfernen::
366 def join_word(word
, assert_complete
=False):
368 # Einfache Trennzeichen:
370 # == ================================================================
371 # \· ungewichtete Trennstelle (solche, wo sich noch niemand um die
372 # Gewichtung gekümmert hat)
373 # \. unerwünschte Trennstelle (sinnentstellend), z.B. Ur·in.stinkt
374 # oder ungünstige Trennstelle (verwirrend), z.B. Atom·en.er·gie
375 # in ungewichteten Wörtern
376 # \= Trennstelle an Wortfugen (Wort=fu-ge)
377 # \< Trennstelle nach Präfix (Vor<sil-be)
378 # \> Trennstelle vor Suffix (Freund>schaf-ten)
379 # \- Nebentrennstelle (ge-hen)
380 # == ================================================================
385 for char
in u
'·.=|-_<>':
386 table
[ord(char
)] = None
387 key
= word
.translate(table
)
389 # Spezielle Trennungen für die traditionelle Rechtschreibung
390 # (siehe ../../dokumente/README.wortliste)::
392 if '{' in key
or '}' in key
:
393 key
= key
.replace(u
'{ck/kk}', u
'ck')
394 key
= key
.replace(u
'{ck/k', u
'k')
395 key
= key
.replace(u
'k}', u
'k')
396 # Konsonanthäufungen an Wortfuge: '{xx/xxx}' -> 'xx':
397 key
= re
.sub(ur
'\{(.)\1/\1\1\1\}', ur
'\1\1', key
)
398 # schon getrennt: ('{xx/xx' -> 'xx' und 'x}' -> 'x'):
399 key
= re
.sub(ur
'\{(.)\1/\1\1$', ur
'\1\1', key
)
400 key
= re
.sub(ur
'^(.)\}', ur
'\1', key
)
402 # Trennstellen in doppeldeutigen Wörtern::
404 if '[' in key
or ']' in key
:
405 key
= re
.sub(ur
'\[(.*)/\1\]', ur
'\1', key
)
407 key
= re
.sub(ur
'\[([^/\[]+)$', ur
'\1', key
)
408 key
= re
.sub(ur
'^([^/\]]+)\]', ur
'\1', key
)
410 # Test auf verbliebene komplexe Trennstellen::
413 for spez
in u
'[{/}]':
415 raise AssertionError('Spezialtrennung %s, %s' %
416 (word
.encode('utf8'), key
.encode('utf8')))
423 # Zerlege ein Wort mit Trennzeichen in eine Liste von Silben und eine Liste
426 # >>> from werkzeug import zerlege
428 # >>> zerlege(u'Haupt=stel-le')
429 # ([u'Haupt', u'stel', u'le'], [u'=', u'-'])
430 # >>> zerlege(u'Ge<samt=be<triebs=rats==chef')
431 # ([u'Ge', u'samt', u'be', u'triebs', u'rats', u'chef'], [u'<', u'=', u'<', u'=', u'=='])
432 # >>> zerlege(u'an<stands>los')
433 # ([u'an', u'stands', u'los'], [u'<', u'>'])
434 # >>> zerlege(u'An<al.pha-bet')
435 # ([u'An', u'al', u'pha', u'bet'], [u'<', u'.', u'-'])
440 silben
= re
.split(u
'[-·._<>=]+', wort
)
441 trennzeichen
= re
.split(u
'[^-·._|<>=]+', wort
)
442 return silben
, [tz
for tz
in trennzeichen
if tz
]
447 # Fehler beim Übertragen von Trennstellen mit uebertrage_::
449 class TransferError(ValueError):
450 def __init__(self
, wort1
, wort2
):
451 msg
= u
'Inkompatibel: %s %s' % (wort1
, wort2
)
452 ValueError.__init
__(self
, msg
.encode('utf8'))
454 def __unicode__(self
):
455 return str(self
).decode('utf8')
461 # Übertrage die Trennzeichen von `wort1` auf `wort2`:
463 # >>> from werkzeug import uebertrage, TransferError
465 # >>> uebertrage(u'Haupt=stel-le', u'Haupt·stel·le')
468 # Auch teilweise Übertragung, von "kategorisiert" nach "unkategorisiert":
470 # >>> print uebertrage(u'Haupt=stel-le', u'Haupt=stel·le')
473 # >>> print uebertrage(u'Haupt·stel-le', u'Haupt=stel·le')
476 # >>> print uebertrage(u'Aus<stel-ler', u'Aus-stel-ler')
479 # >>> print uebertrage(u'Freund>schaf·ten', u'Freund-schaf-ten')
482 # Übertragung doppelter Marker:
484 # >>> print uebertrage(u'ver<<aus<ga-be', u'ver<aus<ga-be')
487 # >>> print uebertrage(u'freund>lich>>keit', u'freund>lich>keit')
490 # Kein Überschreiben doppelter Marker:
491 # >>> print uebertrage(u'ver<aus<ga-be', u'ver<<aus<ga-be')
494 # Erhalt des Markers für ungünstige Stellen:
495 # >>> print uebertrage(u'An·al.pha·bet', u'An<al.pha-bet')
498 # Keine Übertragung, wenn die Zahl oder Position der Trennstellen
499 # unterschiedlich ist oder bei unterschiedlichen Wörtern:
502 # ... uebertrage(u'Ha-upt=stel-le', u'Haupt=stel·le')
503 # ... uebertrage(u'Haupt=ste-lle', u'Haupt=stel·le')
504 # ... uebertrage(u'Waupt=stel-le', u'Haupt=stel·le')
505 # ... except TransferError:
508 # Übertragung auch bei unterschiedlicher Schreibung oder Position der
509 # Trennstellen mit `strict=False` (für Abgleich zwischen Sprachvarianten):
511 # >>> uebertrage(u'er-ster', u'ers·ter', strict=False)
513 # >>> uebertrage(u'Fluß=bett', u'Fluss·bett', strict=False)
515 # >>> uebertrage(u'ab>bei-ßen', u'ab>beis·sen', strict=False)
517 # >>> print uebertrage(u'Aus<tausch=dien-stes', u'Aus-tausch=diens-tes', False)
518 # Aus<tausch=diens-tes
520 # Auch mit `strict=False` muß die Zahl der Trennstellen übereinstimmen
521 # (Ausnahmen siehe unten):
524 # ... uebertrage(u'Ha-upt=ste-lle', u'Haupt=stel·le', strict=False)
525 # ... except TransferError:
528 # Akzeptiere unterschiedliche Anzahl von Trennungen bei st und ck nach
531 # >>> uebertrage(u'acht=ecki-ge', u'acht·e{ck/k·k}i·ge', strict=False)
532 # u'acht=e{ck/k-k}i-ge'
533 # >>> uebertrage(u'As-to-ria', u'Asto·ria', strict=False)
535 # >>> uebertrage(u'Asto-ria', u'As·to·ria', strict=False)
537 # >>> uebertrage(u'So-fa=ecke', u'So·fa=e{ck/k-k}e', strict=False)
538 # u'So-fa=e{ck/k-k}e'
540 # Mit ``upgrade=False`` werden nur unspezifische Trennstellen überschrieben:
542 # >>> print uebertrage(u'an=stel-le', u'an<stel·le', upgrade=False)
545 # >>> print uebertrage(u'Aus<stel-ler', u'Aus-stel-ler', upgrade=False)
548 # >>> print uebertrage(u'Aus-stel-ler', u'Aus<stel-ler', upgrade=False)
551 # >>> print uebertrage(u'vor<an<<stel-le', u'vor-an<stel·le', upgrade=False)
556 selbstlaute
= u
'aeiouäöüAEIOUÄÖÜ'
558 def uebertrage(wort1
, wort2
, strict
=True, upgrade
=True):
560 silben1
, trennzeichen1
= zerlege(wort1
)
561 silben2
, trennzeichen2
= zerlege(wort2
)
562 # Prüfe strikte Übereinstimmung:
563 if silben1
!= silben2
and strict
:
564 if u
'<' in trennzeichen1
or u
'·' in trennzeichen2
:
565 raise TransferError(wort1
, wort2
)
568 # Prüfe ungefähre Übereinstimmung:
569 if len(trennzeichen1
) != len(trennzeichen2
):
570 # Selbstlaut + st oder ck?
571 for s
in selbstlaute
:
572 if (wort2
.find(s
+u
'{ck/k·k}') != -1 or
573 wort2
.find(s
+u
'{ck/k-k}') != -1):
574 wort1
= wort1
.replace(s
+u
'ck', s
+u
'-ck')
575 silben1
, trennzeichen1
= zerlege(wort1
)
576 if wort2
.find(s
+u
's·t') != -1:
577 wort1
= wort1
.replace(s
+u
'st', s
+u
's-t')
578 silben1
, trennzeichen1
= zerlege(wort1
)
579 elif wort1
.find(s
+u
's-t') != -1:
580 wort1
= wort1
.replace(s
+u
's-t', s
+u
'st')
581 silben1
, trennzeichen1
= zerlege(wort1
)
582 # print u'retry:', silben1, trennzeichen1
583 # immer noch ungleiche Zahl an Trennstellen?
584 if len(trennzeichen1
) != len(trennzeichen2
):
585 raise TransferError(wort1
, wort2
)
587 # Baue wort3 aus silben2 und spezifischeren Trennzeichen:
588 wort3
= silben2
.pop(0)
589 for t1
,t2
in zip(trennzeichen1
, trennzeichen2
):
590 if ((t2
== u
'·' and t1
!= u
'.') # unspezifisch
592 ((t2
in (u
'-', u
'<') and t1
in (u
'<', u
'<<', u
'<=')) # Praefixe
593 or (t2
in (u
'-', u
'>') and t1
in (u
'>', u
'>>', u
'=>')) # Suffixe
594 or (t2
in (u
'-', u
'=') and t1
in (u
'=', u
'==', u
'===')) # W-fugen
598 elif t2
== u
'.' and t1
!= u
'·':
602 wort3
+= silben2
.pop(0)
606 # Übertrag kategorisierter Trennstellen zwischen den Feldern aller Einträge
609 def sprachabgleich(entry
, vorbildentry
=None):
612 return # allgemeine Schreibung
617 for field
in entry
[1:]:
618 if field
.startswith('-'): # -2-, -3-, ...
627 for field
in vorbildentry
[1:]:
628 if field
.startswith('-'): # -2-, -3-, ...
630 if u
'<' in field
and not mit_vorsilbe
:
632 elif u
'·' not in field
and (not gewichtet
) and ungewichtet
:
634 # print 've:', mit_vorsilbe, gewichtet, ungewichtet
635 if mit_vorsilbe
and (gewichtet
or ungewichtet
):
636 for i
in range(1,len(entry
)):
637 if entry
[i
].startswith('-'): # -2-, -3-, ...
639 if u
'<' not in entry
[i
] or u
'·' in entry
[i
]:
641 entry
[i
] = uebertrage(mit_vorsilbe
, entry
[i
], strict
=False)
642 except TransferError
, e
:
643 print u
'Sprachabgleich:', unicode(e
)
644 print mit_vorsilbe
+u
':', unicode(entry
)
645 elif gewichtet
and ungewichtet
:
646 for i
in range(1,len(entry
)):
649 entry
[i
] = uebertrage(gewichtet
, entry
[i
], strict
=False)
650 except TransferError
, e
:
651 print u
'Sprachabgleich:', unicode(e
)
652 print gewichtet
, unicode(entry
)
655 # Großschreibung in Kleinschreibung wandeln und umgekehrt
657 # Diese Version funktioniert auch für Wörter mit Trennzeichen (während
658 # str.title() nach jedem Trennzeichen wieder groß anfängt)
660 # >>> from werkzeug import toggle_case
661 # >>> toggle_case(u'Ha-se')
663 # >>> toggle_case(u'arm')
665 # >>> toggle_case(u'frei=bier')
667 # >>> toggle_case(u'L}a-ger')
670 # Keine Änderung bei Wörtern mit Großbuchstaben im Inneren:
672 # >>> toggle_case(u'USA')
675 # >>> toggle_case(u'gri[f-f/{ff/ff')
677 # >>> toggle_case(u'Gri[f-f/{ff/ff')
682 def toggle_case(wort
):
684 key
= join_word(wort
, assert_complete
=True)
685 except AssertionError:
690 return wort
[0].upper() + wort
[1:]
698 # Vergleiche zwei Sequenzen von `WordEntries`, gib einen "unified diff" als
699 # Byte-String zurück (weil difflib nicht mit Unicode-Strings arbeiten kann).
703 # >>> from werkzeug import udiff
704 # >>> print udiff([abbeissen, aalbestand], [abbeissen], 'alt', 'neu')
708 # abbeissen;-2-;-3-;-4-;-5-;test;ab<beis-sen;ab<beis-sen
709 # -Aalbestand;Aal=be<stand # Test
713 def udiff(a
, b
, fromfile
='', tofile
='',
714 fromfiledate
='', tofiledate
='', n
=1, encoding
='utf8'):
716 a
= [unicode(entry
).encode(encoding
) for entry
in a
]
717 b
= [unicode(entry
).encode(encoding
) for entry
in b
]
719 diff
= difflib
.unified_diff(a
, b
, fromfile
, tofile
,
720 fromfiledate
, tofiledate
, n
, lineterm
='')
723 return '\n'.join(diff
)
728 def test_keys(wortliste
):
729 """Teste Übereinstimmung des ungetrennten Wortes in Feld 1
730 mit den Trennmustern nach Entfernen der Trennmarker.
731 Schreibe Inkonsistenzen auf die Standardausgabe.
733 `wortliste` ist ein Iterator über die Einträge (Klasse `WordEntry`)
736 for entry
in wortliste
:
737 # Test der Übereinstimmung ungetrenntes/getrenntes Wort
740 for wort
in entry
[1:]:
741 if wort
.startswith(u
'-'): # leere Felder
743 if key
!= join_word(wort
):
745 print u
"\nkey '%s' != '%s'" % (key
, wort
),
746 if key
.lower() == join_word(wort
).lower():
747 print(u
" Abgleich der Großschreibung mit"
748 u
"`prepare-patch.py grossabgleich`."),
757 if __name__
== '__main__':
760 # sys.stdout mit UTF8 encoding (wie in Python 3)
761 sys
.stdout
= codecs
.getwriter('UTF-8')(sys
.stdout
)
763 print u
"Test der Werkzeuge und inneren Konsistenz der Wortliste\n"
765 # wordfile = WordFile('../../wortliste-binnen-s')
766 wordfile
= WordFile('../../wortliste')
767 # print 'Dateiobjekt:', wordfile
769 # Liste der Datenfelder (die Klasseninstanz als Argument für `list` liefert
770 # den Iterator über die Felder, `list` macht daraus eine Liste)::
772 wortliste
= list(wordfile
)
773 print len(wortliste
), u
"Einträge\n"
779 # sprache = 'de-1901' # traditionell
780 # sprache = 'de-1996' # Reformschreibung
781 # sprache = 'de-x-GROSS' # ohne ß (Schweiz oder GROSS) allgemein
782 # sprache = 'de-1901-x-GROSS' # ohne ß (Schweiz oder GROSS) "traditionell"
783 # sprache = 'de-1996-x-GROSS' # ohne ß (Schweiz oder GROSS) "reformiert"
784 # sprache = 'de-CH-1901' # ohne ß (Schweiz) "traditionell" ("süssauer")
786 # worte = [entry.get(sprache) for entry in wortliste if wort is not None]
787 # print len(worte), u"Einträge für Sprachvariante", sprache
792 print u
"Teste Schlüssel-Trennmuster-Übereinstimmung:",
793 if test_keys(wortliste
):
801 for entry
in wortliste
:
802 key
= entry
[0].lower()
808 print u
"Doppeleinträge (ohne Berücksichtigung der Großschreibung)."
810 print u
" Entfernen mit `prepare-patch.py doppelte`."
811 print u
" Patch vor Anwendung durchsehen!"
814 # Ein Wörterbuch (dict Instanz)::
816 # wordfile.seek(0) # Pointer zurücksetzen
817 # words = wordfile.asdict()
819 # print len(words), u"Wörterbucheinträge"
821 # Zeilenrekonstruktion::
823 # am Beispiel der Scheiterbeige:
824 # original = u'beige;beige # vgl. Scheiter-bei-ge'
825 # entry = words[u"beige"]
826 # line = unicode(entry)
827 # assert original == line, "Rejoined %s != %s" % (line, original)
830 wordfile
.seek(0) # Pointer zurücksetzen
832 line
= wordfile
.readline().rstrip().decode(wordfile
.encoding
)
834 entry
= WordEntry(line
)
835 if line
== unicode(entry
):
839 print u
'+', unicode(entry
)
840 line
= wordfile
.readline().rstrip().decode(wordfile
.encoding
)
842 print OK
, u
"Einträge rekonstruiert"
849 # .. [BCP47] A. Phillips und M. Davis, (Editoren.),
850 # `Tags for Identifying Languages`, http://www.rfc-editor.org/rfc/bcp/bcp47.txt
852 # .. _Wortliste der deutschsprachigen Trennmustermannschaft:
853 # http://mirrors.ctan.org/language/hyphenation/dehyph-exptl/projektbeschreibung.pdf