bel 0.7.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/{bel.gemspec → .gemspec} +8 -4
  3. data/README.md +3 -3
  4. data/VERSION +1 -0
  5. data/bin/bel +8 -8
  6. data/bin/bel2rdf.rb +1 -1
  7. data/bin/bel_summarize.rb +4 -4
  8. data/bin/bel_upgrade.rb +6 -6
  9. data/lib/bel.rb +3 -2
  10. data/lib/bel/completion.rb +13 -10
  11. data/lib/bel/completion_rule.rb +29 -21
  12. data/lib/bel/dsl.rb +75 -0
  13. data/lib/bel/gen.rb +2 -2
  14. data/lib/bel/gen/annotation.rb +2 -2
  15. data/lib/bel/gen/citation.rb +6 -6
  16. data/lib/bel/gen/document_header.rb +1 -1
  17. data/lib/bel/gen/{evidence.rb → nanopub.rb} +15 -15
  18. data/lib/bel/gen/parameter.rb +6 -6
  19. data/lib/bel/gen/sample_resources.rb +4 -4
  20. data/lib/bel/gen/statement.rb +1 -1
  21. data/lib/bel/gen/term.rb +1 -1
  22. data/lib/bel/language.rb +0 -20
  23. data/lib/bel/namespace.rb +7 -3
  24. data/lib/bel/nanopub.rb +15 -0
  25. data/lib/bel/{evidence_model/buffering_evidence_combiner.rb → nanopub/buffering_nanopub_combiner.rb} +39 -45
  26. data/lib/bel/{evidence_model → nanopub}/citation.rb +2 -2
  27. data/lib/bel/{evidence_model → nanopub}/experiment_context.rb +7 -1
  28. data/lib/bel/{evidence_model → nanopub}/hash_map_references.rb +1 -1
  29. data/lib/bel/{evidence_model → nanopub}/map_references.rb +1 -1
  30. data/lib/bel/nanopub/map_references_combiner.rb +30 -0
  31. data/lib/bel/nanopub/metadata.rb +102 -0
  32. data/lib/bel/nanopub/nanopub.rb +122 -0
  33. data/lib/bel/{evidence_model → nanopub}/references.rb +50 -38
  34. data/lib/bel/{evidence_model/streaming_evidence_combiner.rb → nanopub/streaming_nanopub_combiner.rb} +8 -8
  35. data/lib/bel/{evidence_model/summary_text.rb → nanopub/support.rb} +8 -2
  36. data/lib/bel/{evidence_model → nanopub}/util.rb +10 -10
  37. data/lib/bel/resource/annotation.rb +15 -24
  38. data/lib/bel/resource/annotation_value.rb +24 -20
  39. data/lib/bel/resource/annotations.rb +12 -11
  40. data/lib/bel/resource/concept.rb +62 -0
  41. data/lib/bel/resource/concept_scheme.rb +49 -0
  42. data/lib/bel/resource/namespace.rb +15 -24
  43. data/lib/bel/resource/namespace_value.rb +26 -23
  44. data/lib/bel/resource/namespaces.rb +11 -11
  45. data/lib/bel/script.rb +367 -367
  46. data/lib/bel/translate.rb +7 -7
  47. data/lib/bel/translator.rb +10 -10
  48. data/lib/bel/translator/plugins/bnj.rb +37 -0
  49. data/lib/bel/translator/plugins/{json_evidence → bnj}/translator.rb +17 -34
  50. data/lib/bel/translator/plugins/jgf.rb +1 -1
  51. data/lib/bel/translator/plugins/jgf/translator.rb +10 -10
  52. data/lib/bel/translator/plugins/jsonld.rb +1 -1
  53. data/lib/bel/translator/plugins/nquads.rb +1 -1
  54. data/lib/bel/translator/plugins/ntriples.rb +1 -1
  55. data/lib/bel/translator/plugins/rdf/bel_schema.rb +134 -126
  56. data/lib/bel/translator/plugins/rdf/graph_translator.rb +6 -6
  57. data/lib/bel/translator/plugins/rdf/monkey_patch.rb +50 -49
  58. data/lib/bel/translator/plugins/rdf/reader.rb +42 -42
  59. data/lib/bel/translator/plugins/rdf/translator.rb +6 -6
  60. data/lib/bel/translator/plugins/rdf/writer.rb +4 -4
  61. data/lib/bel/translator/plugins/rdf2/belv2_0.rb +416 -0
  62. data/lib/bel/translator/plugins/rdf2/converter.rb +13 -0
  63. data/lib/bel/translator/plugins/rdf2/namespace_converter.rb +24 -0
  64. data/lib/bel/translator/plugins/rdf2/nanopub_converter.rb +82 -0
  65. data/lib/bel/translator/plugins/rdf2/parameter_converter.rb +50 -0
  66. data/lib/bel/translator/plugins/rdf2/rdf_converter.rb +13 -0
  67. data/lib/bel/translator/plugins/rdf2/rdf_writer.rb +63 -0
  68. data/lib/bel/translator/plugins/rdf2/reader.rb +172 -0
  69. data/lib/bel/translator/plugins/rdf2/relationship_converter.rb +49 -0
  70. data/lib/bel/translator/plugins/rdf2/statement_converter.rb +65 -0
  71. data/lib/bel/translator/plugins/rdf2/term_converter.rb +262 -0
  72. data/lib/bel/translator/plugins/rdf2/translator.rb +51 -0
  73. data/lib/bel/translator/plugins/rdf2/uuid.rb +20 -0
  74. data/lib/bel/translator/plugins/rdf2/writer.rb +53 -0
  75. data/lib/bel/translator/plugins/rdfa.rb +1 -1
  76. data/lib/bel/translator/plugins/rdfxml.rb +1 -1
  77. data/lib/bel/translator/plugins/rj.rb +1 -1
  78. data/lib/bel/translator/plugins/trig.rb +1 -1
  79. data/lib/bel/translator/plugins/trix.rb +1 -1
  80. data/lib/bel/translator/plugins/turtle.rb +3 -6
  81. data/lib/bel/translator/plugins/xbel.rb +5 -6
  82. data/lib/bel/translator/plugins/xbel/nanopub_handler.rb +625 -0
  83. data/lib/bel/translator/plugins/xbel/{evidence_yielder.rb → nanopub_yielder.rb} +3 -3
  84. data/lib/bel/translator/plugins/xbel/translator.rb +2 -5
  85. data/lib/bel/translator/plugins/xbel/xbel_yielder.rb +135 -74
  86. data/lib/bel/version.rb +31 -1
  87. metadata +81 -33
  88. data/lib/bel/evidence_model.rb +0 -15
  89. data/lib/bel/evidence_model/bel_parameter.rb +0 -56
  90. data/lib/bel/evidence_model/bel_statement.rb +0 -97
  91. data/lib/bel/evidence_model/bel_term.rb +0 -87
  92. data/lib/bel/evidence_model/evidence.rb +0 -127
  93. data/lib/bel/evidence_model/map_references_combiner.rb +0 -30
  94. data/lib/bel/evidence_model/metadata.rb +0 -49
  95. data/lib/bel/parser.rb +0 -39
  96. data/lib/bel/translator/plugins/bel_script.rb +0 -36
  97. data/lib/bel/translator/plugins/bel_script/bel_citation_serialization.rb +0 -125
  98. data/lib/bel/translator/plugins/bel_script/bel_discrete_serialization.rb +0 -109
  99. data/lib/bel/translator/plugins/bel_script/bel_top_down_serialization.rb +0 -100
  100. data/lib/bel/translator/plugins/bel_script/bel_yielder.rb +0 -180
  101. data/lib/bel/translator/plugins/bel_script/evidence_serialization.rb +0 -79
  102. data/lib/bel/translator/plugins/bel_script/evidence_yielder.rb +0 -87
  103. data/lib/bel/translator/plugins/bel_script/translator.rb +0 -35
  104. data/lib/bel/translator/plugins/json_evidence.rb +0 -38
  105. data/lib/bel/translator/plugins/xbel/evidence_handler.rb +0 -495
