moxml 0.1.10 → 0.1.12

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.
Files changed (140) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/docs.yml +1 -1
  3. data/.github/workflows/rake.yml +16 -13
  4. data/.github/workflows/release.yml +1 -0
  5. data/.github/workflows/round-trip.yml +74 -0
  6. data/.gitignore +1 -0
  7. data/.rubocop.yml +1 -0
  8. data/.rubocop_todo.yml +160 -38
  9. data/Gemfile +2 -1
  10. data/README.adoc +236 -0
  11. data/Rakefile +11 -0
  12. data/data/w3c_entities.json +2131 -0
  13. data/docs/ENTITY_SUPPORT_FOR_LUTAML_MODEL.md +102 -0
  14. data/docs/_pages/adapters/ox.adoc +30 -0
  15. data/docs/_pages/configuration.adoc +43 -0
  16. data/docs/_pages/node-api-reference.adoc +35 -0
  17. data/docs/_tutorials/namespace-handling.adoc +21 -0
  18. data/examples/rss_parser/rss_parser.rb +1 -3
  19. data/lib/moxml/adapter/base.rb +26 -2
  20. data/lib/moxml/adapter/headed_ox.rb +5 -4
  21. data/lib/moxml/adapter/libxml.rb +3 -2
  22. data/lib/moxml/adapter/nokogiri.rb +16 -3
  23. data/lib/moxml/adapter/oga.rb +124 -20
  24. data/lib/moxml/adapter/ox.rb +4 -3
  25. data/lib/moxml/adapter/rexml.rb +41 -7
  26. data/lib/moxml/builder.rb +6 -0
  27. data/lib/moxml/config.rb +52 -1
  28. data/lib/moxml/context.rb +21 -2
  29. data/lib/moxml/document.rb +6 -1
  30. data/lib/moxml/document_builder.rb +45 -1
  31. data/lib/moxml/element.rb +4 -3
  32. data/lib/moxml/entity_reference.rb +29 -0
  33. data/lib/moxml/entity_registry.rb +278 -0
  34. data/lib/moxml/node.rb +10 -8
  35. data/lib/moxml/node_set.rb +10 -6
  36. data/lib/moxml/version.rb +1 -1
  37. data/lib/moxml/xml_utils.rb +25 -2
  38. data/lib/moxml.rb +1 -0
  39. data/spec/consistency/README.md +3 -1
  40. data/spec/consistency/round_trip_spec.rb +479 -0
  41. data/spec/examples/readme_examples_spec.rb +1 -1
  42. data/spec/fixtures/round-trips/metanorma/a.xml +66 -0
  43. data/spec/fixtures/round-trips/metanorma/bilingual-en.xml +7682 -0
  44. data/spec/fixtures/round-trips/metanorma/bilingual-fr.xml +7520 -0
  45. data/spec/fixtures/round-trips/metanorma/bilingual.presentation.xml +21211 -0
  46. data/spec/fixtures/round-trips/metanorma/collection1.xml +313 -0
  47. data/spec/fixtures/round-trips/metanorma/collection1nested.xml +291 -0
  48. data/spec/fixtures/round-trips/metanorma/collection_docinline.xml +544 -0
  49. data/spec/fixtures/round-trips/metanorma/collection_full.xml +1776 -0
  50. data/spec/fixtures/round-trips/metanorma/dummy.1.xml +295 -0
  51. data/spec/fixtures/round-trips/metanorma/dummy.xml +349 -0
  52. data/spec/fixtures/round-trips/metanorma/footnotes.xml +70 -0
  53. data/spec/fixtures/round-trips/metanorma/iho.xml +116 -0
  54. data/spec/fixtures/round-trips/metanorma/rice-amd.final.xml +186 -0
  55. data/spec/fixtures/round-trips/metanorma/rice-amd.final_1.xml +180 -0
  56. data/spec/fixtures/round-trips/metanorma/rice-en.final.norepo.xml +116 -0
  57. data/spec/fixtures/round-trips/metanorma/rice-en.final.xml +149 -0
  58. data/spec/fixtures/round-trips/metanorma/rice-en.final_1.xml +144 -0
  59. data/spec/fixtures/round-trips/metanorma/rice1-en.final.xml +120 -0
  60. data/spec/fixtures/round-trips/metanorma/rice2-en.final.xml +116 -0
  61. data/spec/fixtures/round-trips/metanorma/test_sectionsplit.xml +119 -0
  62. data/spec/fixtures/round-trips/niso-jats/bmj_sample.xml +1068 -0
  63. data/spec/fixtures/round-trips/niso-jats/element_citation.xml +7 -0
  64. data/spec/fixtures/round-trips/niso-jats/pnas_sample.xml +3768 -0
  65. data/spec/fixtures/round-trips/rfcxml/rfc8881.xml +45848 -0
  66. data/spec/fixtures/round-trips/rfcxml/rfc8994.xml +6607 -0
  67. data/spec/fixtures/round-trips/rfcxml/rfc9000.xml +9064 -0
  68. data/spec/fixtures/round-trips/rfcxml/rfc9043.xml +5527 -0
  69. data/spec/fixtures/round-trips/rfcxml/rfc9051.xml +14286 -0
  70. data/spec/fixtures/round-trips/rfcxml/rfc9110.xml +18156 -0
  71. data/spec/fixtures/round-trips/rfcxml/rfc9260.xml +9136 -0
  72. data/spec/fixtures/round-trips/rfcxml/rfc9293.xml +8300 -0
  73. data/spec/fixtures/round-trips/rfcxml/rfc9380.xml +8916 -0
  74. data/spec/fixtures/round-trips/rfcxml/rfc9420.xml +8927 -0
  75. data/spec/fixtures/w3c/namespaces/1.0/001.xml +7 -0
  76. data/spec/fixtures/w3c/namespaces/1.0/002.xml +8 -0
  77. data/spec/fixtures/w3c/namespaces/1.0/003.xml +7 -0
  78. data/spec/fixtures/w3c/namespaces/1.0/004.xml +7 -0
  79. data/spec/fixtures/w3c/namespaces/1.0/005.xml +7 -0
  80. data/spec/fixtures/w3c/namespaces/1.0/006.xml +7 -0
  81. data/spec/fixtures/w3c/namespaces/1.0/007.xml +20 -0
  82. data/spec/fixtures/w3c/namespaces/1.0/008.xml +20 -0
  83. data/spec/fixtures/w3c/namespaces/1.0/009.xml +19 -0
  84. data/spec/fixtures/w3c/namespaces/1.0/010.xml +19 -0
  85. data/spec/fixtures/w3c/namespaces/1.0/011.xml +20 -0
  86. data/spec/fixtures/w3c/namespaces/1.0/012.xml +19 -0
  87. data/spec/fixtures/w3c/namespaces/1.0/013.xml +5 -0
  88. data/spec/fixtures/w3c/namespaces/1.0/014.xml +3 -0
  89. data/spec/fixtures/w3c/namespaces/1.0/015.xml +3 -0
  90. data/spec/fixtures/w3c/namespaces/1.0/016.xml +3 -0
  91. data/spec/fixtures/w3c/namespaces/1.0/017.xml +3 -0
  92. data/spec/fixtures/w3c/namespaces/1.0/018.xml +3 -0
  93. data/spec/fixtures/w3c/namespaces/1.0/019.xml +3 -0
  94. data/spec/fixtures/w3c/namespaces/1.0/020.xml +3 -0
  95. data/spec/fixtures/w3c/namespaces/1.0/021.xml +6 -0
  96. data/spec/fixtures/w3c/namespaces/1.0/022.xml +6 -0
  97. data/spec/fixtures/w3c/namespaces/1.0/023.xml +6 -0
  98. data/spec/fixtures/w3c/namespaces/1.0/024.xml +6 -0
  99. data/spec/fixtures/w3c/namespaces/1.0/025.xml +3 -0
  100. data/spec/fixtures/w3c/namespaces/1.0/026.xml +3 -0
  101. data/spec/fixtures/w3c/namespaces/1.0/027.xml +3 -0
  102. data/spec/fixtures/w3c/namespaces/1.0/028.xml +3 -0
  103. data/spec/fixtures/w3c/namespaces/1.0/029.xml +4 -0
  104. data/spec/fixtures/w3c/namespaces/1.0/030.xml +4 -0
  105. data/spec/fixtures/w3c/namespaces/1.0/031.xml +4 -0
  106. data/spec/fixtures/w3c/namespaces/1.0/032.xml +5 -0
  107. data/spec/fixtures/w3c/namespaces/1.0/033.xml +4 -0
  108. data/spec/fixtures/w3c/namespaces/1.0/034.xml +3 -0
  109. data/spec/fixtures/w3c/namespaces/1.0/035.xml +8 -0
  110. data/spec/fixtures/w3c/namespaces/1.0/036.xml +8 -0
  111. data/spec/fixtures/w3c/namespaces/1.0/037.xml +8 -0
  112. data/spec/fixtures/w3c/namespaces/1.0/038.xml +8 -0
  113. data/spec/fixtures/w3c/namespaces/1.0/039.xml +10 -0
  114. data/spec/fixtures/w3c/namespaces/1.0/040.xml +9 -0
  115. data/spec/fixtures/w3c/namespaces/1.0/041.xml +8 -0
  116. data/spec/fixtures/w3c/namespaces/1.0/042.xml +4 -0
  117. data/spec/fixtures/w3c/namespaces/1.0/043.xml +7 -0
  118. data/spec/fixtures/w3c/namespaces/1.0/044.xml +7 -0
  119. data/spec/fixtures/w3c/namespaces/1.0/045.xml +7 -0
  120. data/spec/fixtures/w3c/namespaces/1.0/046.xml +10 -0
  121. data/spec/fixtures/w3c/namespaces/1.0/047.xml +4 -0
  122. data/spec/fixtures/w3c/namespaces/1.0/048.xml +5 -0
  123. data/spec/fixtures/w3c/namespaces/1.0/LICENSE.md +32 -0
  124. data/spec/fixtures/w3c/namespaces/1.0/README.adoc +42 -0
  125. data/spec/fixtures/w3c/namespaces/1.0/rmt-ns10.xml +156 -0
  126. data/spec/integration/shared_examples/node_wrappers/element_behavior.rb +14 -0
  127. data/spec/integration/shared_examples/node_wrappers/namespace_behavior.rb +14 -2
  128. data/spec/integration/shared_examples/w3c_namespace_examples.rb +10 -0
  129. data/spec/integration/w3c_namespace_spec.rb +69 -0
  130. data/spec/moxml/adapter/libxml_spec.rb +7 -1
  131. data/spec/moxml/adapter/oga_spec.rb +92 -0
  132. data/spec/moxml/config_spec.rb +75 -0
  133. data/spec/moxml/entity_registry_spec.rb +184 -0
  134. data/spec/moxml/error_spec.rb +2 -2
  135. data/spec/moxml/namespace_uri_validation_spec.rb +140 -0
  136. data/spec/moxml/xpath/axes_spec.rb +3 -4
  137. data/spec/performance/xpath_benchmark_spec.rb +6 -54
  138. data/spec/support/w3c_namespace_helpers.rb +41 -0
  139. data/spec/unit/rexml_isolated_test.rb +271 -0
  140. metadata +98 -2
