lingo 1.8.0 → 1.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. data/ChangeLog +13 -0
  2. data/README +49 -29
  3. data/Rakefile +28 -4
  4. data/TODO +2 -9
  5. data/bin/lingo +24 -0
  6. data/bin/lingoctl +24 -0
  7. data/de/lingo-dic.txt +559 -74
  8. data/info/gpl-hdr.txt +21 -24
  9. data/lib/lingo.rb +83 -112
  10. data/lib/lingo/agenda_item.rb +53 -0
  11. data/lib/lingo/attendee.rb +261 -0
  12. data/lib/lingo/attendee/abbreviator.rb +95 -97
  13. data/lib/lingo/attendee/debugger.rb +94 -93
  14. data/lib/lingo/attendee/decomposer.rb +76 -83
  15. data/lib/lingo/attendee/dehyphenizer.rb +141 -144
  16. data/lib/lingo/attendee/formatter.rb +65 -0
  17. data/lib/lingo/attendee/multi_worder.rb +302 -0
  18. data/lib/lingo/attendee/noneword_filter.rb +89 -84
  19. data/lib/lingo/attendee/object_filter.rb +91 -0
  20. data/lib/lingo/attendee/sequencer.rb +159 -158
  21. data/lib/lingo/attendee/synonymer.rb +81 -84
  22. data/lib/lingo/attendee/text_reader.rb +242 -0
  23. data/lib/lingo/attendee/text_writer.rb +169 -0
  24. data/lib/lingo/attendee/tokenizer.rb +192 -191
  25. data/lib/lingo/attendee/variator.rb +152 -156
  26. data/lib/lingo/attendee/vector_filter.rb +140 -135
  27. data/lib/lingo/attendee/word_searcher.rb +98 -0
  28. data/lib/lingo/buffered_attendee.rb +69 -0
  29. data/lib/lingo/cachable.rb +58 -0
  30. data/lib/lingo/call.rb +72 -0
  31. data/lib/lingo/cli.rb +26 -0
  32. data/lib/lingo/config.rb +23 -26
  33. data/lib/lingo/core_ext.rb +42 -0
  34. data/lib/lingo/ctl.rb +239 -173
  35. data/lib/lingo/database.rb +148 -496
  36. data/lib/lingo/database/crypter.rb +85 -0
  37. data/lib/lingo/database/gdbm_store.rb +49 -0
  38. data/lib/lingo/database/hash_store.rb +67 -0
  39. data/lib/lingo/database/libcdb_store.rb +58 -0
  40. data/lib/lingo/database/sdbm_store.rb +64 -0
  41. data/lib/lingo/database/show_progress.rb +81 -0
  42. data/lib/lingo/database/source.rb +134 -0
  43. data/lib/lingo/database/source/key_value.rb +62 -0
  44. data/lib/lingo/database/source/multi_key.rb +65 -0
  45. data/lib/lingo/database/source/multi_value.rb +65 -0
  46. data/lib/lingo/database/source/single_word.rb +60 -0
  47. data/lib/lingo/database/source/word_class.rb +64 -0
  48. data/lib/lingo/error.rb +122 -0
  49. data/lib/lingo/language.rb +78 -518
  50. data/lib/lingo/language/dictionary.rb +173 -0
  51. data/lib/lingo/language/grammar.rb +211 -0
  52. data/lib/lingo/language/lexical.rb +66 -0
  53. data/lib/lingo/language/lexical_hash.rb +88 -0
  54. data/lib/lingo/language/token.rb +48 -0
  55. data/lib/lingo/language/word.rb +130 -0
  56. data/lib/lingo/language/word_form.rb +83 -0
  57. data/lib/lingo/reportable.rb +59 -0
  58. data/lib/lingo/version.rb +1 -1
  59. data/lingo-all.cfg +14 -10
  60. data/lingo-call.cfg +5 -5
  61. data/lingo.cfg +14 -12
  62. data/lingo.rb +26 -0
  63. data/lir.cfg +13 -9
  64. data/spec/spec_helper.rb +1 -0
  65. data/test.cfg +11 -11
  66. data/test/attendee/ts_abbreviator.rb +0 -6
  67. data/test/attendee/ts_decomposer.rb +0 -6
  68. data/test/attendee/{ts_multiworder.rb → ts_multi_worder.rb} +1 -7
  69. data/test/attendee/ts_noneword_filter.rb +1 -7
  70. data/test/attendee/{ts_objectfilter.rb → ts_object_filter.rb} +1 -7
  71. data/test/attendee/ts_sequencer.rb +0 -6
  72. data/test/attendee/ts_synonymer.rb +0 -6
  73. data/test/attendee/{ts_textreader.rb → ts_text_reader.rb} +1 -7
  74. data/test/attendee/{ts_textwriter.rb → ts_text_writer.rb} +1 -7
  75. data/test/attendee/ts_tokenizer.rb +0 -6
  76. data/test/attendee/ts_variator.rb +0 -6
  77. data/test/attendee/ts_vector_filter.rb +1 -7
  78. data/test/attendee/{ts_wordsearcher.rb → ts_word_searcher.rb} +1 -7
  79. data/test/ref/artikel.non +2 -29
  80. data/test/ref/artikel.seq +13 -8
  81. data/test/ref/artikel.vec +30 -15
  82. data/test/ref/artikel.ven +29 -14
  83. data/test/ref/artikel.ver +58 -43
  84. data/test/ref/lir.csv +146 -145
  85. data/test/ref/lir.non +186 -210
  86. data/test/ref/lir.seq +54 -50
  87. data/test/test_helper.rb +41 -36
  88. data/test/ts_database.rb +12 -11
  89. data/test/ts_language.rb +118 -68
  90. metadata +67 -29
  91. data/lib/lingo/attendee/multiworder.rb +0 -301
  92. data/lib/lingo/attendee/objectfilter.rb +0 -86
  93. data/lib/lingo/attendee/textreader.rb +0 -237
  94. data/lib/lingo/attendee/textwriter.rb +0 -196
  95. data/lib/lingo/attendee/wordsearcher.rb +0 -96
  96. data/lib/lingo/attendees.rb +0 -289
  97. data/lib/lingo/const.rb +0 -131
  98. data/lib/lingo/modules.rb +0 -98
  99. data/lib/lingo/types.rb +0 -285
  100. data/lib/lingo/utilities.rb +0 -40
