5 # Dieses Perl-Skript extrahiert einfache Wortlisten aus der
6 # »wortliste«-Datenbank im Langformat (oder ähnlichen Dateien mit gleichem
7 # Dateiformat), die beispielsweise als Eingabedateien für »patgen« verwendet
12 # perl extract-tex.pl [Optionen...] [liste1 liste2 ...] > input.patgen
14 # Die Eingabedateien müssen in UTF-8 kodiert sein; ist keine Eingabedatei
15 # angegeben, verwendet das Skript die Standardeingabe. Beispiele:
17 # perl extract-tex.pl -l < ../wortliste > wortliste.ref.latin9
18 # perl extract-tex.pl -t ../wortliste > wortliste.trad.utf8
22 # perl extract-tex.pl -1 ...
23 # perl extract-tex.pl -t -1 ...
24 # perl extract-tex.pl -s -1 ...
26 # liefern jeweils die gleiche Ausgabe wie
28 # sprachauszug.py -l de-1996-x-versal,de-1996 ...
29 # sprachauszug.py -l de-1901-x-versal,de-1901 ...
30 # sprachauszug.py -l de-CH-1901,de-1901 ...
37 # -s Option »-t« wählt die traditionelle deutsche Rechtschreibung aus,
38 # Option »-s« die traditionelle (deutsch)schweizerische Rechtschreibung.
39 # Wenn weder »-s« noch »-t« gesetzt ist, wird die reformierte deutsche
40 # Rechtschreibung ausgewählt.
42 # -x Ignoriere Optionen »-g«, »-u« sowie »-1« und gib die
43 # sprachspezifischen Felder unbearbeitet aus (inklusive Kommentare).
45 # -g Gib Wörter mit gewichteten Trennstellen aus. Optional kann ein
46 # ganzzahliges Argument angegeben werden: Wert 0 gibt alle gewichtete
47 # Trennstellen aus inklusive »-« (das ist der Standardwert), Wert 1 nur
48 # die Trennstellen mit der höchsten Wichtung (ohne »-«), Wert 2 die
49 # Trennstellen mit der höchsten und zweithöchsten Wichtung (ohne »-«),
52 # Beachte, dass bei nahe beieinanderstehenden Trennstellen derzeit keine
53 # zusätzliche Wichtung vorgenommen wird. Beispielsweise ist in dem Wort
57 # die Trennung »abbe-rufen« schlecht, weil ganz nahe der optimalen
58 # Trennstelle (nach »ab«). Das Skript gibt trotzdem diese Trennstelle
61 # -u Verhindere die Ausgabe von Wörtern mit Markern für unerwünschte
62 # Trennungen (z.B. »An<=al-.pha=bet«). Wenn nicht gesetzt, werden als
63 # ungünstig markierte Trennstellen entfernt (z.B. »An<=alpha=bet«).
65 # -1 (Ziffer 1) Verhindere einbuchstabige Trennungen. Ist die Option
66 # gesetzt, wird die erste dieser Trennungen unterdrückt, falls beide
67 # Trennstellen gleichwertig sind (z.B. »eu-ro-päi-sche« statt
68 # »eu-ro-pä-i-sche«), anderenfalls bleibt die stärkere erhalten (z.B.
69 # »päd<ago-gisch« statt »pä-d<a-go-gisch«).
71 # -v Verhindere die Ausgabe von Versalformen, wo »ß« durch »ss« ersetzt
74 # -l (Kleinbuchstabe L) Konvertiere die Ausgabe von UTF-8 nach latin-9.
78 use English
'-no_match_vars';
79 use utf8
; # String-Literals direkt als UTF-8.
80 use open qw(:std :utf8);
81 use Getopt
::Long
qw(:config bundling);
84 my ($opt_g, $opt_l, $opt_s, $opt_t, $opt_u, $opt_v, $opt_x, $opt_1);
87 GetOptions
("g:i" => \
$opt_g,
102 binmode(STDOUT
, ":encoding(iso-8859-15)") if $opt_l;
105 # Zwei Konstanten für reguläre Ausdrücke, um die Lesbarkeit zu erhöhen.
106 my $marker = qr/[.·<>=-]/x;
107 my $buchstabe = qr/(?: [^.·<>=-] | ch)/x;
110 sub entferne_marker
{
112 $arg =~ s/$marker//g;
118 # Gebe Kommentarzeilen direkt aus, falls verlangt.
127 # Entferne Kommentare.
130 my $kommentar = $1 // "";
132 # Entferne Leerzeichen aller Art.
135 my @feld = split(';');
138 # reformiert: Felder 2, 4, 5, 7
139 # traditionell: Felder 2, 3, 5, 6
140 # traditionell Schweiz: Felder 2, 3, 5, 6, 8
142 # Beachte: Feld n hat Index n-1.
144 $zeile = $feld[2] if defined $feld[2]
145 && $feld[2] ne "-3-" && ($opt_t || $opt_s);
146 $zeile = $feld[3] if defined $feld[3]
147 && $feld[3] ne "-4-" && !($opt_t || $opt_s);
149 # Wir nehmen Versalformen nur dann, wenn es keine normalen Formen (in
150 # Feld 2 oder 3) gibt.
151 $zeile = $feld[4] if defined $feld[4]
152 && $feld[4] ne "-5-" && !$opt_v;
153 $zeile = $feld[5] if defined $feld[5]
154 && $feld[5] ne "-6-" && ($opt_t || $opt_s) && !$opt_v;
155 $zeile = $feld[6] if defined $feld[6]
156 && $feld[6] ne "-7-" && !($opt_t || $opt_s) && !$opt_v;
157 $zeile = $feld[7] if defined $feld[7]
158 && $feld[7] ne "-8-" && $opt_s && !$opt_v;
164 next if $zeile eq "-2-";
167 # Entferne spezielle Trennungen.
168 $zeile =~ s
|\
{ (.*?
) / .*? \
}|$1|gx
;
170 # Entferne Doppeldeutigkeiten.
171 $zeile =~ s
|\
[ (.*?
) / .*? \
]|entferne_marker
($1)|egx
;
173 # Ausgabe von Wörtern mit unerwünschten Trennungen?
174 next if $zeile =~ /\./ and $opt_u;
176 # Entferne einbuchstabige Trennstellen, falls verlangt.
178 # * Die »stärkere« Gruppe von Markern gewinnt; z.B. werden sowohl
179 # »a-b.c« als auch »a<=b-c« zu »a-bc«.
180 # * Bei Gleichwertigkeit gewinnt der rechte Marker, außer er ist als
181 # ungünstig markiert. Daraus folgt, daß »a-b-c« zu »ab-c« wird,
182 # während »a-b-.c« sich zu »a-bc« auflöst.
183 # * »ch« wird wie ein Buchstabe behandelt.
185 $zeile =~ s/[-.]+ (?= $buchstabe [<>=] [.·<>=]* )//gx;
186 $zeile =~ s/[<>=] [.·<>=]* $buchstabe \K [-.]+//gx;
188 $zeile =~ s/-?\. ( $buchstabe - )/$1/gx;
189 $zeile =~ s/( - $buchstabe ) -?\./$1/gx;
191 $zeile =~ s/- ( $buchstabe - )/$1/gx;
194 # Entferne Markierungen für unerwünschte Trennungen (»-.«, »=..«, etc.).
195 $zeile =~ s/[·<>=-]+ \.+//gx;
197 # Wir erlauben Trennung bei allen übrigen Schwankungsfällen.
200 # Entferne Gesangstrennstellen.
201 # TODO: Ergänze Option für »Gesangstext-Trennmuster«
202 $zeile =~ s/($buchstabe) [.·<>=-]* ·+ [.·<>=-]*/$1/gx;
205 # Berechne Wichtungen. Wir verwenden folgende Werte:
216 # Bei mehrfachem Auftreten von »<« hat das am meisten links stehende
217 # den höchsten Rang. Bei mehrfachem Auftreten von »>« hat das am
218 # meisten rechts stehende den höchsten Rang. Beispiel:
220 # Mit<ver<ant-wort>lich>keit
223 # Das bezieht sich auch auf Ketten mit »=>« u.ä:
225 # Ei-gen=wirt>schaft=>lich>keit
233 # Wir zerlegen mit `split' unter Beibehaltung der Begrenzer.
234 my @zerlegung = split /([<>=-]+)/, $zeile;
236 # Wir speichern Wichtung und Rang als Felder.
237 my @wichtung = (-2) x
($#zerlegung + 1);
238 my @rang = (0) x
($#zerlegung + 1);
240 # Erster Durchgang: Ermittle Wichtungswerte.
242 # Wir starten bei erstem Marker (mit Index 1).
243 foreach my $i (1 .. ($#zerlegung - 1)) {
244 # Ignoriere Nicht-Marker.
252 elsif ($m =~ /^--$/) {
255 elsif ($m =~ /^[<>]$/) {
258 elsif ($m =~ /^=$/) {
261 elsif ($m =~ /( ==*>? | <?=*= )/x) {
265 warn "Zeile $INPUT_LINE_NUMBER:"
266 . " unbekannter Marker »$m« behandelt als »-«\n";
273 # Zweiter Durchgang: Adjustiere Wichtung von »<« und »>«.
275 # Behandle »<« von rechts nach links gehend.
277 foreach my $i (reverse(1 .. ($#zerlegung - 1))) {
278 # Ignoriere Nicht-Marker.
281 if (index ($zerlegung[$i], "<") >= 0) {
282 # Hat der rechte Marker in einer Kette von »<« eine höhere
283 # Wichtung, wird diese übernommen.
286 if ($w_vorher >= $w) {
287 $wichtung[$i] = $w_vorher;
293 # »-«-Marker zwischen zwei »<« ändert nicht deren Wichtung.
294 elsif ($zerlegung[$i] ne "-") {
299 # Behandle »>« von links nach rechts gehend.
301 foreach my $i (1 .. ($#zerlegung - 1)) {
302 # Ignoriere Nicht-Marker.
305 if (index ($zerlegung[$i], ">") >= 0) {
306 # Hat der linke Marker in einer Kette von »>« eine höhere
307 # Wichtung, wird diese übernommen.
310 if ($w_vorher >= $w) {
311 $wichtung[$i] = $w_vorher;
317 # »-«-Marker zwischen zwei »>« ändert nicht deren Wichtung.
318 elsif ($zerlegung[$i] ne "-") {
323 # Dritter Durchgang: Ermittle Rang von »<« und »>«.
325 # Behandle »<« von links nach rechts gehend.
327 foreach my $i (1 .. ($#zerlegung - 1)) {
328 # Ignoriere Nicht-Marker.
331 if (index ($zerlegung[$i], "<") >= 0) {
334 # »-«-Marker zwischen zwei »<« ändert nicht den Rang.
335 elsif ($zerlegung[$i] ne "-") {
340 # Behandle »>« von rechts nach links gehend.
342 foreach my $i (reverse(1 .. ($#zerlegung - 1))) {
343 # Ignoriere Nicht-Marker.
346 if (index ($zerlegung[$i], ">") >= 0) {
349 # »-«-Marker zwischen zwei »>« ändert nicht den Rang.
350 elsif ($zerlegung[$i] ne "-") {
355 # Sortiere Indexfeld für Marker mit absteigender Wichtung.
356 my @wichtungsindices =
358 # Benutze Rang für Sekundärsortierung.
359 if ($wichtung[$a] == $wichtung[$b]) {
360 -($rang[$a] <=> $rang[$b]);
363 -($wichtung[$a] <=> $wichtung[$b]);
365 } (0 .. $#zerlegung);
367 # Entferne Trennstellen unter Berücksichtigung des Arguments von »-g«.
372 foreach my $i (@wichtungsindices) {
373 # Alle Wortteile haben einen geraden Index und sind stets am Schluß
374 # von @wichtungsindices.
380 if ($w_vorher == $w) {
381 $g++ if $r_vorher != $r;
390 # Entferne Trennung mit zu geringer Wichtung.
391 $zerlegung[$i] = "" if $g > $opt_g || $w < 0;
394 $zeile = join '', @zerlegung;
397 # Reduziere Trennstellenmarker zu »-«.
398 $zeile =~ s/$marker+/-/g;
403 print " " . $kommentar if $kommentar && $opt_x;