From 06d2ffae7ac0a1c11e263103f1dbd15478937d65 Mon Sep 17 00:00:00 2001 From: =?utf8?q?G=C3=BCnter=20Milde?= Date: Wed, 9 May 2018 10:33:36 +0200 Subject: [PATCH] Neuer Trennstil "dehyphen". MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Wähle Trennungen wie bisher im 'dehyphen-exptl' TeX-Paket (etymologisch, keine „Flatterbuchstaben“). --- dokumente/Trennstile.txt | 2 + skripte/python/edit_tools/sprachauszug.py | 73 ++- skripte/python/edit_tools/wortliste.py | 774 ++++++++++++++++-------------- 3 files changed, 466 insertions(+), 383 deletions(-) diff --git a/dokumente/Trennstile.txt b/dokumente/Trennstile.txt index b99f83a..3215801 100644 --- a/dokumente/Trennstile.txt +++ b/dokumente/Trennstile.txt @@ -191,6 +191,8 @@ Trennstellen mit Abstand eins. (Die angegebenen „Filter“ sind Funktionen in Zum Teil von der bisherigen Praxis (nimm stets die 2.) abweichende Vorzugstrennung (La-sal-le-a-.ner, Athe-i-.sten (AR)). + + Filter: keine_einzelvokale 2. einvokalische Silben am Wortanfang und Ende (auch in Komposita) diff --git a/skripte/python/edit_tools/sprachauszug.py b/skripte/python/edit_tools/sprachauszug.py index 5578334..58d49bb 100755 --- a/skripte/python/edit_tools/sprachauszug.py +++ b/skripte/python/edit_tools/sprachauszug.py @@ -7,7 +7,7 @@ # sprachauszug.py: Einträge einer Sprachvariante auswählen. # ========================================================= -# +# # :: u"""Schreibe getrennte Wörter für eine Sprachvarante. @@ -19,36 +19,80 @@ Ausgabe: Nach Trennregeln der Sprachvariante getrenntes Wort. Bsp: python sprachauszug.py < wortliste > wortliste-de """ +# Abhängigkeiten:: + import sys, os, argparse, codecs, re from wortliste import (WordEntry, ShortEntry, verblasst, fremdwortsilben, - scoretext) + keine_einzelvokale, scoretext) + -# >>> from sprachauszug import traditionell -# >>> traditionell(u'Psy-ch>> from sprachauszug import etymologisch +# >>> etymologisch(u'Psy-ch>> traditionell(u'An>> etymologisch(u'An>> from sprachauszug import modern -# >>> modern(u'Psy-ch>> modern(u'An>> print modern(u'Pä-d>> from sprachauszug import dehyphen +# >>> dehyphen(u'Psy-ch>> dehyphen(u'An>> from wortliste import fremdwortsilben +# Ableitung von de-1901 aus de-1996 (Reversion der Reform 1996). # -# >>> fremdwoerter = (u'no-b-le Zy-k-lus Ma-g-net Fe-b-ru-ar ' -# ... u'Hy-d-rant Ar-th-ri-tis') -# >>> for wort in fremdwoerter.split(): -# ... print wort, '->', fremdwortsilben(wort) -# no-b-le -> no-ble -# Zy-k-lus -> Zy-klus -# Ma-g-net -> Ma-gnet -# Fe-b-ru-ar -> Fe-bru-ar -# Hy-d-rant -> Hy-drant -# Ar-th-ri-tis -> Ar-thri-tis +# Mit keep_key == True werden nur Änderungen vorgenommen, die die +# Schreibung des (ungetrennten) Wortes nicht verändern. # -# >>> for wort in fremdwoerter.split(): -# ... print wort, '->', fremdwortsilben(wort, 'modern') -# no-b-le -> nob-le -# Zy-k-lus -> Zyk-lus -# Ma-g-net -> Mag-net -# Fe-b-ru-ar -> Feb-ru-ar -# Hy-d-rant -> Hyd-rant -# Ar-th-ri-tis -> Arth-ri-tis +# >>> from wortliste import ableitung1901 # # :: -def fremdwortsilben(wort, style='traditional'): - """Select in-word hyphenation of foreign words.""" - if style == "modern": # Sprechsilbenregel - return re.sub(u'-([bcdfgkptv]|th|st)-(?=[lrn])', u'\\1-', wort) - else: # traditionell - return re.sub(u'-([bcdfgkptv]|th|st)-(?=[lrn])', u'-\\1', wort) - # Versuch: auch Alternativtrennung nach führendem Vokal: - # Ap-ri-kose -> Apri-kose aber auch Ad-ler -> Adler (!) - # return re.sub(u'(-|^[AEIOUÄÖÜaeiouäöü])([bcdfgkptv]|th|st)-(?=[lrn])', - # u'\\1\\2', wort) +def ableitung1901(wort, keep_key=False): + """Reverse regular changes of the 1996 orthography reform.""" -# Tests: + +# Trennregeländerungen +# ~~~~~~~~~~~~~~~~~~~~ # -# K86 Untrennbar sind in Fremdwörtern die Verbindungen von Verschluß- und -# Reibelauten mit l und r, ... +# Diese Regeln ändern nicht das Wort, nur die Trennmöglichkeiten. # -# >>> fremdwoerter = (u'Pu-b-li-kum flexi-b-ler Zy-k-lone Qua-d-rat ' -# ... u'Spek-t-rum manö-v-rieren') -# >>> for wort in fremdwoerter.split(): -# ... print wort, '->', fremdwortsilben(wort) -# Pu-b-li-kum -> Pu-bli-kum -# flexi-b-ler -> flexi-bler -# Zy-k-lone -> Zy-klone -# Qua-d-rat -> Qua-drat -# Spek-t-rum -> Spek-trum -# manö-v-rieren -> manö-vrieren +# Alternativtrennungen auswählen:: + + wort = fremdwortsilben(wort) + wort = verblasst(wort) + +# st-Trennung +# """"""""""" # -# die Lautfolge st+r bleibt ungetrennt, wenn keine Wortfuge vorliegt. +# K75: Trenne nie st. # -# >>> fremdwoerter = u'Di-st-rikt Magi-st-rat laku-st-risch ab-st-rakt' -# >>> for wort in fremdwoerter.split(): -# ... print wort, '->', fremdwortsilben(wort) -# Di-st-rikt -> Di-strikt -# Magi-st-rat -> Magi-strat -# laku-st-risch -> laku-strisch -# ab-st-rakt -> ab-strakt +# Ersetze 's-t' mit '-st': # -# K 87 Untrennbar ist die Konsonantenverbindung "gn". +# >>> ableitung1901(u'Diens-te') +# u'Dien-ste' +# >>> print ableitung1901(u'wuss-te', keep_key=True) +# wuss-te # -# >>> fremdwoerter = u'Ma-g-net Pro-g-nose Si-g-net' -# >>> for wort in fremdwoerter.split(): -# ... print wort, '->', fremdwortsilben(wort) -# Ma-g-net -> Ma-gnet -# Pro-g-nose -> Pro-gnose -# Si-g-net -> Si-gnet +# Aber Trennung von s-theta erlaubt (nach K74): # -# Keine Übergeneralisierung: +# >>> print ableitung1901(u'Äs-thet') +# Äs-thet # -# >>> woerter = u'Seg-ler bast-le Ad-ler' -# >>> for wort in woerter.split(): -# ... print wort, '->', fremdwortsilben(wort) -# Seg-ler -> Seg-ler -# bast-le -> bast-le -# Ad-ler -> Ad-ler +# :: + + wort = re.sub(u'(? Apri-kose -# ig-no-rie-ren -> igno-rie-ren +# K76: Trenne 'ck' als 'k-k'. # +# Ersetze '-ck' mit '{ck/k-k}': # -# verblasst() -# -------------- +# >>> ableitung1901(u'Ha-cke') +# u'Ha{ck/k-k}e' +# >>> ableitung1901(u'Acker') +# u'A{ck/k-k}er' +# >>> ableitung1901(u'Got-tes=acker') +# u'Got-tes=a{ck/k-k}er' +# >>> ableitung1901(u'Aal=beck') +# u'Aal=beck' +# >>> ableitung1901(u'be>> ableitung1901(u'Es-te') +# u'Este' +# >>> print ableitung1901(u'Nord=os-ten') +# Nord=osten +# >>> print ableitung1901(u'Po-ly>> from wortliste import verblasst -# >>> blasse = (u'hi-nes-sant Li-n>> for wort in blasse.split(): -# ... print wort, '->', verblasst(wort) -# hi-n hin her dar Chrys Hekt He-li-koes-sant -> in-ter>es-sant -# Li-n Lin Päd>> for wort in blasse.split(): -# ... print wort, '->', verblasst(wort, 'modern') -# hi-n hi-nauf -# he-r he-ran -# da-r da-rum -# Chry-s Chry-san-the-me -# Hek-t Hek-tar -# He-li-ko He-li-kop-ter -# in-te-r>es-sant -> in-te-res-sant -# Li-n Li-noleum -# Pä-d Pä-da-go-gik +# >>> print ableitung1901(u'the-is-tisch') +# the-i-stisch # -# Ersetze, wenn zwischen Haupttrennstelle und Nebentrennstelle nur ein -# Buchstabe liegt. -# (Die Haupttrennstelle kann vor oder nach der Nebentrennstelle liegen.) # :: -def verblasst(wort, style='traditional'): - """Select hyphenation of foreign words with obscure etymology.""" - if style == "modern": # Sprechsilbenregel - wort = re.sub(u'[<>=]+[.]*(.[-.]+)', u'\\1', wort) - wort = re.sub(u'([-.]+.)[<>=]+[.]*', u'\\1', wort) - else: # etymologisch - wort = re.sub(u'([<>=]+[.]*.)[-.]+', u'\\1', wort) - wort = re.sub(u'[-.]+(.[<>=]+)', u'\\1', wort) - return wort - + wort = re.sub(u'((?<=[=<].)|(?<=^.))-', ur'', wort) + if keep_key: + return wort -# Tests: +# Rechtschreibänderungen +# ~~~~~~~~~~~~~~~~~~~~~~ # -# K44 „ſ“ (langes s) steht in Fremdwörtern... +# Diese Regeln ändern die Schreibung des ungetrennten Worts (und somit den +# Schlüssel im Langformat der Wortliste). # -# >>> blasse = (u'tran>> for wort in blasse.split(): -# ... print wort, '->', verblasst(wort) -# tran tran tran ab Ab Pros>> blasse = (u'Bür-ger=in<.i-ti-a-ti-ve Pä-..d>> for wort in blasse.split(): -# ... print wort, '->', verblasst(wort) -# Bür-ger=in<.i-ti-a-ti-ve -> Bür-ger=in<.iti-a-ti-ve -# Pä-..d Päd>> for wort in blasse.split(): -# ... print wort, '->', verblasst(wort, 'modern') -# Bür-ger=in<.i-ti-a-ti-ve -> Bür-ger=ini-ti-a-ti-ve -# Pä-..d Pä-..de-..rast +# Ersetze ungetrenntes 'ss' mit 'ß': # +# >>> print ableitung1901(u'passt') +# paßt +# >>> print ableitung1901(u'Hass') +# Haß +# >>> print ableitung1901(u'Fass=brau-se') +# Faß=brau-se +# >>> print ableitung1901(u'wuss-te') +# wuß-te # -# scoretext() -# ------------ +# ß steht für inlautendes ss, wenn ein 'e' ausfällt (und der Ausfall nicht +# durch Apostroph angedeutet wird) # -# Füge Trennmöglichkeiten am Wortanfang und -ende zu, die nach K79 (bzw. §107 -# E2 des Regelwerkes) verboten sind aber in Notentexten gebraucht werden. +# >>> print ableitung1901(u'wäss-rig') +# wäß-rig +# >>> print ableitung1901(u'an>> print ableitung1901(u'duss-lig') +# duß-lig +# >>> print ableitung1901(u'bissl') +# bißl # -# >>> from wortliste import scoretext +# Keine Wandlung zu "ß": +# getrenntes Doppel-s (s-s) # -# >>> scoretext(u'Abend') -# u'A.bend' -# >>> scoretext(u'Ra-dio') -# u'Ra-di.o' +# >>> print ableitung1901(u'Was-ser') +# Was-ser # -# Das gleiche gilt für Trennmöglichkeiten am Anfang/Ende von Teilwörtern: +# Vokal folgt (Fremdwörter): +# >>> print ableitung1901(u'Com-tesse') +# Com-tesse # -# >>> scoretext(u'Eis=ano-ma-lie') -# u'Eis=a.no-ma-lie' -# >>> scoretext(u'Ra-dio>> scoretext(u'Ai-chin-ger'), scoretext(u'Ai-da') -# (u'Ai-chin-ger', u'A.i-da') -# >>> scoretext(u'Ma-rie'), scoretext(u'Li-nie') -# (u'Ma-rie', u'Li-ni.e') -# >>> scoretext(u'Ta-too'), scoretext(u'Zoo>> scoretext(u'A-pnoe'), scoretext(u'O-boe') -# (u'A-pnoe', u'O-bo.e') -# >>> scoretext(u'Plaque'), scoretext(u'treue') -# (u'Plaque', u'treu.e') -# >>> scoretext(u'Fon-due=pfan-ne'), scoretext(u'Aue') -# (u'Fon-due=pfan-ne', u'Au.e') -# >>> scoretext(u'Ge-nie'), scoretext(u'Iphi-ge-nie') -# (u'Ge-nie', u'I.phi-ge-nie') -# >>> scoretext(u'Ago-nie'), scoretext(u'Be-go-nie') -# (u'A.go-nie', u'Be-go-ni.e') -# >>> scoretext(u'Kom-pa-nie'), scoretext(u'Kas-ta-nie'), scoretext(u'Ge-ra-nie') -# (u'Kom-pa-nie', u'Kas-ta-ni.e', u'Ge-ra-ni.e') -# -# ungelöst: Knie / Kni.e # pl. -# :: - -def scoretext(word): - """Mark up leading one-letter syllables.""" - # Führender Vokal, gefolgt von Silbenanfang - # (optionaler Konsonant (auch ch/ck/ph/rh/sch/sh/th) + Vokal) - for match in re.finditer(u'(^|[<=])([aeiouäöü])((.|ch|ck|ph|sch|th)?[aeiouäöü])', - word, flags=re.IGNORECASE): - # print match.groups() - # Ausnahmen: Doppellaute, Diphtonge (außer A-i-da), Umlaute - if (re.search(u'(aa|ae|ai|au|äu|ei|eu|oe|oo|ou|ue)', - match.group(0), flags=re.IGNORECASE) - and word != u'Ai-da' or word == u'io-ta' ): - continue - word = ''.join((word[:match.start()], match.expand(u'\\1\\2.\\3'), - scoretext(word[match.end():]))) - break - # zwei Vokale am Wortende - for match in re.finditer(u'([aeiouäöü])([aeiouäöü])([<>=]|$)', word): - # if re.search(u'(oo)', match.group(0)): - # if 'ie' in match.group(0) and re.search(u'([a]-nie)', word, flags=re.IGNORECASE): - # sys.stderr.write(word+' '+match.group(0)+'\n') - # Ausnahmen: Doppellaute, Diphtonge, Umlaute (außer "Oboe") - if (re.search(u'(aa|ae|ai|au|äu|ee|ei|eu|oe|oi|ou|ui)', match.group(0)) - and not word[:match.end()].endswith(u'waii') # ! Hawaii - and not word[:match.end()].endswith(u'boe')): # ! Oboe - continue - # Ausnahmen mit Ausnahmen: - # …oo außer zoo<, ... - if 'oo' in match.group(0) and match.group(0) != 'oo<': - continue - # …ie außer "-(l)inie", Iphigenie, Kastanie, Geranie, Begonie - if ('ie' in match.group(0) - and not word[:match.end()].endswith(u'i-nie') # Linie, - and not word[:match.end()].endswith(u'ta-nie') # Kastanie, - and not word[:match.end()].endswith(u'ra-nie') # Geranie, - and not word[:match.end()].endswith(u'e-go-nie') # Begonie != Agonie - and not word == u'Iphi-ge-nie'): - continue - # …ue (Plaque, Re-vue, vogue) außer "-tue, -aue, ... -äue" - if 'ue' in match.group(0) and re.search(u'[^aeät]ue([<>=]|$)', - word[:match.end()], flags=re.IGNORECASE): - continue - - word = ''.join((word[:match.start()], match.expand(u'\\1.\\2\\3'), - scoretext(word[match.end():]))) - break - return word - - -# ableitung1901() -# --------------- -# -# Ableitung von de-1901 aus de-1996 (Reversion der Reform 1996). -# -# Mit keep_key == True werden nur Änderungen vorgenommen, die die -# Schreibung des (ungetrennten) Wortes nicht verändern. -# -# >>> from wortliste import ableitung1901 -# -# :: - -def ableitung1901(wort, keep_key=False): - """Reverse regular changes of the 1996 orthography reform.""" - - -# Trennregeländerungen -# ~~~~~~~~~~~~~~~~~~~~ -# -# Diese Regeln ändern nicht das Wort, nur die Trennmöglichkeiten. -# -# Alternativtrennungen auswählen:: - - wort = fremdwortsilben(wort) - wort = verblasst(wort) - -# st-Trennung -# """"""""""" -# -# K75: Trenne nie st. -# -# Ersetze 's-t' mit '-st': -# -# >>> ableitung1901(u'Diens-te') -# u'Dien-ste' -# >>> print ableitung1901(u'wuss-te', keep_key=True) -# wuss-te -# -# Aber Trennung von s-theta erlaubt (nach K74): -# -# >>> print ableitung1901(u'Äs-thet') -# Äs-thet -# -# :: - - wort = re.sub(u'(?>> ableitung1901(u'Ha-cke') -# u'Ha{ck/k-k}e' -# >>> ableitung1901(u'Acker') -# u'A{ck/k-k}er' -# >>> ableitung1901(u'Got-tes=acker') -# u'Got-tes=a{ck/k-k}er' -# >>> ableitung1901(u'Aal=beck') -# u'Aal=beck' -# >>> ableitung1901(u'be>> ableitung1901(u'Es-te') -# u'Este' -# >>> print ableitung1901(u'Nord=os-ten') -# Nord=osten -# >>> print ableitung1901(u'Po-ly>> print ableitung1901(u'the-is-tisch') -# the-i-stisch -# -# :: - - wort = re.sub(u'((?<=[=<].)|(?<=^.))-', ur'', wort) - - if keep_key: - return wort - -# Rechtschreibänderungen -# ~~~~~~~~~~~~~~~~~~~~~~ -# -# Diese Regeln ändern die Schreibung des ungetrennten Worts (und somit den -# Schlüssel im Langformat der Wortliste). -# -# Schluss-ss -# """""""""" -# -# K38: Kein "ss" und "sst" am Silbenende (ungetrenntes "ss" nur in Ausnahmen) -# (Andererseit ist 'ßt' und Schluss-ß auch in de-1996 möglich (langer Vokal).) -# -# Ersetze ungetrenntes 'ss' mit 'ß': -# -# >>> print ableitung1901(u'passt') -# paßt -# >>> print ableitung1901(u'Hass') -# Haß -# >>> print ableitung1901(u'Fass=brau-se') -# Faß=brau-se -# >>> print ableitung1901(u'wuss-te') -# wuß-te -# -# ß steht für inlautendes ss, wenn ein 'e' ausfällt (und der Ausfall nicht -# durch Apostroph angedeutet wird) -# -# >>> print ableitung1901(u'wäss-rig') -# wäß-rig -# >>> print ableitung1901(u'an>> print ableitung1901(u'duss-lig') -# duß-lig -# >>> print ableitung1901(u'bissl') -# bißl -# -# Keine Wandlung zu "ß": -# getrenntes Doppel-s (s-s) -# -# >>> print ableitung1901(u'Was-ser') -# Was-ser -# -# Vokal folgt (Fremdwörter): -# >>> print ableitung1901(u'Com-tesse') -# Com-tesse -# -# Großbuchstabe folgt +# Großbuchstabe folgt # # >>> print ableitung1901(u'WissZeitVG') # Abkürzung # WissZeitVG @@ -2650,6 +2382,310 @@ def long2short(lines, prune=True, drop_sz=False): # [ShortEntry(u'# toller Kommentar')] # # +# Trennfilter +# =========== +# +# Funktionen, die einen Trennstil (oder einen Aspekt eines Trennstils) +# implementieren (siehe auch dokumentation/Trennstile.txt). +# +# fremdwortsilben() +# ----------------- +# +# Entferne Alternativtrennungen bei einfachen und suffigierten Fremdwörtern: +# +# Regelwerk (1996) § 112: +# In Fremdwörtern können die Verbindungen aus Buchstaben für einen +# Konsonanten + l, n oder r entweder entsprechend § 110 getrennt werden, +# oder sie kommen ungetrennt auf die neue Zeile. +# +# >>> from wortliste import fremdwortsilben +# +# >>> fremdwoerter = (u'no-b-le Zy-k-lus Ma-g-net Fe-b-ru-ar ' +# ... u'Hy-d-rant Ar-th-ri-tis') +# >>> for wort in fremdwoerter.split(): +# ... print wort, '->', fremdwortsilben(wort) +# no-b-le -> no-ble +# Zy-k-lus -> Zy-klus +# Ma-g-net -> Ma-gnet +# Fe-b-ru-ar -> Fe-bru-ar +# Hy-d-rant -> Hy-drant +# Ar-th-ri-tis -> Ar-thri-tis +# +# >>> for wort in fremdwoerter.split(): +# ... print wort, '->', fremdwortsilben(wort, 'modern') +# no-b-le -> nob-le +# Zy-k-lus -> Zyk-lus +# Ma-g-net -> Mag-net +# Fe-b-ru-ar -> Feb-ru-ar +# Hy-d-rant -> Hyd-rant +# Ar-th-ri-tis -> Arth-ri-tis +# +# :: + +def fremdwortsilben(wort, style='etymologisch'): + """Select in-word hyphenation of foreign words.""" + if style == "modern": # Sprechsilbenregel + return re.sub(u'-([bcdfgkptv]|th|st)-(?=[lrn])', u'\\1-', wort) + else: # etymologisch + return re.sub(u'-([bcdfgkptv]|th|st)-(?=[lrn])', u'-\\1', wort) + # Versuch: auch Alternativtrennung nach führendem Vokal: + # Ap-ri-kose -> Apri-kose aber auch Ad-ler -> Adler (!) + # return re.sub(u'(-|^[AEIOUÄÖÜaeiouäöü])([bcdfgkptv]|th|st)-(?=[lrn])', + # u'\\1\\2', wort) + +# Tests: +# +# K86 Untrennbar sind in Fremdwörtern die Verbindungen von Verschluß- und +# Reibelauten mit l und r, ... +# +# >>> fremdwoerter = (u'Pu-b-li-kum flexi-b-ler Zy-k-lone Qua-d-rat ' +# ... u'Spek-t-rum manö-v-rieren') +# >>> for wort in fremdwoerter.split(): +# ... print wort, '->', fremdwortsilben(wort) +# Pu-b-li-kum -> Pu-bli-kum +# flexi-b-ler -> flexi-bler +# Zy-k-lone -> Zy-klone +# Qua-d-rat -> Qua-drat +# Spek-t-rum -> Spek-trum +# manö-v-rieren -> manö-vrieren +# +# die Lautfolge st+r bleibt ungetrennt, wenn keine Wortfuge vorliegt. +# +# >>> fremdwoerter = u'Di-st-rikt Magi-st-rat laku-st-risch ab-st-rakt' +# >>> for wort in fremdwoerter.split(): +# ... print wort, '->', fremdwortsilben(wort) +# Di-st-rikt -> Di-strikt +# Magi-st-rat -> Magi-strat +# laku-st-risch -> laku-strisch +# ab-st-rakt -> ab-strakt +# +# K 87 Untrennbar ist die Konsonantenverbindung "gn". +# +# >>> fremdwoerter = u'Ma-g-net Pro-g-nose Si-g-net' +# >>> for wort in fremdwoerter.split(): +# ... print wort, '->', fremdwortsilben(wort) +# Ma-g-net -> Ma-gnet +# Pro-g-nose -> Pro-gnose +# Si-g-net -> Si-gnet +# +# Keine Übergeneralisierung: +# +# >>> woerter = u'Seg-ler bast-le Ad-ler' +# >>> for wort in woerter.split(): +# ... print wort, '->', fremdwortsilben(wort) +# Seg-ler -> Seg-ler +# bast-le -> bast-le +# Ad-ler -> Ad-ler +# +# wegen Übergeneralisierung nicht möglich: +# Ap-ri-kose -> Apri-kose +# ig-no-rie-ren -> igno-rie-ren +# +# +# verblasst() +# -------------- +# +# Entferne Alternativtrennungen nach §113 (verblasste Etymologie). +# +# Regelwerk (1996) §113: +# Wörter, die sprachhistorisch oder von der Herkunftssprache her gesehen +# Zusammensetzungen oder Präfigierungen sind, aber nicht mehr als solche +# empfunden oder erkannt werden, kann man entweder nach § 108 oder nach § +# 109 bis § 112 trennen. +# +# >>> from wortliste import verblasst +# >>> blasse = (u'hi-nes-sant Li-n>> for wort in blasse.split(): +# ... print wort, '->', verblasst(wort) +# hi-n hin her dar Chrys Hekt He-li-koes-sant -> in-ter>es-sant +# Li-n Lin Päd>> for wort in blasse.split(): +# ... print wort, '->', verblasst(wort, 'modern') +# hi-n hi-nauf +# he-r he-ran +# da-r da-rum +# Chry-s Chry-san-the-me +# Hek-t Hek-tar +# He-li-ko He-li-kop-ter +# in-te-r>es-sant -> in-te-res-sant +# Li-n Li-noleum +# Pä-d Pä-da-go-gik +# +# Ersetze, wenn zwischen Haupttrennstelle und Nebentrennstelle nur ein +# Buchstabe liegt. +# (Die Haupttrennstelle kann vor oder nach der Nebentrennstelle liegen.) +# :: + +def verblasst(wort, style='etymologisch'): + """Select hyphenation of foreign words with obscure etymology.""" + if style == "modern": # Sprechsilbenregel + wort = re.sub(u'[<>=]+[.]*(.[-.]+)', u'\\1', wort) + wort = re.sub(u'([-.]+.)[<>=]+[.]*', u'\\1', wort) + else: # etymologisch + wort = re.sub(u'([<>=]+[.]*.)[-.]+', u'\\1', wort) + wort = re.sub(u'[-.]+(.[<>=]+)', u'\\1', wort) + return wort + + + +# Tests: +# +# K44 „ſ“ (langes s) steht in Fremdwörtern... +# +# >>> blasse = (u'tran>> for wort in blasse.split(): +# ... print wort, '->', verblasst(wort) +# tran tran tran ab Ab Pros>> blasse = (u'Bür-ger=in<.i-ti-a-ti-ve Pä-..d>> for wort in blasse.split(): +# ... print wort, '->', verblasst(wort) +# Bür-ger=in<.i-ti-a-ti-ve -> Bür-ger=in<.iti-a-ti-ve +# Pä-..d Päd>> for wort in blasse.split(): +# ... print wort, '->', verblasst(wort, 'modern') +# Bür-ger=in<.i-ti-a-ti-ve -> Bür-ger=ini-ti-a-ti-ve +# Pä-..d Pä-..de-..rast +# +# +# scoretext() +# ------------ +# +# Füge Trennmöglichkeiten am Wortanfang und -ende zu, die nach K79 (bzw. §107 +# E2 des Regelwerkes) verboten sind aber in Notentexten gebraucht werden. +# +# >>> from wortliste import scoretext +# >>> scoretext(u'Abend') +# u'A.bend' +# >>> scoretext(u'Ra-dio') +# u'Ra-di.o' +# +# Das gleiche gilt für Trennmöglichkeiten am Anfang/Ende von Teilwörtern: +# +# >>> scoretext(u'Eis=ano-ma-lie') +# u'Eis=a.no-ma-lie' +# >>> scoretext(u'Ra-dio>> scoretext(u'Ai-chin-ger'), scoretext(u'Ai-da') +# (u'Ai-chin-ger', u'A.i-da') +# >>> scoretext(u'Ma-rie'), scoretext(u'Li-nie') +# (u'Ma-rie', u'Li-ni.e') +# >>> scoretext(u'Ta-too'), scoretext(u'Zoo>> scoretext(u'A-pnoe'), scoretext(u'O-boe') +# (u'A-pnoe', u'O-bo.e') +# >>> scoretext(u'Plaque'), scoretext(u'treue') +# (u'Plaque', u'treu.e') +# >>> scoretext(u'Fon-due=pfan-ne'), scoretext(u'Aue') +# (u'Fon-due=pfan-ne', u'Au.e') +# >>> scoretext(u'Ge-nie'), scoretext(u'Iphi-ge-nie') +# (u'Ge-nie', u'I.phi-ge-nie') +# >>> scoretext(u'Ago-nie'), scoretext(u'Be-go-nie') +# (u'A.go-nie', u'Be-go-ni.e') +# >>> scoretext(u'Kom-pa-nie'), scoretext(u'Kas-ta-nie'), scoretext(u'Ge-ra-nie') +# (u'Kom-pa-nie', u'Kas-ta-ni.e', u'Ge-ra-ni.e') +# +# ungelöst: Knie / Kni.e # pl. +# :: + +def scoretext(word): + """Mark up leading one-letter syllables.""" + # Führender Vokal, gefolgt von Silbenanfang + # (optionaler Konsonant (auch ch/ck/ph/rh/sch/sh/th) + Vokal) + for match in re.finditer(u'(^|[<=])([aeiouäöü])((.|ch|ck|ph|sch|th)?[aeiouäöü])', + word, flags=re.IGNORECASE): + # print match.groups() + # Ausnahmen: Doppellaute, Diphtonge (außer A-i-da), Umlaute + if (re.search(u'(aa|ae|ai|au|äu|ei|eu|oe|oo|ou|ue)', + match.group(0), flags=re.IGNORECASE) + and word != u'Ai-da' or word == u'io-ta' ): + continue + word = ''.join((word[:match.start()], match.expand(u'\\1\\2.\\3'), + scoretext(word[match.end():]))) + break + # zwei Vokale am Wortende + for match in re.finditer(u'([aeiouäöü])([aeiouäöü])([<>=]|$)', word): + # if re.search(u'(oo)', match.group(0)): + # if 'ie' in match.group(0) and re.search(u'([a]-nie)', word, flags=re.IGNORECASE): + # sys.stderr.write(word+' '+match.group(0)+'\n') + # Ausnahmen: Doppellaute, Diphtonge, Umlaute (außer "Oboe") + if (re.search(u'(aa|ae|ai|au|äu|ee|ei|eu|oe|oi|ou|ui)', match.group(0)) + and not word[:match.end()].endswith(u'waii') # ! Hawaii + and not word[:match.end()].endswith(u'boe')): # ! Oboe + continue + # Ausnahmen mit Ausnahmen: + # …oo außer zoo<, ... + if 'oo' in match.group(0) and match.group(0) != 'oo<': + continue + # …ie außer "-(l)inie", Iphigenie, Kastanie, Geranie, Begonie + if ('ie' in match.group(0) + and not word[:match.end()].endswith(u'i-nie') # Linie, + and not word[:match.end()].endswith(u'ta-nie') # Kastanie, + and not word[:match.end()].endswith(u'ra-nie') # Geranie, + and not word[:match.end()].endswith(u'e-go-nie') # Begonie != Agonie + and not word == u'Iphi-ge-nie'): + continue + # …ue (Plaque, Re-vue, vogue) außer "-tue, -aue, ... -äue" + if 'ue' in match.group(0) and re.search(u'[^aeät]ue([<>=]|$)', + word[:match.end()], flags=re.IGNORECASE): + continue + + word = ''.join((word[:match.start()], match.expand(u'\\1.\\2\\3'), + scoretext(word[match.end():]))) + break + return word + + +# keine_einzelvokale() +# -------------------- +# +# Traditionell enthalten die TeX-Trennmuster keine Trennstellen deren Abstand +# zur Nachbartrennstelle einen Buchstaben beträgt. Dies ist eine *ästhetische* +# Entscheidung um „Flatterbuchstaben“ zu vermeiden +# +# Bei einvokalischen Silben im Wortinneren, nimm die zweite: +# +# >>> from wortliste import keine_einzelvokale +# >>> einzelne = (u'The-a-ter me-ri-di-.o-nal') +# >>> for wort in einzelne.split(): +# ... print wort, '->', keine_einzelvokale(wort) +# The-a-ter -> Thea-ter +# me-ri-di-.o-nal -> me-ri-dio-nal +# +# Allerdings nicht, wenn die erste Trennstelle unterdrückt ist: +# +# >>> einzelne = (u'La-sal-le-a-.ner Athe-i-.sten') +# >>> for wort in einzelne.split(): +# ... print wort, '->', keine_einzelvokale(wort) +# La-sal-le-a-.ner -> La-sal-le-a-.ner +# Athe-i-.sten -> Athe-i-.sten +# +# :: + +def keine_einzelvokale(wort): + """Drop marker after single vowels.""" + return re.sub(u'-[.]*([aeiouyäöü]-[^.])', u'\\1', wort) + + # Hilfsfunktionen # =============== # -- 2.11.4.GIT