5 # Dieses Perl-Skript sortiert eine Wortlisten-Datei (entweder im alten oder
6 # neuen Format des »wortlisten«-Projekts) zeilenweise.
8 # Die Eingabe auf stdin muß UTF-8-kodiert sein; die Ausgabe erfolgt auf
11 # Die angewandte Sortierung ist die Duden-Sortierung für Deutsch, basierend
12 # auf dem Zeichenrepertoire von ISO-8859-15 (latin9) plus »ſ«.
16 # wlsort.pl < eingabe > ausgabe
20 use utf8
; # String-Literals direkt als UTF-8.
21 use open qw(:std :utf8);
22 use feature
'unicode_strings';
27 # Bestimme den Schlüsselwert einer Zeile für die Hash-Tabelle; wir
28 # verwenden das erste nicht-leere Feld (ohne Trennzeichen).
32 # abartigste;-2-;ab<ar-tig-ste;ab<ar-tigs-te -> abartigste
33 # -1-;an<ge<rauht -> angerauht
38 $wort =~ s/\# .*+ $//x;
40 # {»Variante A«/»Variante B«} -> »Variante A«
41 # [»Variante A«/»Variante B«] -> »Variante A«
43 # Es genügt, den ersten Treffer zu bearbeiten.
44 $wort =~ s/\{ ([^\/]*+) \/ [^}]*+ \
}/$1/x;
45 $wort =~ s/\[ ([^\/]*+) \/ [^]]*+ \
]/$1/x;
47 # Entferne alle Nicht-Buchstaben außer »;«.
48 $wort =~ s/[^\p{Alpha};]//g;
50 # Reduziere auf erstes nicht-leeres Feld.
51 $wort =~ /^ ;*+ ([^;]++)/x;
55 foreach my $erstes_feld
57 # Retourniere das originale Wort (also das vierte Element)
58 # nach dem Suchvorgang.
65 # Damit das Sortieren möglichst schnell abläuft, verwenden
66 # wir einerseits »sort« ohne eine explizite Subroutine (das
67 # bedeutet im besonderen, daß wir uns auf eine reine
68 # lexikographische Sortierung beschränken müssen),
69 # andererseits »tr///« zum Erstellen der Sortierschlüssel,
70 # soweit wie möglich. Als Abbildung benutzen wir daher
71 # passende Unicode-Zeichen, deren Werte ausschließlich zur
72 # Sortierung verwendet werden.
78 my $hat_ligatur = /[ßÆ挜]/;
80 # Wir brauchen drei Sortierschlüssel, siehe weiter unten.
81 # Die Zeichen »ß«, »Æ«, »æ«, »Œ« und »œ« werden wie
82 # zweibuchstabige Sequenzen behandelt.
84 # Alle nicht explizit erwähnten Zeichen werden anhand ihres
85 # Unicode-Wertes sortiert.
87 # Beachte, daß beim Sortieren der Daten im »wortliste«-Projekt
88 # die tertiäre Sortierung nicht zum Einsatz kommt, da es keine
89 # Dopplungen gibt, die sich nur durch die Groß- und
90 # Kleinschreibung unterscheiden.
92 # Die primäre Sortierung vergleicht Zeichen in
93 # Kleinschreibung ohne diakritischen Akzent (oder
94 # Äquivalente; wir bilden beispielsweise »ð« auf »d« ab).
96 $s1 =~ tr
[àáâãäåçðèéêëìíîïñòóôõöøšſþùúûüýÿž
]
97 [aaaaaacdeeeeiiiinoooooosstuuuuyyz
];
105 # Die sekundäre Sortierung ordnet die Akzente
106 # bzw. Äquivalente (zuerst Grundbuchstaben, dann Zeichen
109 # Die Formatierung des ersten und zweiten Arguments von
110 # »tr« muß identisch sein!
132 [\x
{200}\x
{201}\x
{202}\x
{203}\x
{204}\x
{205}\x
{206}
137 \x
{240}\x
{241}\x
{242}\x
{243}\x
{244}
138 \x
{250}\x
{251}\x
{252}
139 \x
{260}\x
{261}\x
{262}\x
{263}\x
{264}
140 \x
{270}\x
{271}\x
{272}\x
{273}
143 \x
{290}\x
{291}\x
{292}\x
{293}\x
{294}\x
{295}\x
{296}
144 \x
{300}\x
{301}\x
{302}
145 \x
{310}\x
{311}\x
{313}
148 \x
{330}\x
{331}\x
{332}\x
{333}\x
{334}
149 \x
{340}\x
{341}\x
{342}
150 \x
{350}\x
{351}\x
{352}
154 $s2 =~ s/ß/\x{310}\x{312}/g;
155 $s2 =~ s/æ/\x{200}\x{245}/g;
156 $s2 =~ s/œ/\x{290}\x{245}/g;
159 # Die tertiäre Sortierung gibt die Groß- und
160 # Kleinschreibung an (zuerst Klein-, dann Großbuchstaben).
170 # Die Formatierung des ersten und zweiten Arguments von
171 # »tr« muß identisch sein!
173 [A
-ZÀÁÂÃÄÅÇÐÈÉÊËÌÍÎÏÑÒÓÔÕÖØŠÞÙÚÛÜÝŸŽ
174 a
-zàáâãäåçðèéêëìíîïñòóôõöøšþùúûüýÿž
]
175 [a
-zaaaaaacdeeeeiiiinoooooostuuuuyyz
176 A
-ZAAAAAACDEEEEIIIINOOOOOOSTUUUUYYZ
];
178 # Wir konstruieren jetzt den Sortierschlüssel (als
179 # Rückgabewert dieser »map«-Funktion). Zu diesem Zweck
180 # hängen wir die Sortierschlüssel mit dem Wort zusammen
181 # (wobei das Wort am Schluß kommt), unter Verwendung von
182 # Nullbytes als Feldtrenner.
184 # http://www.sysarch.com/Perl/sort_paper.html
186 # Wir verwenden Typ »a« für das Originalwort in »pack«,
187 # damit es unverändert bleibt und kein Padding angewandt
189 pack("A*xA*xA*xa*", $s1, $s2, $s3, $_);
192 print $wortliste{$erstes_feld};