@@ -4,7 +4,7 @@ module BEL::Translator::Plugins
4
4
 
5
5
  ID = :rdfa
6
6
  NAME = 'RDFa RDF Translator'
7
- DESCRIPTION = 'A translator that can read and write RDFa (https://rdfa.info/) for BEL evidence.'
7
+ DESCRIPTION = 'A translator that can read/write BEL nanopubs to RDFa (https://rdfa.info/).'
8
8
  MEDIA_TYPES = %i(application/xml)
9
9
  EXTENSIONS = %i(rdfa)
10
10
 
@@ -4,7 +4,7 @@ module BEL::Translator::Plugins
4
4
 
5
5
  ID = :rdfxml
6
6
  NAME = 'RDF/XML RDF Translator'
7
- DESCRIPTION = 'A translator that can read and write RDF/XML for BEL evidence.'
7
+ DESCRIPTION = 'A translator that can read/write BEL nanopubs to RDF/XML.'
8
8
  MEDIA_TYPES = %i(application/rdf+xml)
9
9
  EXTENSIONS = %i(rdf)
10
10
 
@@ -4,7 +4,7 @@ module BEL::Translator::Plugins
4
4
 
5
5
  ID = :rj
6
6
  NAME = 'RDF/JSON RDF Translator'
7
- DESCRIPTION = 'A translator that can read and write RDF/JSON (https://dvcs.w3.org/hg/rdf/raw-file/default/rdf-json/index.html) for BEL evidence.'
7
+ DESCRIPTION = 'A translator that can read/write BEL nanopubs to RDF/JSON (https://dvcs.w3.org/hg/rdf/raw-file/default/rdf-json/index.html).'
8
8
  MEDIA_TYPES = %i(application/rdf+json)
