3 # :Copyright: © 2012, 2014 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.3 (2014-06-14)
10 # ===================================================================
11 # Langes oder rundes S: Automatische Konversion nach Silbentrennung
12 # ===================================================================
17 Erstelle eine Wortliste mit (hoffentlich) korrekter lang-S Schreibung.
19 Automatische Bestimmung der S-Schreibung auf Basis der Silbentrennung
20 in der `Wortliste der deutschsprachigen Trennmustermannschaft`.
22 Für die Wandlung mit Hilfe der patgen-generierten Muster siehe
31 # Lade Funktionen und Klassen für reguläre Ausdrücke::
33 import codecs
, os
, optparse
, re
, sys
35 # path for local Python modules (parent dir of this file's dir)
37 os
.path
.dirname(os
.path
.dirname(os
.path
.abspath(__file__
))))
38 from edit_tools
.wortliste
import WordFile
, WordEntry
, join_word
44 # Die Trennzeichen der Wortliste sind
46 # == ================================================================
47 # \· ungewichtete Trennstellen (solche, wo noch niemand sich um die
48 # Gewichtung gekümmert hat)
49 # . unerwünschte Trennstellen (sinnverwirrend), z.B. Ur-in.stinkt
51 # \- Nebentrennstellen
52 # < Trennstellen nach Vorsilben
53 # > Trennstellen vor Suffixen
54 # == ================================================================
63 # Siehe [wikipedia]_ und ("DDR"-) [Duden]_ (Regeln K 44,45)::
70 # Für sz und sk gelten Regeln, welche die Herkunft der Wörter beachten.
71 # Diese und weitere spezielle Fälle, welche Lang-S vor Trennstellen verlangen
72 # sind in `Ausnahmen Lang-S`_ gelistet::
74 for (ausnahme
, ersetzung
) in ausnahmen_lang_s
:
76 word
= word
.replace(ausnahme
, ersetzung
)
77 # print u"ſ-Ausnahme", ersetzung, word
82 # ſ steht im Silbenanlaut::
84 word
= re
.sub(ur
'(^|[-<>=·.])s', ur
'\1ſ', word
)
86 # ſ steht im Inlaut als stimmhaftes s zwischen Vokalen
87 # (gilt auch für ungetrenntes ss zwischen Selbstlauten, z.B. Hausse, Baisse)::
89 word
= re
.sub(ur
'([AEIOUYÄÖÜaeiouäöüé])s([aeiouyäöüé])', ur
'\1ſ\2', word
)
90 word
= re
.sub(ur
'([AEIOUYÄÖÜaeiouäöüé])ss([aeiouyäöüé])', ur
'\1ſſ\2', word
)
96 # Wenn kein ß vorhanden ist (GROSSSCHREIBUNG) und in der Schweiz wird ss
97 # statt ß geschrieben. Seit 1996 wird auch am Wort-/Silbenende und vor t nach
98 # kurzem Vokal ss geschrieben. Der "Reformduden" empfielt im Fraktursatz die
99 # Schreibung "ſs" (die auch vor 1901 in Gebrauch war).
101 # Wir übernehmen diese Schreibung am Wort-/Silbenende::
103 word
= re
.sub(u
'ss($|[-=<>.])', ur
'ſs\1', word
)
105 # Vor t schreiben wir nach kurzem Vokal Doppel-ſ::
107 word
= word
.replace(u
'sst', u
'ſſt')
109 # Nach langem Vokal steht auch in de-1996 ein ß, in de-x-GROSS ist keine
110 # ſ-Wandlung nötig/möglich.
111 # TODO: in der Schweizer Orthographie müßte nach langem Vokal oder Zwielaut
112 # auch vor t ein ſs stehen (beißt -> beiſst).
114 # Verbindungen und Digraphen
115 # --------------------------
117 # ſ steht in den Verbindungen sp, st, sch und in Digraphen::
119 word
= word
.replace(u
'st', u
'ſt')
120 word
= word
.replace(u
'sp', u
'ſp')
121 word
= word
.replace(u
'sch', u
'ſch')
123 # word = word.replace(u'ps', u'pſ')
124 word
= word
.replace(u
'Ps', u
'Pſ') # Ψ
125 word
= re
.sub(ur
'^ps', ur
'pſ', word
) # ψ (ps am Wortanfang)
126 word
= re
.sub(ur
'([-<>=·.])ps', ur
'\1pſ', word
) # ψ (ps am Silbenanfang)
132 # Die Verbindungen ss, sp¹, st werden zu ſſ, ſp und ſt, auch wenn sie
133 # durch eine Nebentrennstelle (Trennung innerhalb eines Wortbestandteiles)
134 # getrennt sind. Das s bleibt rund im Auslaut, d.h. am Wortende und vor
135 # einer Haupttrennstelle (Trennung an der Grenze zweier Wortbestandteile
136 # (Vorsilb<Stamm, Bestimmungswort=Grundwort).
138 # ¹ s bleibt rund vor Nebentrennstelle wenn ph folgt (Phos-phor).
139 # TODO: es müsste Phos<phor (Lichtträger) markiert sein.
143 word
= re
.sub(ur
's([-.]+)ſ([aeiouyäöüé])', ur
'ſ\1ſ\2', word
)
144 word
= re
.sub(ur
's([-.]+)p([^h])', ur
'ſ\1p\2', word
)
145 word
= re
.sub(ur
'(^|[^s])s([-.]+)t', ur
'\1ſ\2t', word
) # Reformschreibung
147 # ſ wird auch geschrieben, wenn der S-Laut nur scheinbar im Auslaut steht,
148 # weil ein folgendes unbetontes e ausfällt:
150 # "ss-l", aber nicht bei "...eiss-l" und "Ess-lingen" mit ss statt ß::
152 word
= re
.sub(ur
'([^iE])ss-l', ur
'\1ſſ-l', word
) # Droſſ-lung, ...
154 # "s-l" (Baſ-ler, pinſ-le, Kapſ-lung, Wechſ-ler, wechſ-le, Rieſ-ling),
156 # M.s-l: Mus-lim, Mos-lem, ...
157 # [iys]s-l: Gris-ly, is-lam, Crys-ler, ... (ss-l siehe obige Regel)
158 # s-la: Bra-tis-la-va, Gos-lar, Bres-lau,
160 word
= re
.sub(ur
'([^mM][^siy])s-l([^a])', ur
'\1ſ-l\2', word
)
162 # (für weitere Fälle siehe auch `Ausnahmen Lang-S`_):
165 # Fremdwörter und Eigennamen mit Schluss-ß
166 # """"""""""""""""""""""""""""""""""""""""
168 # Der 1971er [Duden]_ führt zu englischen Fremdwörtern mit Schluß-ß die
169 # österreichische Schreibung mit "ss" auf (Miß, engl. und österr. Schreibung
170 # Miss) wobei das Schluß-s nicht unterstrichen ist (also lang sein müßte?). So
171 # auch Boss, Business, Stewardess.
173 # Dagegen sagt [en.wiktionary.org]_: "the digraph «ss» was often written «ſs»
174 # rather than «ſſ»". Die Lang-S Seite der [wikipedia]_ zeigt Beispiele der
175 # englischen Schreibung "Congreſs".
179 # TODO ſſ oder ſs (wie in de-1996)? :
180 # if lang == 'de-1901':
181 # word = re.sub(ur'ss$', ur'ſſ', word)
182 # word = word.replace(u'ss=', u'ſſ=')
183 # word = word.replace(u'ss-ſch', u'ſſ-ſch')
189 # ~~~~~~~~~~~~~~~~~~~
191 # Teilstrings mit Lang-S vor Trennstelle.
193 # ſ wird geschrieben, wenn der S-Laut nur scheinbar im Auslaut steht,
194 # weil ein folgendes unbetontes e ausfällt::
198 u
'Pilſ-ner', # < Pilsen, aber Mes-ner, Meiss-ner (de-ch)
199 u
'Klauſ-ner', # < Klause, aber Gleiss-ner (de-ch)
200 u
'riſſ-ne', # ge<riss-ne, ... (de-ch)
201 u
'oſſ-ne', # ge<schoss-ne, ge<schloss-ne, ... (de-ch)
202 u
'er<leſ-ne', # auserlesne
203 u
'unſ-r', # unsre, unsrige, ...
205 u
'ſl', # Beiſl, Häuſl
209 u
'Pſſſt', # im Duden pst!
210 u
'WiſſZeitVG', # Abkürzung Wiſſenſchaft...
213 # ſ steht in Abkürzungen, wenn es im abgekürzten Wort steht
214 # (Abſ. - Abſatz/Abſender, (de)creſc. - (de)creſcendo, daſ. - daſelbst ...)
217 ausnahmen_lang_s
.extend([
219 u
'creſc', # creſcendo
220 u
'Diſſ', # Diſſertation
221 u
'Maſſ', # Maſſachuſetts
225 # Alternativtrennung, wo beide Fälle ſ verlangen::
227 ausnahmen_lang_s
.extend([
229 u
'er<.]ſat', # Kin[-der=/d=er<.]satz, ..-zes
230 u
'ſ[-ter=/t' # Tes[-ter=/t=er<.]ken-nung
235 # Fremdwörter und Eigennamen
236 # --------------------------
238 # Schreibung nach Regeln der Herkunftssprache. Dabei ist zu bedenken, daß zu
239 # der Zeit, als das lange s im Antiquasatz noch üblich war (bis ca. 1800), die
240 # Rechtschreibung freier gehandhabt wurde und mehrfach Wandlungen unterworfen
243 # Im Deutschen werden im Fraktursatz nicht eingedeutschte Fremdwörter
244 # lateinischen und romanischen Ursprungs in Antiqua mit rund-s geschrieben.
247 # The long, medial, or descending ess, as distinct from the short or
248 # terminal ess. In Roman script, the long ess was used everywhere except at
249 # the end of words, where the short ess was used, and frequently in what is
250 # now the digraph «ss», which was often written «ſs» rather than «ſſ»
251 # [en.wiktionary.org]_. See also [Typefounder08]_ and [West06]_.
255 ausnahmen_lang_s
.extend([
258 # u'Diſc', # (englisch) TODO: so, oder Disc (wie eingedeutscht Disk)
259 u
'Cſar', # Cs -> Tsch (Csardas, ... ungarisch)
260 u
'ſz', # polnisch, ungarisch (Liszt, Puszta)
262 # ts am Silbenanfang (chinesisch, japanisch, griechisch)::
264 u
'Tſa', u
'Tſe', u
'tſe', u
'tſi', u
'Tſu', u
'tſu',
266 # In vielen (aber nicht allen) Fremdwörtern steht ſz trotz Trennzeichen::
268 u
'ſ-ce-', # Fluo-res-ce-in
269 u
'ſ-ze-', # Aszese, aszetisch, Damaszener, vis-ze-ral, ...
270 u
'ſ-zen', # Adoleszenz, Aszendent, ...
272 # ſ-zi (aber Dis-zi-plin):
273 u
'Aſ-be', # Asbest, ...
274 u
'aſ-be', # asbesthaltig, ...
275 u
'Aſ-zi', # Aszites, ...
276 u
'aſ-zi', # [Ll]asziv, laszive, ...
277 u
'ſ-zil-l' , # Oszillation, Oszilloskop, ...
278 u
'asſ-zi', # faszinieren, fasziniert, ...
279 u
'gnoſ-zie', # rekognoszieren,
280 u
'reſ-zi', # fluoreszieren, phosporeszieren, Fluo-res-cin, ...
281 u
'le-biſ-zi', # Plebiszit, ...
282 u
'viſ-zi', # Mukoviszidose
284 # ſ steht in der Endung sk in Wörtern und Namen slawischen Ursprungs
295 # ſſ steht wenn auf die Vorsilbe "dis-" oder "as-" ein "s" folgt::
297 u
'aſ<ſ', # Assoziation, ...
298 u
'diſ<ſ', # Dissoziation, ...
299 u
'Diſ<ſ', # dissonant, ...
303 # Wandel in liste mit (Ausnahme, Ersetzung)::
305 ausnahmen_lang_s
= [(ex
.replace(u
'ſ', u
's'), ex
) for ex
in ausnahmen_lang_s
]
310 # Test auf verbliebene Unklarheiten
312 # Wenn ein Wort "s" nur an Stellen enthält wo die Regeln rundes S vorsehen,
313 # ist die automatische Konversion abgeschlossen.
315 # Ausnahmen und spezielle Regeln
317 # Liste von Teilstrings, welche stets rund-s behalten ::
323 u
'Ausg', # Ausgan, Ausgabe
325 u
'desgl', # des<gleichen
326 u
'hrsg', # herausgegeben
327 u
'Hrsg', # Herausgeber
330 # ausgelassenes flüchtiges e::
332 u
'Dresd-ne', # Dresd-ner/Dresd-ne-rin
334 # s steht auch in einigen Fremdwörtern vor z und c::
336 u
'on<fis-zie', # konfiszieren, ...
337 # u'le-bis-z', # plebiszit (nach [duden]_ mit Lang-S)
338 u
'is-zi-pl', # Disziplin (nach [duden]_, aber Duden (1934) Diſziplin)
339 u
'mas-ze-ner', # Damaszener
340 u
'Disc', # TODO: rund oder Diſc (aber eingedeutscht Disk)
342 # ss im Auslaut (vgl. `Fremdwörter und Eigennamen`_)::
344 # u'Gauss', # vgl. "Briefwechsel zwischen C.F. Gauss und H.C. Schumacher, herausg. von C.A.F. Peters"
345 # aber Boſſ, Busineſſ, Dreſſ
350 def is_complete(word
):
352 # Ersetze s an Stellen, wo es rund zu schreiben ist, durch ~ und teste auf
353 # verbliebene Vorkommen.
355 # Einzelfälle mit rundem S (substrings)::
357 for fall
in ausnahmen_rund_s
:
359 # print u's-Ausnahme', fall, word
360 word
= word
.replace(fall
, fall
.replace('s', '~'))
362 # s steht am Wortende, auch in Zusammensetzungen (vor Haupttrennstellen)::
364 word
= re
.sub(ur
's($|[=<>])', ur
'~\1', word
)
366 # Mit Ausnahme der Vorsilben "trans" (manchmal) und "abs" (abſtrakt)::
367 # TODO: wie ist es bei trans? (Transport / tranſitiv)
369 # word = word.replace('tran~<', u'tranſ<')
370 word
= word
.replace('ab~<', u
'abſ<')
372 # Einige ältere Quellen schreiben ss am Schluss von Fremdwörtern oder Namen
373 # (Gauss). Andere schreiben ſs oder ſſ. (Vgl. `Fremdwörter und Eigennamen
374 # mit Schluss-ß`_) Wir verwenden ſs (TODO oder?)::
376 #word = re.sub(ur'ss(=|$)', ur'~~\1', word)
378 # s steht am Silbenende (vor Nebentrennstellen), wenn kein p, t, z oder ſ
379 # folgt (in der traditionellen Schreibung wird st nicht getrennt)::
381 word
= re
.sub(ur
'ss?([·.\-][^ptzſ])', ur
'~\1', word
) # konservativ
383 # s steht auch vor Nebentrennstellen, wenn ph oder sch folgt::
385 word
= word
.replace(u
's-ph', u
'~-ph')
386 word
= word
.replace(u
's-ſch', u
'~-ſch')
388 # s steht nach Vorsilben (wie aus<) auch wenn s, p, t, oder z folgt::
390 word
= word
.replace(u
's<', u
'~<')
392 # s steht vor Trennstellen am Suffixanfang (wie)
393 # auch wenn s, p, t, oder z folgt (Ols>sen, Jonas>son, Wachs>tum)::
395 word
= word
.replace(u
's>', u
'~>')
397 # s steht meist im Inlaut vor k, n, w (aber: siehe Lang-ſ-Ausnahmen)::
399 word
= re
.sub(ur
's([knw])', ur
'~\1', word
)
401 # s steht in der Verbindung sst, die in der Schweiz und
402 # bei fehlendem ß (GROSS) für ßt steht::
404 # TODO: nur nach Zwielaut und langem Vokal.
405 # word = word.replace(u'ſst', u'ſ~t')
406 # word = word.replace(u'ſs-t', u'ſ~-t')
408 # s steht als zweiter Buchstabe im ersetzten ß::
410 word
= word
.replace(u
'-ſs', u
'-ſ~') # traditionelle Orthographie
412 # und suche nach übrigen Vorkommen::
414 return 's' not in word
417 # Aufruf von der Kommandozeile
418 # ============================
422 if __name__
== '__main__':
426 usage
= u
'%prog [Optionen]\n' + __doc__
427 parser
= optparse
.OptionParser(usage
=usage
)
428 parser
.add_option('-i', '--infile', dest
='infile',
429 help=u
'Eingangsdatei ("-" oder "stdin" für '
430 u
'Standardeingabe), Vorgabe "../../../wortliste"',
431 default
='../../../wortliste')
432 parser
.add_option('-o', '--outfile', dest
='outfile',
433 help=u
'Ausgangsdatei, ("-" oder "stdout" für '
434 u
'Standardausgabe) Vorgabe: "words-<language>-Latf.txt"',
435 default
='') # wird später ausgefüllt
436 parser
.add_option('-l', '--language', dest
='language',
437 help=u
'Sprachvariante(n) (kommagetrennte Liste von '
438 u
'ISO Sprachtags), Vorgabe "de-1901"',
440 parser
.add_option('-d', '--drop-homonyms', action
="store_true",
442 help=u
'Bei mehrdeutigen Wörtern, die sich nur in '
443 'Lang-S-Schreibung unterscheiden, nimm nur das erste.')
445 (options
, args
) = parser
.parse_args()
447 # sys.stdout mit UTF8 encoding::
449 sys
.stdout
= codecs
.getwriter('UTF-8')(sys
.stdout
)
451 # Angabe der Sprachvariante nach [BCP47]_ (Reformschreibung 'de' oder
452 # 'de-1996', Schweiz 'de-CH', ...)::
454 lang
= options
.language
458 if options
.infile
in ('-', 'stdin'):
459 wordfile
= (WordEntry(line
.rstrip().decode('utf-8'))
460 for line
in sys
.stdin
)
462 wordfile
= WordFile(options
.infile
)
465 if options
.outfile
in ('-', 'stdout'):
466 outstream
= sys
.stdout
468 outfile
= options
.outfile
or (
469 'words-' + lang
.replace(',','-') + '-Latf.txt')
470 outstream
= file(outfile
, 'w')
476 # Konvertiere die Wörter der Trennliste und sortiere die Ergebnisse in
479 no_of_words
= 0 # Gesamtwortzahl der gewählten Sprache(n)
480 completed
= [] # Automatisch konvertiert
481 irreversible
= [] # Rückkonversion ungleich Original (Fehler)
482 unkategorisiert
= [] # Unterscheidung in Haupt- und Nebentrennstellen fehlt
483 offen
= [] # Der Algorithmus kann die Schreibweise (noch) nicht ermitteln
485 # Iteration über alle Zeilen der Wortliste::
487 for entry
in wordfile
:
489 word
= entry
.get(lang
) # Wort mit Trennstellen
490 if word
is None: # Wort existiert nicht in der Sprachvariante
497 # Wörter ohne Binnen-s müssen nicht konvertiert werden. Damit wird die
498 # Wortliste ungefähr um die Hälfte kürzer::
500 if 's' not in entry
[0][:-1]:
501 completed
.append(entry
[0])
504 # Regelbasierte s/ſ-Schreibung::
506 lang_s_word
= s_ersetzen(word
)
508 # Einsortieren nach Vollständigkeit der Ersetzungen::
510 entry
.set(lang_s_word
, lang
) # Rückschreiben von teilweisen Ersetzungen
512 if lang_s_word
.replace(u
'ſ', u
's') != word
:
513 entry
.comment
= lang_s_word
.replace(u
'ſ', u
's') + u
" != " + word
514 irreversible
.append(entry
)
517 if not is_complete(lang_s_word
):
518 if lang_s_word
.find(u
's·') != -1:
519 unkategorisiert
.append(entry
)
524 # Mehrdeutigkeiten [ſ/s] oder [s/ſ] auflösen::
526 lang_s_word
= join_word(lang_s_word
)
527 if u
'/' in lang_s_word
:
529 completed
.append(re
.sub(ur
'\[(.+)/.+\]', ur
'\1', lang_s_word
))
530 if not options
.drop_homonyms
:
531 completed
.append(re
.sub(ur
'\[.+/(.+)\]', ur
'\1', lang_s_word
))
533 completed
.append(lang_s_word
)
534 # completed.append(lang_s_word)
540 # Wortliste mit automatisch bestimmter S-Schreibung, ohne Trennstellen::
542 outstream
.write(u
'\n'.join(completed
).encode('utf8') + '\n')
549 sys
.stderr
.write("# Gesamtwortzahl %s %s\n" % (lang
, no_of_words
))
550 sys
.stderr
.write("# Automatisch konvertiert: %d\n" % len(completed
))
551 sys
.stderr
.write("# erkannte Konvertierungsfehler: %d\n"
553 for entry
in irreversible
:
554 sys
.stderr
.write(unicode(entry
).encode('utf8')+'\n')
555 sys
.stderr
.write("# Kategorisierung der Trennstellen fehlt: %d\n"
556 % len(unkategorisiert
))
557 for entry
in unkategorisiert
:
558 sys
.stderr
.write(unicode(entry
).encode('utf8')+'\n')
559 sys
.stderr
.write("# noch offen/unklar: %d\n" % len(offen
))
561 sys
.stderr
.write(unicode(entry
).encode('utf8')+'\n')
567 # Für gebrochene Schriften gibt es den `ISO Sprachtag`_
569 # :Latf: Latin (Fraktur variant)
571 # also "Lateinisches Alphabet, gebrochen". Dieser Tag wird and die
572 # Ausgabedateien angehängt (e.g. "de-1901-Latf", "de-1996-Latf").
574 # .. _ISO Sprachtag: http://www.unicode.org/iso15924/iso15924-codes.html
579 # Gesamtwortzahl (traditionelle Rechtschreibung): 427746
580 # Automatisch konvertiert: 427740
581 # Kategorisierung der Trennstellen fehlt: 0
584 # Die Mehrzahl der Wörter der Trennliste wurde nach den Regeln des Dudens in
585 # die Schreibung mit langem `S` (ſ) konvertiert (wobei ungefähr die Hälfte der
586 # Wörter kein kleines `s` enthält womit die Konversion trivial wird).
588 # Für eine beschränke Anzahl offener Fälle wurden Ausnahmeregeln und Ausnahmen
591 # Das Resultat muß noch auf nicht erfaßte Ausnahmen und Sonderfälle geprüft
592 # werden. Fehlentscheidungen sind nicht auszuschließen.
598 # Wörter mit identischer Schreibung ohne Lang-S
599 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
601 # Einige mehrdeutige Zusammensetzungen unterscheiden sich in der
602 # Lang-S-Schreibung, z.B.
604 # * Wach[s/ſ]tube: Wach-Stube / Wachs-Tube
605 # * Ga[s/ſ]traſſe: Gas-Trasse / Gast-Rasse
606 # * Schiff[ſ/s]tau: Schiffs-Tau / Schiff-Stau
608 # Im Normalfall schreibt s2long-s.py beide Varianten in die Ausgabedatei. Die
609 # Option --drop_homonyms kann verwendet werden, wenn dies nicht erwünscht ist.
614 # * Ersetztes SZ in reformierter Rechtschreibung, wenn ein Selbstlaut folgt
615 # (z.B. "Straſ-ſe" oder "Straſ-se).
617 # - Während in 1901-er Rechtschreibung die Trennung vor dem "ss" erfolgt
618 # (was Ersetzung mit "ſs" impliziert) wäre bei Trennung "wie normales
619 # Doppel-S" dann ein rundes S am Silbenanfang.
621 # Korrekte Fallunterscheidung geht nur bei Betrachtung der Nachbarfelder.
623 # * Tonarten (As-Dur oder Aſ-Dur)
625 # - Im Fraktur-Duden steht As *in Antiqua* mit rundem s, also
626 # keine Aussage zur Schreibung in Fraktur.
627 # - Im 1976-er [Duden]_ steht As ohne Unterstreichung des `s`,
628 # das wäre Lang-S, obgleich am Wortende!
633 # .. [Duden] `Der Große Duden` 16. Auflage, VEB Bibliographisches Institut
636 # Kennzeichnet im Stichwortteil rundes s durch Unterstreichen.
638 # .. [wikipedia] Langes s
639 # http://de.wikipedia.org/wiki/Langes_s
641 # .. [en.wiktionary.org]
642 # http://en.wiktionary.org/wiki/%C5%BF
645 # http://typefoundry.blogspot.com/2008/01/long-s.html
647 # .. [West06] Andrew West, `The rules for long s`, 2006
648 # http://babelstone.blogspot.com/2006/06/rules-for-long-s.html
650 # .. [BCP47] A. Phillips und M. Davis, (Editoren.),
651 # `Tags for Identifying Languages`, http://www.rfc-editor.org/rfc/bcp/bcp47.txt
655 # .. _Wortliste der deutschsprachigen Trennmustermannschaft:
656 # http://mirrors.ctan.org/language/hyphenation/dehyph-exptl/projektbeschreibung.pdf