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
25 # -s Option »-t« wählt die traditionelle deutsche Rechtschreibung aus,
26 # Option »-s« die traditionelle (deutsch)schweizerische Rechtschreibung.
27 # Wenn weder »-s« noch »-t« gesetzt ist, wird die reformierte deutsche
28 # Rechtschreibung ausgewählt.
30 # -x Ignoriere Optionen »-g«, »-u« und »-1« und gib die sprachspezifischen
31 # Felder unbearbeitet aus (inklusive Kommentare).
33 # -g Gib Wörter mit gewichteten Trennstellen aus. Optional kann ein
34 # ganzzahliges Argument angegeben werden: Wert 0 gibt alle gewichtete
35 # Trennstellen aus inklusive »-« (das ist der Standardwert), Wert 1 nur
36 # die Trennstellen mit der höchsten Wichtung (ohne »-«), Wert 2 die
37 # Trennstellen mit der höchsten und zweithöchsten Wichtung (ohne »-«),
40 # Beachte, dass bei nahe beieinanderstehenden Trennstellen derzeit keine
41 # zusätzliche Wichtung vorgenommen wird. Beispielsweise ist in dem Wort
45 # die Trennung »abbe-rufen« schlecht, weil ganz nahe der optimalen
46 # Trennstelle (nach »ab«). Das Skript gibt trotzdem diese Trennstelle
49 # -u Verhindere die Ausgabe von Wörtern mit Markern für unerwünschte
50 # Trennungen (z.B. »An<=al-.pha=bet«). Wenn nicht gesetzt, werden als
51 # ungünstig markierte Trennstellen entfernt (z.B. »An<=alpha=bet«).
53 # -1 (Ziffer 1) Verhindere einbuchstabige Trennungen. Ist die Option
54 # gesetzt, wird die erste dieser Trennungen unterdrückt, falls beide
55 # Trennstellen gleichwertig sind (z.B. »eu-ro-päi-sche« statt
56 # »eu-ro-pä-i-sche«), anderenfalls bleibt die stärkere erhalten (z.B.
57 # »päd<ago-gisch« statt »pä-d<a-go-gisch«). Diese Option wird nach der
58 # Behandlung von Ungünstigkeitsmarkern ausgeführt.
60 # -v Verhindere die Ausgabe von Versalformen, wo »ß« durch »ss« ersetzt
63 # -l (Kleinbuchstabe L) Konvertiere die Ausgabe von UTF-8 nach latin-9 (wie
64 # von »patgen« benötigt).
68 use English
'-no_match_vars';
69 use utf8
; # String-Literals direkt als UTF-8.
70 use open qw(:std :utf8);
71 use Getopt
::Long
qw(:config bundling);
74 my ($opt_g, $opt_l, $opt_s, $opt_t, $opt_u, $opt_v, $opt_x, $opt_1);
77 GetOptions
("g:i" => \
$opt_g,
92 binmode(STDOUT
, ":encoding(iso-8859-15)") if $opt_l;
103 # Gebe Kommentarzeilen direkt aus, falls verlangt.
112 # Entferne Kommentare.
115 my $kommentar = $1 // "";
117 # Entferne Leerzeichen aller Art.
120 my @feld = split(';');
123 # reformiert: Felder 2, 4, 5, 7
124 # traditionell: Felder 2, 3, 5, 6
125 # traditionell Schweiz: Felder 2, 3, 5, 6, 8
127 # Beachte: Feld n hat Index n-1.
128 my $zeile = $feld[1];
129 $zeile = $feld[2] if defined $feld[2]
130 && $feld[2] ne "-3-" && ($opt_t || $opt_s);
131 $zeile = $feld[3] if defined $feld[3]
132 && $feld[3] ne "-4-" && !($opt_t || $opt_s);
133 $zeile = $feld[4] if defined $feld[4]
134 && $feld[4] ne "-5-" && !$opt_v;
135 $zeile = $feld[5] if defined $feld[5]
136 && $feld[5] ne "-6-" && ($opt_t || $opt_s) && !$opt_v;
137 $zeile = $feld[6] if defined $feld[6]
138 && $feld[6] ne "-7-" && !($opt_t || $opt_s) && !$opt_v;
139 $zeile = $feld[7] if defined $feld[7]
140 && $feld[7] ne "-8-" && $opt_s && !$opt_v;
142 next if $zeile eq "-2-";
145 # Entferne spezielle Trennungen.
146 $zeile =~ s
|\
{ (.*?
) / .*? \
}|$1|gx
;
148 # Entferne Doppeldeutigkeiten.
149 $zeile =~ s
|\
[ (.*?
) / .*? \
]|entferne_marker
($1)|egx
;
151 # Ausgabe von Wörtern mit unerwünschten Trennungen?
152 next if $zeile =~ /\./ and $opt_u;
154 # Entferne Markierungen für unerwünschte Trennungen.
155 $zeile =~ s/[·<>=-]* \.+ [·<>=-]*//gx;
157 # Entferne einbuchstabige Trennstellen, falls verlangt.
158 $zeile =~ s/- ([^·<>=-]) (?= [-<>=])/$1/gx if $opt_1;
159 $zeile =~ s/([<>=] [^·<>=-]) -/$1/gx if $opt_1;
162 # Berechne Wichtungen. Wir verwenden folgende Werte:
173 # Bei mehrfachem Auftreten von »<« hat das am meisten links stehende
174 # den höchsten Rang. Bei mehrfachem Auftreten von »>« hat das am
175 # meisten rechts stehende den höchsten Rang. Beispiel:
177 # Mit<ver<ant-wort>lich>keit
180 # Das bezieht sich auch auf Ketten mit »=>« u.ä:
182 # Ei-gen=wirt>schaft=>lich>keit
190 # Wir zerlegen mit `split' unter Beibehaltung der Begrenzer.
191 my @zerlegung = split /([<>=-]+)/, $zeile;
193 # Wir speichern Wichtung und Rang als Felder.
194 my @wichtung = (-2) x
($#zerlegung + 1);
195 my @rang = (0) x
($#zerlegung + 1);
197 # Erster Durchgang: Ermittle Wichtungswerte.
199 # Wir starten bei erstem Marker (mit Index 1).
200 foreach my $i (1 .. ($#zerlegung - 1)) {
201 # Ignoriere Nicht-Marker.
209 elsif ($m =~ /^--$/) {
212 elsif ($m =~ /^[<>]$/) {
215 elsif ($m =~ /^=$/) {
218 elsif ($m =~ /( ==*>? | <?=*= )/x) {
222 warn "Zeile $INPUT_LINE_NUMBER:"
223 . " unbekannter Marker »$m« behandelt als »-«\n";
230 # Zweiter Durchgang: Adjustiere Wichtung von »<« und »>«.
232 # Behandle »<« von rechts nach links gehend.
234 foreach my $i (reverse(1 .. ($#zerlegung - 1))) {
235 # Ignoriere Nicht-Marker.
238 if (index ($zerlegung[$i], "<") >= 0) {
239 # Hat der rechte Marker in einer Kette von »<« eine höhere
240 # Wichtung, wird diese übernommen.
243 if ($w_vorher >= $w) {
244 $wichtung[$i] = $w_vorher;
250 # »-«-Marker zwischen zwei »<« ändert nicht deren Wichtung.
251 elsif ($zerlegung[$i] ne "-") {
256 # Behandle »>« von links nach rechts gehend.
258 foreach my $i (1 .. ($#zerlegung - 1)) {
259 # Ignoriere Nicht-Marker.
262 if (index ($zerlegung[$i], ">") >= 0) {
263 # Hat der linke Marker in einer Kette von »>« eine höhere
264 # Wichtung, wird diese übernommen.
267 if ($w_vorher >= $w) {
268 $wichtung[$i] = $w_vorher;
274 # »-«-Marker zwischen zwei »>« ändert nicht deren Wichtung.
275 elsif ($zerlegung[$i] ne "-") {
280 # Dritter Durchgang: Ermittle Rang von »<« und »>«.
282 # Behandle »<« von links nach rechts gehend.
284 foreach my $i (1 .. ($#zerlegung - 1)) {
285 # Ignoriere Nicht-Marker.
288 if (index ($zerlegung[$i], "<") >= 0) {
291 # »-«-Marker zwischen zwei »<« ändert nicht den Rang.
292 elsif ($zerlegung[$i] ne "-") {
297 # Behandle »>« von rechts nach links gehend.
299 foreach my $i (reverse(1 .. ($#zerlegung - 1))) {
300 # Ignoriere Nicht-Marker.
303 if (index ($zerlegung[$i], ">") >= 0) {
306 # »-«-Marker zwischen zwei »>« ändert nicht den Rang.
307 elsif ($zerlegung[$i] ne "-") {
312 # Sortiere Indexfeld für Marker mit absteigender Wichtung.
313 my @wichtungsindices =
315 # Benutze Rang für Sekundärsortierung.
316 if ($wichtung[$a] == $wichtung[$b]) {
317 -($rang[$a] <=> $rang[$b]);
320 -($wichtung[$a] <=> $wichtung[$b]);
322 } (0 .. $#zerlegung);
324 # Entferne Trennstellen unter Berücksichtigung des Arguments von »-g«.
329 foreach my $i (@wichtungsindices) {
330 # Alle Wortteile haben einen geraden Index und sind stets am Schluß
331 # von @wichtungsindices.
337 if ($w_vorher == $w) {
338 $g++ if $r_vorher != $r;
347 # Entferne Trennung mit zu geringer Wichtung.
348 $zerlegung[$i] = "" if $g > $opt_g || $w < 0;
351 $zeile = join '', @zerlegung;
354 # Reduziere Trennstellenmarker zu »-«.
355 $zeile =~ s/[·<>=-]+/-/g;
360 print " " . $kommentar if $kommentar && $opt_x;