9
9
  EXTENSIONS = %i(rj)
10
10
 
@@ -4,7 +4,7 @@ module BEL::Translator::Plugins
4
4
 
5
5
  ID = :trig
6
6
  NAME = 'TriG RDF Translator'
7
- DESCRIPTION = 'A translator that can read and write TriG (https://www.w3.org/TR/trig/) for BEL evidence.'
7
+ DESCRIPTION = 'A translator that can read/write BEL nanopubs to TriG.'
8
8
  MEDIA_TYPES = %i(application/trig)
9
9
  EXTENSIONS = %i(trig)
10
10
 
@@ -4,7 +4,7 @@ module BEL::Translator::Plugins
4
4
 
5
5
  ID = :trix
6
6
  NAME = 'TriX RDF Translator'
7
- DESCRIPTION = 'A translator that can read and write TriX (https://en.wikipedia.org/wiki/TriX_(syntax)) for BEL evidence.'
7
+ DESCRIPTION = 'A translator that can read/write BEL nanopubs to TriX.'
8
8
  MEDIA_TYPES = %i(application/trix)
9
9
  EXTENSIONS = %i(trix)
10
10
 
@@ -4,18 +4,15 @@ module BEL::Translator::Plugins
4
4
 
5
5
  ID = :turtle
6
6
  NAME = 'Turtle RDF Translator'
7
- DESCRIPTION = 'A translator that can read and write turtle for BEL evidence.'
7
+ DESCRIPTION = 'A translator that can read/write BEL nanopubs to RDF Turtle.'
8
8
  MEDIA_TYPES = %i(application/turtle application/x-turtle)
9
9
  EXTENSIONS = %i(ttl)
10
10
 
11
11
  def self.create_translator(options = {})
12
12
  require 'rdf'
13
13
  require 'rdf/turtle'
14
- require_relative 'rdf/translator'
15
- BELRDF::Translator.new(
16
- ID,
17
- options[:write_schema]
18
- )
14
+ require_relative 'rdf2/translator'
15
+ BEL::BELRDF::Translator.new(ID, options[:write_schema])
19
16
  end
20
17
 
21
18
  def self.id
@@ -1,12 +1,11 @@
1
1
  module BEL::Translator::Plugins
2
-
3
2
  module Xbel
4
-
5
3
  ID = :xbel
6
- NAME = 'XBEL Translator'
7
- DESCRIPTION = 'A translator that can read and write evidence to XBEL (version 1.0). XBEL is an XML dialect. XML Schema for version 1.0 is published here (http://resource.belframework.org/belframework/1.0/schema/xbel.xsd).'
8
- MEDIA_TYPES = %i(application/xml)
9
- EXTENSIONS = %i(xml xbel)
4
+ NAME = 'XBEL Translator'.freeze
5
+ DESCRIPTION =
6
+ 'A translator that can read/write BEL nanopubs to XBEL.'.freeze
7
+ MEDIA_TYPES = %i(application/xml).freeze
8
+ EXTENSIONS = %i(xml xbel).freeze
10
9
 
