Korrigiere "schlaffesten".
[wortliste.git] / skripte / sort.py
blob56b81b076a13ce9f9da8130eae76ccf80a5dce88
1 #!/usr/bin/env python3
2 # :Copyright: © 2012, 2019 Günter Milde.
3 # :Licence: This work may be distributed and/or modified under
4 # the conditions of the `LaTeX Project Public License`,
5 # either version 1.3 of this license or (at your option)
6 # any later version.
7 # :Version: 0.3 (2019-06-14)
9 # sort.py
10 # *******
12 # ::
14 """
15 Sortiere eine oder mehrere Dateien im "Wortliste-Format".
17 Filter:
18 ./sort.py <../wortliste > ../wortliste.sortiert
20 Zusammenfügen:
21 ./sort.py liste.c liste.a liste.b > liste.abc
23 Einsortieren (zusammenfügen und wieder aufteilen):
24 ./sort.py neu.todo wl-* --split -o wl-
26 Einsortieren und Patch erstellen:
27 ./sort.py ../wortliste neu.todo --diff -o ../wortliste.patch
28 """
30 usage = '%(prog)s [Optionen] [Eingangsdatei(en)]\n' + __doc__
32 # Alle Eingabedateien werden in eine Liste gelesen und dann sortiert.
33 # Das spezielle Argument '-' steht für die Standardeingabe.
35 # Mit Option -o kann die Ausgabe in eine/mehrere Datei(en) gelenkt werden.
36 # Das spezielle Argument '-' steht für die Standardausgabe (Vorgabe).
38 # Es wird wahlweise nach Duden oder nach der bis März 2012 für die Wortliste
39 # genutzten Regel sortiert. Voreinstellung ist Dudensortierung.
41 # Siehe auch Optionen
44 import unicodedata, sys, argparse, os
46 # path for local Python modules
47 sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'lib'))
49 from py_wortliste.wortliste import WordEntry, udiff, sortkey_duden
50 from py_wortliste.split_wortliste import split_a_z, write_a_z
52 # sortkey_wl
53 # ----------
55 # Sortierschlüssel für den früher genutzten Algorithmus,
56 # d.h Emulation von:
58 # * Sortieren nach gesamter Zeile
59 # * mit dem Unix-Aufruf `sort -d`
60 # * und locale DE.
62 # ::
64 def sortkey_wl(entry):
65 # Sortieren nach gesamter Zeile
66 key = str(entry)
68 # Ersetzungen:
69 ersetzungen = {ord(u'ß'): u'ss'} # ß -> ss
70 # Feldtrenner und Trennzeichen ignorieren (Simulation von `sort -d`)
71 for char in u';-·=|[]{}':
72 ersetzungen[ord(char)] = None
73 key = key.translate(ersetzungen)
75 # Akzente/Umlaute weglassen:
76 key = unicodedata.normalize('NFKD', key) # Akzente mit 2-Zeichen-Kombi
77 key = key.encode('ascii', 'ignore').decode('ascii') # ignoriere nicht-ASCII Zeichen
78 # Großschreibung ignorieren
79 key = key.lower()
81 return key
84 # Aufruf von der Kommandozeile
85 # ============================
87 # ::
89 if __name__ == '__main__':
91 # Optionen::
93 parser = argparse.ArgumentParser(usage=usage)
94 parser.add_argument('infiles', nargs='*',
95 help='Eingangsdatei(en), Vorgabe: - (Standardeingabe)',
96 default=['-'])
97 parser.add_argument('-o', '--outfile',
98 help=u'Ausgangsdatei, Vorgabe: - (Standardausgabe)',
99 default='-')
100 parser.add_argument('-p', '--diff', action='store_true', default=False,
101 help=u'Erstelle Patch im "unified diff" Format. '
102 'Vergleicht die erste Eingangsdatei mit dem Resultat.')
103 parser.add_argument('-s', '--split',
104 help=u'Aufteilen in Dateien "OUTFILEa" bis "OUTFILEz".'
105 'Vorgabe: False (nicht splitten)',
106 action="store_true", default=False)
107 parser.add_argument('-u', '--unsorted', action='store_true', default=False,
108 help=u'Überspringe die Sortierung.')
109 parser.add_argument('-d', '--dump', action="store_true", default=False,
110 help=u'Für Rückwärtskompatibilität. Obsolet, ignoriert.')
111 parser.add_argument('--legacy-sort', action="store_true",
112 help=u'alternative (obsolete) Sortierordnung',
113 default=False)
115 args = parser.parse_args()
117 if args.legacy_sort:
118 sortkey = sortkey_wl
119 else:
120 sortkey = sortkey_duden
122 if args.split and args.diff:
123 print('Aufteilen nach a-z für Patch nicht implementiert.')
124 sys.exit()
125 if args.split and args.outfile == '-':
126 print('Aufteilen nach a-z auf Standardausgabe nicht möglich.')
127 sys.exit()
129 # Einlesen in eine Liste::
131 filenames = ', '.join(arg.replace('-', '<stdin>') for arg in args.infiles)
132 infiles = [sys.stdin if arg=='-' else open(arg) for arg in args.infiles]
134 # Vergleichsdatei bei patch ist erste Datei
135 wordlist = list(infiles.pop(0))
136 if args.diff:
137 wordlist_pre = wordlist[:]
139 # Restliche Dateien anhängen
140 # verschachtelte Listen entflechten [i for lst in lsts for i in lst]
141 wordlist += [line for infile in infiles for line in infile]
143 # Aufteilen::
145 if args.split:
146 lists = split_a_z(wordlist)
147 if not args.unsorted:
148 for l in lists.values():
149 l.sort(key=sortkey)
150 write_a_z(lists, args.outfile)
151 sys.exit()
153 # Sortieren::
155 if not args.unsorted:
156 wordlist.sort(key=sortkey)
158 # Patch erstellen::
160 if args.diff:
161 output = udiff(wordlist_pre, wordlist,
162 filenames, filenames+'-sortiert')
163 if not output:
164 print('keine Änderungen')
165 sys.exit()
166 else:
167 output = ''.join(wordlist)
169 # Ausgabe::
171 if args.outfile == '-':
172 outfile = sys.stdout
173 else:
174 outfile = open(args.outfile, 'w')
176 outfile.write(output)