metanorma 1.7.6 → 2.0.0

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 (59) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +5 -1
  3. data/lib/metanorma/array_monkeypatch.rb +9 -0
  4. data/lib/metanorma/asciidoctor_extensions/glob_include_processor.rb +13 -11
  5. data/lib/metanorma/collection/collection.rb +225 -0
  6. data/lib/metanorma/collection/config/bibdata.rb +12 -0
  7. data/lib/metanorma/collection/config/compile_options.rb +13 -0
  8. data/lib/metanorma/collection/config/config.rb +163 -0
  9. data/lib/metanorma/collection/config/converters.rb +30 -0
  10. data/lib/metanorma/collection/config/directive.rb +10 -0
  11. data/lib/metanorma/collection/config/manifest.rb +88 -0
  12. data/lib/metanorma/collection/document/document.rb +133 -0
  13. data/lib/metanorma/collection/filelookup/filelookup.rb +250 -0
  14. data/lib/metanorma/collection/filelookup/filelookup_sectionsplit.rb +87 -0
  15. data/lib/metanorma/collection/manifest/manifest.rb +237 -0
  16. data/lib/metanorma/collection/renderer/fileparse.rb +247 -0
  17. data/lib/metanorma/collection/renderer/fileprocess.rb +173 -0
  18. data/lib/metanorma/collection/renderer/navigation.rb +133 -0
  19. data/lib/metanorma/collection/renderer/render_word.rb +133 -0
  20. data/lib/metanorma/collection/renderer/renderer.rb +157 -0
  21. data/lib/metanorma/collection/renderer/utils.rb +183 -0
  22. data/lib/metanorma/collection/sectionsplit/sectionsplit.rb +218 -0
  23. data/lib/metanorma/collection/util/disambig_files.rb +37 -0
  24. data/lib/metanorma/collection/util/util.rb +72 -0
  25. data/lib/metanorma/collection/xrefprocess/xrefprocess.rb +222 -0
  26. data/lib/metanorma/{compile.rb → compile/compile.rb} +17 -11
  27. data/lib/metanorma/{compile_options.rb → compile/compile_options.rb} +9 -5
  28. data/lib/metanorma/{compile_validate.rb → compile/compile_validate.rb} +1 -1
  29. data/lib/metanorma/{extract.rb → compile/extract.rb} +2 -2
  30. data/lib/metanorma/{config.rb → config/config.rb} +1 -1
  31. data/lib/metanorma/input/asciidoc.rb +3 -3
  32. data/lib/metanorma/input/base.rb +1 -5
  33. data/lib/metanorma/processor/processor.rb +54 -0
  34. data/lib/metanorma/processor.rb +1 -49
  35. data/lib/metanorma/{registry.rb → registry/registry.rb} +0 -1
  36. data/lib/metanorma/shale_monkeypatch.rb +15 -0
  37. data/lib/metanorma/util/fontist_helper.rb +130 -0
  38. data/lib/metanorma/util/util.rb +45 -0
  39. data/lib/metanorma/util/worker_pool.rb +39 -0
  40. data/lib/metanorma/version.rb +1 -1
  41. data/lib/metanorma.rb +13 -8
  42. data/metanorma.gemspec +2 -1
  43. metadata +51 -26
  44. data/Gemfile.devel +0 -2
  45. data/lib/metanorma/collection.rb +0 -243
  46. data/lib/metanorma/collection_fileparse.rb +0 -254
  47. data/lib/metanorma/collection_fileprocess.rb +0 -157
  48. data/lib/metanorma/collection_manifest.rb +0 -139
  49. data/lib/metanorma/collection_render_utils.rb +0 -169
  50. data/lib/metanorma/collection_render_word.rb +0 -131
  51. data/lib/metanorma/collection_renderer.rb +0 -230
  52. data/lib/metanorma/document.rb +0 -133
  53. data/lib/metanorma/files_lookup.rb +0 -208
  54. data/lib/metanorma/files_lookup_sectionsplit.rb +0 -84
  55. data/lib/metanorma/fontist_utils.rb +0 -122
  56. data/lib/metanorma/sectionsplit.rb +0 -216
  57. data/lib/metanorma/sectionsplit_links.rb +0 -189
  58. data/lib/metanorma/util.rb +0 -127
  59. data/lib/metanorma/worker_pool.rb +0 -29