11
10
  def self.create_translator(options = {})
12
11
  require_relative 'xbel/translator'
@@ -0,0 +1,625 @@
1
+ require 'rexml/streamlistener'
2
+
3
+ module BEL::Translator::Plugins
4
+ module Xbel
5
+ class NanopubHandler
6
+ include REXML::StreamListener
7
+ include ::BEL::Nanopub
8
+
9
+ ANNOTATION = 'annotation'.freeze
10
+ ANNOTATION_DEFINITION_GROUP = 'annotationDefinitionGroup'.freeze
11
+ ANNOTATION_GROUP = 'annotationGroup'.freeze
12
+ AUTHOR = 'author'.freeze
13
+ AUTHOR_GROUP = 'authorGroup'.freeze
14
+ BEL_VERSION = 'belVersion'.freeze
15
+ CITATION = 'citation'.freeze
16
+ COMMENT = 'comment'.freeze
17
+ CONTACT_INFO = 'contactInfo'.freeze
18
+ COPYRIGHT = 'copyright'.freeze
19
+ DATE = 'date'.freeze
20
+ DEFAULT_NAMESPACE = 'defaultNamespace'.freeze
21
+ DESCRIPTION = 'description'.freeze
22
+ DOCUMENT = 'document'.freeze
23
+ EVIDENCE = 'evidence'.freeze
24
+ EXTERNAL_ANNOTATION_DEFINITION = 'externalAnnotationDefinition'.freeze
25
+ FUNCTION = 'function'.freeze
26
+ HEADER = 'header'.freeze
27
+ ID = 'id'.freeze
28
+ INTERNAL_ANNOTATION_DEFINITION = 'internalAnnotationDefinition'.freeze
29
+ LICENSE = 'license'.freeze
30
+ LICENSE_GROUP = 'licenseGroup'.freeze
31
+ LIST_ANNOTATION = 'listAnnotation'.freeze
32
+ LIST_VALUE = 'listValue'.freeze
33
+ NAME = 'name'.freeze
34
+ NAMESPACE = 'namespace'.freeze
35
+ NAMESPACE_GROUP = 'namespaceGroup'.freeze
36
+ NANOPUB = 'nanopub'.freeze
37
+ NS = 'ns'.freeze
38
+ OBJECT = 'object'.freeze
39
+ PARAMETER = 'parameter'.freeze
40
+ PATTERN_ANNOTATION = 'patternAnnotation'.freeze
41
+ PREFIX = 'prefix'.freeze
42
+ RESOURCE = 'resource'.freeze
43
+ REFERENCE = 'reference'.freeze
44
+ REF_ID = 'refID'.freeze
45
+ RELATIONSHIP = 'relationship'.freeze
46
+ RESOURCE_LOCATION = 'resourceLocation'.freeze
47
+ STATEMENT = 'statement'.freeze
48
+ STATEMENT_GROUP = 'statementGroup'.freeze
49
+ SUBJECT = 'subject'.freeze
50
+ SUPPORT = 'support'.freeze
51
+ TERM = 'term'.freeze
52
+ TYPE = 'type'.freeze
53
+ URI = 'uri'.freeze
54
+ URL = 'url'.freeze
55
+ USAGE = 'usage'.freeze
56
+ VERSION = 'version'.freeze
57
+ Model = BELParser::Expression::Model
58
+
59
+ def initialize(callable)
60
+ @callable = callable
61
+ @element_stack = []
62
+ @text = nil
63
+ @nanopub = Nanopub.new
64
+ @annotations = {}
65
+ @namespaces = {}
66
+ @spec = BELParser::Language.latest_supported_specification
67
+
68
+ @last_prefix = nil
69
+ @last_keyword = nil
70
+ # default BEL version to 1 for backwards compatibility
71
+ @bel_version = 1
72
+ @nanopub.metadata.bel_version = "1.0"
73
+ end
74
+
75
+ # Called on element start by REXML.
76
+ def tag_start(name, attributes)
77
+ name.
78
+ sub!(/^bel:/, '').
79
+ gsub!(/([A-Z])/) { |match| "_#{match.downcase}" }
80
+
81
+ start_method = "start_#{name}"
82
+ if self.respond_to? start_method
83
+ self.send(start_method, attributes)
84
+ end
85
+ end
86
+
87
+ # Called on element end by REXML.
88
+ def tag_end(name)
89
+ name.
90
+ sub!(/^bel:/, '').
91
+ gsub!(/([A-Z])/) { |match| "_#{match.downcase}" }
92
+
93
+ end_method = "end_#{name}"
94
+ if self.respond_to? end_method
95
+ self.send end_method
96
+ end
97
+ end
98
+
99
+ # Called on text node by REXML.
100
+ def text(*args)
101
+ if args.size.zero?
102
+ @text = ''
103
+ else
104
+ @text = args.first
105
+ end
106
+ end
107
+
108
+ # Start element methods, dynamically invoked.
109
+
110
+ def start_header(attributes)
111
+ @element_stack << :header
112
+ end
113
+
114
+ def start_namespace_group(attributes)
115
+ @element_stack << :namespace_group
116
+ end
117
+
118
+ def start_annotation_definition_group(attributes)
119
+ @element_stack << :annotation_definition_group
120
+ end
121
+
122
+ def start_namespace(attributes)
123
+ if stack_top == :namespace_group
124
+ prefix = attr_value(attributes, PREFIX)
125
+ @last_prefix = prefix
126
+ if @bel_version == 1
127
+ resource_location = attr_value(attributes, RESOURCE_LOCATION)
128
+ @namespaces[prefix] = {keyword: prefix, uri: resource_location}
129
+ end
130
+ end
131
+ @element_stack << :namespace
132
+ end
133
+
134
+ def start_external_annotation_definition(attributes)
135
+ if stack_top == :annotation_definition_group
136
+ keyword = attr_value(attributes, ID)
137
+ @last_keyword = keyword
138
+ if @bel_version == 1
139
+ uri = attr_value(attributes, URL)
140
+ @annotations[keyword] =
141
+ {keyword: keyword, type: :uri, domain: uri}
142
+ end
143
+ end
144
+ @element_stack << :external_annotation_definition
145
+ end
146
+
147
+ def start_internal_annotation_definition(attributes)
148
+ if stack_top == :annotation_definition_group
149
+ @current_anno_def = {
150
+ :keyword => attr_value(attributes, ID)
151
+ }
152
+ end
153
+ @element_stack << :internal_annotation_definition
154
+ end
155
+
156
+ def start_list_annotation(attributes)
157
+ if stack_top == :internal_annotation_definition
158
+ @current_anno_def[:type] = :list
159
+ @current_anno_def[:domain] = []
160
+ end
161
+ @element_stack << :list_annotation
162
+ end
163
+
164
+ def start_pattern_annotation(attributes)
165
+ if stack_top == :internal_annotation_definition
166
+ @current_anno_def[:type] = :pattern
167
+ end
168
+ @element_stack << :pattern_annotation
169
+ end
170
+
171
+ def start_statement_group(attributes)
172
+ @element_stack << :statement_group
173
+ end
174
+
175
+ def start_statement(attributes)
176
+ relationship = attr_value(attributes, RELATIONSHIP)
177
+ stmt = {
178
+ relationship: convert_relationship(relationship)
179
+ }
180
+ if stack_top == :statement_group
181
+ @statement_stack = []
182
+ @statement_stack << stmt
183
+ elsif stack_top == :object
184
+ #@statement_stack.last[:object] = stmt
185
+ @statement_stack << stmt
186
+ end
187
+
188
+ @element_stack << :statement
189
+ end
190
+
191
+ def start_subject(attributes)
192
+ @element_stack << :subject
193
+ end
194
+
195
+ def start_object(attributes)
196
+ @element_stack << :object
197
+ end
198
+
199
+ def start_term(attributes)
200
+ function = @spec.function(attr_value(attributes, FUNCTION).to_sym)
201
+ term = BELParser::Expression::Model::Term.new(function, [])
202
+ if stack_top == :subject || stack_top == :object
203
+ # outer term
204
+ @term_stack = []
205
+ elsif stack_top == :term
206
+ # nested term
207
+ @term_stack.last.arguments << term
208
+ end
209
+
210
+ @term_stack << term
211
+ @element_stack << :term
212
+ end
213
+
214
+ def start_parameter(attributes)
215
+ if stack_top == :term
216
+ ns =
217
+ if has_attr?(attributes, NS)
218
+ ns_id = attr_value(attributes, NS)
219
+ namespace_reference(ns_id, @nanopub)
220
+ else
221
+ nil
222
+ end
223
+ @current_parameter = Model::Parameter.new(ns, ns_id)
224
+ end
225
+ @element_stack << :parameter
226
+ end
227
+
228
+ def start_annotation_group(attributes)
229
+ @annotation_id = nil
230
+ @element_stack << :annotation_group
231
+ end
232
+
233
+ def start_annotation(attributes)
234
+ if @element_stack[-2] == :statement
235
+ ref_id = attr_value(attributes, REF_ID)
236
+ @annotation_id = ref_id
237
+ @element_stack << :annotation
238
+ end
239
+ end
240
+
241
+ def start_evidence(attributes)
242
+ @element_stack << :evidence
243
+ end
244
+
245
+ def start_support(attributes)
246
+ @element_stack << :support
247
+ end
248
+
249
+ def start_citation(attributes)
250
+ type = attr_value(attributes, TYPE)
251
+ @nanopub.citation.type = type
252
+ @element_stack << :citation
253
+ end
254
+
255
+ def start_nanopub(attributes)
256
+ @element_stack << :nanopub
257
+ end
258
+
259
+ def start_default_namespace(attributes)
260
+ if stack_top == :namespace_group
261
+ prefix = attr_value(attributes, PREFIX)
262
+ @namespaces[prefix] = {keyword: prefix}
263
+ @last_prefix = prefix
264
+ end
265
+ @element_stack << :default_namespace
266
+ end
267
+
268
+ def end_default_namespace
269
+ @element_stack.pop
270
+ @last_prefix = nil
271
+ end
272
+
273
+ def start_resource(attributes)
274
+ @element_stack << :resource
275
+ end
276
+
277
+ def end_resource
278
+ @element_stack.pop
279
+ end
280
+
281
+ def start_uri(attributes)
282
+ @element_stack << :uri
283
+ end
284
+
285
+ def end_uri
286
+ # context is namespace or annotation
287
+ context = peek(-2)
288
+ if context == :namespace || context == :default_namespace
289
+ @namespaces[@last_prefix][:uri] = @text
290
+ elsif context == :external_annotation_definition
291
+ annotation = @annotations[@last_keyword]
292
+ annotation[:type] = :uri
293
+ annotation[:domain] = @text
294
+ end
295
+ @element_stack.pop
296
+ end
297
+
298
+ def start_url(attributes)
299
+ @element_stack << :url
300
+ end
301
+
302
+ def end_url
303
+ # context is namespace or annotation
304
+ context = peek(-2)
305
+ if context == :namespace || context == :default_namespace
306
+ @namespaces[@last_prefix][:url] = @text
307
+ elsif context == :external_annotation_definition
308
+ annotation = @annotations[@last_keyword]
309
+ annotation[:type] = :url
310
+ annotation[:domain] = @text
311
+ end
312
+ @element_stack.pop
313
+ end
314
+
315
+ # End element methods, dynamically invoked.
316
+
317
+ def end_header
318
+ @element_stack.pop
319
+ end
320
+
321
+ def end_version
322
+ if stack_top == :header
323
+ @nanopub.metadata.document_header[:Version] = @text
324
+ end
325
+ end
326
+
327
+ def end_copyright
328
+ if stack_top == :header
329
+ @nanopub.metadata.document_header[:Copyright] = @text
330
+ end
331
+ end
332
+
333
+ def end_contact_info
334
+ if stack_top == :header
335
+ @nanopub.metadata.document_header[:ContactInfo] = @text
336
+ end
337
+ end
338
+
339
+ def end_license
340
+ if stack_top == :header
341
+ @nanopub.metadata.document_header[:Licenses] ||= []
342
+ @nanopub.metadata.document_header[:Licenses] << @text
343
+ end
344
+ end
345
+
346
+ def end_bel_version
347
+ if stack_top == :header
348
+ @nanopub.metadata.document_header[:BELVersion] ||= []
349
+ version = @text
350
+ @nanopub.metadata.document_header[:BELVersion] << version
351
+ @bel_version = version
352
+ @nanopub.metadata.bel_version = @bel_version
353
+ end
354
+ end
355
+
356
+ def end_namespace_group
357
+ @element_stack.pop
358
+ end
359
+
360
+ def end_annotation_definition_group
361
+ @element_stack.pop
362
+ end
363
+
364
+ def end_namespace
365
+ @element_stack.pop
366
+ @last_prefix = nil
367
+ end
368
+
369
+ def end_external_annotation_definition
370
+ @element_stack.pop
371
+ @last_keyword = nil
372
+ end
373
+
374
+ def end_internal_annotation_definition
375
+ @element_stack.pop
376
+ keyword, type, domain =
377
+ @current_anno_def.values_at(:keyword, :type, :domain)
378
+ @annotations[keyword] =
379
+ {keyword: keyword, type: type, domain: domain}
380
+ end
381
+
382
+ def end_list_annotation
383
+ @element_stack.pop
384
+ end
385
+
386
+ def end_pattern_annotation
387
+ begin
388
+ @current_anno_def[:domain] = Regexp.new(@text)
389
+ rescue RegexpError
390
+ @text = Regexp.escape(@text)
391
+ retry
392
+ end
393
+ @element_stack.pop
394
+ end
395
+
396
+ def end_description
397
+ if stack_top == :header
398
+ @nanopub.metadata.document_header[:Description] = @text
399
+ end
400
+
401
+ if stack_top == :internal_annotation_definition
402
+ @current_anno_def[:description] = @text
403
+ end
404
+ end
405
+
406
+ def end_usage
407
+ if stack_top == :internal_annotation_definition
408
+ @current_anno_def[:usage] = @text
409
+ end
410
+ end
411
+
412
+ def end_list_value
413
+ if stack_top == :list_annotation
414
+ @current_anno_def[:domain] << @text
415
+ end
416
+ end
417
+
418
+ def end_statement_group
419
+ @element_stack.pop
420
+ end
421
+
422
+ def end_statement
423
+ @element_stack.pop
424
+ stmt = @statement_stack.pop
425
+
426
+ if stack_top == :object
427
+ @statement_stack.last[:object] =
428
+ BELParser::Expression::Model::Statement.new(
429
+ stmt[:subject],
430
+ stmt[:relationship],
431
+ stmt[:object],
432
+ stmt[:comment]
433
+ )
434
+ elsif @statement_stack.empty?
435
+ # create new nanopub from parsed data
436
+ nanopub_copy = Nanopub.create({
437
+ :bel_statement =>
438
+ BELParser::Expression::Model::Statement.new(
439
+ stmt[:subject],
440
+ stmt[:relationship],
441
+ stmt[:object],
442
+ stmt[:comment]
443
+ ),
444
+ :citation => @nanopub.citation.to_h,
445
+ :support => @nanopub.support.value,
446
+ :experiment_context => @nanopub.experiment_context.values.dup,
447
+ :references => {
448
+ :annotations => @annotations.values,
449
+ :namespaces => @namespaces.values
450
+ },
451
+ :metadata => @nanopub.metadata.values.dup
452
+ })
453
+
454
+ # yield nanopub
455
+ @callable.call(nanopub_copy)
456
+
457
+ # clear nanopub parser state
458
+ # note:
459
+ # - preserve @nanopub.references
460
+ # - preserve @nanopub.metadata.document_header
461
+ @nanopub.bel_statement = nil
462
+ @nanopub.citation = nil
463
+ @nanopub.support = nil
464
+ @nanopub.experiment_context = nil
465
+ @nanopub.metadata.delete_if { |key|
466
+ key != :document_header
467
+ }
468
+ end
469
+ end
470
+
471
+ def end_subject
472
+ @statement_stack.last[:subject] = @term_stack.last
473
+ @element_stack.pop
474
+ end
475
+
476
+ def end_object
477
+ if @statement_stack.last[:object] == nil
478
+ # sets object if it wasn't already set by OBJECT STATEMENT
479
+ @statement_stack.last[:object] = @term_stack.last
480
+ end
481
+ @element_stack.pop
482
+ end
483
+
484
+ def end_term
485
+ @element_stack.pop
486
+
487
+ if @term_stack.size > 1
488
+ @term_stack.pop
489
+ @current_term = @term_stack.last
490
+ end
491
+ end
492
+
493
+ def end_parameter
494
+ @current_parameter.value = @text
495
+ @term_stack.last.arguments << @current_parameter
496
+ @element_stack.pop
497
+ end
498
+
499
+ def end_annotation_group
500
+ @element_stack.pop
501
+ end
502
+
503
+ def end_evidence
504
+ @nanopub.support.value = @text
505
+ @element_stack.pop
506
+ end
507
+
508
+ def end_support
509
+ @nanopub.support.value = @text
510
+ @element_stack.pop
511
+ end
512
+
513
+ def end_annotation
514
+ if @element_stack[-3] == :statement
515
+ ref_id = @annotation_id
516
+
517
+ annotation = @nanopub.experiment_context.find { |annotation|
518
+ annotation[:name] == ref_id
519
+ }
520
+ if annotation
521
+ # create array for multiple values by refID
522
+ annotation[:value] = [annotation[:value], @text].flatten
523
+ else
524
+ @nanopub.experiment_context << {
525
+ :name => ref_id,
526
+ :value => @text
527
+ }
528
+ end
529
+ end
530
+
531
+ @element_stack.pop
532
+ end
533
+
534
+ def end_nanopub
535
+ if @element_stack[-3] == :statement
536
+ @nanopub.support.value = @text
537
+ end
538
+
539
+ @element_stack.pop
540
+ end
541
+
542
+ def end_citation
543
+ @element_stack.pop
544
+ end
545
+
546
+ def end_reference
547
+ if stack_top == :citation
548
+ @nanopub.citation.id = @text
549
+ end
550
+ end
551
+
552
+ def end_name
553
+ if stack_top == :header
554
+ @nanopub.metadata.document_header[:Name] = @text
555
+ end
556
+
557
+ if stack_top == :citation
558
+ @nanopub.citation.name = @text
559
+ end
560
+ end
561
+
562
+ def end_date
563
+ if stack_top == :citation
564
+ @nanopub.citation.date = @text
565
+ end
566
+ end
567
+
568
+ def end_author
569
+ if stack_top == :header
570
+ @nanopub.metadata.document_header[:Authors] ||= []
571
+ @nanopub.metadata.document_header[:Authors] << @text
572
+ end
573
+
574
+ if stack_top == :citation
575
+ @nanopub.citation.authors ||= []
576
+ @nanopub.citation.authors << @text
577
+ end
578
+ end
579
+
580
+ def end_comment
581
+ if stack_top == :citation
582
+ @nanopub.citation.comment = @text
583
+ elsif stack_top == :statement
584
+ @statement_stack.last[:comment] = @text
585
+ end
586
+ end
587
+
588
+ private
589
+
590
+ def stack_top
591
+ @element_stack.last
592
+ end
593
+
594
+ def peek(index)
595
+ @element_stack[index]
596
+ end
597
+
598
+ def attr_value(attributes, attr_name)
599
+ attributes["bel:#{attr_name}"]
600
+ end
601
+
602
+ def has_attr?(attributes, attr_name)
603
+ attributes.has_key?("bel:#{attr_name}")
604
+ end
605
+
606
+ def namespace_reference(ns_id, nanopub)
607
+ namespace_reference = @namespaces[ns_id]
608
+ if namespace_reference
609
+ keyword, uri = namespace_reference.values_at(:keyword, :uri)
610
+ BELParser::Expression::Model::Namespace.new(keyword, uri)
611
+ else
612
+ nil
613
+ end
614
+ end
615
+
616
+ def convert_relationship(relationship)
617
+ if relationship
618
+ @spec.relationship(relationship.to_sym)
619
+ else
620
+ nil
621
+ end
622
+ end
623
+ end
624
+ end
625
+ end