metanorma 2.1.4 → 2.5.4
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 +4 -4
- data/.rubocop.yml +23 -2
- data/Gemfile +14 -0
- data/README.adoc +1 -1
- data/lib/metanorma/collection/artifact_store.rb +142 -0
- data/lib/metanorma/collection/collection.rb +140 -131
- data/lib/metanorma/collection/config/bibdata.rb +1 -1
- data/lib/metanorma/collection/config/config.rb +50 -20
- data/lib/metanorma/collection/config/converters.rb +89 -31
- data/lib/metanorma/collection/config/doc_container.rb +28 -0
- data/lib/metanorma/collection/config/manifest.rb +30 -6
- data/lib/metanorma/collection/config/namespaces.rb +12 -0
- data/lib/metanorma/collection/document/document.rb +54 -15
- data/lib/metanorma/collection/filelookup/filelookup.rb +170 -74
- data/lib/metanorma/collection/filelookup/filelookup_sectionsplit.rb +62 -27
- data/lib/metanorma/collection/filelookup/utils.rb +52 -0
- data/lib/metanorma/collection/helpers.rb +82 -0
- data/lib/metanorma/collection/log.rb +24 -0
- data/lib/metanorma/collection/manifest/manifest.rb +27 -14
- data/lib/metanorma/collection/multilingual/multilingual.rb +1 -1
- data/lib/metanorma/collection/renderer/filelocation.rb +166 -0
- data/lib/metanorma/collection/renderer/fileparse.rb +60 -55
- data/lib/metanorma/collection/renderer/fileprocess.rb +184 -40
- data/lib/metanorma/collection/renderer/navigation.rb +20 -6
- data/lib/metanorma/collection/renderer/render_word.rb +8 -4
- data/lib/metanorma/collection/renderer/renderer.rb +202 -19
- data/lib/metanorma/collection/renderer/svg.rb +60 -5
- data/lib/metanorma/collection/renderer/utils.rb +76 -42
- data/lib/metanorma/collection/sectionsplit/collection.rb +14 -4
- data/lib/metanorma/collection/sectionsplit/sectionsplit.rb +141 -61
- data/lib/metanorma/collection/util/disambig_files.rb +4 -5
- data/lib/metanorma/collection/util/util.rb +147 -23
- data/lib/metanorma/collection/xrefprocess/xrefprocess.rb +7 -7
- data/lib/metanorma/compile/assets/icc-boilerplate.adoc +41 -0
- data/lib/metanorma/compile/compile.rb +180 -165
- data/lib/metanorma/compile/compile_options.rb +155 -83
- data/lib/metanorma/compile/extract.rb +76 -56
- data/lib/metanorma/compile/flavor.rb +19 -0
- data/lib/metanorma/compile/output_filename.rb +75 -0
- data/lib/metanorma/compile/output_filename_config.rb +27 -0
- data/lib/metanorma/compile/relaton_drop.rb +56 -0
- data/lib/metanorma/compile/render.rb +196 -0
- data/lib/metanorma/compile/validator.rb +26 -0
- data/lib/metanorma/compile/writeable.rb +12 -0
- data/lib/metanorma/util/fontist_helper.rb +35 -19
- data/lib/metanorma/version.rb +1 -1
- data/lib/metanorma.rb +1 -7
- data/metanorma.gemspec +11 -20
- data/plans/collection-rendering-architecture-review.md +516 -0
- metadata +42 -122
- data/.hound.yml +0 -5
- data/lib/metanorma/asciidoctor_extensions/glob_include_processor.rb +0 -22
- data/lib/metanorma/asciidoctor_extensions.rb +0 -1
- data/lib/metanorma/compile/compile_validate.rb +0 -68
- data/lib/metanorma/config/config.rb +0 -23
- data/lib/metanorma/input/asciidoc.rb +0 -88
- data/lib/metanorma/input/base.rb +0 -9
- data/lib/metanorma/input.rb +0 -7
- data/lib/metanorma/processor/processor.rb +0 -54
- data/lib/metanorma/processor.rb +0 -6
- data/lib/metanorma/registry/registry.rb +0 -63
- data/lib/metanorma/util/util.rb +0 -45
|
@@ -5,12 +5,14 @@ require_relative "converters"
|
|
|
5
5
|
require_relative "bibdata"
|
|
6
6
|
require_relative "directive"
|
|
7
7
|
require_relative "manifest"
|
|
8
|
+
require_relative "namespaces"
|
|
9
|
+
require_relative "doc_container"
|
|
8
10
|
|
|
9
11
|
module Metanorma
|
|
10
12
|
class Collection
|
|
11
13
|
module Config
|
|
12
14
|
Lutaml::Model::Config.configure do |config|
|
|
13
|
-
config.
|
|
15
|
+
config.xml_adapter_type = :nokogiri
|
|
14
16
|
end
|
|
15
17
|
|
|
16
18
|
class Config < ::Lutaml::Model::Serializable
|
|
@@ -20,12 +22,13 @@ module Metanorma
|
|
|
20
22
|
attribute :directive, Directive, collection: true
|
|
21
23
|
attribute :manifest, Manifest
|
|
22
24
|
attribute :coverpage, :string, default: -> { "cover.html" }
|
|
25
|
+
attribute :coverpage_pdf_portfolio, :string
|
|
23
26
|
attribute :format, :string, collection: true, default: -> { [:html] }
|
|
24
27
|
attribute :output_folder, :string
|
|
25
28
|
attribute :compile, CompileOptions
|
|
26
29
|
attribute :prefatory_content, :string, raw: true
|
|
27
30
|
attribute :final_content, :string, raw: true
|
|
28
|
-
attribute :documents,
|
|
31
|
+
attribute :documents, DocContainer, collection: true
|
|
29
32
|
attribute :xmlns, :string, default: -> { "http://metanorma.org" }
|
|
30
33
|
|
|
31
34
|
yaml do
|
|
@@ -34,18 +37,21 @@ module Metanorma
|
|
|
34
37
|
map "bibdata", to: :bibdata, with: { from: :bibdata_from_yaml,
|
|
35
38
|
to: :bibdata_to_yaml }
|
|
36
39
|
map "manifest", to: :manifest
|
|
40
|
+
map "entry", to: :manifest, with: { from: :entry_from_yaml,
|
|
41
|
+
to: :nop_to_yaml }
|
|
37
42
|
map "format", to: :format, render_default: true
|
|
38
43
|
map "output_folder", to: :output_folder
|
|
39
44
|
map "coverpage", to: :coverpage, render_default: true
|
|
45
|
+
map "coverpage-pdf-portfolio", to: :coverpage_pdf_portfolio,
|
|
46
|
+
render_default: true
|
|
40
47
|
map "compile", to: :compile, render_default: true
|
|
41
48
|
map "prefatory-content", to: :prefatory_content
|
|
42
49
|
map "final-content", to: :final_content
|
|
43
50
|
end
|
|
44
51
|
|
|
45
52
|
xml do
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
# map_attribute "xmlns", to: :xmlns
|
|
53
|
+
element "metanorma-collection"
|
|
54
|
+
namespace MetanormaCollectionNamespace
|
|
49
55
|
map_element "bibdata", to: :bibdata, with: { from: :bibdata_from_xml,
|
|
50
56
|
to: :bibdata_to_xml }
|
|
51
57
|
map_element "directive", to: :directive
|
|
@@ -54,15 +60,14 @@ module Metanorma
|
|
|
54
60
|
map_element "format", to: :format, render_default: true
|
|
55
61
|
map_element "output_folder", to: :output_folder
|
|
56
62
|
map_element "coverpage", to: :coverpage, render_default: true
|
|
63
|
+
map_element "coverpage-pdf-portfolio", to: :coverpage_pdf_portfolio,
|
|
64
|
+
render_default: true
|
|
57
65
|
map_element "compile", to: :compile, render_default: true
|
|
58
66
|
map_element "prefatory-content",
|
|
59
67
|
to: :prefatory_content,
|
|
60
68
|
with: { from: :prefatory_from_xml,
|
|
61
69
|
to: :prefatory_to_xml }
|
|
62
|
-
map_element "doc-container",
|
|
63
|
-
to: :documents,
|
|
64
|
-
with: { from: :documents_from_xml,
|
|
65
|
-
to: :documents_to_xml }
|
|
70
|
+
map_element "doc-container", to: :documents
|
|
66
71
|
map_element "final-content",
|
|
67
72
|
to: :final_content,
|
|
68
73
|
with: { from: :final_from_xml,
|
|
@@ -73,9 +78,9 @@ module Metanorma
|
|
|
73
78
|
model.manifest = Manifest.from_xml(node.to_xml)
|
|
74
79
|
end
|
|
75
80
|
|
|
76
|
-
def manifest_to_xml(model,
|
|
81
|
+
def manifest_to_xml(model, _parent, doc)
|
|
77
82
|
model.collection&.manifest&.clean_manifest(model.manifest)
|
|
78
|
-
doc
|
|
83
|
+
add_raw_xml_element(doc, model.manifest.to_xml)
|
|
79
84
|
end
|
|
80
85
|
|
|
81
86
|
def prefatory_from_xml(model, node)
|
|
@@ -90,17 +95,17 @@ module Metanorma
|
|
|
90
95
|
content_to_xml(model, parent, doc, "final")
|
|
91
96
|
end
|
|
92
97
|
|
|
93
|
-
def content_to_xml(model,
|
|
98
|
+
def content_to_xml(model, _parent, doc, type)
|
|
94
99
|
x = model.send("#{type}_content") or return
|
|
95
100
|
n = Nokogiri::XML(x)
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
doc
|
|
101
|
+
raw = if n.elements.size == 1
|
|
102
|
+
"<#{type}-content>#{x}</#{type}-content>"
|
|
103
|
+
else
|
|
104
|
+
b = Nokogiri::XML::Builder.new
|
|
105
|
+
model.collection.content_to_xml(type, b)
|
|
106
|
+
b.parent.elements.first.to_xml
|
|
107
|
+
end
|
|
108
|
+
add_raw_xml_element(doc, raw)
|
|
104
109
|
end
|
|
105
110
|
|
|
106
111
|
def final_from_xml(model, node)
|
|
@@ -124,6 +129,31 @@ module Metanorma
|
|
|
124
129
|
end
|
|
125
130
|
end
|
|
126
131
|
|
|
132
|
+
def entry_from_yaml(model, value)
|
|
133
|
+
model.manifest ||= value
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def self.flavor_from_yaml(yaml)
|
|
137
|
+
yaml["directives"]&.detect do |x|
|
|
138
|
+
x.is_a?(Hash) && x.has_key?("flavor")
|
|
139
|
+
end&.dig("flavor")&.upcase
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def self.flavor_to_bibdata(file)
|
|
143
|
+
# propagate flavor from directives to bibdata
|
|
144
|
+
yaml = YAML.safe_load(file)
|
|
145
|
+
flavor = flavor_from_yaml(yaml) or return file
|
|
146
|
+
yaml["bibdata"] or return file
|
|
147
|
+
yaml["bibdata"]["ext"] ||= {}
|
|
148
|
+
yaml["bibdata"]["ext"]["flavor"] ||= flavor
|
|
149
|
+
yaml.to_yaml
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def self.from_yaml(file)
|
|
153
|
+
file = flavor_to_bibdata(file)
|
|
154
|
+
super
|
|
155
|
+
end
|
|
156
|
+
|
|
127
157
|
include Converters
|
|
128
158
|
end
|
|
129
159
|
end
|
|
@@ -1,54 +1,112 @@
|
|
|
1
|
-
require "relaton
|
|
1
|
+
require "relaton/bib"
|
|
2
|
+
require "relaton/bib/hash_parser_v1"
|
|
3
|
+
require_relative "namespaces"
|
|
2
4
|
|
|
3
5
|
module Metanorma
|
|
4
6
|
class Collection
|
|
5
7
|
module Config
|
|
6
8
|
module Converters
|
|
9
|
+
# Keys present only in 1.x YAML format — unambiguously absent in 2.x
|
|
10
|
+
V1_BIBDATA_KEYS = %w[docid link biblionote].freeze
|
|
11
|
+
|
|
7
12
|
def bibdata_from_yaml(model, value)
|
|
8
|
-
value and !value.empty? or return
|
|
9
|
-
|
|
13
|
+
(value and !value.empty?) or return
|
|
14
|
+
if value.is_a?(String)
|
|
15
|
+
value = YAML.safe_load_file(value,
|
|
16
|
+
permitted_classes: [Date,
|
|
17
|
+
Symbol])
|
|
18
|
+
end
|
|
19
|
+
force_primary_docidentifier_yaml(value)
|
|
20
|
+
model.bibdata = if bibdata_yaml_v1_format?(value)
|
|
21
|
+
# 1.x YAML format (docid:/link:/biblionote: present) —
|
|
22
|
+
# bridge via HashParserV1 for backward compatibility
|
|
23
|
+
h = Relaton::Bib::HashParserV1.hash_to_bib(value)
|
|
24
|
+
Relaton::Bib::ItemData.new(**h)
|
|
25
|
+
else
|
|
26
|
+
# 2.x YAML format (docidentifier:/uri:/note: keys) —
|
|
27
|
+
# parse directly with lutaml-model
|
|
28
|
+
Relaton::Bib::Item.from_yaml(value.to_yaml)
|
|
29
|
+
end
|
|
10
30
|
end
|
|
11
31
|
|
|
12
|
-
|
|
13
|
-
|
|
32
|
+
# Recursively detect 1.x-format YAML by presence of renamed keys.
|
|
33
|
+
# Checks the entire nested structure so relation:/contributor: entries
|
|
34
|
+
# are also detected.
|
|
35
|
+
def bibdata_yaml_v1_format?(obj)
|
|
36
|
+
case obj
|
|
37
|
+
when Hash
|
|
38
|
+
return true if (obj.keys.map(&:to_s) & V1_BIBDATA_KEYS).any?
|
|
39
|
+
|
|
40
|
+
obj.values.any? { |v| bibdata_yaml_v1_format?(v) }
|
|
41
|
+
when Array
|
|
42
|
+
obj.any? { |v| bibdata_yaml_v1_format?(v) }
|
|
43
|
+
else
|
|
44
|
+
false
|
|
45
|
+
end
|
|
14
46
|
end
|
|
15
47
|
|
|
16
|
-
def
|
|
17
|
-
|
|
18
|
-
|
|
48
|
+
def force_primary_docidentifier_yaml(value)
|
|
49
|
+
case value["docid"]
|
|
50
|
+
when Array
|
|
51
|
+
value["docid"].empty? ||
|
|
52
|
+
value["docid"].none? do |x|
|
|
53
|
+
x["primary"] == "true"
|
|
54
|
+
end or
|
|
55
|
+
value["docid"].first["primary"] = "true"
|
|
56
|
+
when Hash
|
|
57
|
+
value["docid"]["primary"] ||= "true"
|
|
58
|
+
end
|
|
19
59
|
end
|
|
20
60
|
|
|
21
|
-
def
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
doc.
|
|
61
|
+
def bibdata_to_yaml(model, doc)
|
|
62
|
+
return unless model.bibdata
|
|
63
|
+
|
|
64
|
+
doc["bibdata"] = YAML.safe_load(model.bibdata.to_yaml,
|
|
65
|
+
permitted_classes: [Date, Symbol])
|
|
25
66
|
end
|
|
26
67
|
|
|
27
|
-
def
|
|
68
|
+
def bibdata_from_xml(model, node)
|
|
69
|
+
node or return
|
|
70
|
+
force_primary_docidentifier_xml(node.adapter_node.native)
|
|
71
|
+
model.bibdata = Relaton::Cli.parse_xml(node.adapter_node.native)
|
|
72
|
+
end
|
|
28
73
|
|
|
29
|
-
def
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
end
|
|
74
|
+
def force_primary_docidentifier_xml(node)
|
|
75
|
+
node.at("//docidentifier[@primary = 'true']") and return node
|
|
76
|
+
d = node.at("//docidentifier") or return node
|
|
77
|
+
d["primary"] = "true"
|
|
34
78
|
end
|
|
35
79
|
|
|
36
|
-
def
|
|
37
|
-
|
|
38
|
-
b
|
|
39
|
-
xml.document do |m|
|
|
40
|
-
model.collection.doccontainer(m) or return
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
b.parent.elements.first.elements
|
|
44
|
-
.each { |x| doc.add_element(parent, x) }
|
|
80
|
+
def bibdata_to_xml(model, _parent, doc)
|
|
81
|
+
b = model.bibdata or return
|
|
82
|
+
add_raw_xml_element(doc, b.to_xml(bibdata: true, date_format: :full))
|
|
45
83
|
end
|
|
46
84
|
|
|
47
|
-
def
|
|
48
|
-
|
|
49
|
-
|
|
85
|
+
def nop_to_yaml(model, doc); end
|
|
86
|
+
def nop_to_xml(model, parent, doc); end
|
|
87
|
+
|
|
88
|
+
# Add a single-element XML string as a child of the wrapper's current
|
|
89
|
+
# context, preserving inline namespace declarations.
|
|
90
|
+
#
|
|
91
|
+
# The custom-method `doc.add_element(parent, str)` path under
|
|
92
|
+
# lutaml-model 0.8 routes through Moxml fragment parsing, whose graft
|
|
93
|
+
# (`CustomMethodWrapper#add_fragment_children_to_parent`) discards
|
|
94
|
+
# xmlns declarations on grafted DataModel children. The
|
|
95
|
+
# `create_and_add_element` + `raw_content` path goes through the XML
|
|
96
|
+
# adapter's raw-content handler, which uses Nokogiri's native fragment
|
|
97
|
+
# parser and keeps xmlns intact. Tag the new element with
|
|
98
|
+
# MetanormaCollectionNamespace so it inherits cleanly from the
|
|
99
|
+
# metanorma-collection root rather than emitting `xmlns=""`.
|
|
100
|
+
def add_raw_xml_element(doc, raw)
|
|
101
|
+
parsed = Nokogiri::XML.fragment(raw)
|
|
102
|
+
src = parsed.elements.first or return
|
|
103
|
+
el = doc.create_and_add_element(src.name)
|
|
104
|
+
el.namespace_class = MetanormaCollectionNamespace
|
|
105
|
+
src.attribute_nodes.each do |a|
|
|
106
|
+
doc.add_attribute(el, a.name, a.value)
|
|
50
107
|
end
|
|
51
|
-
|
|
108
|
+
el.raw_content = src.children.map(&:to_xml).join
|
|
109
|
+
el
|
|
52
110
|
end
|
|
53
111
|
end
|
|
54
112
|
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require "lutaml/model"
|
|
2
|
+
require_relative "namespaces"
|
|
3
|
+
|
|
4
|
+
module Metanorma
|
|
5
|
+
class Collection
|
|
6
|
+
module Config
|
|
7
|
+
# Serializable wrapper for a single <doc-container> element.
|
|
8
|
+
#
|
|
9
|
+
# The body of a doc-container is the inline presentation XML of an
|
|
10
|
+
# individual document, in a flavour-specific namespace (e.g. bipm,
|
|
11
|
+
# iso, ietf). We round-trip it as an opaque string via `map_all`
|
|
12
|
+
# so the underlying XML adapter (Nokogiri) preserves the inner xmlns
|
|
13
|
+
# declaration; if we let lutaml-model parse the body into typed
|
|
14
|
+
# children it would lose the inner namespace.
|
|
15
|
+
class DocContainer < ::Lutaml::Model::Serializable
|
|
16
|
+
attribute :id, :string
|
|
17
|
+
attribute :content, :string
|
|
18
|
+
|
|
19
|
+
xml do
|
|
20
|
+
element "doc-container"
|
|
21
|
+
namespace MetanormaCollectionNamespace
|
|
22
|
+
map_attribute "id", to: :id
|
|
23
|
+
map_all to: :content
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
require "lutaml/model"
|
|
2
|
-
require "lutaml/model/xml_adapter/nokogiri_adapter"
|
|
3
2
|
require_relative "../../array_monkeypatch"
|
|
4
3
|
require_relative "converters"
|
|
5
4
|
require_relative "bibdata"
|
|
@@ -8,12 +7,12 @@ module Metanorma
|
|
|
8
7
|
class Collection
|
|
9
8
|
module Config
|
|
10
9
|
Lutaml::Model::Config.configure do |config|
|
|
11
|
-
config.
|
|
10
|
+
config.xml_adapter_type = :nokogiri
|
|
12
11
|
end
|
|
13
12
|
|
|
14
13
|
class Manifest < ::Lutaml::Model::Serializable
|
|
15
14
|
attribute :identifier, :string,
|
|
16
|
-
|
|
15
|
+
default: -> { UUIDTools::UUID.random_create.to_s }
|
|
17
16
|
attribute :id, :string
|
|
18
17
|
attribute :bibdata, Bibdata
|
|
19
18
|
attribute :type, :string
|
|
@@ -25,9 +24,15 @@ module Metanorma
|
|
|
25
24
|
attribute :index, :boolean, default: -> { true }
|
|
26
25
|
attribute :entry, Manifest, collection: true
|
|
27
26
|
attribute :file, :string
|
|
27
|
+
attribute :pdffile, :string
|
|
28
|
+
attribute :format, :string, collection: true
|
|
29
|
+
attribute :output_filename, :string
|
|
30
|
+
attribute :sectionsplit_filename, :string
|
|
31
|
+
attribute :sectionsplit_output, :boolean
|
|
28
32
|
|
|
29
33
|
yaml do
|
|
30
34
|
map "identifier", to: :identifier
|
|
35
|
+
map "pdf-file", to: :pdffile
|
|
31
36
|
map "type", to: :type
|
|
32
37
|
map "level", to: :level,
|
|
33
38
|
with: { from: :level_from_yaml, to: :nop_to_yaml }
|
|
@@ -46,6 +51,10 @@ module Metanorma
|
|
|
46
51
|
with: { from: :docref_from_yaml, to: :nop_to_yaml }
|
|
47
52
|
map "bibdata", to: :bibdata, with: { from: :bibdata_from_yaml,
|
|
48
53
|
to: :bibdata_to_yaml }
|
|
54
|
+
map "format", to: :format, render_default: true
|
|
55
|
+
map "output-filename", to: :output_filename
|
|
56
|
+
map "sectionsplit-filename", to: :sectionsplit_filename
|
|
57
|
+
map "sectionsplit-output", to: :sectionsplit_output
|
|
49
58
|
end
|
|
50
59
|
|
|
51
60
|
xml do
|
|
@@ -55,26 +64,41 @@ module Metanorma
|
|
|
55
64
|
map_attribute "sectionsplit", to: :sectionsplit
|
|
56
65
|
map_attribute "index", to: :index
|
|
57
66
|
map_attribute "url", to: :url
|
|
67
|
+
map_attribute "pdf-file", to: :pdffile
|
|
58
68
|
map_attribute "fileref", to: :file
|
|
59
69
|
map_element "identifier", to: :identifier, render_default: true
|
|
60
70
|
map_element "type", to: :type
|
|
61
71
|
map_element "title", to: :title
|
|
72
|
+
map_element "format", to: :format
|
|
62
73
|
map_element "bibdata", to: :bibdata, with: { from: :bibdata_from_xml,
|
|
63
74
|
to: :bibdata_to_xml }
|
|
64
75
|
map_element "entry", to: :entry
|
|
76
|
+
map_element "output-filename", to: :output_filename,
|
|
77
|
+
with: { from: :output_filename_from_xml,
|
|
78
|
+
to: :nop_to_xml }
|
|
79
|
+
map_element "sectionsplit-filename", to: :sectionsplit_filename,
|
|
80
|
+
with: { from: :sectionsplit_filename_from_xml,
|
|
81
|
+
to: :nop_to_xml }
|
|
65
82
|
end
|
|
66
83
|
|
|
67
84
|
def entry_from_xml(model, node)
|
|
68
85
|
model.entry = Manifest.from_xml(node.node.to_xml)
|
|
69
86
|
end
|
|
70
87
|
|
|
71
|
-
def entry_to_xml(model,
|
|
88
|
+
def entry_to_xml(model, _parent, doc)
|
|
72
89
|
Array(model.entry).each do |e|
|
|
73
|
-
|
|
74
|
-
doc.add_element(parent, elem)
|
|
90
|
+
add_raw_xml_element(doc, e.to_xml)
|
|
75
91
|
end
|
|
76
92
|
end
|
|
77
93
|
|
|
94
|
+
def output_filename_from_xml(model, node)
|
|
95
|
+
model.output_filename ||= node.content
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def sectionsplit_filename_from_xml(model, node)
|
|
99
|
+
model.sectionsplit_filename ||= node.content
|
|
100
|
+
end
|
|
101
|
+
|
|
78
102
|
def level_from_yaml(model, value)
|
|
79
103
|
model.type ||= value
|
|
80
104
|
end
|
|
@@ -48,26 +48,65 @@ module Metanorma
|
|
|
48
48
|
|
|
49
49
|
private
|
|
50
50
|
|
|
51
|
+
# Select the appropriate Relaton parser class for the given flavor tag.
|
|
52
|
+
# Uses the flavor's Item class (not Bibdata) because in Relaton 2.x,
|
|
53
|
+
# Bibdata.from_xml produces a generic Relaton::Bib::ItemData instance
|
|
54
|
+
# (due to BibdataShared resolving `model ItemData` in the definer's scope),
|
|
55
|
+
# while Item.from_xml correctly produces a flavor-specific ItemData instance.
|
|
56
|
+
# @param tag [String, nil] flavor tag (e.g. "iso", "ietf")
|
|
57
|
+
# @return [Class] Relaton Item parser class
|
|
51
58
|
def mn2relaton_parser(tag)
|
|
52
|
-
case tag
|
|
53
|
-
when "bipm"
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
when "
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
when "
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
59
|
+
case tag
|
|
60
|
+
when "bipm"
|
|
61
|
+
require "relaton/bipm" unless defined?(::Relaton::Bipm::Item)
|
|
62
|
+
::Relaton::Bipm::Item
|
|
63
|
+
when "bsi"
|
|
64
|
+
require "relaton/bsi" unless defined?(::Relaton::Bsi::Item)
|
|
65
|
+
::Relaton::Bsi::Item
|
|
66
|
+
when "ietf"
|
|
67
|
+
require "relaton/ietf" unless defined?(::Relaton::Ietf::Item)
|
|
68
|
+
::Relaton::Ietf::Item
|
|
69
|
+
when "iho"
|
|
70
|
+
require "relaton/iho" unless defined?(::Relaton::Iho::Item)
|
|
71
|
+
::Relaton::Iho::Item
|
|
72
|
+
when "itu"
|
|
73
|
+
require "relaton/itu" unless defined?(::Relaton::Itu::Item)
|
|
74
|
+
::Relaton::Itu::Item
|
|
75
|
+
when "iec"
|
|
76
|
+
require "relaton/iec" unless defined?(::Relaton::Iec::Item)
|
|
77
|
+
::Relaton::Iec::Item
|
|
78
|
+
when "iso"
|
|
79
|
+
require "relaton/iso" unless defined?(::Relaton::Iso::Item)
|
|
80
|
+
::Relaton::Iso::Item
|
|
81
|
+
when "nist"
|
|
82
|
+
require "relaton/nist" unless defined?(::Relaton::Nist::Item)
|
|
83
|
+
::Relaton::Nist::Item
|
|
84
|
+
when "ogc"
|
|
85
|
+
require "relaton/ogc" unless defined?(::Relaton::Ogc::Item)
|
|
86
|
+
::Relaton::Ogc::Item
|
|
87
|
+
else
|
|
88
|
+
::Relaton::Bib::Item
|
|
63
89
|
end
|
|
90
|
+
rescue LoadError => e
|
|
91
|
+
warn "Warning: Failed to load relaton gem for '#{tag}': #{e.message}. Falling back to Relaton::Bib::Item"
|
|
92
|
+
::Relaton::Bib::Item
|
|
64
93
|
end
|
|
65
94
|
|
|
66
95
|
# #param xml [Nokogiri::XML::Document, Nokogiri::XML::Element]
|
|
67
96
|
# @return [RelatonBib::BibliographicItem,RelatonIso::IsoBibliographicItem]
|
|
68
97
|
def from_xml(xml)
|
|
69
98
|
b = xml.at("//xmlns:bibitem|//xmlns:bibdata")
|
|
70
|
-
|
|
99
|
+
# <bibitem> elements are always flavor-independent: use the base
|
|
100
|
+
# Relaton::Bib::Bibitem regardless of collection flavor.
|
|
101
|
+
# <bibdata> elements carry flavor-specific metadata (<ext> etc.) and
|
|
102
|
+
# must be parsed with the appropriate flavor Bibdata class.
|
|
103
|
+
r = if b.name == "bibitem"
|
|
104
|
+
::Relaton::Bib::Bibitem
|
|
105
|
+
else
|
|
106
|
+
mn2relaton_parser(xml.root["flavor"])
|
|
107
|
+
end
|
|
108
|
+
# Relaton doesn't understand Pres XML tags
|
|
109
|
+
b.xpath("//xmlns:fmt-identifier").each(&:remove)
|
|
71
110
|
r.from_xml(b.to_xml)
|
|
72
111
|
end
|
|
73
112
|
|
|
@@ -113,9 +152,9 @@ module Metanorma
|
|
|
113
152
|
|
|
114
153
|
# @return [String]
|
|
115
154
|
def type
|
|
116
|
-
first = @bibitem.docidentifier
|
|
155
|
+
first = @bibitem.docidentifier&.first
|
|
117
156
|
@type ||= (first&.type&.downcase ||
|
|
118
|
-
first&.
|
|
157
|
+
first&.content&.match(/^[^\s]+/)&.to_s)&.downcase ||
|
|
119
158
|
"standoc"
|
|
120
159
|
end
|
|
121
160
|
|
|
@@ -125,7 +164,7 @@ module Metanorma
|
|
|
125
164
|
if @raw
|
|
126
165
|
builder.parent.add_child(@bibitem.root)
|
|
127
166
|
else
|
|
128
|
-
builder.send(
|
|
167
|
+
builder.send(:metanorma) do |b|
|
|
129
168
|
b << @bibitem.to_xml(bibdata: true)
|
|
130
169
|
end
|
|
131
170
|
end
|