mexico 0.0.10 → 0.0.11

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- YjlkOGE4MmM3ZjZiNDEwOTJhODIxZTFkOGYyOGJiNmRjMGUzZGY5Nw==
4
+ NTU2MmVjZDQ1ZGUyZjIyZTU2YWZjNzY5YzVmZGNhYmUzOTM0ZjE3Yw==
5
5
  data.tar.gz: !binary |-
6
- NDA4NjY1ZGJjNWY0NWFjN2VlMTM2YTE2Y2ZiZDA4ZTMyOGVkZGQ5MA==
6
+ Zjc3NDE2NWUzMTM0ZTIwMzJiZDQ5ODQwMDQ0YWJiMDY5MDUzMzNiMQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- MDc4OGI0NGRkN2U1OTAwMTgzOWUwNDU4OGQzYTE4NDgxYWJmYmI2ZmRiNjhi
10
- ZDY5ZDQ1M2U1NmZhOWRmOTg0MTA0OTkzY2M4MzI5OTJhMTgwYWRkZTBlODNi
11
- ZWVhNDA1MzNmMDgyMWY3N2Y4ZDI4ZWNiZjNhNDMwOGJmOWNiNWU=
9
+ ODNiZmI3N2JjMzY0ZjQ2YWQ3NGFiNTgwNTA1YzJiY2IxZDZkOTU4MGEzOWI1
10
+ MTllMjdjZTdiNGMzMGVmNTg4YWZjYmY4NGI2NTNlNDQ1NjRmNmI3YTcyNTMw
11
+ MWQ5ZDNjMzRkOWIwNmVjZWZkMWUzYTA4N2YyYWMzMDk0OGUzMzA=
12
12
  data.tar.gz: !binary |-
13
- ODEzOGE0NDFhYTY5NzgwMjUyZWM0MDQ0NWQ0YTU3ZjM1Zjk2ZTk3NWFiZWQz
14
- YWEzYjBiN2YyMGZmNTcxMmU2ZjQyMTY4MjA4ZmQxZDcyM2ZmYzgwM2NhNDgz
15
- NmVkOGNjNDA5Y2U5MmQ4Mjc4NTI5YmQwNDE5N2IyMDQ3MGYzMzU=
13
+ ZjRhODUzODVjMWY4YjlhMzNhZmRmYmZjYzU0ZTU4Nzc5NzNmZWU2ZTlkOThh
14
+ MzBkODNkZDU4M2RlNDNhNWI1YjUzNTdlMjMyZDc2MWJiZmZlYTZhNDQzOTg3
15
+ ZDk5NTUxNmQ4YmY4ZDRiMGUwYTIxYjZjYjliN2Q4NWU4M2FmZGM=
data/README.md CHANGED
@@ -10,6 +10,27 @@ Its central organising unit is the **Corpus** class which allows researchers to
10
10
 
11
11
  ## Last Changes
12
12
 
