metanorma 1.7.6 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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