athena 0.0.2.56 → 0.0.3.58
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.
- data/README +2 -2
- data/Rakefile +17 -16
- data/bin/athena +5 -5
- data/lib/athena.rb +6 -3
- data/lib/athena/formats.rb +40 -44
- data/lib/athena/formats/dbm.rb +22 -26
- data/lib/athena/formats/ferret.rb +91 -0
- data/lib/athena/formats/lingo.rb +69 -73
- data/lib/athena/formats/sisis.rb +36 -40
- data/lib/athena/formats/xml.rb +159 -163
- data/lib/athena/parser.rb +49 -53
- data/lib/athena/record.rb +50 -54
- data/lib/athena/util.rb +14 -18
- data/lib/athena/version.rb +16 -20
- metadata +8 -7
data/lib/athena/formats/sisis.rb
CHANGED
@@ -3,9 +3,9 @@
|
|
3
3
|
# #
|
4
4
|
# A component of athena, the database file converter. #
|
5
5
|
# #
|
6
|
-
# Copyright (C) 2007 University of Cologne,
|
7
|
-
#
|
8
|
-
#
|
6
|
+
# Copyright (C) 2007-2008 University of Cologne, #
|
7
|
+
# Albertus-Magnus-Platz, #
|
8
|
+
# 50932 Cologne, Germany #
|
9
9
|
# #
|
10
10
|
# Authors: #
|
11
11
|
# Jens Wille <jens.wille@uni-koeln.de> #
|
@@ -26,56 +26,52 @@
|
|
26
26
|
###############################################################################
|
27
27
|
#++
|
28
28
|
|
29
|
-
|
29
|
+
class Athena::Formats
|
30
30
|
|
31
|
-
class Formats
|
31
|
+
class Sisis < Athena::Formats
|
32
32
|
|
33
|
-
|
33
|
+
register_format :in, 'sisis'
|
34
34
|
|
35
|
-
|
35
|
+
attr_reader :record_element, :config, :parser
|
36
36
|
|
37
|
-
|
37
|
+
def initialize(parser)
|
38
|
+
config = parser.config.dup
|
38
39
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
raise NoRecordElementError, 'no record element specified'
|
47
|
-
else
|
48
|
-
raise IllegalRecordElementError, "illegal record element #{@record_element}"
|
49
|
-
end
|
50
|
-
|
51
|
-
@config = config
|
52
|
-
@parser = parser
|
40
|
+
case @record_element = config.delete(:__record_element)
|
41
|
+
when String
|
42
|
+
# fine!
|
43
|
+
when nil
|
44
|
+
raise NoRecordElementError, 'no record element specified'
|
45
|
+
else
|
46
|
+
raise IllegalRecordElementError, "illegal record element #{@record_element}"
|
53
47
|
end
|
54
48
|
|
55
|
-
|
56
|
-
|
49
|
+
@config = config
|
50
|
+
@parser = parser
|
51
|
+
end
|
57
52
|
|
58
|
-
|
59
|
-
|
53
|
+
def parse(source)
|
54
|
+
record = nil
|
60
55
|
|
61
|
-
|
62
|
-
|
63
|
-
record.close if record
|
64
|
-
record = Athena::Record.new(parser.block, value)
|
65
|
-
else
|
66
|
-
record.update(element, value, config[element])
|
67
|
-
end
|
68
|
-
}
|
56
|
+
source.each { |line|
|
57
|
+
element, value = line.match(/(\d+).*?:\s*(.*)/)[1, 2]
|
69
58
|
|
70
|
-
|
71
|
-
|
59
|
+
case element
|
60
|
+
when record_element
|
61
|
+
record.close if record
|
62
|
+
record = Athena::Record.new(parser.block, value)
|
63
|
+
else
|
64
|
+
record.update(element, value, config[element])
|
65
|
+
end
|
66
|
+
}
|
72
67
|
|
73
|
-
|
74
|
-
|
68
|
+
record.close if record
|
69
|
+
end
|
75
70
|
|
76
|
-
|
77
|
-
|
71
|
+
class NoRecordElementError < StandardError
|
72
|
+
end
|
78
73
|
|
74
|
+
class IllegalRecordElementError < StandardError
|
79
75
|
end
|
80
76
|
|
81
77
|
end
|
data/lib/athena/formats/xml.rb
CHANGED
@@ -3,9 +3,9 @@
|
|
3
3
|
# #
|
4
4
|
# A component of athena, the database file converter. #
|
5
5
|
# #
|
6
|
-
# Copyright (C) 2007 University of Cologne,
|
7
|
-
#
|
8
|
-
#
|
6
|
+
# Copyright (C) 2007-2008 University of Cologne, #
|
7
|
+
# Albertus-Magnus-Platz, #
|
8
|
+
# 50932 Cologne, Germany #
|
9
9
|
# #
|
10
10
|
# Authors: #
|
11
11
|
# Jens Wille <jens.wille@uni-koeln.de> #
|
@@ -33,244 +33,240 @@ require 'rubygems'
|
|
33
33
|
require 'xmlstreamin'
|
34
34
|
require 'nuggets/hash/insert'
|
35
35
|
|
36
|
-
|
36
|
+
class Athena::Formats
|
37
37
|
|
38
|
-
class Formats
|
38
|
+
class XML < Athena::Formats
|
39
39
|
|
40
|
-
|
40
|
+
include Athena::Util
|
41
41
|
|
42
|
-
|
42
|
+
register_format :in, 'xml'
|
43
43
|
|
44
|
-
|
44
|
+
attr_reader :spec, :listener
|
45
45
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
@listener = XMLStreamin::XMLStreamListener.new(@spec)
|
51
|
-
end
|
46
|
+
def initialize(parser)
|
47
|
+
@spec = build_spec(parser)
|
48
|
+
@listener = XMLStreamin::XMLStreamListener.new(@spec)
|
49
|
+
end
|
52
50
|
|
53
|
-
|
54
|
-
|
55
|
-
|
51
|
+
def parse(source)
|
52
|
+
REXML::Document.parse_stream(source, listener)
|
53
|
+
end
|
56
54
|
|
57
|
-
|
55
|
+
private
|
58
56
|
|
59
|
-
|
60
|
-
|
57
|
+
def build_spec(parser)
|
58
|
+
config = parser.config.dup
|
61
59
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
60
|
+
case record_element = config.delete(:__record_element)
|
61
|
+
when String
|
62
|
+
# fine!
|
63
|
+
when nil
|
64
|
+
raise NoRecordElementError, 'no record element specified'
|
65
|
+
else
|
66
|
+
raise IllegalRecordElementError, "illegal record element #{record_element}"
|
67
|
+
end
|
70
68
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
}
|
69
|
+
element_specs = config.inject({}) { |specs, (element, element_spec)|
|
70
|
+
element_spec.each { |field, c|
|
71
|
+
element.split('/').reverse.inject({}) { |hash, part|
|
72
|
+
s = define_spec(element, field, c, hash.empty? ? :default : hash)
|
73
|
+
merge_specs(hash, part, s)
|
74
|
+
}.each { |key, s|
|
75
|
+
merge_specs(specs, key, s)
|
79
76
|
}
|
80
|
-
|
81
|
-
specs
|
82
77
|
}
|
83
78
|
|
84
|
-
|
85
|
-
|
79
|
+
specs
|
80
|
+
}
|
86
81
|
|
87
|
-
|
88
|
-
|
82
|
+
record_spec = RecordSpec.new(parser)
|
83
|
+
record_spec.specs!(element_specs)
|
89
84
|
|
90
|
-
|
91
|
-
|
85
|
+
root_spec = BaseSpec.new
|
86
|
+
root_spec.specs!(record_element => record_spec)
|
92
87
|
|
93
|
-
|
94
|
-
|
95
|
-
end
|
88
|
+
spec = BaseSpec.new
|
89
|
+
spec.default!(root_spec)
|
96
90
|
|
97
|
-
|
91
|
+
verbose(:spec, BaseSpec) do
|
92
|
+
spec.inspect_spec
|
98
93
|
end
|
99
94
|
|
100
|
-
|
101
|
-
|
95
|
+
spec
|
96
|
+
end
|
102
97
|
|
103
|
-
|
104
|
-
|
105
|
-
spec.specs!(arg)
|
106
|
-
else
|
107
|
-
spec.default!(SubElementSpec.new(spec))
|
108
|
-
end
|
98
|
+
def define_spec(element, field, config, arg)
|
99
|
+
spec = ElementSpec.new(element, field, config)
|
109
100
|
|
110
|
-
|
101
|
+
case arg
|
102
|
+
when Hash
|
103
|
+
spec.specs!(arg)
|
104
|
+
else
|
105
|
+
spec.default!(SubElementSpec.new(spec))
|
111
106
|
end
|
112
107
|
|
113
|
-
|
114
|
-
|
115
|
-
if s1.respond_to?(:specs!)
|
116
|
-
s1.specs!(s2.respond_to?(:specs) ? s2.specs : s2)
|
117
|
-
s1
|
118
|
-
else
|
119
|
-
s1.merge(s2)
|
120
|
-
end
|
121
|
-
}
|
122
|
-
end
|
108
|
+
spec
|
109
|
+
end
|
123
110
|
|
124
|
-
|
111
|
+
def merge_specs(container, key, spec)
|
112
|
+
container.insert!(key, spec) { |s1, s2|
|
113
|
+
if s1.respond_to?(:specs!)
|
114
|
+
s1.specs!(s2.respond_to?(:specs) ? s2.specs : s2)
|
115
|
+
s1
|
116
|
+
else
|
117
|
+
s1.merge(s2)
|
118
|
+
end
|
119
|
+
}
|
120
|
+
end
|
125
121
|
|
126
|
-
|
122
|
+
class BaseSpec < XMLStreamin::XMLSpec
|
127
123
|
|
128
|
-
|
124
|
+
include Athena::Util
|
129
125
|
|
130
|
-
|
131
|
-
verbose(:xml) do
|
132
|
-
spit "#{indent(level)}<#{name}>"
|
133
|
-
step :down
|
126
|
+
@level = 0
|
134
127
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
128
|
+
def start(context, name, attrs)
|
129
|
+
verbose(:xml) do
|
130
|
+
spit "#{indent(level)}<#{name}>"
|
131
|
+
step :down
|
139
132
|
|
140
|
-
|
133
|
+
attrs.each { |attr|
|
134
|
+
spit "#{indent(level + 1)}[#{attr[0]} = #{attr[1]}]"
|
135
|
+
}
|
141
136
|
end
|
142
137
|
|
143
|
-
|
144
|
-
|
145
|
-
content = data.strip
|
146
|
-
spit "#{indent(level)}#{content}" unless content.empty?
|
147
|
-
end
|
138
|
+
return context
|
139
|
+
end
|
148
140
|
|
149
|
-
|
141
|
+
def text(context, data)
|
142
|
+
verbose(:xml) do
|
143
|
+
content = data.strip
|
144
|
+
spit "#{indent(level)}#{content}" unless content.empty?
|
150
145
|
end
|
151
146
|
|
152
|
-
|
153
|
-
|
154
|
-
step :up
|
155
|
-
spit "#{indent(level)}</#{name}>"
|
156
|
-
end
|
147
|
+
return context
|
148
|
+
end
|
157
149
|
|
158
|
-
|
150
|
+
def done(context, name)
|
151
|
+
verbose(:xml) do
|
152
|
+
step :up
|
153
|
+
spit "#{indent(level)}</#{name}>"
|
159
154
|
end
|
160
155
|
|
161
|
-
|
162
|
-
|
163
|
-
step :up
|
164
|
-
end
|
156
|
+
return context
|
157
|
+
end
|
165
158
|
|
166
|
-
|
159
|
+
def empty(context)
|
160
|
+
verbose(:xml) do
|
161
|
+
step :up
|
167
162
|
end
|
168
163
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
164
|
+
return context
|
165
|
+
end
|
166
|
+
|
167
|
+
def inspect_spec(element = nil, level = 0)
|
168
|
+
if respond_to?(:field)
|
169
|
+
msg = "#{indent(level)}[#{element}] #{field.to_s.upcase} -> #{name}"
|
170
|
+
respond_to?(:spit) ? spit(msg) : warn(msg)
|
171
|
+
specs.each { |e, s|
|
172
|
+
s.inspect_spec(e, level + 1)
|
173
|
+
}
|
174
|
+
else
|
175
|
+
if specs.empty?
|
176
|
+
specs.default.inspect_spec('?', level)
|
177
|
+
else
|
173
178
|
specs.each { |e, s|
|
174
|
-
s.inspect_spec(e, level
|
179
|
+
s.inspect_spec(e, level)
|
175
180
|
}
|
176
|
-
else
|
177
|
-
if specs.empty?
|
178
|
-
specs.default.inspect_spec('?', level)
|
179
|
-
else
|
180
|
-
specs.each { |e, s|
|
181
|
-
s.inspect_spec(e, level)
|
182
|
-
}
|
183
|
-
end
|
184
181
|
end
|
185
182
|
end
|
183
|
+
end
|
186
184
|
|
187
|
-
|
188
|
-
|
189
|
-
def level
|
190
|
-
BaseSpec.instance_variable_get(:@level)
|
191
|
-
end
|
185
|
+
private
|
192
186
|
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
end
|
187
|
+
def level
|
188
|
+
BaseSpec.instance_variable_get(:@level)
|
189
|
+
end
|
197
190
|
|
191
|
+
def step(direction)
|
192
|
+
steps = { :down => 1, :up => -1 }
|
193
|
+
BaseSpec.instance_variable_set(:@level, level + steps[direction])
|
198
194
|
end
|
199
195
|
|
200
|
-
|
196
|
+
end
|
201
197
|
|
202
|
-
|
203
|
-
attr_accessor :record
|
198
|
+
class RecordSpec < BaseSpec
|
204
199
|
|
205
|
-
|
206
|
-
|
200
|
+
attr_reader :parser
|
201
|
+
attr_accessor :record
|
207
202
|
|
208
|
-
|
209
|
-
|
203
|
+
def initialize(parser)
|
204
|
+
super()
|
210
205
|
|
211
|
-
|
212
|
-
|
206
|
+
@parser = parser
|
207
|
+
end
|
213
208
|
|
214
|
-
|
215
|
-
|
209
|
+
def start(context, name, attrs)
|
210
|
+
super
|
216
211
|
|
217
|
-
|
218
|
-
|
212
|
+
self.record = Athena::Record.new(parser.block)
|
213
|
+
end
|
219
214
|
|
220
|
-
|
221
|
-
|
215
|
+
def done(context, name)
|
216
|
+
super
|
222
217
|
|
218
|
+
record.close
|
223
219
|
end
|
224
220
|
|
225
|
-
|
221
|
+
end
|
226
222
|
|
227
|
-
|
228
|
-
attr_accessor :record
|
223
|
+
class ElementSpec < BaseSpec
|
229
224
|
|
230
|
-
|
231
|
-
|
225
|
+
attr_reader :name, :field, :config
|
226
|
+
attr_accessor :record
|
232
227
|
|
233
|
-
|
234
|
-
|
235
|
-
@config = config
|
236
|
-
end
|
228
|
+
def initialize(name, field, config)
|
229
|
+
super()
|
237
230
|
|
238
|
-
|
239
|
-
|
231
|
+
@name = name
|
232
|
+
@field = field
|
233
|
+
@config = config
|
234
|
+
end
|
240
235
|
|
241
|
-
|
242
|
-
|
236
|
+
def start(context, name, attrs)
|
237
|
+
super
|
243
238
|
|
244
|
-
|
245
|
-
|
239
|
+
self.record = Athena::Record[field, config]
|
240
|
+
end
|
246
241
|
|
247
|
-
|
248
|
-
|
242
|
+
def text(context, data)
|
243
|
+
super
|
249
244
|
|
245
|
+
record.update(name, data)
|
250
246
|
end
|
251
247
|
|
252
|
-
|
248
|
+
end
|
253
249
|
|
254
|
-
|
250
|
+
class SubElementSpec < BaseSpec
|
255
251
|
|
256
|
-
|
257
|
-
def_delegators :@parent, :name, :field, :config, :record, :start, :text
|
252
|
+
extend Forwardable
|
258
253
|
|
259
|
-
|
260
|
-
|
254
|
+
# Forward to parent element; need to specify *all* its attributes and methods
|
255
|
+
def_delegators :@parent, :name, :field, :config, :record, :start, :text
|
261
256
|
|
262
|
-
|
263
|
-
|
264
|
-
end
|
257
|
+
def initialize(parent)
|
258
|
+
super()
|
265
259
|
|
260
|
+
@parent = parent
|
261
|
+
default!(self)
|
266
262
|
end
|
267
263
|
|
268
|
-
|
269
|
-
end
|
264
|
+
end
|
270
265
|
|
271
|
-
|
272
|
-
|
266
|
+
class NoRecordElementError < StandardError
|
267
|
+
end
|
273
268
|
|
269
|
+
class IllegalRecordElementError < StandardError
|
274
270
|
end
|
275
271
|
|
276
272
|
end
|