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