mexico 0.0.10 → 0.0.11

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.
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