lingo 1.8.0 → 1.8.1
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +13 -0
- data/README +49 -29
- data/Rakefile +28 -4
- data/TODO +2 -9
- data/bin/lingo +24 -0
- data/bin/lingoctl +24 -0
- data/de/lingo-dic.txt +559 -74
- data/info/gpl-hdr.txt +21 -24
- data/lib/lingo.rb +83 -112
- data/lib/lingo/agenda_item.rb +53 -0
- data/lib/lingo/attendee.rb +261 -0
- data/lib/lingo/attendee/abbreviator.rb +95 -97
- data/lib/lingo/attendee/debugger.rb +94 -93
- data/lib/lingo/attendee/decomposer.rb +76 -83
- data/lib/lingo/attendee/dehyphenizer.rb +141 -144
- data/lib/lingo/attendee/formatter.rb +65 -0
- data/lib/lingo/attendee/multi_worder.rb +302 -0
- data/lib/lingo/attendee/noneword_filter.rb +89 -84
- data/lib/lingo/attendee/object_filter.rb +91 -0
- data/lib/lingo/attendee/sequencer.rb +159 -158
- data/lib/lingo/attendee/synonymer.rb +81 -84
- data/lib/lingo/attendee/text_reader.rb +242 -0
- data/lib/lingo/attendee/text_writer.rb +169 -0
- data/lib/lingo/attendee/tokenizer.rb +192 -191
- data/lib/lingo/attendee/variator.rb +152 -156
- data/lib/lingo/attendee/vector_filter.rb +140 -135
- data/lib/lingo/attendee/word_searcher.rb +98 -0
- data/lib/lingo/buffered_attendee.rb +69 -0
- data/lib/lingo/cachable.rb +58 -0
- data/lib/lingo/call.rb +72 -0
- data/lib/lingo/cli.rb +26 -0
- data/lib/lingo/config.rb +23 -26
- data/lib/lingo/core_ext.rb +42 -0
- data/lib/lingo/ctl.rb +239 -173
- data/lib/lingo/database.rb +148 -496
- data/lib/lingo/database/crypter.rb +85 -0
- data/lib/lingo/database/gdbm_store.rb +49 -0
- data/lib/lingo/database/hash_store.rb +67 -0
- data/lib/lingo/database/libcdb_store.rb +58 -0
- data/lib/lingo/database/sdbm_store.rb +64 -0
- data/lib/lingo/database/show_progress.rb +81 -0
- data/lib/lingo/database/source.rb +134 -0
- data/lib/lingo/database/source/key_value.rb +62 -0
- data/lib/lingo/database/source/multi_key.rb +65 -0
- data/lib/lingo/database/source/multi_value.rb +65 -0
- data/lib/lingo/database/source/single_word.rb +60 -0
- data/lib/lingo/database/source/word_class.rb +64 -0
- data/lib/lingo/error.rb +122 -0
- data/lib/lingo/language.rb +78 -518
- data/lib/lingo/language/dictionary.rb +173 -0
- data/lib/lingo/language/grammar.rb +211 -0
- data/lib/lingo/language/lexical.rb +66 -0
- data/lib/lingo/language/lexical_hash.rb +88 -0
- data/lib/lingo/language/token.rb +48 -0
- data/lib/lingo/language/word.rb +130 -0
- data/lib/lingo/language/word_form.rb +83 -0
- data/lib/lingo/reportable.rb +59 -0
- data/lib/lingo/version.rb +1 -1
- data/lingo-all.cfg +14 -10
- data/lingo-call.cfg +5 -5
- data/lingo.cfg +14 -12
- data/lingo.rb +26 -0
- data/lir.cfg +13 -9
- data/spec/spec_helper.rb +1 -0
- data/test.cfg +11 -11
- data/test/attendee/ts_abbreviator.rb +0 -6
- data/test/attendee/ts_decomposer.rb +0 -6
- data/test/attendee/{ts_multiworder.rb → ts_multi_worder.rb} +1 -7
- data/test/attendee/ts_noneword_filter.rb +1 -7
- data/test/attendee/{ts_objectfilter.rb → ts_object_filter.rb} +1 -7
- data/test/attendee/ts_sequencer.rb +0 -6
- data/test/attendee/ts_synonymer.rb +0 -6
- data/test/attendee/{ts_textreader.rb → ts_text_reader.rb} +1 -7
- data/test/attendee/{ts_textwriter.rb → ts_text_writer.rb} +1 -7
- data/test/attendee/ts_tokenizer.rb +0 -6
- data/test/attendee/ts_variator.rb +0 -6
- data/test/attendee/ts_vector_filter.rb +1 -7
- data/test/attendee/{ts_wordsearcher.rb → ts_word_searcher.rb} +1 -7
- data/test/ref/artikel.non +2 -29
- data/test/ref/artikel.seq +13 -8
- data/test/ref/artikel.vec +30 -15
- data/test/ref/artikel.ven +29 -14
- data/test/ref/artikel.ver +58 -43
- data/test/ref/lir.csv +146 -145
- data/test/ref/lir.non +186 -210
- data/test/ref/lir.seq +54 -50
- data/test/test_helper.rb +41 -36
- data/test/ts_database.rb +12 -11
- data/test/ts_language.rb +118 -68
- metadata +67 -29
- data/lib/lingo/attendee/multiworder.rb +0 -301
- data/lib/lingo/attendee/objectfilter.rb +0 -86
- data/lib/lingo/attendee/textreader.rb +0 -237
- data/lib/lingo/attendee/textwriter.rb +0 -196
- data/lib/lingo/attendee/wordsearcher.rb +0 -96
- data/lib/lingo/attendees.rb +0 -289
- data/lib/lingo/const.rb +0 -131
- data/lib/lingo/modules.rb +0 -98
- data/lib/lingo/types.rb +0 -285
- 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
|