@@ -1,86 +0,0 @@
1
- # encoding: utf-8
2
-
3
- #--
4
- # LINGO ist ein Indexierungssystem mit Grundformreduktion, Kompositumzerlegung,
5
- # Mehrworterkennung und Relationierung.
6
- #
7
- # Copyright (C) 2005-2007 John Vorhauer
8
- # Copyright (C) 2007-2011 John Vorhauer, Jens Wille
9
- #
10
- # This program is free software; you can redistribute it and/or modify it under
11
- # the terms of the GNU Affero General Public License as published by the Free
12
- # Software Foundation; either version 3 of the License, or (at your option)
13
- # any later version.
14
- #
15
- # This program is distributed in the hope that it will be useful, but WITHOUT
16
- # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17
- # FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
18
- # details.
19
- #
20
- # You should have received a copy of the GNU Affero General Public License along
21
- # with this program; if not, write to the Free Software Foundation, Inc.,
22
- # 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
23
- #
24
- # For more information visit http://www.lex-lingo.de or contact me at
25
- # welcomeATlex-lingoDOTde near 50°55'N+6°55'E.
26
- #
27
- # Lex Lingo rules from here on
28
- #++
29
-
30
- class Lingo
31
-
32
- # Der Objectfilter ermöglicht es, beliebige Objekte aus dem Datenstrom herauszufiltern.
33
- # Um die gewünschten Objekte zu identifizieren, sind ein paar Ruby-Kenntnisse und das Wissen
34
- # um die Lingo Klassen notwendig. Hier sollen kurz die häufigsten Fälle angesprochen werden:
35
- #
36
- # Filtern nach einem bestimmten Typ, z.B. Token oder Word wird beispielsweise durch den Ausdruck
37
- # 'obj.kind_of?(Word)' ermöglicht. Token und Words haben jeweils ein Attribut +attr+.
38
- # Bei Token gibt +attr+ an, mit welcher Tokenizer-Regel das Token erkannt wurde. So können z.B.
39
- # alle numerischen Token mit dem Ausdruck 'obj.kind_of?(Token) && obj.attr=="NUMS"' identifiziert
40
- # werden. Wie bereits gezeigt, können Bedingungen durch logisches UND (&&) oder ODER (||) verknüpft werden.
41
- # Das Attribut +form+ kann genutzt werden, um auf den Text eines Objektes zuzugreifen, z.B.
42
- # 'obj.form=="John"'.
43
- #
44
- # === Mögliche Verlinkung
45
- # Erwartet:: Daten beliebigen Typs von allen Attendees
46
- # Erzeugt:: Daten, die der als Parameter übergebenen Bedingung entsprechen
47
- #
48
- # === Parameter
49
- # Kursiv dargestellte Parameter sind optional (ggf. mit Angabe der Voreinstellung).
50
- # Alle anderen Parameter müssen zwingend angegeben werden.
51
- # <b>in</b>:: siehe allgemeine Beschreibung des Attendee
52
- # <b>out</b>:: siehe allgemeine Beschreibung des Attendee
53
- # <b><i>objects</i></b>:: (Standard: true) Gibt einen Ruby-Ausdruck an, der, wenn der Ausdruck
54
- # als Wahr ausgewertet wird, das Objekt weiterleitet und ansonsten filtert.
55
- #
56
- # === Beispiele
57
- # Bei der Verarbeitung einer normalen Textdatei mit der Ablaufkonfiguration <tt>t1.cfg</tt>
58
- # meeting:
59
- # attendees:
60
- # - textreader: { out: lines, files: '$(files)' }
61
- # - tokenizer: { in: lines, out: token }
62
- # - wordsearcher: { in: token, out: words, source: 'sys-dic' }
63
- # - objectfilter: { in: words, out: filtr, objects: 'obj.kind_of?(Word) && obj.lexicals.size>0 && obj.lexicals[0].attr==LA_SUBSTANTIV' }
64
- # - debugger: { in: filtr, prompt: 'out>' }
65
- # ergibt die Ausgabe über den Debugger: <tt>lingo -c t1 test.txt</tt>
66
- # out> *FILE('test.txt')
67
- # out> <Indexierung = [(indexierung/s)]>
68
- # out> <Indexierung = [(indexierung/s)]>
69
- # out> *EOL('test.txt')
70
- # out> *EOF('test.txt')
71
-
72
- class Attendee::Objectfilter < Attendee
73
-
74
- protected
75
-
76
- def init
77
- @obj_eval = get_key('objects', 'true')
78
- end
79
-
80
- def process(obj)
81
- forward(obj) if eval(@obj_eval)
82
- end
83
-
84
- end
85
-
86
- end
@@ -1,237 +0,0 @@
1
- # encoding: utf-8
2
-
3
- #--
4
- # LINGO ist ein Indexierungssystem mit Grundformreduktion, Kompositumzerlegung,
5
- # Mehrworterkennung und Relationierung.
6
- #
7
- # Copyright (C) 2005-2007 John Vorhauer
8
- # Copyright (C) 2007-2011 John Vorhauer, Jens Wille
9
- #
10
- # This program is free software; you can redistribute it and/or modify it under
11
- # the terms of the GNU Affero General Public License as published by the Free
12
- # Software Foundation; either version 3 of the License, or (at your option)
13
- # any later version.
14
- #
15
- # This program is distributed in the hope that it will be useful, but WITHOUT
16
- # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17
- # FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
18
- # details.
19
- #
20
- # You should have received a copy of the GNU Affero General Public License along
21
- # with this program; if not, write to the Free Software Foundation, Inc.,
22
- # 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
23
- #
24
- # For more information visit http://www.lex-lingo.de or contact me at
25
- # welcomeATlex-lingoDOTde near 50°55'N+6°55'E.
26
- #
27
- # Lex Lingo rules from here on
28
- #++
29
-
30
- %w[filemagic mime/types hpricot pdf-reader].each { |lib|
31
- begin
32
- require lib
33
- rescue LoadError
34
- end
35
- }
36
-
37
- class Lingo
38
-
39
- # Der Textreader ist eine klassische Datenquelle. Er liest eine oder mehrere Dateien
40
- # und gibt sie Zeilenweise in den Ausgabekanal. Der Start bzw. Wechsel einer Datei
41
- # wird dabei über den Kommandokanal angekündigt, ebenso wie das Ende.
42
- #
43
- # Der Textreader kann ebenfalls ein spezielles Dateiformat verarbeiten, welches zum
44
- # Austausch mit dem LIR-System dient. Dabei enthält die Datei Record-basierte Informationen,
45
- # die wie mehrere Dateien verarbeitet werden.
46
- #
47
- # === Mögliche Verlinkung
48
- # Erzeugt:: Daten des Typs *String* (Textzeile) z.B. für Tokenizer, Textwriter
49
- #
50
- # === Parameter
51
- # Kursiv dargestellte Parameter sind optional (ggf. mit Angabe der Voreinstellung).
52
- # Alle anderen Parameter müssen zwingend angegeben werden.
53
- # <b>out</b>:: siehe allgemeine Beschreibung des Attendee
54
- # <b>files</b>:: Es können eine oder mehrere Dateien angegeben werden, die nacheinander
55
- # eingelesen und zeilenweise weitergeleitet werden. Die Dateien werden mit
56
- # Komma voneinander getrennt, z.B.
57
- # files: 'readme.txt'
58
- # files: 'readme.txt,lingo.cfg'
59
- # <b><i>lir-record-pattern</i></b>:: Mit diesem Parameter wird angegeben, woran der Anfang
60
- # eines neuen Records erkannt werden kann und wie die
61
- # Record-Nummer identifiziert wird. Das Format einer
62
- # LIR-Datei ist z.B.
63
- # [00001.]
64
- # 020: ¬Die Aufgabenteilung zwischen Wortschatz und Grammatik.
65
- #
66
- # [00002.]
67
- # 020: Nicht-konventionelle Thesaurusrelationen als Orientierungshilfen.
68
- # Mit der Angabe von
69
- # lir-record-pattern: "^\[(\d+)\.\]"
70
- # werden die Record-Zeilen erkannt und jeweils die Record-Nummer +00001+,
71
- # bzw. +00002+ erkannt.
72
- #
73
- # === Generierte Kommandos
74
- # Damit der nachfolgende Datenstrom einwandfrei verarbeitet werden kann, generiert der Textreader
75
- # Kommandos, die mit in den Datenstrom eingefügt werden.
76
- # <b>*FILE(<dateiname>)</b>:: Kennzeichnet den Beginn der Datei <dateiname>
77
- # <b>*EOF(<dateiname>)</b>:: Kennzeichnet das Ende der Datei <dateiname>
78
- # <b>*LIR_FORMAT('')</b>:: Kennzeichnet die Verarbeitung einer Datei im LIR-Format (nur bei LIR-Format).
79
- # <b>*RECORD(<nummer>)</b>:: Kennzeichnet den Beginn eines neuen Records (nur bei LIR-Format).
80
- # === Beispiele
81
- # Bei der Verarbeitung einer normalen Textdatei mit der Ablaufkonfiguration <tt>t1.cfg</tt>
82
- # meeting:
83
- # attendees:
84
- # - textreader: { out: lines, files: '$(files)' }
85
- # - debugger: { in: lines, prompt: 'out>' }
86
- # ergibt die Ausgabe über den Debugger: <tt>lingo -c t1 test.txt</tt>
87
- # out> *FILE('test.txt')
88
- # out> "Dies ist eine Zeile."
89
- # out> "Dies ist noch eine."
90
- # out> *EOF('test.txt')
91
- # Bei der Verarbeitung einer LIR-Datei mit der Ablaufkonfiguration <tt>t2.cfg</tt>
92
- # meeting:
93
- # attendees:
94
- # - textreader: { out: lines, files: '$(files)', lir-record-pattern: "^\[(\d+)\.\]" }
95
- # - debugger: { in: lines, prompt: 'out>'}
96
- # ergibt die Ausgabe mit <tt>lingo -c t2 lir.txt</tt>
97
- # out> *LIR-FORMAT('')
98
- # out> *FILE('lir.txt')
99
- # out> *RECORD('00001')
100
- # out> "020: \254Die Aufgabenteilung zwischen Wortschatz und Grammatik."
101
- # out> *RECORD('00002')
102
- # out> "020: Nicht-konventionelle Thesaurusrelationen als Orientierungshilfen."
103
- # out> *EOF('lir.txt')
104
-
105
- class Attendee::Textreader < Attendee
106
-
107
- protected
108
-
109
- # TODO: FILE und LIR-FILE
110
- # TODO: lir-record-pattern abkürzen
111
- # Interpretation der Parameter
112
- def init
113
- @files = Array(get_key('files', '-'))
114
- @rec_pat = Regexp.new(get_key('lir-record-pattern', ''))
115
- @is_LIR_file = has_key?('lir-record-pattern')
116
- @chomp = get_key('chomp', true)
117
- @filter = get_key('filter', false)
118
- end
119
-
120
- def control(cmd, param)
121
- if cmd==STR_CMD_TALK
122
- forward(STR_CMD_LIR, '') if @is_LIR_file
123
- @files.each { |filename| spool(filename) }
124
- end
125
- end
126
-
127
- private
128
-
129
- # Gibt eine Datei zeilenweise in den Ausgabekanal
130
- def spool(filename)
131
- unless stdin?(filename)
132
- FileTest.exist?(filename) || forward(STR_CMD_ERR, "Datei #{filename} nicht gefunden")
133
-
134
- inc('Anzahl Dateien')
135
- add('Anzahl Bytes', File.stat(filename).size)
136
- end
137
-
138
- forward(STR_CMD_FILE, filename)
139
-
140
- filter(filename) { |line|
141
- inc('Anzahl Zeilen')
142
- line.chomp! if @chomp
143
- line.gsub!(/\303\237/, "ß")
144
- ### HACK
145
- if @is_LIR_file && line =~ @rec_pat
146
- forward(STR_CMD_RECORD, $1)
147
- else
148
- forward(line) if line.size>0
149
- end
150
- }
151
-
152
- forward(STR_CMD_EOF, filename)
153
- end
154
-
155
- def filter(filename, &block)
156
- file = stdin?(filename) ?
157
- @lingo.config.stdin.set_encoding(ENC) :
158
- File.open(filename, 'rb', encoding: ENC)
159
-
160
- file = case @filter == true ? file_type(filename, file) : @filter.to_s
161
- when /html/ then filter_html(file)
162
- when /xml/ then filter_html(file, true)
163
- when /pdf/ then filter_pdf(file, &block) or return
164
- else file
165
- end if @filter
166
-
167
- file.each_line(&block)
168
- end
169
-
170
- def filter_pdf(file, &block)
171
- if Object.const_defined?(:PDF) && PDF.const_defined?(:Reader)
172
- PDFFilter.filter(file, &block)
173
- nil
174
- else
175
- warn "PDF filter not available. Please install `pdf-reader'."
176
- file
177
- end
178
- end
179
-
180
- def filter_html(file, xml = false)
181
- if Object.const_defined?(:Hpricot)
182
- Hpricot(file, xml: xml).inner_text
183
- else
184
- warn "#{xml ? 'X' : 'HT'}ML filter not available. Please install `hpricot'."
185
- file
186
- end
187
- end
188
-
189
- def file_type(filename, file)
190
- if Object.const_defined?(:FileMagic) && file.respond_to?(:rewind)
191
- type = FileMagic.fm(:mime, simplified: true).buffer(file.read(256))
192
- file.rewind
193
- type
194
- elsif Object.const_defined?(:MIME) && MIME.const_defined?(:Types)
195
- if type = MIME::Types.of(filename).first
196
- type.content_type
197
- else
198
- warn 'Filters not available. File type could not be determined.'
199
- nil
200
- end
201
- else
202
- warn "Filters not available. Please install `ruby-filemagic' or `mime-types'."
203
- nil
204
- end
205
- end
206
-
207
- def stdin?(filename)
208
- %w[STDIN -].include?(filename)
209
- end
210
-
211
- class PDFFilter
212
-
213
- def self.filter(file, &block)
214
- PDF::Reader.new.parse(file, new(&block))
215
- end
216
-
217
- def initialize(&block)
218
- @block = block
219
- end
220
-
221
- def show_text(string, *params)
222
- @block[string << '|']
223
- end
224
-
225
- alias_method :super_show_text, :show_text
226
- alias_method :move_to_next_line_and_show_text, :show_text
227
- alias_method :set_spacing_next_line_show_text, :show_text
228
-
229
- def show_text_with_positioning(params, *)
230
- params.each { |param| show_text(param) if param.is_a?(String) }
231
- end
232
-
233
- end
234
-
235
- end
236
-
237
- end
@@ -1,196 +0,0 @@
1
- # encoding: utf-8
2
-
3
- #--
4
- # LINGO ist ein Indexierungssystem mit Grundformreduktion, Kompositumzerlegung,
5
- # Mehrworterkennung und Relationierung.
6
- #
7
- # Copyright (C) 2005-2007 John Vorhauer
8
- # Copyright (C) 2007-2011 John Vorhauer, Jens Wille
9
- #
10
- # This program is free software; you can redistribute it and/or modify it under
11
- # the terms of the GNU Affero General Public License as published by the Free
12
- # Software Foundation; either version 3 of the License, or (at your option)
13
- # any later version.
14
- #
15
- # This program is distributed in the hope that it will be useful, but WITHOUT
16
- # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17
- # FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
18
- # details.
19
- #
20
- # You should have received a copy of the GNU Affero General Public License along
21
- # with this program; if not, write to the Free Software Foundation, Inc.,
22
- # 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
23
- #
24
- # For more information visit http://www.lex-lingo.de or contact me at
25
- # welcomeATlex-lingoDOTde near 50°55'N+6°55'E.
26
- #
27
- # Lex Lingo rules from here on
28
- #++
29
-
30
- class Lingo
31
-
32
- # Der Textwriter ermöglicht die Umleitung des Datenstroms in eine Textdatei. Dabei werden
33
- # Objekte, die nicht vom Typ String sind in eine sinnvolle Textrepresentation gewandelt.
34
- # Der Name der Ausgabedatei wird durch den Namen der Eingabedatei (des Textreaders) bestimmt.
35
- # Es kann lediglich die Extension verändert werden. Der Textwriter kann auch das LIR-Format
36
- # erzeugen.
37
- #
38
- # === Mögliche Verlinkung
39
- # Erwartet:: Daten verschiedenen Typs
40
- #
41
- # === Parameter
42
- # Kursiv dargestellte Parameter sind optional (ggf. mit Angabe der Voreinstellung).
43
- # Alle anderen Parameter müssen zwingend angegeben werden.
44
- # <b>in</b>:: siehe allgemeine Beschreibung des Attendee
45
- # <b>out</b>:: siehe allgemeine Beschreibung des Attendee
46
- # <b><i>ext</i></b>:: (Standard: txt2) Gibt die Dateinamen-Erweiertung für die Ausgabedatei an.
47
- # Wird z.B. dem Textreader die Datei <tt>Dokument.txt</tt> angegeben und
48
- # über die Lingo-Konfiguration alle Indexwörter herausgefiltert, kann mit
49
- # <tt>ext: 'idx'</tt> der Textwriter veranlasst werden, die Indexwörter in
50
- # die Datei <tt>Dokument.idx</tt> zu schreiben.
51
- # <b><i>sep</i></b>:: (Standard: ' ') Gibt an, mit welchem Trennzeichen zwei aufeinanderfolgende
52
- # Objekte in der Ausgabedatei getrennt werden sollen. Gängige Werte sind auch
53
- # noch '\n', welches die Ausgabe jedes Objektes in eine Zeile ermöglicht.
54
- # <b><i>lir-format</i></b>:: (Standard: false) Dieser Parameter hat keinen Wert. Wird er angegeben,
55
- # dann wird er als true ausgewertet. Damit ist es möglich, die Ausgabedatei
56
- # im für LIR lesbarem Format zu erstellen.
57
- #
58
- # === Beispiele
59
- # Bei der Verarbeitung der oben angegebenen Funktionsbeschreibung des Textwriters mit der Ablaufkonfiguration <tt>t1.cfg</tt>
60
- # meeting:
61
- # attendees:
62
- # - textreader: { out: lines, files: '$(files)' }
63
- # - tokenizer: { in: lines, out: token }
64
- # - wordsearcher: { in: token, out: words, source: 'sys-dic' }
65
- # - vector_filter: { in: words, out: filtr, sort: 'term_rel' }
66
- # - textwriter: { in: filtr, ext: 'vec', sep: '\n' }
67
- # ergibt die Ausgabe in der Datei <tt>test.vec</tt>
68
- # 0.03846 name
69
- # 0.01923 ausgabedatei
70
- # 0.01923 datenstrom
71
- # 0.01923 extension
72
- # 0.01923 format
73
- # 0.01923 objekt
74
- # 0.01923 string
75
- # 0.01923 textdatei
76
- # 0.01923 typ
77
- # 0.01923 umleitung
78
-
79
- class Attendee::Textwriter < Attendee
80
-
81
- protected
82
-
83
- def init
84
- @ext = get_key('ext', 'txt2')
85
- @lir = get_key('lir-format', false)
86
- @sep = @lir ? ' ' : eval("\"#{@config['sep'] || ' '}\"")
87
- @no_sep, @no_puts = true, false
88
- end
89
-
90
- def control(cmd, par)
91
- case cmd
92
- when STR_CMD_LIR
93
- @lir = true
94
- when STR_CMD_FILE
95
- @no_sep = true
96
-
97
- if stdout?(@ext)
98
- @filename = @ext
99
- @file = @lingo.config.stdout
100
- else
101
- @filename = par.sub(/(\.[^.]+)?$/, '.'+@ext)
102
- @file = File.new(@filename,'w')
103
- inc('Anzahl Dateien')
104
- end
105
-
106
- @lir_rec_no = ''
107
- @lir_rec_buf = Array.new
108
- when STR_CMD_RECORD
109
- @no_sep = true
110
- if @lir
111
- flush_lir_buffer
112
- @lir_rec_no = par
113
- end
114
- when STR_CMD_EOL
115
- @no_sep = true
116
- unless @lir
117
- @file.puts unless @no_puts # unless @sep=="\n"
118
- inc('Anzahl Zeilen')
119
- end
120
- when STR_CMD_EOF
121
- flush_lir_buffer if @lir
122
-
123
- unless stdout?(@filename)
124
- @file.close
125
- add('Anzahl Bytes', File.stat(@filename).size)
126
- end
127
- end
128
- end
129
-
130
- def process(obj)
131
- if @lir
132
- @lir_rec_buf << (obj.kind_of?(Token) ? obj.form : obj.to_s)
133
- else
134
- @file.print @sep unless @no_sep
135
- @no_sep=false if @no_sep
136
- if obj.is_a?(Word) || obj.is_a?(Token)
137
- @file.print obj.form
138
- else
139
- @file.print obj
140
- end
141
- end
142
- end
143
-
144
- private
145
-
146
- def flush_lir_buffer
147
- unless @lir_rec_no.empty? || @lir_rec_buf.empty?
148
- if @sep =~ /\n/
149
- @file.print '*', @lir_rec_no, "\n", @lir_rec_buf.join(@sep), "\n"
150
- else
151
- @file.print @lir_rec_no, '*', @lir_rec_buf.join(@sep), "\n"
152
- end
153
- end
154
- @lir_rec_no = ''
155
- @lir_rec_buf.clear
156
- end
157
-
158
- def stdout?(filename)
159
- %w[STDOUT -].include?(filename)
160
- end
161
-
162
- end
163
-
164
- class Attendee::Formatter < Attendee::Textwriter
165
-
166
- protected
167
-
168
- def init
169
- super
170
-
171
- @ext = get_key('ext', '-')
172
- @format = get_key('format', '%s')
173
- @map = get_key('map', Hash.new { |h, k| h[k] = k })
174
-
175
- @no_puts = true
176
- end
177
-
178
- def process(obj)
179
- if obj.is_a?(Word) || obj.is_a?(Token)
180
- str = obj.form
181
-
182
- if obj.respond_to?(:lexicals)
183
- lex = obj.lexicals.first # TODO
184
- att = @map[lex.attr] if lex
185
- str = @format % [str, lex.form, att] if att
186
- end
187
- else
188
- str = obj.to_s
189
- end
190
-
191
- @lir ? @lir_rec_buf << str : @file.print(str)
192
- end
193
-
194
- end
195
-
196
- end