@@ -1,254 +0,0 @@
1
- module Metanorma
2
- # XML collection renderer
3
- class CollectionRenderer
4
- def update_bibitem(bib, identifier)
5
- docid = get_bibitem_docid(bib, identifier) or return
6
- newbib = dup_bibitem(docid, bib)
7
- _file, url = @files
8
- .targetfile_id(docid, relative: true, read: false,
9
- doc: !@files.get(docid, :attachment))
10
- dest = newbib.at("./docidentifier") || newbib.at(ns("./docidentifier"))
11
- dest or dest = newbib.elements[-1]
12
- dest.previous = "<uri type='citation'>#{url}</uri>"
13
- bib.replace(newbib)
14
- end
15
-
16
- # Resolves references to other files in the collection. Three routines:
17
- # 1. Eref to a document that has been split into multiple documents
18
- # (sectionsplit) are resolved to direct eref to the split document
19
- # 2. Indirect erefs to a file anchor in an unknwon file in the collection
20
- # (bibitem[@type = 'internal'] ) are resolved to direct eref to the
21
- # containing document
22
- # 3. Direct erefs to other files in collection
23
- # (repo(current-metanorma-collection/x) are resolved to hyperlinks
24
- # @param file [String] XML content
25
- # @param identifier [String] docid
26
- # @param internal_refs [Hash{String=>Hash{String=>String}] schema name to
27
- # anchor to filename
28
- # @return [String] XML content
29
- def update_xrefs(file, docid, internal_refs)
30
- docxml = file.is_a?(String) ? Nokogiri::XML(file, &:huge) : file
31
- supply_repo_ids(docxml)
32
- @nested or update_indirect_refs_to_docs(docxml, docid, internal_refs)
33
- @files.add_document_suffix(docid, docxml)
34
- @nested or update_sectionsplit_refs_to_docs(docxml, internal_refs)
35
- update_direct_refs_to_docs(docxml, docid)
36
- hide_refs(docxml)
37
- @files.get(docid, :sectionsplit_output) and eref2link(docxml)
38
- svgmap_resolve(datauri_encode(docxml), @files.get(docid, :ids))
39
- docxml.to_xml
40
- end
41
-
42
- def update_sectionsplit_refs_to_docs(docxml, internal_refs)
43
- Util::gather_citeases(docxml).each do |k, v|
44
- (@files.get(k) && @files.get(k, :sectionsplit)) or next
45
- opts = { key: @files.get(k, :indirect_key),
46
- source_suffix: docxml.root["document_suffix"],
47
- target_suffix: @files.get(k, :document_suffix) }
48
- refs = v.each_with_object({}) do |eref, m|
49
- update_sectionsplit_eref_to_doc(eref, internal_refs, m, opts)
50
- end
51
- add_hidden_bibliography(docxml, refs)
52
- end
53
- end
54
-
55
- def update_sectionsplit_eref_to_doc(eref, internal_refs, doclist, opts)
56
- a = eref.at(ns("./localityStack/locality[@type = 'anchor']/" \
57
- "referenceFrom")) or return
58
- doc = internal_refs[opts[:key]]["#{a.text}_#{opts[:target_suffix]}"]
59
- bibitemid = Metanorma::Utils::to_ncname("#{doc}_#{opts[:source_suffix]}")
60
- eref["bibitemid"] = bibitemid
61
- doclist[bibitemid] ||= doc
62
- doclist
63
- end
64
-
65
- def new_hidden_ref(xmldoc)
66
- ins = xmldoc.at(ns("bibliography")) or
67
- xmldoc.root << "<bibliography/>" and ins = xmldoc.at(ns("bibliography"))
68
- ins.at(ns("./referenced[@hidden = 'true']")) or
69
- ins.add_child("<references hidden='true' normative='false'/>").first
70
- end
71
-
72
- def add_hidden_bibliography(xmldoc, refs)
73
- ins = new_hidden_ref(xmldoc)
74
- refs.each do |k, v|
75
- _, url = @files.targetfile_id(v, {})
76
- ins << <<~XML
77
- <bibitem id="#{k}">
78
- <docidentifier type="repository">current-metanorma-collection/#{v}</docidentifier>
79
- <uri type='citation'>#{url}</uri>
80
- </bibitem>
81
- XML
82
- end
83
- end
84
-
85
- def eref2link(docxml)
86
- isodoc = IsoDoc::PresentationXMLConvert.new({})
87
- isodoc.bibitem_lookup(docxml)
88
- isodoc.eref2link(docxml)
89
- end
90
-
91
- def supply_repo_ids(doc)
92
- doc.xpath(
93
- ns("//bibitem[not(ancestor::bibitem)]" \
94
- "[not(./docidentifier[@type = 'repository'])]"),
95
- ).each do |b|
96
- b.xpath(ns("./docidentifier")).each do |docid|
97
- id = @isodoc.docid_prefix(docid["type"], docid.children.to_xml)
98
- @files.get(id) or next
99
- @files.get(id, :indirect_key) and next # will resolve as indirect key
100
- docid.next = "<docidentifier type='repository'>" \
101
- "current-metanorma-collection/#{id}</docidentifier>"
102
- end
103
- end
104
- end
105
-
106
- def svgmap_resolve(docxml, ids)
107
- isodoc = IsoDoc::PresentationXMLConvert.new({})
108
- isodoc.bibitem_lookup(docxml)
109
- docxml.xpath(ns("//svgmap//eref")).each do |e|
110
- svgmap_resolve1(e, isodoc, docxml, ids)
111
- end
112
- Vectory::SvgMapping.new(docxml, "").call
113
- docxml.xpath(ns("//svgmap")).each { |s| isodoc.svgmap_extract(s) }
114
- end
115
-
116
- def svgmap_resolve1(eref, isodoc, _docxml, ids)
117
- href = isodoc.eref_target(eref) or return
118
- href == "##{eref['bibitemid']}" ||
119
- (href =~ /^#/ && !ids[href.sub(/^#/, "")]) and return
120
- eref["target"] = href.strip
121
- eref.name = "link"
122
- eref.elements&.remove
123
- end
124
-
125
- # repo(current-metanorma-collection/ISO 17301-1:2016)
126
- # replaced by bibdata of "ISO 17301-1:2016" in situ as bibitem.
127
- # Any erefs to that bibitem id are replaced with relative URL
128
- # Preferably with anchor, and is a job to realise dynamic lookup
129
- # of localities.
130
- def update_direct_refs_to_docs(docxml, identifier)
131
- erefs, erefs1 = update_direct_refs_to_docs_prep(docxml)
132
- docxml.xpath(ns("//bibitem")).each do |b|
133
- docid = b.at(ns("./docidentifier[@type = 'repository']")) or next
134
- strip_unresolved_repo_erefs(identifier, docid, erefs1, b) or next
135
- update_bibitem(b, identifier)
136
- docid = docid_to_citeas(b) or next
137
- erefs[docid] and update_anchors(b, docid, erefs[docid])
138
- end
139
- end
140
-
141
- def update_direct_refs_to_docs_prep(docxml)
142
- @ncnames = {}
143
- [Util::gather_citeases(docxml), Util::gather_bibitemids(docxml)]
144
- end
145
-
146
- # strip erefs if they are repository erefs, but do not point to a document
147
- # within the current collection. This can happen if a collection consists
148
- # of many documents, but not all are included in the current collection.
149
- # Do not do this if this is a sectionsplit collection or a nested manifest.
150
- # Return false if bibitem is not to be further processed
151
- def strip_unresolved_repo_erefs(_document_id, bib_docid, erefs, bibitem)
152
- %r{^current-metanorma-collection/(?!Missing:)}.match?(bib_docid.text) and
153
- return true
154
- @nested and return false
155
- erefs[bibitem["id"]]&.each { |x| x.parent and strip_eref(x) }
156
- false
157
- end
158
-
159
- # Resolve erefs to a container of ids in another doc,
160
- # to an anchor eref (direct link)
161
- def update_indirect_refs_to_docs(docxml, _docidentifier, internal_refs)
162
- bibitems, erefs = update_indirect_refs_to_docs_prep(docxml)
163
- internal_refs.each do |schema, ids|
164
- ids.each do |id, file|
165
- k = indirect_ref_key(schema, id, docxml)
166
- update_indirect_refs_to_docs1(docxml, k,
167
- file, bibitems, erefs)
168
- end
169
- end
170
- end
171
-
172
- def update_indirect_refs_to_docs_prep(docxml)
173
- bibitems = Util::gather_bibitems(docxml)
174
- erefs = Util::gather_bibitemids(docxml)
175
- @updated_anchors = {}
176
- [bibitems, erefs]
177
- end
178
-
179
- def indirect_ref_key(schema, id, docxml)
180
- /^#{schema}_/.match?(id) and return id
181
- ret = "#{schema}_#{id}"
182
- suffix = docxml.root['document_suffix']
183
- (k = docxml.root["type"]) && k != schema && suffix and
184
- ret = "#{ret}_#{suffix}"
185
- ret
186
- end
187
-
188
- def update_indirect_refs_to_docs1(_docxml, key, file, bibitems, erefs)
189
- erefs[key]&.each do |e|
190
- e["citeas"] = file
191
- update_indirect_refs_to_docs_anchor(e, file)
192
- end
193
- update_indirect_refs_to_docs_docid(bibitems[key], file)
194
- end
195
-
196
- def update_indirect_refs_to_docs_anchor(eref, file)
197
- a = eref.at(ns(".//locality[@type = 'anchor']/referenceFrom")) or return
198
- suffix = file
199
- @files.get(file) && p = @files.get(file, :parentid) and
200
- suffix = "#{p}_#{suffix}"
201
- existing = a.text
202
- anchor = Metanorma::Utils::to_ncname("#{existing}_#{suffix}")
203
- @updated_anchors[existing] or a.children = anchor
204
- @updated_anchors[anchor] = true
205
- end
206
-
207
- def update_indirect_refs_to_docs_docid(bibitem, file)
208
- docid = bibitem&.at(ns("./docidentifier[@type = 'repository']")) or
209
- return
210
- docid.children = "current-metanorma-collection/#{file}"
211
- docid.previous =
212
- "<docidentifier type='metanorma-collection'>#{file}</docidentifier>"
213
- end
214
-
215
- # update crossrefences to other documents, to include
216
- # disambiguating document suffix on id
217
- def update_anchors(bib, docid, erefs)
218
- erefs.each do |e|
219
- if @files.get(docid) then update_anchor_loc(bib, e, docid)
220
- else
221
- msg = "<strong>** Unresolved reference to document #{docid} " \
222
- "from eref</strong>"
223
- e << msg
224
- strip_eref(e)
225
- @log&.add("Cross-References", e, msg)
226
- end
227
- end
228
- end
229
-
230
- def update_anchor_loc(bib, eref, docid)
231
- loc = eref.at(".//xmlns:locality[@type = 'anchor']") or
232
- return update_anchor_create_loc(bib, eref, docid)
233
- @ncnames[docid] ||= Metanorma::Utils::to_ncname(docid)
234
- ref = loc.at("./xmlns:referenceFrom") or return
235
- anchor = "#{ref.text}_#{@ncnames[docid]}"
236
- @files.get(docid, :anchors).inject([]) do |m, (_, x)|
237
- m += x.values
238
- end.include?(anchor) or return
239
- ref.content = anchor
240
- end
241
-
242
- # if there is a crossref to another document, with no anchor, retrieve the
243
- # anchor given the locality, and insert it into the crossref
244
- def update_anchor_create_loc(_bib, eref, docid)
245
- ins = eref.at(ns("./localityStack")) or return
246
- type = ins.at(ns("./locality/@type"))&.text
247
- type = "clause" if type == "annex"
248
- ref = ins.at(ns("./locality/referenceFrom"))&.text
249
- anchor = @files.get(docid, :anchors).dig(type, ref) or return
250
- ins << "<locality type='anchor'><referenceFrom>#{anchor.sub(/^_/, '')}" \
251
- "</referenceFrom></locality>"
252
- end
253
- end
254
- end
@@ -1,157 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "isodoc"
4
- require "metanorma-utils"
5
- require_relative "collection_fileparse"
6
-
7
- module Metanorma
8
- # XML collection renderer
9
- class CollectionRenderer
10
- # compile and output individual file in collection
11
- # warn "metanorma compile -x html #{f.path}"
12
- def file_compile(file, filename, identifier)
13
- return if @files.get(identifier, :sectionsplit) == "true"
14
-
15
- opts = {
16
- format: :asciidoc,
17
- extension_keys: @format,
18
- output_dir: @outdir,
19
- }.merge(compile_options_update(identifier))
20
-
21
- @compile.compile file, opts
22
- @files.set(identifier, :outputs, {})
23
- file_compile_formats(filename, identifier)
24
- end
25
-
26
- def compile_options_update(identifier)
27
- ret = @compile_options.dup
28
- Array(@directives).include?("presentation-xml") ||
29
- @files.get(identifier, :presentationxml) and
30
- ret.merge!(passthrough_presentation_xml: true)
31
- @files.get(identifier, :sectionsplit) == "true" and
32
- ret.merge!(sectionsplit: "true")
33
- @files.get(identifier, :bare) == true and
34
- ret.merge!(bare: true)
35
- ret
36
- end
37
-
38
- def file_compile_formats(filename, identifier)
39
- f = @files.get(identifier, :outputs)
40
- @format << :presentation if @format.include?(:pdf)
41
- @format.each do |e|
42
- ext = @compile.processor.output_formats[e]
43
- fn = File.basename(filename).sub(/(?<=\.)[^.]+$/, ext.to_s)
44
- (/html$/.match?(ext) && @files.get(identifier, :sectionsplit)) or
45
- f[e] = File.join(@outdir, fn)
46
- end
47
- @files.set(identifier, :outputs, f)
48
- end
49
-
50
- def copy_file_to_dest(identifier)
51
- dest = File.join(@outdir, @files.get(identifier, :out_path))
52
- FileUtils.mkdir_p(File.dirname(dest))
53
- FileUtils.cp @files.get(identifier, :ref), dest
54
- end
55
-
56
- # process each file in the collection
57
- # files are held in memory, and altered as postprocessing
58
- def files # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
59
- warn "\n\n\n\n\nRender Files: #{DateTime.now.strftime('%H:%M:%S')}"
60
- internal_refs = locate_internal_refs
61
- @files.keys.each_with_index do |ident, i|
62
- i.positive? && Array(@directives).include?("bare-after-first") and
63
- @compile_options.merge!(bare: true)
64
- if @files.get(ident, :attachment) then copy_file_to_dest(ident)
65
- else
66
- file, filename = @files.targetfile_id(ident, read: true)
67
- warn "\n\n\n\n\nProcess #{filename}: #{DateTime.now.strftime('%H:%M:%S')}"
68
- collection_xml = update_xrefs(file, ident, internal_refs)
69
- collection_filename = File.basename(filename, File.extname(filename))
70
- collection_xml_path = File.join(Dir.tmpdir,
71
- "#{collection_filename}.xml")
72
- File.write collection_xml_path, collection_xml, encoding: "UTF-8"
73
- file_compile(collection_xml_path, filename, ident)
74
- FileUtils.rm(collection_xml_path)
75
- end
76
- end
77
- end
78
-
79
- # gather internal bibitem references
80
- def gather_internal_refs
81
- @files.keys.each_with_object({}) do |i, refs|
82
- @files.get(i, :attachment) and next
83
- file, = @files.targetfile_id(i, read: true)
84
- gather_internal_refs1(file, i, refs)
85
- end
86
- end
87
-
88
- def gather_internal_refs1(file, ident, refs)
89
- f = Nokogiri::XML(file, &:huge)
90
- !@files.get(ident, :sectionsplit) and
91
- gather_internal_refs_indirect(f, refs)
92
- key = @files.get(ident, :indirect_key) and
93
- gather_internal_refs_sectionsplit(f, ident, key, refs)
94
- end
95
-
96
- def gather_internal_refs_indirect(doc, refs)
97
- doc.xpath(ns("//bibitem[@type = 'internal']/" \
98
- "docidentifier[@type = 'repository']")).each do |d|
99
- a = d.text.split(%r{/}, 2)
100
- a.size > 1 or next
101
- refs[a[0]] ||= {}
102
- refs[a[0]][a[1]] = false
103
- end
104
- end
105
-
106
- def gather_internal_refs_sectionsplit(_doc, ident, key, refs)
107
- refs[key] ||= {}
108
- @files.get(ident, :ids).each_key do |k|
109
- refs[key][k] = false
110
- end
111
- end
112
-
113
- def populate_internal_refs(refs)
114
- @files.keys.reject do |k|
115
- @files.get(k, :attachment) || @files.get(k, :sectionsplit)
116
- end.each do |ident|
117
- locate_internal_refs1(refs, ident, @isodoc.docid_prefix("", ident.dup))
118
- end
119
- refs
120
- end
121
-
122
- # resolve file location for the target of each internal reference
123
- def locate_internal_refs
124
- warn "\n\n\n\n\nInternal Refs: #{DateTime.now.strftime('%H:%M:%S')}"
125
- refs = populate_internal_refs(gather_internal_refs)
126
- refs.each do |schema, ids|
127
- ids.each do |id, key|
128
- key and next
129
- refs[schema][id] = "Missing:#{schema}:#{id}"
130
- @log&.add("Cross-References", nil, refs[schema][id])
131
- end
132
- end
133
- refs
134
- end
135
-
136
- def locate_internal_refs1(refs, identifier, ident)
137
- t = locate_internal_refs1_prep(ident)
138
- refs.each do |schema, ids|
139
- ids.keys.select { |id| t[id] }.each do |id|
140
- t[id].at("./ancestor-or-self::*[@type = '#{schema}']") and
141
- refs[schema][id] = identifier
142
- end
143
- end
144
- end
145
-
146
- def locate_internal_refs1_prep(ident)
147
- file, = @files.targetfile_id(ident, read: true)
148
- xml = Nokogiri::XML(file, &:huge)
149
- r = xml.root["document_suffix"]
150
- xml.xpath("//*[@id]").each_with_object({}) do |i, x|
151
- /^semantic_/.match?(i.name) and next
152
- x[i["id"]] = i
153
- r and x[i["id"].sub(/_#{r}$/, "")] = i
154
- end
155
- end
156
- end
157
- end
@@ -1,139 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "util"
4
-
5
- module Metanorma
6
- # Metanorma collection's manifest
7
- class CollectionManifest
8
- # @return [Metanorma::Collection]
9
- attr_reader :collection
10
-
11
- # @param level [String]
12
- # @param title [String, nil]
13
- # @param docref [Array<Hash{String=>String}>]
14
- # @param manifest [Array<Metanorma::CollectionManifest>]
15
- def initialize(level, title = nil, docref = [], manifest = [])
16
- @level = level
17
- @title = title
18
- @docref = docref
19
- @manifest = manifest
20
- @disambig = Util::DisambigFiles.new
21
- end
22
-
23
- class << self
24
- # @param mnf [Nokogiri::XML::Element]
25
- # @return [Metanorma::CollectionManifest]
26
- def from_yaml(mnf)
27
- manifest = RelatonBib.array(mnf["manifest"]).map do |m|
28
- from_yaml m
29
- end
30
- docref = RelatonBib.array mnf["docref"]
31
- new(mnf["level"], mnf["title"], docref, manifest)
32
- end
33
-
34
- # @param mnf [Nokogiri::XML::Element]
35
- # @return [Metanorma::CollectionManifest]
36
- def from_xml(mnf)
37
- level = mnf.at("level").text
38
- title = mnf.at("title")&.text
39
- manifest = mnf.xpath("xmlns:manifest").map { |m| from_xml(m) }
40
- new(level, title, parse_docref(mnf), manifest)
41
- end
42
-
43
- private
44
-
45
- # @param mnf [Nokogiri::XML::Element]
46
- # @return [Hash{String=>String}]
47
- def parse_docref(mnf)
48
- mnf.xpath("xmlns:docref").map do |dr|
49
- h = { "identifier" => dr.at("identifier").children.to_xml }
50
- %i(fileref attachment sectionsplit index).each do |s|
51
- h[s.to_s] = dr[s] if dr[s]
52
- end
53
- h["presentation-xml"] = dr[:presentationxml] if dr[:presentationxml]
54
- h
55
- end
56
- end
57
- end
58
-
59
- # @param col [Metanorma::Collection]
60
- def collection=(col)
61
- @collection = col
62
- @manifest.each { |mnf| mnf.collection = col }
63
- end
64
-
65
- # @param dir [String] path to collection
66
- # @return [Hash<String, Metanorma::Document>]
67
- def documents(dir = "")
68
- docs = @docref.each_with_object({}) do |dr, m|
69
- dr["fileref"] or next m
70
- m[Util::key dr["identifier"]] = Document.parse_file(
71
- Util::rel_path_resolve(dir, dr["fileref"]),
72
- dr["attachment"], dr["identifier"], dr["index"]
73
- )
74
- m
75
- end
76
- @manifest.reduce(docs) { |mem, mnf| mem.merge mnf.documents(dir) }
77
- end
78
-
79
- # @param builder [Nokogiri::XML::Builder]
80
- def to_xml(builder)
81
- builder.manifest do |b|
82
- b.level @level
83
- b.title @title if @title
84
- docref_to_xml b
85
- @manifest.each { |m| m.to_xml b }
86
- end
87
- end
88
-
89
- # @return [Array<Hash{String=>String}>]
90
- def docrefs
91
- return @docrefs if @docrefs
92
-
93
- drfs = @docref.map { |dr| dr }
94
- @manifest.reduce(drfs) { |mem, mnf| mem + mnf.docrefs }
95
- end
96
-
97
- def docref_by_id(docid)
98
- refs = docrefs
99
- dref = refs.detect { |k| k["identifier"] == docid }
100
- dref || docrefs.detect { |k| /^#{k["identifier"]}/ =~ docid }
101
- end
102
-
103
- private
104
-
105
- # @param builder [Nokogiri::XML::Builder]
106
- def docref_to_xml(builder)
107
- @disambig = Util::DisambigFiles.new
108
- @docref.each do |dr|
109
- drf = builder.docref do |b|
110
- b.identifier { |i| i << dr["identifier"] }
111
- !dr["attachment"] && !dr["sectionsplit"] &&
112
- d = @collection.bibdatas[Util::key dr["identifier"]] and
113
- b.parent.add_child(d.bibitem.to_xml(bibdata: true))
114
- end
115
- docref_to_xml_attrs(drf, dr)
116
- end
117
- end
118
-
119
- def docref_to_xml_attrs(elem, docref)
120
- elem[:fileref] = @disambig.strip_root(docref["fileref"])
121
- %i(attachment sectionsplit).each do |i|
122
- elem[i] = docref[i.to_s] if docref[i.to_s]
123
- end
124
- elem[:index] = docref.has_key?("index") ? docref["index"] : "true"
125
- elem[:presentationxml] = "true" if docref["presentation-xml"] &&
126
- [true, "true"].include?(docref["presentation-xml"])
127
- docref_to_xml_attrs_id(elem, docref)
128
- end
129
-
130
- def docref_to_xml_attrs_id(elem, docref)
131
- if collection.directives.include?("documents-inline")
132
- id = collection.documents.find_index do |k, _|
133
- k == docref["identifier"]
134
- end
135
- elem[:id] = format("doc%<index>09d", index: id)
136
- end
137
- end
138
- end
139
- end