13
+ ## 0.0.11
14
+
15
+ Completed on March 24 2014.
16
+
17
+ + [**#258**](http://intranet.sfb673.org/issues/258): Adds first working version of FancyWriter for creating formatted plain text file formats.
18
+
19
+ + [**#154**](http://intranet.sfb673.org/issues/154): Adds export routine into the Praat ShortTextGrid format.
20
+ + [**#155**](http://intranet.sfb673.org/issues/155): Adds TextGrid export functionality.
21
+
22
+ + [**#156**](http://intranet.sfb673.org/issues/156): EAF export should now be complete, including metadata:
23
+
24
+ + [**#234**](http://intranet.sfb673.org/issues/234): Spec test files are adopted to reflect additional ELAN features.
25
+ + [**#248**](http://intranet.sfb673.org/issues/248): Layers now use property structures for additional configuration.
26
+ + [**#251**](http://intranet.sfb673.org/issues/251): ELAN import now uses up-to-date method for adding layers.
27
+ + [**#252**](http://intranet.sfb673.org/issues/252): Adds custom setter methods for identifiers in order to produce XML-valid IDs.
28
+ + [**#253**](http://intranet.sfb673.org/issues/253): Fixes a bug where annotations with empty string values were skipped.
29
+ + [**#255**](http://intranet.sfb673.org/issues/255): Persists the ANNOTATOR attribute from ELAN during import and export.
30
+ + [**#256**](http://intranet.sfb673.org/issues/256): Resolves and exports Elan parent refs correctly.
31
+ + [**#257**](http://intranet.sfb673.org/issues/257): Implements various missing ELAN (meta)data.
32
+
33
+
13
34
  ## 0.0.10
14
35
 
15
36
  Completed on February 26 2014.
@@ -121,4 +142,4 @@ but **WITHOUT ANY WARRANTY**; without even the implied warranty of
121
142
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
122
143
  GNU Lesser General Public License for more details.
123
144
 
124
- See LICENSE.txt for further details.
145
+ See LICENSE.txt for further details.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.10
1
+ 0.0.11
@@ -0,0 +1,13 @@
1
+ <FiestaDocument>
2
+ <ScaleSet>
3
+ <Scale id="timeline01" name="Timeline" unit="s" dimension="time"/>
4
+ </ScaleSet>
5
+ <LayerSet>
6
+ <Layer id="layer" name="Layer">
7
+ <PropertyMap key="layerProperties">
8
+ <Property key="elanTierType">TIME_SUBDIVISION</Property>
9
+ </PropertyMap>
10
+ </Layer>
11
+ </LayerSet>
12
+ <ItemSet/>
13
+ </FiestaDocument>
@@ -0,0 +1,17 @@
1
+ ## Release notes for version 0.0.11 – Complete ELAN and Praat support
2
+
3
+ + [**#258**](http://intranet.sfb673.org/issues/258): Adds first working version of FancyWriter for creating formatted plain text file formats.
4
+
5
+ + [**#154**](http://intranet.sfb673.org/issues/154): Adds export routine into the Praat ShortTextGrid format.
6
+ + [**#155**](http://intranet.sfb673.org/issues/155): Adds TextGrid export functionality.
7
+
8
+ + [**#156**](http://intranet.sfb673.org/issues/156): EAF export should now be complete, including metadata:
9
+
10
+ + [**#234**](http://intranet.sfb673.org/issues/234): Spec test files are adopted to reflect additional ELAN features.
11
+ + [**#248**](http://intranet.sfb673.org/issues/248): Layers now use property structures for additional configuration.
12
+ + [**#251**](http://intranet.sfb673.org/issues/251): ELAN import now uses up-to-date method for adding layers.
13
+ + [**#252**](http://intranet.sfb673.org/issues/252): Adds custom setter methods for identifiers in order to produce XML-valid IDs.
14
+ + [**#253**](http://intranet.sfb673.org/issues/253): Fixes a bug where annotations with empty string values were skipped.
15
+ + [**#255**](http://intranet.sfb673.org/issues/255): Persists the ANNOTATOR attribute from ELAN during import and export.
16
+ + [**#256**](http://intranet.sfb673.org/issues/256): Resolves and exports Elan parent refs correctly.
17
+ + [**#257**](http://intranet.sfb673.org/issues/257): Implements various missing ELAN (meta)data.
@@ -26,6 +26,13 @@ class Mexico::Fiesta::Interfaces::ElanInterface
26
26
  include Singleton
27
27
  include Mexico::FileSystem
28
28
 
29
+ CONSTRAINTS = {
30
+ 'Included_In' => "Time alignable annotations within the parent annotation's time interval, gaps are allowed",
31
+ 'Time_Subdivision' => "Time subdivision of parent annotation's time interval, no time gaps allowed within this interval",
32
+ 'Symbolic_Subdivision' => 'Symbolic subdivision of a parent annotation. Annotations refering to the same parent are ordered',
33
+ 'Symbolic_Association' => '1-1 association with a parent annotation'
34
+ }
35
+
29
36
  def self.import(io=$stdin, params = {})
30
37
  puts 'class method import'
31
38
  instance.import(io, params)
@@ -36,7 +43,6 @@ class Mexico::Fiesta::Interfaces::ElanInterface
36
43
  end
37
44
 
38
45
  def import(io=$stdin, params = {})
39
- puts 'instance method import'
40
46
 
41
47
  io.rewind
42
48
 
@@ -45,6 +51,68 @@ class Mexico::Fiesta::Interfaces::ElanInterface
45
51
 
46
52
  document = Mexico::FileSystem::FiestaDocument.new
47
53
 
54
+ sec_datamodel = document.head[Mexico::FileSystem::Section::DATA_MODEL]
55
+
56
+ sec_datamodel.properties << Mexico::FileSystem::Property.new('sourceFormat', 'ELAN/EAF')
57
+ sec_datamodel.properties << Mexico::FileSystem::Property.new('converterClass', 'Mexico::Fiesta::Interfaces::ElanInterface')
58
+
59
+ # import attributes on root element
60
+
61
+ xmldoc.xpath("/ANNOTATION_DOCUMENT").each do |annodoc|
62
+ # atts: DATE, AUTHOR, VERSION, FORMAT
63
+ # xmlns:xsi xsi:noNamespaceSchemaLocation
64
+
65
+ puts xmldoc.namespaces
66
+ sec_lifecycle = document.head[Mexico::FileSystem::Section::LIFECYCLE]
67
+ date = DateTime.iso8601(annodoc['DATE'])
68
+ sec_lifecycle.properties << Mexico::FileSystem::Property.new('creationDate', date)
69
+ puts date.class.name
70
+ sec_lifecycle.properties << Mexico::FileSystem::Property.new('authorKey', annodoc['AUTHOR'])
71
+
72
+
73
+ sec_datamodel.properties << Mexico::FileSystem::Property.new('annotationToolVersion', annodoc['VERSION'])
74
+ sec_datamodel.properties << Mexico::FileSystem::Property.new('annotationToolFormat', annodoc['FORMAT'])
75
+ sec_datamodel.properties << Mexico::FileSystem::Property.new('xmlSchemaDeclaration', xmldoc.namespaces['xmlns:xsi'])
76
+ sec_datamodel.properties << Mexico::FileSystem::Property.new('xsiNoNamespaceSchemaLocation', annodoc['xsi:noNamespaceSchemaLocation'])
77
+
78
+ annodoc.attributes.each do |a|
79
+ puts a
80
+ end
81
+ end
82
+
83
+ # import heaader
84
+ # - @MEDIA_FILE
85
+ # - @TIME_UNITS
86
+ # - MEDIA DESCRIPTOR
87
+ # - PROPERTY/@name=lastUsedAnnotationId
88
+
89
+ xmldoc.xpath("//HEADER").each do |header|
90
+ header['MEDIA_FILE']
91
+ header['TIME_UNTIS']
92
+
93
+ document.head[Mexico::FileSystem::Section::MEDIA_CONTEXT].property_maps << Mexico::FileSystem::PropertyMap.new(key: 'referencedMedia')
94
+ refMediaMap = document.head[Mexico::FileSystem::Section::MEDIA_CONTEXT].property_maps.find{|m| m.key=='referencedMedia'}
95
+ datModelSec = document.head[Mexico::FileSystem::Section::DATA_MODEL]
96
+
97
+ refMediaMap.properties << Mexico::FileSystem::Property.new('primaryMediaUrl', header['MEDIA_FILE'])
98
+
99
+ # time units should go into another section!
100
+ datModelSec.properties << Mexico::FileSystem::Property.new('timeUnits', header['TIME_UNITS'])
101
+
102
+ header.xpath('./MEDIA_DESCRIPTOR').each_with_index do |mediafile,n|
103
+ file_map = Mexico::FileSystem::PropertyMap.new(key: "#{n}")
104
+ # prop = Mexico::FileSystem::Property.new('path', mediafile['RELATIVE_MEDIA_URL'])
105
+ #puts " %s : %s" % [prop.key, prop.value]
106
+ file_map.properties << Mexico::FileSystem::Property.new('path', mediafile['RELATIVE_MEDIA_URL'])
107
+ file_map.properties << Mexico::FileSystem::Property.new('mimeType', mediafile['MIME_TYPE'])
108
+ file_map.properties << Mexico::FileSystem::Property.new('uri', mediafile['MEDIA_URL'])
109
+ refMediaMap.property_maps << file_map
110
+ end
111
+ header.xpath('./PROPERTY').each do |property|
112
+ datModelSec.properties << Mexico::FileSystem::Property.new(property['NAME'], property.text)
113
+ end
114
+ end
115
+ # actual data:
48
116
  # 1. create a standard timeline
49
117
  timeline = document.add_standard_timeline('s')
50
118
 
@@ -56,6 +124,53 @@ class Mexico::Fiesta::Interfaces::ElanInterface
56
124
  timeslots[slot] = val
57
125
  end
58
126
 
127
+ # read cv entries
128
+
129
+ # cvs = Hash.new
130
+
131
+ xmldoc.xpath("//CONTROLLED_VOCABULARY").each do |c|
132
+ container_map = Mexico::FileSystem::PropertyMap.new(key: c['CV_ID'])
133
+ metamap = Mexico::FileSystem::PropertyMap.new(key: 'info')
134
+ metamap.properties << Mexico::FileSystem::Property.new('identifier', c['CV_ID'])
135
+ metamap.properties << Mexico::FileSystem::Property.new('description', c['DESCRIPTION'])
136
+ valuemap = Mexico::FileSystem::PropertyMap.new(key: 'data')
137
+ c.xpath("./CV_ENTRY").each do |entry|
138
+ desc = entry['DESCRIPTION']
139
+ val = entry.text
140
+ valprop = Mexico::FileSystem::PropertyMap.new
141
+ valprop.properties << Mexico::FileSystem::Property.new('description', desc)
142
+ valprop.properties << Mexico::FileSystem::Property.new('value', val)
143
+ valuemap.property_maps << valprop
144
+ end
145
+ container_map.property_maps << metamap
146
+ container_map.property_maps << valuemap
147
+ document.head.section(Mexico::FileSystem::Section::VOCABULARIES).property_maps << container_map
148
+ end
149
+
150
+ # Read ling type entries
151
+ lingTypes = Hash.new
152
+ xmldoc.xpath("//LINGUISTIC_TYPE").each do |lingtype|
153
+ cnstrs, cntvoc = nil
154
+ cnstrs = lingtype['CONSTRAINTS'] unless lingtype['CONSTRAINTS'].nil?
155
+ graphr = lingtype['GRAPHIC_REFERENCES']=="true" ? true : false
156
+ lngtid = lingtype['LINGUISTIC_TYPE_ID']
157
+ timeal = lingtype['TIME_ALIGNABLE']=="true" ? true : false
158
+ cntvoc = lingtype['CONTROLLED_VOCABULARY_REF'] unless lingtype['CONTROLLED_VOCABULARY_REF'].nil?
159
+ lingTypeEntry = { constraints: cnstrs, graphicReferences: graphr, timeAlignable: timeal, controlledVocabulary: cntvoc }
160
+ lingTypes[lngtid] = lingTypeEntry
161
+ end
162
+
163
+ lingTypes.each do |key,val|
164
+ sec = document.head[Mexico::FileSystem::Section::LAYER_TYPES]
165
+ pmap = Mexico::FileSystem::PropertyMap.new(key: key)
166
+ val.each do |skey,sval|
167
+ unless sval.nil?
168
+ pmap.properties << Mexico::FileSystem::Property::new(skey,sval)
169
+ end
170
+ end
171
+ sec.property_maps << pmap
172
+ end
173
+
59
174
  # create temporary hash for storage of layers
60
175
  layerHash = Hash.new
61
176
 
@@ -65,23 +180,29 @@ class Mexico::Fiesta::Interfaces::ElanInterface
65
180
  tierID = t["TIER_ID"]
66
181
  puts 'Read layers, %s' % tierID
67
182
 
68
- layer = Mexico::FileSystem::Layer.new(identifier: tierID,
69
- name: tierID,
70
- document: document)
183
+ layer = document.add_layer(identifier: tierID, name: tierID)
71
184
  #layer.name = tierID
72
185
  #layer.id = ToE::Util::to_xml_id(tierID)
73
186
 
74
- document.layers << layer
187
+ layer.add_property Mexico::FileSystem::Property.new('elanTierType', t['LINGUISTIC_TYPE_REF'])
188
+
189
+ if t.attributes.has_key?('ANNOTATOR')
190
+ layer.add_property Mexico::FileSystem::Property.new('annotator', t['ANNOTATOR'])
191
+ end
192
+ # document.layers << layer
75
193
 
76
- puts t.attributes
77
- puts t.attributes.has_key?('PARENT_REF')
194
+ puts "Attributes: %s" % t.attributes.to_s
195
+ puts "Parent ref? %s" % t.attributes.has_key?('PARENT_REF')
78
196
  if t.attributes.has_key?('PARENT_REF')
79
197
  # puts "TATT: %s" % t['PARENT_REF']
80
- document.layers.each do |l|
81
- puts "LAYER %s %s" % [l.identifier, l.name]
82
- end
83
- parent_layer = document.get_layer_by_id(t['PARENT_REF'])
84
- puts parent_layer
198
+ # document.layers.each do |l|
199
+ # puts "LAYER %s %s" % [l.identifier, l.name]
200
+ # end
201
+ puts 'ID of parent layer %s' % t['PARENT_REF']
202
+ puts 'ID, xmlified %s' % Mexico::Util::to_xml_id(t['PARENT_REF'])
203
+ puts 'available ids: %s' % (document.layers.collect{|l| l.identifier}).join(' ')
204
+ parent_layer = document.get_layer_by_id(Mexico::Util::to_xml_id(t['PARENT_REF']))
205
+ puts "Found parent layer: %s" % parent_layer
85
206
  if parent_layer
86
207
  layer_connector = Mexico::FileSystem::LayerConnector.new parent_layer, layer, {
87
208
  identifier: "#{parent_layer.identifier}_TO_#{layer.identifier}",
@@ -101,7 +222,7 @@ class Mexico::Fiesta::Interfaces::ElanInterface
101
222
  if anno.name == "ALIGNABLE_ANNOTATION"
102
223
 
103
224
  # puts anno.xpath("./ANNOTATION_VALUE/text()").first
104
- if annoVal!=nil && annoVal.strip != ""
225
+ if annoVal!=nil # && annoVal.strip != ""
105
226
  i.add_interval_link Mexico::FileSystem::IntervalLink.new(identifier: "#{i.identifier}-int",
106
227
  min: timeslots[anno["TIME_SLOT_REF1"]].to_f,
107
228
  max: timeslots[anno["TIME_SLOT_REF2"]].to_f,
@@ -110,13 +231,20 @@ class Mexico::Fiesta::Interfaces::ElanInterface
110
231
  end
111
232
  if anno.name == "REF_ANNOTATION"
112
233
 
113
- puts pp anno
114
- puts document.items.collect{|x| x.identifier}.join(', ')
115
- puts '-'*80
234
+ #puts pp anno
235
+ #puts document.items.collect{|x| x.identifier}.join(', ')
236
+ #puts '-'*80
116
237
 
117
238
  i.add_item_link Mexico::FileSystem::ItemLink.new(identifier: "#{i.identifier}-itm",
118
239
  target_object: document.items({identifier: anno["ANNOTATION_REF"]}).first,
119
240
  role: Mexico::FileSystem::ItemLink::ROLE_PARENT)
241
+
242
+ # @todo add previous anno if present
243
+ if anno.has_attribute?('PREVIOUS_ANNOTATION')
244
+ i.add_item_link Mexico::FileSystem::ItemLink.new(identifier: "#{i.identifier}-pre",
245
+ target_object: document.items({identifier: anno["PREVIOUS_ANNOTATION"]}).first,
246
+ role: Mexico::FileSystem::ItemLink::ROLE_PREDECESSOR)
247
+ end
120
248
  end
121
249
  i.add_layer_link Mexico::FileSystem::LayerLink.new(identifier: "#{i.identifier}-lay",
122
250
  target_object: layer)
@@ -140,7 +268,220 @@ class Mexico::Fiesta::Interfaces::ElanInterface
140
268
 
141
269
  def export(doc, io=$stdout, params = {})
142
270
 
271
+ # Create an XML builder object that serialises into an XML structure
272
+ builder = Nokogiri::XML::Builder.new do |xml|
273
+
274
+ sec_datamodel = doc.head[Mexico::FileSystem::Section::DATA_MODEL]
275
+ sec_lifecycle = doc.head[Mexico::FileSystem::Section::LIFECYCLE]
276
+
277
+ date = sec_lifecycle['creationDate'].value
278
+ author = sec_lifecycle['authorKey'].value
279
+ format = sec_datamodel['annotationToolFormat'].value
280
+ version = sec_datamodel['annotationToolVersion'].value
281
+ schema_location = sec_datamodel['xsiNoNamespaceSchemaLocation'].value
282
+ ad_attrs = {
283
+ DATE: date, AUTHOR: author,
284
+ FORMAT: format, VERSION: version,
285
+ 'xmlns:xsi'=>'http://www.w3.org/2001/XMLSchema-instance',
286
+ 'xsi:noNamespaceSchemaLocation' => schema_location
287
+ }
288
+ #xml.root() do
289
+ #end
290
+ xml.ANNOTATION_DOCUMENT(ad_attrs) do
291
+ # @TODO implement the export of the header
292
+ mediaFile = ''
293
+ mediaFile = doc.head[Mexico::FileSystem::Section::MEDIA_CONTEXT]['primaryMediaUrl'].value unless doc.head[Mexico::FileSystem::Section::MEDIA_CONTEXT]['primaryMediaUrl'].nil?
294
+ timeUnits = doc.head[Mexico::FileSystem::Section::DATA_MODEL]['timeUnits'].value
295
+ xml.HEADER({MEDIA_FILE: mediaFile, TIME_UNITS: timeUnits}) do
296
+ doc.head[Mexico::FileSystem::Section::MEDIA_CONTEXT]['referencedMedia'].property_maps.each do |m|
297
+ uri = m['uri'].value
298
+ path = m['path'].value
299
+ mimeType = m['mimeType'].value
300
+
301
+ xml.MEDIA_DESCRIPTOR({MEDIA_URL: uri, MIME_TYPE: mimeType, RELATIVE_MEDIA_URL: path})
302
+ end
303
+ end
304
+
305
+ # create the time stamp data structure
306
+ time_hash = Hash.new
307
+ counter = 1
308
+
309
+ # @todo #254 rework to use unit conversions!
310
+ doc.items.each do |item|
311
+ item.point_links.each do |pl|
312
+ unless time_hash.has_key?(pl.point)
313
+ time_hash[pl.point] = "ts#{counter}"
314
+ counter += 1
315
+ end
316
+ end
317
+ item.interval_links.each do |il|
318
+ unless time_hash.has_key?(il.min)
319
+ time_hash[il.min] = "ts#{counter}"
320
+ counter += 1
321
+ end
322
+ unless time_hash.has_key?(il.max)
323
+ time_hash[il.max] = "ts#{counter}"
324
+ counter += 1
325
+ end
326
+ end
327
+ end
328
+
329
+ xml.TIME_ORDER do
330
+ # collect all timestamps
331
+ # create a hash for them
332
+ time_hash.each do |tkey, tval|
333
+ xml.TIME_SLOT({'TIME_SLOT_ID' => tval, 'TIME_VALUE'=>tkey.to_i.to_s})
334
+ end
335
+ end
336
+ inverted_time_hash = time_hash.invert
337
+
338
+
339
+ # read ling types from map
340
+ ling_types = Hash.new
341
+
342
+ lt_section = doc.head.section(Mexico::FileSystem::Section::LAYER_TYPES)
343
+ lt_section.property_maps.each do |pm|
344
+ key = pm.key
345
+ puts key
346
+
347
+ pm.properties.each do |p|
348
+ puts " .. %s -> %s" % [p.key, p.value]
349
+
350
+ end
351
+ # puts pm.size
352
+ ling_type = Hash.new
353
+
354
+ if pm.has_key?('constraints')
355
+ ling_type['constraints'] = pm['constraints'].value
356
+ end
357
+ if pm.has_key?('graphicReferences')
358
+ ling_type['graphicReferences'] = pm['graphicReferences'].value
359
+ end
360
+ if pm.has_key?('timeAlignable')
361
+ ling_type['timeAlignable'] = pm['timeAlignable'].value
362
+ end
363
+ if pm.has_key?('controlledVocabulary')
364
+ ling_type['controlledVocabulary'] = pm['controlledVocabulary'].value
365
+ end
366
+ ling_types[key] = ling_type
367
+ end
368
+ puts ling_types
369
+
370
+
371
+
372
+ # export layer by layer
373
+ # caveat: only annotations with at least one layer link will be exported.
374
+ # caveat 2: annotations with multiple layer links will be exported multiple times.
375
+
376
+
377
+
378
+ doc.layers.each do |layer|
379
+ ling_type = layer.properties['elanTierType'].value
380
+ ling_type_object = doc.head[Mexico::FileSystem::Section::LAYER_TYPES].property_maps.find{|m| m.key == ling_type}
381
+ puts "ling type object %s" % ling_type_object
382
+ constraint = ling_type_object['constraints']
383
+ unless constraint.nil?
384
+ constraint = constraint.value
385
+ end
386
+ attrs = {TIER_ID: layer.name, LINGUISTIC_TYPE_REF: ling_type}
387
+
388
+ annotator = layer.properties['annotator'].value
389
+ attrs.merge!({ANNOTATOR: annotator}) unless annotator.nil?
390
+
391
+ # check if this layer is the child of another one.
392
+ # if yes: add attribute PARENT_REF
393
+
394
+ # find a parent layer
395
+ parent_id=nil
396
+ parent_connectors = doc.layer_connectors.select{|c| c.target == layer}
397
+ if parent_connectors.size>0
398
+ parent_id = parent_connectors.first.source.name
399
+ attrs.merge!({PARENT_REF: parent_id})
400
+ end
401
+
402
+ tier = xml.TIER(attrs) do
403
+ puts "inside tier"
404
+ layer.items.each do |item|
405
+ xml.ANNOTATION do
406
+ # depending on the layer type, use either ALIGNABLE or REF annotations
407
+ if %w(Symbolic_Subdivision Symbolic_Association).include?(constraint)
408
+ ref_attrs = {ANNOTATION_ID: item.identifier}
409
+ parent_ref = item.item_links.find{|l| l.role == Mexico::FileSystem::ItemLink::ROLE_PARENT}
410
+ unless parent_ref.nil?
411
+ ref_attrs.merge!({ANNOTATION_REF: parent_ref.target_item.identifier})
412
+ end
413
+ pre_ref = item.item_links.find{|l| l.role == Mexico::FileSystem::ItemLink::ROLE_PREDECESSOR}
414
+ unless pre_ref.nil?
415
+ ref_attrs.merge!({PREVIOUS_ANNOTATION: pre_ref.target_item.identifier})
416
+ end
417
+ xml.REF_ANNOTATION(ref_attrs) do
418
+ xml.ANNOTATION_VALUE item.data.string_value
419
+ end
420
+ else
421
+ tsref1, tsref2 = nil
422
+ unless item.interval_links.empty?
423
+ tsref1 = time_hash[item.interval_links.first.min]
424
+ tsref2 = time_hash[item.interval_links.first.max]
425
+ end
426
+ xml.ALIGNABLE_ANNOTATION({'ANNOTATION_ID'=>item.identifier,TIME_SLOT_REF1: tsref1,TIME_SLOT_REF2: tsref2}) do
427
+ xml.ANNOTATION_VALUE item.data.string_value
428
+ end
429
+ end
430
+ end
431
+ end
432
+ end
433
+ puts "%s :: %s" % [tier["TIER_ID"], layer.identifier]
434
+ end
435
+
436
+ # @todo #257 a :: LINGUISTIC_TYPE
437
+ types = doc.head[Mexico::FileSystem::Section::LAYER_TYPES]
438
+ types.property_maps.each do |tp|
439
+ puts tp.class.name
440
+ puts tp.properties.size
441
+ puts tp.property_maps.size
442
+ puts "PROPMAP: %s" % tp.properties.collect{|m| "#{m.key}: #{m.value}"}.join(' ')
443
+ puts "TIME ALIGNABLE? %s" % tp.has_key?('timeAlignable')
444
+ puts "TIME ALIGNABLE? %s" % tp['timeAlignable']
445
+ # puts "TIME ALIGNABLE? %s" % tp['timeAlignable'].value
446
+
447
+ time_alignable = tp.has_key?('timeAlignable') ? tp['timeAlignable'].value : nil
448
+ graphic_references = tp.has_key?('graphicReferences') ? tp['graphicReferences'].value : nil
449
+ controlled_vocabulary_ref = tp.has_key?('controlledVocabulary') ? tp['controlledVocabulary'].value : nil
450
+ constraints = tp.has_key?('constraints') ? tp['constraints'].value : nil
451
+
452
+ puts "TIME ALIGNABLE? %s" % time_alignable
453
+
454
+ attrs = {LINGUISTIC_TYPE_ID: tp.key}
455
+ attrs.merge!({ TIME_ALIGNABLE: time_alignable}) unless time_alignable.nil?
456
+ attrs.merge!({ GRAPHIC_REFERENCES: graphic_references}) unless graphic_references.nil?
457
+ attrs.merge!({CONTROLLED_VOCABULARY_REF: controlled_vocabulary_ref}) unless controlled_vocabulary_ref.nil?
458
+ attrs.merge!({ CONSTRAINTS: constraints}) unless constraints.nil?
459
+
460
+ xml.LINGUISTIC_TYPE(attrs)
461
+ end
462
+
463
+ # Exports ELAN constraints.
464
+ # These are static, so the same for all documents.
465
+ Mexico::Fiesta::Interfaces::ElanInterface::CONSTRAINTS.each do |conk,conv|
466
+ xml.CONSTRAINT STEREOTYPE: conk, DESCRIPTION: conv
467
+ end
468
+
469
+ # CONTROLLED_VOCABULARY
470
+ vocs = doc.head[Mexico::FileSystem::Section::VOCABULARIES]
471
+ vocs.property_maps.each do |voc|
472
+ metamap = voc['info']
473
+ datamap = voc['data']
474
+ xml.CONTROLLED_VOCABULARY({CV_ID: voc.key, DESCRIPTION: metamap['description'].value }) do
475
+ datamap.property_maps.each do |cv_entry|
476
+ xml.CV_ENTRY(cv_entry['value'].value, {DESCRIPTION: cv_entry['description'].value})
477
+ end
478
+ end
479
+ end
480
+
481
+ end
482
+ end
483
+ io << builder.to_xml
143
484
  end
144
485
 
145
486
 
146
- end
487
+ end
@@ -99,4 +99,63 @@ class Mexico::Fiesta::Interfaces::ShortTextGridInterface
99
99
  fdoc
100
100
  end
101
101
 
102
+ def export(doc, io=$stdout, params = {})
103
+ Mexico::Util::FancyWriter.new(io) do
104
+ line 'File type = "ooTextFile"'
105
+ line 'Object class = "TextGrid"'
106
+ line
107
+
108
+ # overall min and max values
109
+ total_item_links = doc.items.collect{|i| i.interval_links}.flatten
110
+ total_min = total_item_links.collect{|l| l.min}.min
111
+ total_max = total_item_links.collect{|l| l.max}.max
112
+ line total_min, total_max
113
+ line '<exists>'
114
+ line doc.layers.size
115
+
116
+ # FOREACH layer : print layer header block
117
+ doc.layers.each do |layer|
118
+ # "IntervalTier", "name", min, max, annocount
119
+
120
+ line '"IntervalTier"'
121
+ line %Q("#{layer.name}")
122
+ layer_item_links = doc.items.collect{|i| i.interval_links}.flatten
123
+ layer_min = layer_item_links.collect{|l| l.min}.min
124
+ layer_max = layer_item_links.collect{|l| l.max}.max
125
+ line layer_min, layer_max
126
+
127
+ # FOREACH item in layer : min, max, value
128
+ sorted_items = layer.items.sort{|i,j| i.interval_links.first.min <=> i.interval_links.first.min}
129
+ time_points = [total_min, total_max, layer_min, layer_max]
130
+ sorted_items.each do |i|
131
+ time_points << i.interval_links.first.min
132
+ time_points << i.interval_links.first.max
133
+ end
134
+ time_points.uniq!.sort!
135
+ # print effective number of annotations
136
+ line time_points.size-1
137
+ time_points.each_with_index do |current_point, n|
138
+ next_point = nil
139
+ unless n == time_points.size-1
140
+ next_point = time_points[n+1]
141
+ end
142
+ unless next_point.nil?
143
+ #puts "-"*48
144
+ #puts "TL: %20.18f - %20.18f" % [current_point, next_point]
145
+ #sorted_items.each do |it|
146
+ # puts "IT: %20.18f - %20.18f -- %20.18f - %20.18f, %s" % [it.interval_links.first.min, it.interval_links.first.max, (it.interval_links.first.min-current_point), (it.interval_links.first.max-next_point), ((it.interval_links.first.min-current_point).abs<0.00001 && (it.interval_links.first.max-next_point).abs<0.00001)]
147
+ #end
148
+ item = sorted_items.select{|i| (i.interval_links.first.min-current_point).abs<0.00001 && (i.interval_links.first.max-next_point).abs<0.00001}.first
149
+ #puts item
150
+ line current_point, next_point
151
+ if item.nil?
152
+ line '""'
153
+ else
154
+ line %Q("#{item.data.string_value}")
155
+ end
156
+ end
157
+ end
158
+ end
159
+ end
160
+ end
102
161
  end
@@ -70,14 +70,11 @@ class Mexico::Fiesta::Interfaces::TextGridInterface
70
70
  layer = fdoc.add_layer({identifier:tierName, name:tierName})
71
71
 
72
72
  for anno_num in (1..tierSize)
73
-
74
73
  io.gets
75
74
  annoMin = io.gets.match(/(\d+(\.\d+)?)/)[1].to_f
76
75
  annoMax = io.gets.match(/(\d+(\.\d+)?)/)[1].to_f
77
76
  annoVal = io.gets.match(/"(.*)"/)[1]
78
-
79
77
  if annoVal.strip != ""
80
-
81
78
  item = fdoc.add_item({identifier:"l#{tier_num}a#{anno_num}"}) do |i|
82
79
  i.add_interval_link IntervalLink.new(
83
80
  identifier:"#{i.identifier}-il",
@@ -89,17 +86,82 @@ class Mexico::Fiesta::Interfaces::TextGridInterface
89
86
  identifier:"#{i.identifier}-ll",
90
87
  target_object: layer )
91
88
  end
92
-
93
- puts item
94
-
89
+ # puts item
95
90
  end
96
-
97
91
  end
98
-
99
92
  end
100
-
101
93
  fdoc
102
-
103
94
  end
104
95
 
96
+
97
+ def export(doc, io=$stdout, params = {})
98
+ Mexico::Util::FancyWriter.new(io) do
99
+ line 'File type = "ooTextFile"'
100
+ line 'Object class = "TextGrid"'
101
+ line
102
+
103
+ # overall min and max values
104
+ total_item_links = doc.items.collect{|i| i.interval_links}.flatten
105
+ total_min = total_item_links.collect{|l| l.min}.min
106
+ total_max = total_item_links.collect{|l| l.max}.max
107
+ line "xmin = %f" % total_min
108
+ line "xmax = %f" % total_max
109
+ line 'tiers? <exists>'
110
+ line "size = %i" % doc.layers.size
111
+ line 'item []:'
112
+ indent 4 do
113
+ # FOREACH layer : print layer header block
114
+ doc.layers.each_with_index do |layer,layer_index|
115
+ line 'item [%i]:' % (layer_index+1)
116
+
117
+ indent 4 do
118
+ # "IntervalTier", "name", min, max, annocount
119
+ line 'class = "IntervalTier"'
120
+ line %Q(name = "#{layer.name}")
121
+ layer_item_links = doc.items.collect{|i| i.interval_links}.flatten
122
+ layer_min = layer_item_links.collect{|l| l.min}.min
123
+ layer_max = layer_item_links.collect{|l| l.max}.max
124
+ line "xmin = %f" % layer_min
125
+ line "xmax = %f" % layer_max
126
+
127
+ # FOREACH item in layer : min, max, value
128
+ sorted_items = layer.items.sort{|i,j| i.interval_links.first.min <=> i.interval_links.first.min}
129
+ time_points = [total_min, total_max, layer_min, layer_max]
130
+ sorted_items.each do |i|
131
+ time_points << i.interval_links.first.min
132
+ time_points << i.interval_links.first.max
133
+ end
134
+ time_points.uniq!.sort!
135
+ # print effective number of annotations
136
+ line "intervals: size = %i" % (time_points.size-1)
137
+ time_points.each_with_index do |current_point, n|
138
+ next_point = nil
139
+ unless n == time_points.size-1
140
+ next_point = time_points[n+1]
141
+ end
142
+ unless next_point.nil?
143
+ #puts "-"*48
144
+ #puts "TL: %20.18f - %20.18f" % [current_point, next_point]
145
+ #sorted_items.each do |it|
146
+ # puts "IT: %20.18f - %20.18f -- %20.18f - %20.18f, %s" % [it.interval_links.first.min, it.interval_links.first.max, (it.interval_links.first.min-current_point), (it.interval_links.first.max-next_point), ((it.interval_links.first.min-current_point).abs<0.00001 && (it.interval_links.first.max-next_point).abs<0.00001)]
147
+ #end
148
+ line 'intervals [%i]:' % (n+1)
149
+ indent 4 do
150
+ item = sorted_items.select{|i| (i.interval_links.first.min-current_point).abs<0.00001 && (i.interval_links.first.max-next_point).abs<0.00001}.first
151
+ #puts item
152
+ line 'xmin = %f' % current_point
153
+ line 'xmax = %f' % next_point
154
+ if item.nil?
155
+ line 'text = ""'
156
+ else
157
+ line %Q(text = "#{item.data.string_value}")
158
+ end
159
+ end
160
+ end
161
+ end
162
+ end
163
+ end
164
+ end
165
+ end
166
+ end
105
167
  end
@@ -341,4 +341,8 @@ class Mexico::FileSystem::FiestaDocument
341
341
  card
342
342
  end
343
343
 
344
+ def identifier=(new_id)
345
+ @identifier = Mexico::Util::to_xml_id(new_id)
346
+ end
347
+
344
348
  end
@@ -30,4 +30,19 @@ class Mexico::FileSystem::Head
30
30
  # many HeadSections with keys
31
31
  xml_accessor :sections, :as => [::Mexico::FileSystem::Section], :from => "Section"
32
32
 
33
+ def initialize(args={})
34
+ @sections = []
35
+ ::Mexico::FileSystem::Section::SECTION_KEYS.each do |key|
36
+ @sections << ::Mexico::FileSystem::Section.new(key)
37
+ end
38
+ end
39
+
40
+ def [](key)
41
+ sections.find{|x| x.key == key }
42
+ end
43
+
44
+ def section(key)
45
+ sections.find{|x| x.key == key }
46
+ end
47
+
33
48
  end
@@ -23,7 +23,11 @@ class Mexico::FileSystem::IntervalLink
23
23
  xml_name "IntervalLink"
24
24
 
25
25
  # identifier
26
- xml_accessor :identifier, :from => '@id'
26
+ xml_reader :identifier, :from => '@id'
27
+
28
+ def identifier=(new_id)
29
+ @identifier = Mexico::Util::to_xml_id(new_id)
30
+ end
27
31
 
28
32
  # type Float
29
33
  xml_accessor :min, :as => Float, :from => "@min"
@@ -22,7 +22,11 @@ class Mexico::FileSystem::Item
22
22
  include ::ROXML
23
23
  xml_name 'I'
24
24
 
25
- xml_accessor :identifier, :from => '@id'
25
+ xml_reader :identifier, :from => '@id'
26
+
27
+ def identifier=(new_id)
28
+ @identifier = Mexico::Util::to_xml_id(new_id)
29
+ end
26
30
 
27
31
  # @todo compound links (later)
28
32
 
@@ -35,7 +35,11 @@ class Mexico::FileSystem::ItemLink
35
35
  xml_name 'ItemLink'
36
36
 
37
37
  # identifier
38
- xml_accessor :identifier, :from => '@id'
38
+ xml_reader :identifier, :from => '@id'
39
+
40
+ def identifier=(new_id)
41
+ @identifier = Mexico::Util::to_xml_id(new_id)
42
+ end
39
43
 
40
44
  # type String
41
45
  xml_accessor :role, :from => '@role'
@@ -21,9 +21,16 @@ class ::Mexico::FileSystem::Layer
21
21
 
22
22
  include ROXML
23
23
 
24
- xml_accessor :identifier, :from => '@id'
24
+ xml_reader :identifier, :from => '@id'
25
+
26
+ def identifier=(new_id)
27
+ @identifier = Mexico::Util::to_xml_id(new_id)
28
+ end
29
+
25
30
  xml_accessor :name, :from => '@name'
26
31
 
32
+ xml_accessor :properties, :as => ::Mexico::FileSystem::PropertyMap, :from => "PropertyMap"
33
+
27
34
  attr_accessor :document
28
35
 
29
36
  # POSEIdON-based RDF augmentation
@@ -42,7 +49,14 @@ class ::Mexico::FileSystem::Layer
42
49
  if self.respond_to?("#{k}=")
43
50
  send("#{k}=", v)
44
51
  end
52
+
53
+ @properties = Mexico::FileSystem::PropertyMap.new
45
54
  end
55
+
56
+ if properties.nil?
57
+ properties = ::Mexico::FileSystem::PropertyMap.new(key: 'layerProperties')
58
+ end
59
+
46
60
  end
47
61
 
48
62
  def items
@@ -85,5 +99,9 @@ class ::Mexico::FileSystem::Layer
85
99
  end
86
100
  end
87
101
 
102
+ def add_property(prop)
103
+ properties.properties << prop
104
+ end
105
+
88
106
 
89
107
  end
@@ -22,7 +22,12 @@ class Mexico::FileSystem::LayerConnector
22
22
 
23
23
  include ROXML
24
24
 
25
- xml_accessor :identifier, :from => '@id'
25
+ xml_reader :identifier, :from => '@id'
26
+
27
+ def identifier=(new_id)
28
+ @identifier = Mexico::Util::to_xml_id(new_id)
29
+ end
30
+
26
31
  xml_accessor :name, :from => '@name'
27
32
 
28
33
  xml_accessor :source_id, :from => '@source'
@@ -23,7 +23,11 @@ class Mexico::FileSystem::LayerLink
23
23
  xml_name 'LayerLink'
24
24
 
25
25
  # identifier
26
- xml_accessor :identifier, :from => '@id'
26
+ xml_reader :identifier, :from => '@id'
27
+
28
+ def identifier=(new_id)
29
+ @identifier = Mexico::Util::to_xml_id(new_id)
30
+ end
27
31
 
28
32
  xml_accessor :role, :from => '@role'
29
33
 
@@ -23,7 +23,11 @@ class Mexico::FileSystem::PointLink
23
23
  xml_name "PointLink"
24
24
 
25
25
  # identifier
26
- xml_accessor :identifier, :from => '@id'
26
+ xml_reader :identifier, :from => '@id'
27
+
28
+ def identifier=(new_id)
29
+ @identifier = Mexico::Util::to_xml_id(new_id)
30
+ end
27
31
 
28
32
  # type Float
29
33
  xml_accessor :point, :as => Float, :from => "@point"
@@ -28,8 +28,22 @@ class Mexico::FileSystem::Property
28
28
  xml_name 'Property'
29
29
 
30
30
  xml_accessor :key, :from => '@key'
31
-
32
31
  xml_accessor :value, :from => :content
33
32
 
33
+ def initialize(arg1=nil, arg2=nil)
34
+ puts "Property init - %s : %s" % [arg1, arg2]
35
+ if arg1.respond_to?(:has_key?)
36
+ args.each do |k,v|
37
+ if self.respond_to?("#{k}=")
38
+ send("#{k}=", v)
39
+ end
40
+ end
41
+ else
42
+ unless (arg1.nil? || arg2.nil?)
43
+ self.key = arg1
44
+ self.value = arg2
45
+ end
46
+ end
47
+ end
34
48
 
35
49
  end
@@ -34,4 +34,42 @@ class Mexico::FileSystem::PropertyMap
34
34
 
35
35
  attr_accessor :values
36
36
 
37
+ def initialize(args={})
38
+ args.each do |k,v|
39
+ if self.respond_to?("#{k}=")
40
+ send("#{k}=", v)
41
+ end
42
+ end
43
+ @properties = []
44
+ @property_maps = []
45
+ end
46
+
47
+ def has_key?(p_key)
48
+ # compare_list(p_key)
49
+ return true if properties.any?{|x| x.key.to_sym == p_key.to_sym}
50
+ return true if property_maps.any?{|x| x.key.to_sym == p_key.to_sym}
51
+ false
52
+ end
53
+
54
+ def [](p_key)
55
+ # compare_list(p_key)
56
+ if properties.any?{|x| x.key.to_sym == p_key.to_sym}
57
+ return properties.find{|x| x.key.to_sym == p_key.to_sym}
58
+ end
59
+ if property_maps.any?{|x| x.key.to_sym == p_key.to_sym}
60
+ return property_maps.find{|x| x.key.to_sym == p_key.to_sym}
61
+ end
62
+ return nil
63
+ end
64
+
65
+ def compare_list(p_key)
66
+ puts " <=> %s :: %s" % %w(ENTRY COMPARE_VAL)
67
+ properties.each do |p|
68
+ puts " <=> >%s< :: >%s< - %s" % [p.key, p_key, (p.key.to_sym==p_key.to_sym)]
69
+ end
70
+ property_maps.each do |p|
71
+ puts " <=> >%s< :: >%s< - %s" % [p.key, p_key, (p.key==p_key)]
72
+ end
73
+ end
74
+
37
75
  end
@@ -26,7 +26,12 @@ class Mexico::FileSystem::Scale
26
26
  include ::ROXML
27
27
  xml_name 'Scale'
28
28
 
29
- xml_accessor :identifier, :from => '@id'
29
+ xml_reader :identifier, :from => '@id'
30
+
31
+ def identifier=(new_id)
32
+ @identifier = Mexico::Util::to_xml_id(new_id)
33
+ end
34
+
30
35
  xml_accessor :name, :from => '@name'
31
36
 
32
37
  xml_accessor :unit, :from => '@unit'
@@ -25,8 +25,12 @@
25
25
  class Mexico::FileSystem::Section
26
26
 
27
27
  LIFECYCLE = 'lifecycle'
28
-
29
28
  VOCABULARIES = 'vocabularies'
29
+ LAYER_TYPES = 'layerTypes'
30
+ MEDIA_CONTEXT = 'mediaContext'
31
+ DATA_MODEL = 'dataModel'
32
+
33
+ SECTION_KEYS = [LIFECYCLE, VOCABULARIES, LAYER_TYPES, MEDIA_CONTEXT, DATA_MODEL]
30
34
 
31
35
  include ::ROXML
32
36
  xml_name 'Section'
@@ -36,6 +40,28 @@ class Mexico::FileSystem::Section
36
40
  xml_accessor :properties, :as => [::Mexico::FileSystem::Property], :from => "Property"
37
41
  xml_accessor :property_maps, :as => [::Mexico::FileSystem::PropertyMap], :from => "PropertyMap"
38
42
 
43
+ def initialize(key='NOTGIVEN')
44
+ @key = key
45
+ @properties = []
46
+ @property_maps = []
47
+ end
48
+
49
+ def has_key?(p_key)
50
+ # compare_list(p_key)
51
+ return true if properties.any?{|x| x.key.to_sym == p_key.to_sym}
52
+ return true if property_maps.any?{|x| x.key.to_sym == p_key.to_sym}
53
+ false
54
+ end
39
55
 
56
+ def [](p_key)
57
+ # compare_list(p_key)
58
+ if properties.any?{|x| x.key.to_sym == p_key.to_sym}
59
+ return properties.find{|x| x.key.to_sym == p_key.to_sym}
60
+ end
61
+ if property_maps.any?{|x| x.key.to_sym == p_key.to_sym}
62
+ return property_maps.find{|x| x.key.to_sym == p_key.to_sym}
63
+ end
64
+ return nil
65
+ end
40
66
 
41
67
  end
@@ -0,0 +1,47 @@
1
+ # encoding: utf-8
2
+
3
+ class Mexico::Util::FancyWriter
4
+
5
+ attr_reader :stream
6
+ attr_reader :prefix_stack
7
+
8
+ def initialize(p_stream, &block)
9
+ @stream = p_stream
10
+ @prefix_stack = []
11
+ if block_given?
12
+ instance_eval &block
13
+ end
14
+ end
15
+
16
+ def prepend(prepend_string=' ', &block)
17
+ @prefix_stack << prepend_string
18
+ instance_eval &block
19
+ @prefix_stack.pop
20
+ end
21
+
22
+ def comment(comment_string='# ', &block)
23
+ if block_given?
24
+ prepend(comment_string, &block)
25
+ end
26
+ end
27
+
28
+ def indent(number=2, &block)
29
+ prepend(' '*number, &block)
30
+ end
31
+
32
+ def tab_indent(number=2, &block)
33
+ prepend("\t"*number, &block)
34
+ end
35
+
36
+ def write(*line)
37
+ lines = line
38
+ lines = [''] if lines == []
39
+ lines.each do |l|
40
+ stream << "%s%s%s" %[@prefix_stack.join(''),l,"\n"]
41
+ end
42
+ end
43
+
44
+ alias :w :write
45
+ alias :<< :write
46
+ alias :line :write
47
+ end
data/lib/mexico/util.rb CHANGED
@@ -39,13 +39,16 @@ module Mexico::Util
39
39
  # @param string [String] The string to be converted to an ID.
40
40
  # @return [String] The resulting ID.
41
41
  def self.to_xml_id(string)
42
+ return nil if string.nil? # @todo auto-assign IDs
42
43
  result = string.downcase
43
44
  UMLAUTS.each_pair do |u,v|
44
45
  result.gsub!(/#{u}/, v)
45
46
  end
46
- return result.gsub(/[^\w\d]/, '')
47
+ result.gsub!(/[^\w\d]/, '_')
48
+ return result.gsub(/_+/, '_')
47
49
  end
48
50
 
49
51
  end
50
52
 
51
- require 'mexico/util/fancy_container'
53
+ require 'mexico/util/fancy_container'
54
+ require 'mexico/util/fancy_writer'
@@ -0,0 +1,77 @@
1
+ # This file is part of the MExiCo gem.
2
+ # Copyright (c) 2012-2014 Peter Menke, SFB 673, Universität Bielefeld
3
+ # http://www.sfb673.org
4
+ #
5
+ # MExiCo is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU Lesser General Public License as
7
+ # published by the Free Software Foundation, either version 3 of
8
+ # the License, or (at your option) any later version.
9
+ #
10
+ # MExiCo is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Lesser General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Lesser General Public
16
+ # License along with MExiCo. If not, see
17
+ # <http://www.gnu.org/licenses/>.
18
+
19
+ require 'spec_helper'
20
+
21
+ describe Mexico::Util::FancyWriter do
22
+
23
+
24
+ # set up an initial corpus representation from the example file
25
+ before(:each) do
26
+ @string = String.new
27
+
28
+ end
29
+
30
+ context 'FancyWriter' do
31
+
32
+ it 'should write lines without method as they are' do
33
+ @writer = Mexico::Util::FancyWriter.new(@string) do
34
+ w "Foo"
35
+ end
36
+ @string.should eq "Foo\n"
37
+ end
38
+
39
+ it "should write comments without options as '# '" do
40
+ @writer = Mexico::Util::FancyWriter.new(@string) do
41
+ comment do
42
+ w "Foo"
43
+ end
44
+ end
45
+ @string.should eq "# Foo\n"
46
+ end
47
+
48
+ it "should write comments with options correctly" do
49
+ @writer = Mexico::Util::FancyWriter.new(@string) do
50
+ comment '// ' do
51
+ w "Foo"
52
+ end
53
+ end
54
+ @string.should eq "// Foo\n"
55
+ end
56
+
57
+ it "should export a complex example correctly." do
58
+ @writer = Mexico::Util::FancyWriter.new(@string) do
59
+ comment '# ' do
60
+ line 'This is an example.'
61
+ line 'This should be a block at the top.'
62
+ end
63
+ line 'config:'
64
+ indent 4 do
65
+ line 'setting:'
66
+ indent 4 do
67
+ line 'key: value.'
68
+ comment do
69
+ line 'This is an inside comment.'
70
+ end
71
+ end
72
+ end
73
+ end
74
+ puts @string
75
+ end
76
+ end
77
+ end
@@ -30,14 +30,47 @@ describe Mexico::Fiesta::Interfaces::ElanInterface do
30
30
  context 'Elan ' do
31
31
  it 'reads data from a test file' do
32
32
  path = File.join @assetspath, 'fiesta', 'elan'
33
- filename = File.join path, 'ElanFileFormat.eaf'
33
+ filename = File.join path, 'Trial04.eaf' #'ElanFileFormat.eaf'
34
34
  @fdoc = ::Mexico::Fiesta::Interfaces::ElanInterface.import(File.open(filename))
35
35
  File.open(File.join(path,'test.out.fst'),'w') do |f|
36
36
  f << @fdoc.to_xml
37
37
  end
38
38
  end
39
+
40
+ it 'reads data from the all-formats file' do
41
+ path = File.join @assetspath, 'fiesta', 'elan'
42
+ filename = File.join path, 'ElanFileFormat.eaf' #'ElanFileFormat.eaf'
43
+ @fdoc = ::Mexico::Fiesta::Interfaces::ElanInterface.import(File.open(filename))
44
+ File.open(File.join(path,'ElanFileFormat.fst'),'w') do |f|
45
+ f << @fdoc.to_xml
46
+ end
47
+ end
48
+
49
+ it 'exports a FiESTA file to EAF' do
50
+ @fdoc = ::Mexico::FileSystem::FiestaDocument.open(File.join(@assetspath, 'fiesta', 'elan', 'test.out.fst')) # Fiesta::Interfaces::ElanInterface.import(File.open(filename))
51
+ @fdoc.should_not be nil
52
+ File.open(File.join(@assetspath, 'fiesta', 'elan', 'test.out.eaf'),'w') do |f|
53
+ ::Mexico::Fiesta::Interfaces::ElanInterface::export(@fdoc, f)
54
+ end
55
+ end
56
+
57
+ it 'imports and exports an EAF document and preserves its structure and contents' do
58
+ path = File.join @assetspath, 'fiesta', 'elan'
59
+ filename = File.join path, 'Trial04.eaf'
60
+ @fdoc = ::Mexico::Fiesta::Interfaces::ElanInterface.import(File.open(filename))
61
+ # ::Mexico::FileSystem::FiestaDocument.open(File.join(@assetspath, 'fiesta', 'elan', 'test.out.fst')) # Fiesta::Interfaces::ElanInterface.import(File.open(filename))
62
+ @fdoc.should_not be nil
63
+ File.open(File.join(@assetspath, 'fiesta', 'elan', 'Trial04.fst'),'w') do |f|
64
+ f << @fdoc.to_xml
65
+ end
66
+ File.open(File.join(@assetspath, 'fiesta', 'elan', 'Trial04.OUT.eaf'),'w') do |f|
67
+ ::Mexico::Fiesta::Interfaces::ElanInterface::export(@fdoc, f)
68
+ end
69
+ end
70
+
71
+
39
72
  end
40
73
  end
41
74
  end
42
75
 
43
- end
76
+ end
@@ -0,0 +1,45 @@
1
+ # This file is part of the MExiCo gem.
2
+ # Copyright (c) 2012-2014 Peter Menke, SFB 673, Universität Bielefeld
3
+ # http://www.sfb673.org
4
+ #
5
+ # MExiCo is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU Lesser General Public License as
7
+ # published by the Free Software Foundation, either version 3 of
8
+ # the License, or (at your option) any later version.
9
+ #
10
+ # MExiCo is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Lesser General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Lesser General Public
16
+ # License along with MExiCo. If not, see
17
+ # <http://www.gnu.org/licenses/>.
18
+
19
+ require 'spec_helper'
20
+
21
+ describe Mexico::FileSystem::Layer do
22
+
23
+ before(:each) do
24
+ @basepath = File.join File.dirname(__FILE__), '..', '..'
25
+ @path = File.join @basepath, 'assets', 'fiesta', 'props'
26
+ @filename = File.join(@path,'props.fst')
27
+ @fdoc = ::Mexico::FileSystem::FiestaDocument.open(@filename)
28
+
29
+ @outfile = File.join(@path,'out.fst')
30
+ File.open(@outfile, 'w') do |f|
31
+ f.write @fdoc.to_xml
32
+ end
33
+ end
34
+
35
+ context 'Fiesta ' do
36
+ context 'Layer' do
37
+ it 'reads props from layers' do
38
+ @fdoc.layers.first.should respond_to(:properties)
39
+ @fdoc.layers.first.properties.should have_key('elanTierType')
40
+ @fdoc.layers.first.properties['elanTierType'].should_not be nil
41
+ @fdoc.layers.first.properties['elanTierType'].value.should eq 'TIME_SUBDIVISION'
42
+ end
43
+ end
44
+ end
45
+ end
@@ -47,6 +47,25 @@ describe Mexico::Fiesta::Interfaces::ShortTextGridInterface do
47
47
  end
48
48
  end
49
49
 
50
+
51
+ it 'writes data to a short text grid file' do
52
+ path = File.join @assetspath, 'fiesta', 'praat'
53
+ filename = File.join path, 'mexico.ShortTextGrid'
54
+ @fdoc = ::Mexico::Fiesta::Interfaces::ShortTextGridInterface.import(File.open(filename))
55
+
56
+ @outfile = File.join path, 'mexico.OUT.ShortTextGrid'
57
+ ::Mexico::Fiesta::Interfaces::ShortTextGridInterface.export(@fdoc, File.open(@outfile, 'w'))
58
+ end
59
+
60
+ it 'writes data to a text grid file' do
61
+ path = File.join @assetspath, 'fiesta', 'praat'
62
+ filename = File.join path, 'mexico.TextGrid'
63
+ @fdoc = ::Mexico::Fiesta::Interfaces::TextGridInterface.import(File.open(filename))
64
+
65
+ @outfile = File.join path, 'mexico.OUT.TextGrid'
66
+ ::Mexico::Fiesta::Interfaces::TextGridInterface.export(@fdoc, File.open(@outfile, 'w'))
67
+ end
68
+
50
69
  end
51
70
  end
52
71
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mexico
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.10
4
+ version: 0.0.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Menke
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-26 00:00:00.000000000 Z
11
+ date: 2014-03-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -236,6 +236,7 @@ files:
236
236
  - assets/fiesta/head/head.fst
237
237
  - assets/fiesta/praat/mexico.ShortTextGrid
238
238
  - assets/fiesta/praat/mexico.TextGrid
239
+ - assets/fiesta/props/props.fst
239
240
  - assets/helpers/collection_ref_handler.rb
240
241
  - assets/helpers/id_ref_handler.rb
241
242
  - assets/helpers/roxml_attribute_handler.rb
@@ -247,6 +248,7 @@ files:
247
248
  - features/support/env.rb
248
249
  - info/releasenotes/0.0.1.md
249
250
  - info/releasenotes/0.0.10.md
251
+ - info/releasenotes/0.0.11.md
250
252
  - info/releasenotes/0.0.2.md
251
253
  - info/releasenotes/0.0.3.md
252
254
  - info/releasenotes/0.0.4.md
@@ -306,11 +308,14 @@ files:
306
308
  - lib/mexico/not_yet_implemented_error.rb
307
309
  - lib/mexico/util.rb
308
310
  - lib/mexico/util/fancy_container.rb
311
+ - lib/mexico/util/fancy_writer.rb
309
312
  - spec/constraints/constraints_spec.rb
313
+ - spec/core/fancy_writer_spec.rb
310
314
  - spec/core/media_type_spec.rb
311
315
  - spec/fiesta/b6_spec.rb
312
316
  - spec/fiesta/elan_spec.rb
313
317
  - spec/fiesta/head_spec.rb
318
+ - spec/fiesta/layer_prop_spec.rb
314
319
  - spec/fiesta/praat_spec.rb
315
320
  - spec/fiesta/read_spec.rb
316
321
  - spec/file_system_based/better_collection_spec.rb