@@ -0,0 +1,295 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <metanorma xmlns="https://www.metanorma.org/ns/standoc" flavor="iso">
3
+ <bibdata type="standard">
4
+ <title language="en" format="text/plain" type="main">Dummy document</title>
5
+ <title language="en" format="text/plain" type="title-main">Dummy document</title>
6
+ <title language="fr" format="text/plain" type="main">Dummy document</title>
7
+ <title language="fr" format="text/plain" type="title-main">Dummy document</title>
8
+ <docidentifier primary="true" type="ISO">ISO 17302:2016</docidentifier>
9
+ <docidentifier type="iso-with-lang">ISO 17302:2016(E)</docidentifier>
10
+ <docidentifier type="iso-reference">ISO 17302:2016(E)</docidentifier>
11
+ <docnumber>17302</docnumber>
12
+ <contributor>
13
+ <role type="author"/>
14
+ <organization>
15
+ <name>International Organization for Standardization</name>
16
+ <abbreviation>ISO</abbreviation>
17
+ </organization>
18
+ </contributor>
19
+ <contributor>
20
+ <role type="publisher"/>
21
+ <organization>
22
+ <name>International Organization for Standardization</name>
23
+ <abbreviation>ISO</abbreviation>
24
+ </organization>
25
+ </contributor>
26
+
27
+ <language>en</language>
28
+ <script>Latn</script>
29
+ <status>
30
+ <stage abbreviation="IS">60</stage>
31
+ <substage>60</substage>
32
+ </status>
33
+ <copyright>
34
+ <from>2016</from>
35
+ <owner>
36
+ <organization>
37
+ <name>International Organization for Standardization</name>
38
+ <abbreviation>ISO</abbreviation>
39
+ </organization>
40
+ </owner>
41
+ </copyright>
42
+ <ext>
43
+ <doctype>international-standard</doctype>
44
+ <ics>
45
+ <code>67.060</code>
46
+ </ics>
47
+ <structuredidentifier>
48
+ <project-number>ISO 17302</project-number>
49
+ </structuredidentifier>
50
+ <stagename>International standard</stagename>
51
+ </ext>
52
+ </bibdata>
53
+ <boilerplate>
54
+ <copyright-statement>
55
+ <clause>
56
+ <p id="boilerplate-year">
57
+ © ISO 2016
58
+ </p>
59
+
60
+ <p id="boilerplate-message">
61
+ All rights
62
+ reserved. Unless otherwise specified, no part of this publication may be
63
+ reproduced or utilized otherwise in any form or by any means, electronic or
64
+ mechanical, including photocopying, or posting on the internet or an intranet,
65
+ without prior written permission. Permission can be requested from either ISO
66
+ at the address below or ISO’s member body in the country of the requester.
67
+ </p>
68
+
69
+ <p id="boilerplate-address" align="left">
70
+ ISO copyright office<br/>
71
+ Ch. de Blandonnet 8 • CP 401<br/>
72
+ CH-1214 Vernier, Geneva, Switzerland<br/>
73
+ Tel.  + 41 22 749 01 11<br/>
74
+ Fax  + 41 22 749 09 47<br/>
75
+ Email: copyright@iso.org<br/>
76
+ Website: www.iso.org
77
+ </p>
78
+ <p id="boilerplate-place">
79
+ Published in Switzerland
80
+ </p>
81
+ </clause>
82
+ </copyright-statement>
83
+
84
+
85
+ </boilerplate>
86
+ <sections><clause id="_scope" obligation="normative"><title>Scope</title><p id="_9f7c3e34-6854-4fa6-bb3b-e967ff9f5bf2">This is a dummy document.</p>
87
+ </clause>
88
+ <clause id="E1" type="express-schema">
89
+ <figure id="_b4013f8f-ee40-4186-a5ed-3a5103f199e1">
90
+ <pre id="A1">
91
+ module Metanorma
92
+ class Document
93
+ # @return [Strin]
94
+ attr_reader :file
95
+
96
+ # @param bibitem [RelatonBib::BibliographicItem]
97
+ def initialize(bibitem, file)
98
+ @bibitem = bibitem
99
+ @file = file
100
+ end
101
+
102
+ class &lt;&lt; self
103
+ # @param file [String] file path
104
+ # @return [Metanorma::Document]
105
+ def parse_file(file)
106
+ new bibitem(file), file
107
+ end
108
+
109
+ # #param xml [Nokogiri::XML::Document, Nokogiri::XML::Element]
110
+ # @return [Metanorma::Document]
111
+ def parse_xml(xml)
112
+ new from_xml(xml)
113
+ end
114
+
115
+ private
116
+
117
+ # #param xml [Nokogiri::XML::Document, Nokogiri::XML::Element]
118
+ # @return [RelatonBib::BibliographicItem,RelatonIso::IsoBibliographicItem]
119
+ def from_xml(xml)
120
+ Relaton::Cli.parse_xml xml.at("//xmlns:bibitem|//xmlns:bibdata")
121
+ end
122
+
123
+ # @param file [String]
124
+ # @return [Symbol] file type
125
+ def format(file)
126
+ case file
127
+ when /\.xml$/ then :xml
128
+ when /.ya?ml$/ then :yaml
129
+ end
130
+ end
131
+
132
+ # @param file [String]
133
+ # @return [RelatonBib::BibliographicItem,
134
+ # RelatonIso::IsoBibliographicItem]
135
+ def bibitem(file)
136
+ case format(file)
137
+ when :xml
138
+ from_xml Nokogiri::XML(File.read(file, encoding: "UTF-8"))
139
+ when :yaml
140
+ yaml = File.read(file, ecoding: "UTF-8")
141
+ Relaton::Cli::YAMLConvertor.convert_single_file(yaml)
142
+ end
143
+ end
144
+ end
145
+
146
+ # @param builder [Nokogiri::XML::Builder, nil]
147
+ # @return [Nokogiri::XML::Builder, String]
148
+ def to_xml(builder = nil)
149
+ if builder
150
+ render_xml builder
151
+ else
152
+ Nokogiri::XML::Builder.new do |b|
153
+ root = render_xml b
154
+ root["xmlns"] = "http://metanorma.org"
155
+ end.to_xml
156
+ end
157
+ end
158
+
159
+ # @return [String]
160
+ def type
161
+ @type ||= (@bibitem.docidentifier.first&amp;.type ||
162
+ @bibitem.docidentifier.first&amp;.id&amp;.match(/^[^\s]+/)&amp;.to_s)&amp;.downcase ||
163
+ "standoc"
164
+ end
165
+
166
+ private
167
+
168
+ def render_xml(builder)
169
+ builder.send(type + "-standard") { |b| @bibitem.to_xml b, bibdata: true }
170
+ end
171
+ end
172
+ end
173
+ </pre>
174
+ </figure></clause>
175
+ <clause id="what" inline-header="false" obligation="normative"><title>What?</title><ol id="_2a3efdd5-8e78-47d9-9721-38699221dd31" type="roman">
176
+ <li>
177
+ <p id="_5bbe5050-8dc1-4b7b-936c-d63ca93fa72a">What?</p>
178
+ </li>
179
+ </ol>
180
+ </clause>
181
+ <clause id="E2" type="express-schema">
182
+ <figure id="A2">
183
+ <pre id="_923365c0-4c6d-473e-bb0e-e2ee87dcc438">
184
+ module Metanorma
185
+ # Metanorma collection's manifest
186
+ class CollectionManifest
187
+ # @return [Metanorma::Collection]
188
+ attr_reader :collection
189
+
190
+ # @param level [String]
191
+ # @param title [String, nil]
192
+ # @param docref [Array&lt;Hash{String=&gt;String}&gt;]
193
+ # @param manifest [Array&lt;Metanorma::CollectionManifest&gt;]
194
+ def initialize(level, title = nil, docref = [], manifest = [])
195
+ @level = level
196
+ @title = title
197
+ @docref = docref
198
+ @manifest = manifest
199
+ end
200
+
201
+ class &lt;&lt; self
202
+ # @param mnf [Nokogiri::XML::Element]
203
+ # @return [Metanorma::CollectionManifest]
204
+ def from_yaml(mnf)
205
+ manifest = RelatonBib::HashConverter.array(mnf["manifest"]).map do |m|
206
+ from_yaml m
207
+ end
208
+ docref = RelatonBib::HashConverter.array mnf["docref"]
209
+ new(mnf["level"], mnf["title"], docref, manifest)
210
+ end
211
+
212
+ # @param mnf [Nokogiri::XML::Element]
213
+ # @return [Metanorma::CollectionManifest]
214
+ def from_xml(mnf)
215
+ level = mnf.at("level").text
216
+ title = mnf.at("title")&amp;.text
217
+ manifest = mnf.xpath("xmlns:manifest").map { |m| from_xml(m) }
218
+ new(level, title, parse_docref(mnf), manifest)
219
+ end
220
+
221
+ private
222
+
223
+ # @param mnf [Nokogiri::XML::Element]
224
+ # @return [Hash{String=&gt;String}]
225
+ def parse_docref(mnf)
226
+ mnf.xpath("xmlns:docref").map do |dr|
227
+ h = { "identifier" =&gt; dr.at("identifier").text }
228
+ h["fileref"] = dr[:fileref] if dr[:fileref]
229
+ h
230
+ end
231
+ end
232
+ end
233
+
234
+ # @param col [Metanorma::Collection]
235
+ def collection=(col)
236
+ @collection = col
237
+ @manifest.each { |mnf| mnf.collection = col }
238
+ end
239
+
240
+ # @param dir [String] path to coolection
241
+ # @return [Hash&lt;String, Metanorma::Document&gt;]
242
+ def documents(dir = "")
243
+ docs = @docref.each_with_object({}) do |dr, m|
244
+ next m unless dr["fileref"]
245
+
246
+ m[dr["identifier"]] = Document.parse_file File.join(dir, dr["fileref"])
247
+ m
248
+ end
249
+ @manifest.reduce(docs) do |mem, mnf|
250
+ mem.merge mnf.documents(dir)
251
+ end
252
+ end
253
+
254
+ # @param builder [Nokogiri::XML::Builder]
255
+ def to_xml(builder)
256
+ builder.manifest do |b|
257
+ b.level @level
258
+ b.title @title if @title
259
+ docref_to_xml b
260
+ @manifest.each { |m| m.to_xml b }
261
+ end
262
+ end
263
+
264
+ # @return [Array&lt;Hash{String=&gt;String}&gt;]
265
+ def docrefs
266
+ return @docrefs if @docrefs
267
+
268
+ drfs = @docref.map { |dr| dr }
269
+ @manifest.reduce(drfs) { |mem, mnf| mem + mnf.docrefs }
270
+ end
271
+
272
+ def docref_by_id(docid)
273
+ refs = docrefs
274
+ dref = refs.detect { |k| k["identifier"] == docid }
275
+ dref || docrefs.detect { |k| /^#{k["identifier"]}/ =~ docid }
276
+ end
277
+
278
+ private
279
+
280
+ # @param builder [Nokogiri::XML::Builder]
281
+ def docref_to_xml(builder)
282
+ @docref.each do |dr|
283
+ drf = builder.docref { |b| b.identifier dr["identifier"] }
284
+ drf[:fileref] = dr["fileref"]
285
+ if collection.directives.include?("documents-inline")
286
+ id = collection.documents.find_index { |k, _| k == dr["identifier"] }
287
+ drf[:id] = format("doc%&lt;index&gt;09d", index: id)
288
+ end
289
+ end
290
+ end
291
+ end
292
+ end
293
+ </pre>
294
+ </figure></clause></sections>
295
+ </metanorma>
@@ -0,0 +1,349 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <metanorma xmlns="https://www.metanorma.org/ns/standoc" flavor="iso">
3
+ <bibdata type="standard">
4
+ <title language="en" format="text/plain" type="main">Dummy document</title>
5
+ <title language="en" format="text/plain" type="title-main">Dummy document</title>
6
+ <title language="fr" format="text/plain" type="main">Dummy document</title>
7
+ <title language="fr" format="text/plain" type="title-main">Dummy document</title>
8
+ <docidentifier primary="true" type="ISO">ISO 17302:2016</docidentifier>
9
+ <docidentifier type="iso-with-lang">ISO 17302:2016(E)</docidentifier>
10
+ <docidentifier type="iso-reference">ISO 17302:2016(E)</docidentifier>
11
+ <docnumber>17302</docnumber>
12
+ <contributor>
13
+ <role type="author"/>
14
+ <organization>
15
+ <name>International Organization for Standardization</name>
16
+ <abbreviation>ISO</abbreviation>
17
+ </organization>
18
+ </contributor>
19
+ <contributor>
20
+ <role type="publisher"/>
21
+ <organization>
22
+ <name>International Organization for Standardization</name>
23
+ <abbreviation>ISO</abbreviation>
24
+ </organization>
25
+ </contributor>
26
+
27
+ <language>en</language>
28
+ <script>Latn</script>
29
+ <status>
30
+ <stage abbreviation="IS">60</stage>
31
+ <substage>60</substage>
32
+ </status>
33
+ <copyright>
34
+ <from>2016</from>
35
+ <owner>
36
+ <organization>
37
+ <name>International Organization for Standardization</name>
38
+ <abbreviation>ISO</abbreviation>
39
+ </organization>
40
+ </owner>
41
+ </copyright>
42
+ <ext>
43
+ <doctype>international-standard</doctype>
44
+ <ics>
45
+ <code>67.060</code>
46
+ </ics>
47
+ <structuredidentifier>
48
+ <project-number>ISO 17302</project-number>
49
+ </structuredidentifier>
50
+ <stagename>International standard</stagename>
51
+ </ext>
52
+ </bibdata>
53
+ <metanorma-extension>
54
+ <attachment name="_dummy_attachments/LICENSE1.TXT">data:application/octet-stream;base64,QlNEIDItQ2xhdXNlIExpY2V
55
+ uc2UKCkNvcHlyaWdodCAoYykgMjAxOCwgUmlib3NlCkFsbCByaWdodHMgcmV
56
+ zZXJ2ZWQuCgpSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQ
57
+ gYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKbW9kaWZpY2F0aW9uLCB
58
+ hcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25
59
+ kaXRpb25zIGFyZSBtZXQ6CgoqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2U
60
+ gY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSw
61
+ gdGhpcwogIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyB
62
+ kaXNjbGFpbWVyLgoKKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0
63
+ gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsCiA
64
+ gdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGl
65
+ zY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbgogIGFuZC9vciBvdGhlciB
66
+ tYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgoKVEh
67
+ JUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTER
68
+ FUlMgQU5EIENPTlRSSUJVVE9SUyAiQVMgSVMiCkFORCBBTlkgRVhQUkVTUyB
69
+ PUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1
70
+ JVEVEIFRPLCBUSEUKSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJ
71
+ JTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJ
72
+ FCkRJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQ
73
+ gSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUKRk9SIEFOWSBESVJ
74
+ FQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlk
75
+ sIE9SIENPTlNFUVVFTlRJQUwKREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9
76
+ UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFM
77
+ gT1IKU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyB
78
+ PUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIKQ0FVU0VEIEFORCB
79
+ PTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkF
80
+ DVCwgU1RSSUNUIExJQUJJTElUWSwKT1IgVE9SVCAoSU5DTFVESU5HIE5FR0x
81
+ JR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9
82
+ GIFRIRSBVU0UKT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9
83
+ GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4K
84
+ </attachment>
85
+ </metanorma-extension>
86
+ <boilerplate>
87
+ <copyright-statement>
88
+ <clause>
89
+ <p id="boilerplate-year">
90
+ © ISO 2016
91
+ </p>
92
+
93
+ <p id="boilerplate-message">
94
+ All rights
95
+ reserved. Unless otherwise specified, no part of this publication may be
96
+ reproduced or utilized otherwise in any form or by any means, electronic or
97
+ mechanical, including photocopying, or posting on the internet or an intranet,
98
+ without prior written permission. Permission can be requested from either ISO
99
+ at the address below or ISO’s member body in the country of the requester.
100
+ </p>
101
+
102
+ <p id="boilerplate-address" align="left">
103
+ ISO copyright office<br/>
104
+ Ch. de Blandonnet 8 • CP 401<br/>
105
+ CH-1214 Vernier, Geneva, Switzerland<br/>
106
+ Tel.  + 41 22 749 01 11<br/>
107
+ Fax  + 41 22 749 09 47<br/>
108
+ Email: copyright@iso.org<br/>
109
+ Website: www.iso.org
110
+ </p>
111
+ <p id="boilerplate-place">
112
+ Published in Switzerland
113
+ </p>
114
+ </clause>
115
+ </copyright-statement>
116
+
117
+
118
+ </boilerplate>
119
+ <sections><clause id="_scope" obligation="normative"><title>Scope</title><p id="_9f7c3e34-6854-4fa6-bb3b-e967ff9f5bf2">This is a dummy document.</p>
120
+ </clause>
121
+ <clause id="E1" type="express-schema">
122
+ <figure id="_b4013f8f-ee40-4186-a5ed-3a5103f199e1">
123
+ <pre id="A1">
124
+ module Metanorma
125
+ class Document
126
+ # @return [Strin]
127
+ attr_reader :file
128
+
129
+ # @param bibitem [RelatonBib::BibliographicItem]
130
+ def initialize(bibitem, file)
131
+ @bibitem = bibitem
132
+ @file = file
133
+ end
134
+
135
+ class &lt;&lt; self
136
+ # @param file [String] file path
137
+ # @return [Metanorma::Document]
138
+ def parse_file(file)
139
+ new bibitem(file), file
140
+ end
141
+
142
+ # #param xml [Nokogiri::XML::Document, Nokogiri::XML::Element]
143
+ # @return [Metanorma::Document]
144
+ def parse_xml(xml)
145
+ new from_xml(xml)
146
+ end
147
+
148
+ private
149
+
150
+ # #param xml [Nokogiri::XML::Document, Nokogiri::XML::Element]
151
+ # @return [RelatonBib::BibliographicItem,RelatonIso::IsoBibliographicItem]
152
+ def from_xml(xml)
153
+ Relaton::Cli.parse_xml xml.at("//xmlns:bibitem|//xmlns:bibdata")
154
+ end
155
+
156
+ # @param file [String]
157
+ # @return [Symbol] file type
158
+ def format(file)
159
+ case file
160
+ when /\.xml$/ then :xml
161
+ when /.ya?ml$/ then :yaml
162
+ end
163
+ end
164
+
165
+ # @param file [String]
166
+ # @return [RelatonBib::BibliographicItem,
167
+ # RelatonIso::IsoBibliographicItem]
168
+ def bibitem(file)
169
+ case format(file)
170
+ when :xml
171
+ from_xml Nokogiri::XML(File.read(file, encoding: "UTF-8"))
172
+ when :yaml
173
+ yaml = File.read(file, ecoding: "UTF-8")
174
+ Relaton::Cli::YAMLConvertor.convert_single_file(yaml)
175
+ end
176
+ end
177
+ end
178
+
179
+ # @param builder [Nokogiri::XML::Builder, nil]
180
+ # @return [Nokogiri::XML::Builder, String]
181
+ def to_xml(builder = nil)
182
+ if builder
183
+ render_xml builder
184
+ else
185
+ Nokogiri::XML::Builder.new do |b|
186
+ root = render_xml b
187
+ root["xmlns"] = "http://metanorma.org"
188
+ end.to_xml
189
+ end
190
+ end
191
+
192
+ # @return [String]
193
+ def type
194
+ @type ||= (@bibitem.docidentifier.first&amp;.type ||
195
+ @bibitem.docidentifier.first&amp;.id&amp;.match(/^[^\s]+/)&amp;.to_s)&amp;.downcase ||
196
+ "standoc"
197
+ end
198
+
199
+ private
200
+
201
+ def render_xml(builder)
202
+ builder.send(type + "-standard") { |b| @bibitem.to_xml b, bibdata: true }
203
+ end
204
+ end
205
+ end
206
+ </pre>
207
+ </figure></clause>
208
+ <clause id="what" inline-header="false" obligation="normative"><title>What?</title><ol id="_2a3efdd5-8e78-47d9-9721-38699221dd31" type="roman">
209
+ <li>
210
+ <p id="_5bbe5050-8dc1-4b7b-936c-d63ca93fa72a">What?</p>
211
+ </li>
212
+ </ol>
213
+ <note id="N3">
214
+ <p id="_3cfcdeb7-bba1-0265-29d1-cc6b3c1e1810"><eref type="inline" bibitemid="License_A" citeas="[LICENSE.TXT]">License A</eref></p>
215
+ </note>
216
+ </clause>
217
+ <clause id="E2" type="express-schema">
218
+ <figure id="A2">
219
+ <pre id="_923365c0-4c6d-473e-bb0e-e2ee87dcc438">
220
+ module Metanorma
221
+ # Metanorma collection's manifest
222
+ class CollectionManifest
223
+ # @return [Metanorma::Collection]
224
+ attr_reader :collection
225
+
226
+ # @param level [String]
227
+ # @param title [String, nil]
228
+ # @param docref [Array&lt;Hash{String=&gt;String}&gt;]
229
+ # @param manifest [Array&lt;Metanorma::CollectionManifest&gt;]
230
+ def initialize(level, title = nil, docref = [], manifest = [])
231
+ @level = level
232
+ @title = title
233
+ @docref = docref
234
+ @manifest = manifest
235
+ end
236
+
237
+ class &lt;&lt; self
238
+ # @param mnf [Nokogiri::XML::Element]
239
+ # @return [Metanorma::CollectionManifest]
240
+ def from_yaml(mnf)
241
+ manifest = RelatonBib::HashConverter.array(mnf["manifest"]).map do |m|
242
+ from_yaml m
243
+ end
244
+ docref = RelatonBib::HashConverter.array mnf["docref"]
245
+ new(mnf["level"], mnf["title"], docref, manifest)
246
+ end
247
+
248
+ # @param mnf [Nokogiri::XML::Element]
249
+ # @return [Metanorma::CollectionManifest]
250
+ def from_xml(mnf)
251
+ level = mnf.at("level").text
252
+ title = mnf.at("title")&amp;.text
253
+ manifest = mnf.xpath("xmlns:manifest").map { |m| from_xml(m) }
254
+ new(level, title, parse_docref(mnf), manifest)
255
+ end
256
+
257
+ private
258
+
259
+ # @param mnf [Nokogiri::XML::Element]
260
+ # @return [Hash{String=&gt;String}]
261
+ def parse_docref(mnf)
262
+ mnf.xpath("xmlns:docref").map do |dr|
263
+ h = { "identifier" =&gt; dr.at("identifier").text }
264
+ h["fileref"] = dr[:fileref] if dr[:fileref]
265
+ h
266
+ end
267
+ end
268
+ end
269
+
270
+ # @param col [Metanorma::Collection]
271
+ def collection=(col)
272
+ @collection = col
273
+ @manifest.each { |mnf| mnf.collection = col }
274
+ end
275
+
276
+ # @param dir [String] path to coolection
277
+ # @return [Hash&lt;String, Metanorma::Document&gt;]
278
+ def documents(dir = "")
279
+ docs = @docref.each_with_object({}) do |dr, m|
280
+ next m unless dr["fileref"]
281
+
282
+ m[dr["identifier"]] = Document.parse_file File.join(dir, dr["fileref"])
283
+ m
284
+ end
285
+ @manifest.reduce(docs) do |mem, mnf|
286
+ mem.merge mnf.documents(dir)
287
+ end
288
+ end
289
+
290
+ # @param builder [Nokogiri::XML::Builder]
291
+ def to_xml(builder)
292
+ builder.manifest do |b|
293
+ b.level @level
294
+ b.title @title if @title
295
+ docref_to_xml b
296
+ @manifest.each { |m| m.to_xml b }
297
+ end
298
+ end
299
+
300
+ # @return [Array&lt;Hash{String=&gt;String}&gt;]
301
+ def docrefs
302
+ return @docrefs if @docrefs
303
+
304
+ drfs = @docref.map { |dr| dr }
305
+ @manifest.reduce(drfs) { |mem, mnf| mem + mnf.docrefs }
306
+ end
307
+
308
+ def docref_by_id(docid)
309
+ refs = docrefs
310
+ dref = refs.detect { |k| k["identifier"] == docid }
311
+ dref || docrefs.detect { |k| /^#{k["identifier"]}/ =~ docid }
312
+ end
313
+
314
+ private
315
+
316
+ # @param builder [Nokogiri::XML::Builder]
317
+ def docref_to_xml(builder)
318
+ @docref.each do |dr|
319
+ drf = builder.docref { |b| b.identifier dr["identifier"] }
320
+ drf[:fileref] = dr["fileref"]
321
+ if collection.directives.include?("documents-inline")
322
+ id = collection.documents.find_index { |k, _| k == dr["identifier"] }
323
+ drf[:id] = format("doc%&lt;index&gt;09d", index: id)
324
+ end
325
+ end
326
+ end
327
+ end
328
+ end
329
+ </pre>
330
+ </figure></clause></sections>
331
+ <bibliography>
332
+ <references id="T" obligation="informative" normative="false">
333
+
334
+
335
+
336
+ <bibitem id="License_A" hidden="true">
337
+ <formattedref format="application/x-isodoc+xml">attachment description</formattedref>
338
+ <uri type="attachment">_dummy_attachments/LICENSE1.TXT</uri>
339
+ <uri type="citation">_dummy_attachments/LICENSE1.TXT</uri>
340
+ <docidentifier type="metanorma">[LICENSE.TXT]</docidentifier>
341
+ </bibitem>
342
+
343
+
344
+
345
+
346
+
347
+ </references>
348
+ </bibliography>
349
+ </metanorma>