metanorma 1.7.7 → 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.
- 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 +225 -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 +247 -0
- data/lib/metanorma/collection/renderer/fileprocess.rb +173 -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 +183 -0
- data/lib/metanorma/collection/sectionsplit/sectionsplit.rb +218 -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} +17 -11
- 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,217 +0,0 @@
|
|
1
|
-
module Metanorma
|
2
|
-
module XrefProcess
|
3
|
-
class << self
|
4
|
-
def xref_preprocess(xml, isodoc)
|
5
|
-
@isodoc = isodoc
|
6
|
-
key = (0...8).map { rand(65..90).chr }.join # random string
|
7
|
-
xml.root["type"] = key # to force recognition of internal refs
|
8
|
-
# bookmarks etc as new id elements introduced in Presentation XML:
|
9
|
-
# add doc suffix
|
10
|
-
Metanorma::Utils::anchor_attributes.each do |(tag_name, attribute_name)|
|
11
|
-
Util::add_suffix_to_attributes(xml, xml.root["document_suffix"],
|
12
|
-
tag_name, attribute_name, isodoc)
|
13
|
-
end
|
14
|
-
key
|
15
|
-
end
|
16
|
-
|
17
|
-
def ns(xpath)
|
18
|
-
@isodoc.ns(xpath)
|
19
|
-
end
|
20
|
-
|
21
|
-
def xref_process(section, xml, key, ident, isodoc)
|
22
|
-
@isodoc ||= isodoc
|
23
|
-
svg_preprocess(section, Metanorma::Utils::to_ncname(ident))
|
24
|
-
refs = eref_to_internal_eref(section, xml, key)
|
25
|
-
refs += xref_to_internal_eref(section, xml, key)
|
26
|
-
ins = new_hidden_ref(section)
|
27
|
-
copied_refs = copy_repo_items_biblio(ins, section, xml)
|
28
|
-
insert_indirect_biblio(ins, refs - copied_refs, key, xml)
|
29
|
-
end
|
30
|
-
|
31
|
-
def svg_preprocess(xml, doc_suffix)
|
32
|
-
suffix = doc_suffix.nil? || doc_suffix.blank? ? "" : "_#{doc_suffix}"
|
33
|
-
xml.xpath("//m:svg", "m" => "http://www.w3.org/2000/svg").each do |s|
|
34
|
-
m = svgmap_wrap(s)
|
35
|
-
svg_xrefs(s, m, suffix)
|
36
|
-
end
|
37
|
-
xml
|
38
|
-
end
|
39
|
-
|
40
|
-
def svgmap_wrap(svg)
|
41
|
-
ret = svg.at("./ancestor::xmlns:svgmap") and return ret
|
42
|
-
ret = svg.at("./ancestor::xmlns:figure")
|
43
|
-
ret.wrap("<svgmap/>")
|
44
|
-
svg.at("./ancestor::xmlns:svgmap")
|
45
|
-
end
|
46
|
-
|
47
|
-
def svg_xrefs(svg, svgmap, suffix)
|
48
|
-
svg.xpath(".//m:a", "m" => "http://www.w3.org/2000/svg").each do |a|
|
49
|
-
/^#/.match? a["href"] or next
|
50
|
-
a["href"] = a["href"].sub(/^#/, "")
|
51
|
-
svgmap << "<target href='#{a['href']}'>" \
|
52
|
-
"<xref target='#{a['href']}#{suffix}'/></target>"
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
def make_anchor(elem, anchor)
|
57
|
-
elem.at(ns("./localityStack | ./locality")) and return
|
58
|
-
elem.text.strip.empty? and elem << anchor
|
59
|
-
elem <<
|
60
|
-
"<localityStack><locality type='anchor'><referenceFrom>" \
|
61
|
-
"#{anchor}</referenceFrom></locality></localityStack>"
|
62
|
-
end
|
63
|
-
|
64
|
-
def xref_to_internal_eref(section, xml, key)
|
65
|
-
key or return [] # no sectionsplit, no playing with xrefs
|
66
|
-
bibitems, indirect = xref_to_internal_eref_prep(section, xml)
|
67
|
-
section.xpath(ns("//xref")).each_with_object({}) do |x, m|
|
68
|
-
xref_prefix_key(x, key, indirect)
|
69
|
-
x["bibitemid"] = x["target"]
|
70
|
-
m[x["bibitemid"]] = true
|
71
|
-
xref_to_internal_eref_anchor(x, key, bibitems,
|
72
|
-
xml.root["document_suffix"])
|
73
|
-
end.keys
|
74
|
-
end
|
75
|
-
|
76
|
-
def xref_to_internal_eref_prep(section, xml)
|
77
|
-
bibitems = Util::gather_bibitems(section)
|
78
|
-
indirect_bibitems = Util::gather_bibitems(xml)
|
79
|
-
.select { |_, v| indirect_bib?(v) }
|
80
|
-
[bibitems, indirect_bibitems]
|
81
|
-
end
|
82
|
-
|
83
|
-
def xref_to_internal_eref_anchor(xref, key, bibitems, document_suffix)
|
84
|
-
t = xref["target"]
|
85
|
-
if d = bibitems[t]&.at(ns("./docidentifier[@type = 'repository']"))
|
86
|
-
m = %r{^([^/]+)}.match(d.text) and
|
87
|
-
t.sub!(%r(#{m[0]}_), "")
|
88
|
-
end
|
89
|
-
key and t.sub!(%r{^#{key}_}, "")
|
90
|
-
make_anchor(xref, t.sub(%r(_#{document_suffix}$), ""))
|
91
|
-
xref.delete("target")
|
92
|
-
xref.name = "eref"
|
93
|
-
end
|
94
|
-
|
95
|
-
def xref_prefix_key(xref, key, indirect)
|
96
|
-
if b = indirect[xref["target"]]
|
97
|
-
t = b.at(ns("./docidentifier[@type = 'repository']"))
|
98
|
-
xref["type"] = t.text.sub(%r{/.*$}, "")
|
99
|
-
elsif key
|
100
|
-
xref["target"] = "#{key}_#{xref['target']}"
|
101
|
-
xref["type"] = key
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
def eref_to_internal_eref(section, xml, key)
|
106
|
-
bibitems, indirect, bibids = eref_to_internal_eref_prep(section, xml)
|
107
|
-
eref_to_internal_eref_select(section, xml, bibitems)
|
108
|
-
.each_with_object([]) do |x, m|
|
109
|
-
url = bibitems[x]&.at(ns("./uri[@type = 'citation']"))&.text
|
110
|
-
bibids[x]&.each do |e|
|
111
|
-
e.at(ns("./localityStack | ./locality")) and next
|
112
|
-
id = eref_to_internal_eref1(e, key, url, indirect) and m << id
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
def eref_to_internal_eref_prep(section, xml)
|
118
|
-
bibitems = Util::gather_bibitems(xml)
|
119
|
-
.delete_if { |_, v| internal_bib?(v) }
|
120
|
-
indirect = Util::gather_bibitems(xml)
|
121
|
-
.select { |_, v| indirect_bib?(v) }
|
122
|
-
bibitemids = Util::gather_bibitemids(section)
|
123
|
-
[bibitems, indirect, bibitemids]
|
124
|
-
end
|
125
|
-
|
126
|
-
def eref_to_internal_eref1(elem, key, url, indirect)
|
127
|
-
if url
|
128
|
-
elem.name = "link"
|
129
|
-
elem["target"] = url
|
130
|
-
nil
|
131
|
-
elsif !indirect[elem["bibitemid"]]
|
132
|
-
nil
|
133
|
-
else
|
134
|
-
eref_to_internal_eref1_internal(elem, key, indirect)
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
def eref_to_internal_eref1_internal(elem, key, indirect)
|
139
|
-
t = elem["bibitemid"]
|
140
|
-
if key
|
141
|
-
t = "#{key}_#{t}"
|
142
|
-
elem["type"] = key
|
143
|
-
elsif d = indirect[t]&.at(ns("./docidentifier[@type = 'repository']"))
|
144
|
-
m = %r{^([^/]+)}.match(d.text) and
|
145
|
-
t.sub!(%r(#{m[0]}_), "")
|
146
|
-
end
|
147
|
-
make_anchor(elem, t)
|
148
|
-
elem["bibitemid"]
|
149
|
-
end
|
150
|
-
|
151
|
-
def eref_to_internal_eref_select(section, _xml, bibitems)
|
152
|
-
refs = Util::gather_bibitemids(section).keys
|
153
|
-
refs.uniq.reject do |x|
|
154
|
-
b = bibitems[x] and (indirect_bib?(b) || internal_bib?(b))
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
|
-
def internal_bib?(bibitem)
|
159
|
-
bibitem["type"] == "internal" ||
|
160
|
-
bibitem.at(ns("./docidentifier[@type = 'repository']"))
|
161
|
-
end
|
162
|
-
|
163
|
-
def indirect_bib?(bibitem)
|
164
|
-
a = bibitem.at(ns("./docidentifier[@type = 'repository']")) or
|
165
|
-
return false
|
166
|
-
%r{^current-metanorma-collection/}.match?(a.text) and return false
|
167
|
-
a.text.include?("/")
|
168
|
-
end
|
169
|
-
|
170
|
-
# from standoc
|
171
|
-
def new_hidden_ref(xmldoc)
|
172
|
-
ins = xmldoc.at("bibliography") or
|
173
|
-
xmldoc.root << "<bibliography/>" and ins = xmldoc.at("bibliography")
|
174
|
-
ins.add_child("<references hidden='true' normative='false'/>").first
|
175
|
-
end
|
176
|
-
|
177
|
-
def copy_repo_items_biblio(ins, section, xml)
|
178
|
-
bibitems = Util::gather_bibitems(section)
|
179
|
-
xml.xpath(ns("//references/bibitem[docidentifier/@type = 'repository']"))
|
180
|
-
.each_with_object([]) do |b, m|
|
181
|
-
bibitems[b["id"]] or next
|
182
|
-
# section.at("//*[@bibitemid = '#{b['id']}']") or next
|
183
|
-
ins << b.dup
|
184
|
-
m << b["id"]
|
185
|
-
end
|
186
|
-
end
|
187
|
-
|
188
|
-
def insert_indirect_biblio(ins, refs, key, xml)
|
189
|
-
refs.empty? and return
|
190
|
-
internal_bibitems, external_bibitems = insert_indirect_biblio_prep(xml)
|
191
|
-
refs.compact.reject do |x|
|
192
|
-
# external_bibitems[x.sub(/^#{key}_/, "")]
|
193
|
-
end.each do |x|
|
194
|
-
ins << if b = internal_bibitems[x.sub(/^#{key}_/, "")]
|
195
|
-
b.dup.tap { |m| m["id"] = x }
|
196
|
-
else new_indirect_bibitem(x, key)
|
197
|
-
end
|
198
|
-
end
|
199
|
-
end
|
200
|
-
|
201
|
-
def insert_indirect_biblio_prep(xml)
|
202
|
-
bibitems = Util::gather_bibitems(xml)
|
203
|
-
internal_bibitems = bibitems.select { |_, v| internal_bib?(v) }
|
204
|
-
external_bibitems = bibitems.reject { |_, v| internal_bib?(v) }
|
205
|
-
[internal_bibitems, external_bibitems]
|
206
|
-
end
|
207
|
-
|
208
|
-
def new_indirect_bibitem(ident, prefix)
|
209
|
-
<<~BIBENTRY
|
210
|
-
<bibitem id="#{ident}" type="internal">
|
211
|
-
<docidentifier type="repository">#{ident.sub(/^#{prefix}_/, "#{prefix}/")}</docidentifier>
|
212
|
-
</bibitem>
|
213
|
-
BIBENTRY
|
214
|
-
end
|
215
|
-
end
|
216
|
-
end
|
217
|
-
end
|
data/lib/metanorma/document.rb
DELETED
@@ -1,133 +0,0 @@
|
|
1
|
-
module Metanorma
|
2
|
-
class Document
|
3
|
-
# @return [Strin]
|
4
|
-
attr_reader :file, :attachment, :bibitem, :index
|
5
|
-
|
6
|
-
# @param bibitem [RelatonBib::BibliographicItem]
|
7
|
-
def initialize(bibitem, file, options = {})
|
8
|
-
@bibitem = bibitem
|
9
|
-
@file = file
|
10
|
-
@attachment = options[:attachment]
|
11
|
-
@index = options[:index]
|
12
|
-
@index = true if @index.nil?
|
13
|
-
@raw = options[:raw]
|
14
|
-
end
|
15
|
-
|
16
|
-
class << self
|
17
|
-
# @param file [String] file path
|
18
|
-
# @param attachment [Bool] is an attachment
|
19
|
-
# @param identifier [String] is the identifier assigned the file
|
20
|
-
# in the collection file
|
21
|
-
# @param index [Bool] is indication on whether to index this file in coverpage
|
22
|
-
# @return [Metanorma::Document]
|
23
|
-
def parse_file(file, attachment, identifier = nil, index = true)
|
24
|
-
new(bibitem(file, attachment, identifier), file,
|
25
|
-
{ attachment: attachment, index: index })
|
26
|
-
end
|
27
|
-
|
28
|
-
# #param xml [Nokogiri::XML::Document, Nokogiri::XML::Element]
|
29
|
-
# @return [Metanorma::Document]
|
30
|
-
def parse_xml(xml)
|
31
|
-
new from_xml(xml)
|
32
|
-
end
|
33
|
-
|
34
|
-
# raw XML file, can be used to put in entire file instead of just bibitem
|
35
|
-
def raw_file(filename)
|
36
|
-
doc = Nokogiri::XML(File.read(filename, encoding: "UTF-8")) do |config|
|
37
|
-
config.huge
|
38
|
-
end
|
39
|
-
new(doc, filename, raw: true)
|
40
|
-
end
|
41
|
-
|
42
|
-
def attachment_bibitem(identifier)
|
43
|
-
Nokogiri::XML <<~DOCUMENT
|
44
|
-
<bibdata><docidentifier>#{identifier}</docidentifier></bibdata>
|
45
|
-
DOCUMENT
|
46
|
-
end
|
47
|
-
|
48
|
-
private
|
49
|
-
|
50
|
-
def mn2relaton_parser(tag)
|
51
|
-
case tag.sub(/-standard/, "")
|
52
|
-
when "bipm" then RelatonBipm::XMLParser
|
53
|
-
when "bsi" then RelatonBsi::XMLParser
|
54
|
-
when "ietf" then RelatonIetf::XMLParser
|
55
|
-
when "iho" then RelatonIho::XMLParser
|
56
|
-
when "itu" then RelatonItu::XMLParser
|
57
|
-
when "iec" then RelatonIec::XMLParser
|
58
|
-
when "iso" then RelatonIsoBib::XMLParser
|
59
|
-
when "nist" then RelatonNist::XMLParser
|
60
|
-
when "ogc" then RelatonOgc::XMLParser
|
61
|
-
else RelatonBib::XMLParser
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
# #param xml [Nokogiri::XML::Document, Nokogiri::XML::Element]
|
66
|
-
# @return [RelatonBib::BibliographicItem,RelatonIso::IsoBibliographicItem]
|
67
|
-
def from_xml(xml)
|
68
|
-
b = xml.at("//xmlns:bibitem|//xmlns:bibdata")
|
69
|
-
r = mn2relaton_parser(xml.root.name)
|
70
|
-
r.from_xml(b.to_xml)
|
71
|
-
end
|
72
|
-
|
73
|
-
# @param file [String]
|
74
|
-
# @return [Symbol] file type
|
75
|
-
def format(file)
|
76
|
-
case file
|
77
|
-
when /\.xml$/ then :xml
|
78
|
-
when /.ya?ml$/ then :yaml
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
# @param file [String]
|
83
|
-
# @return [RelatonBib::BibliographicItem,
|
84
|
-
# RelatonIso::IsoBibliographicItem]
|
85
|
-
def bibitem(file, attachment, identifier)
|
86
|
-
if attachment then attachment_bibitem(identifier)
|
87
|
-
else
|
88
|
-
case format(file)
|
89
|
-
when :xml
|
90
|
-
from_xml (Nokogiri::XML(File.read(file, encoding: "UTF-8")) { |x| x.huge })
|
91
|
-
when :yaml
|
92
|
-
yaml = File.read(file, encoding: "UTF-8")
|
93
|
-
Relaton::Cli::YAMLConvertor.convert_single_file(yaml)
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
# @param builder [Nokogiri::XML::Builder, nil]
|
100
|
-
# @return [Nokogiri::XML::Builder, String]
|
101
|
-
def to_xml(builder = nil)
|
102
|
-
if builder
|
103
|
-
render_xml builder
|
104
|
-
else
|
105
|
-
Nokogiri::XML::Builder.new do |b|
|
106
|
-
root = render_xml b
|
107
|
-
root["xmlns"] = "http://metanorma.org"
|
108
|
-
end.to_xml
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
# @return [String]
|
113
|
-
def type
|
114
|
-
first = @bibitem.docidentifier.first
|
115
|
-
@type ||= (first&.type&.downcase ||
|
116
|
-
first&.id&.match(/^[^\s]+/)&.to_s)&.downcase ||
|
117
|
-
"standoc"
|
118
|
-
end
|
119
|
-
|
120
|
-
private
|
121
|
-
|
122
|
-
def render_xml(builder)
|
123
|
-
if @raw
|
124
|
-
#builder << @bibitem.root.to_xml
|
125
|
-
builder.parent.add_child(@bibitem.root)
|
126
|
-
else
|
127
|
-
builder.send("#{type}-standard") do |b|
|
128
|
-
b << @bibitem.to_xml(bibdata: true)
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
132
|
-
end
|
133
|
-
end
|
@@ -1,224 +0,0 @@
|
|
1
|
-
require "isodoc"
|
2
|
-
require "htmlentities"
|
3
|
-
require "metanorma-utils"
|
4
|
-
require_relative "files_lookup_sectionsplit"
|
5
|
-
|
6
|
-
module Metanorma
|
7
|
-
# XML collection renderer
|
8
|
-
class FileLookup
|
9
|
-
attr_accessor :files_to_delete, :parent
|
10
|
-
|
11
|
-
# hash for each document in collection of document identifier to:
|
12
|
-
# document reference (fileref or id), type of document reference,
|
13
|
-
# and bibdata entry for that file
|
14
|
-
# @param path [String] path to collection
|
15
|
-
def initialize(path, parent)
|
16
|
-
@c = HTMLEntities.new
|
17
|
-
@files = {}
|
18
|
-
@parent = parent
|
19
|
-
@xml = parent.xml
|
20
|
-
@isodoc = parent.isodoc
|
21
|
-
@path = path
|
22
|
-
@compile = parent.compile
|
23
|
-
@documents = parent.documents
|
24
|
-
@files_to_delete = []
|
25
|
-
read_files
|
26
|
-
end
|
27
|
-
|
28
|
-
def read_files
|
29
|
-
@disambig = Util::DisambigFiles.new
|
30
|
-
@xml.xpath(ns("//docref")).each { |d| read_file(d) }
|
31
|
-
end
|
32
|
-
|
33
|
-
def read_file(docref)
|
34
|
-
ident = docref.at(ns("./identifier"))
|
35
|
-
i = key(@isodoc.docid_prefix(ident["type"], ident.children.to_xml))
|
36
|
-
entry = file_entry(docref, ident.children.to_xml) or return
|
37
|
-
bibdata_process(entry, i)
|
38
|
-
bibitem_process(entry)
|
39
|
-
@files[i] = entry
|
40
|
-
end
|
41
|
-
|
42
|
-
def bibdata_process(entry, ident)
|
43
|
-
if entry[:attachment]
|
44
|
-
entry[:bibdata] = Metanorma::Document.attachment_bibitem(ident).root
|
45
|
-
else
|
46
|
-
file, _filename = targetfile(entry, read: true)
|
47
|
-
xml = Nokogiri::XML(file, &:huge)
|
48
|
-
add_document_suffix(ident, xml)
|
49
|
-
entry.merge!(anchors: read_anchors(xml), ids: read_ids(xml),
|
50
|
-
bibdata: xml.at(ns("//bibdata")),
|
51
|
-
document_suffix: xml.root["document_suffix"])
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
def bibitem_process(entry)
|
56
|
-
entry[:bibitem] = entry[:bibdata].dup
|
57
|
-
entry[:bibitem].name = "bibitem"
|
58
|
-
entry[:bibitem]["hidden"] = "true"
|
59
|
-
entry[:bibitem].at("./*[local-name() = 'ext']")&.remove
|
60
|
-
end
|
61
|
-
|
62
|
-
# rel_path is the source file address, determined relative to the YAML.
|
63
|
-
# out_path is the destination file address, with any references outside
|
64
|
-
# the working directory (../../...) truncated
|
65
|
-
# identifier is the id with only spaces, no nbsp
|
66
|
-
def file_entry(ref, identifier)
|
67
|
-
ref["fileref"] or return
|
68
|
-
out = ref["attachment"] ? ref["fileref"] : File.basename(ref["fileref"])
|
69
|
-
out1 = @disambig.source2dest_filename(out)
|
70
|
-
ret = if ref["fileref"]
|
71
|
-
{ type: "fileref", ref: @documents[Util::key identifier].file,
|
72
|
-
rel_path: ref["fileref"], url: ref["url"],
|
73
|
-
out_path: out1 } # @disambig.source2dest_filename(out) }
|
74
|
-
else { type: "id", ref: ref["id"] }
|
75
|
-
end
|
76
|
-
file_entry_copy(ref, ret)
|
77
|
-
ret.compact
|
78
|
-
end
|
79
|
-
|
80
|
-
def file_entry_copy(ref, ret)
|
81
|
-
%w(attachment sectionsplit index presentation-xml url
|
82
|
-
bare-after-first).each do |s|
|
83
|
-
ret[s.gsub("-", "").to_sym] = ref[s] if ref[s]
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
def add_document_suffix(identifier, doc)
|
88
|
-
document_suffix = Metanorma::Utils::to_ncname(identifier)
|
89
|
-
Metanorma::Utils::anchor_attributes.each do |(tag_name, attribute_name)|
|
90
|
-
Util::add_suffix_to_attributes(doc, document_suffix, tag_name,
|
91
|
-
attribute_name, @isodoc)
|
92
|
-
end
|
93
|
-
url_in_css_styles(doc, document_suffix)
|
94
|
-
doc.root["document_suffix"] ||= ""
|
95
|
-
doc.root["document_suffix"] += document_suffix
|
96
|
-
end
|
97
|
-
|
98
|
-
# update relative URLs, url(#...), in CSS in @style attrs (including SVG)
|
99
|
-
def url_in_css_styles(doc, document_suffix)
|
100
|
-
doc.xpath("//*[@style]").each do |s|
|
101
|
-
s["style"] = s["style"]
|
102
|
-
.gsub(%r{url\(#([^)]+)\)}, "url(#\\1_#{document_suffix})")
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
# return citation url for file
|
107
|
-
# @param doc [Boolean] I am a Metanorma document,
|
108
|
-
# so my URL should end with html or pdf or whatever
|
109
|
-
def url(ident, options)
|
110
|
-
data = get(ident)
|
111
|
-
data[:url] || targetfile(data, options)[1]
|
112
|
-
end
|
113
|
-
|
114
|
-
# are references to the file to be linked to a file in the collection,
|
115
|
-
# or externally? Determines whether file suffix anchors are to be used
|
116
|
-
def url?(ident)
|
117
|
-
data = get(ident) or return false
|
118
|
-
data[:url]
|
119
|
-
end
|
120
|
-
|
121
|
-
# return file contents + output filename for each file in the collection,
|
122
|
-
# given a docref entry
|
123
|
-
# @param data [Hash] docref entry
|
124
|
-
# @param read [Boolean] read the file in and return it
|
125
|
-
# @param doc [Boolean] I am a Metanorma document,
|
126
|
-
# so my URL should end with html or pdf or whatever
|
127
|
-
# @param relative [Boolean] Return output path,
|
128
|
-
# formed relative to YAML file, not input path, relative to calling function
|
129
|
-
# @return [Array<String, nil>]
|
130
|
-
def targetfile(data, options)
|
131
|
-
options = { read: false, doc: true, relative: false }.merge(options)
|
132
|
-
path = options[:relative] ? data[:rel_path] : data[:ref]
|
133
|
-
if data[:type] == "fileref"
|
134
|
-
ref_file path, data[:out_path], options[:read], options[:doc]
|
135
|
-
else
|
136
|
-
xml_file data[:id], options[:read]
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
def targetfile_id(ident, options)
|
141
|
-
targetfile(get(ident), options)
|
142
|
-
end
|
143
|
-
|
144
|
-
def ref_file(ref, out, read, doc)
|
145
|
-
file = File.read(ref, encoding: "utf-8") if read
|
146
|
-
filename = out.dup
|
147
|
-
filename.sub!(/\.xml$/, ".html") if doc
|
148
|
-
[file, filename]
|
149
|
-
end
|
150
|
-
|
151
|
-
def xml_file(id, read)
|
152
|
-
file = @xml.at(ns("//doc-container[@id = '#{id}']")).to_xml if read
|
153
|
-
filename = "#{id}.html"
|
154
|
-
[file, filename]
|
155
|
-
end
|
156
|
-
|
157
|
-
# map locality type and label (e.g. "clause" "1") to id = anchor for
|
158
|
-
# a document
|
159
|
-
# Note: will only key clauses, which have unambiguous reference label in
|
160
|
-
# locality. Notes, examples etc with containers are just plunked against
|
161
|
-
# UUIDs, so that their IDs can at least be registered to be tracked
|
162
|
-
# as existing.
|
163
|
-
def read_anchors(xml)
|
164
|
-
xrefs = @isodoc.xref_init(@lang, @script, @isodoc, @isodoc.i18n,
|
165
|
-
{ locale: @locale })
|
166
|
-
xrefs.parse xml
|
167
|
-
xrefs.get.each_with_object({}) do |(k, v), ret|
|
168
|
-
read_anchors1(k, v, ret)
|
169
|
-
end
|
170
|
-
end
|
171
|
-
|
172
|
-
def read_anchors1(key, val, ret)
|
173
|
-
val[:type] ||= "clause"
|
174
|
-
ret[val[:type]] ||= {}
|
175
|
-
index = if val[:container] || val[:label].nil? || val[:label].empty?
|
176
|
-
UUIDTools::UUID.random_create.to_s
|
177
|
-
else val[:label]
|
178
|
-
end
|
179
|
-
ret[val[:type]][index] = key
|
180
|
-
ret[val[:type]][val[:value]] = key if val[:value]
|
181
|
-
end
|
182
|
-
|
183
|
-
# Also parse all ids in doc (including ones which won't be xref targets)
|
184
|
-
def read_ids(xml)
|
185
|
-
ret = {}
|
186
|
-
xml.traverse do |x|
|
187
|
-
x.text? and next
|
188
|
-
/^semantic__/.match?(x.name) and next
|
189
|
-
x["id"] and ret[x["id"]] = true
|
190
|
-
end
|
191
|
-
ret
|
192
|
-
end
|
193
|
-
|
194
|
-
def key(ident)
|
195
|
-
@c.decode(ident).gsub(/(\p{Zs})+/, " ").sub(/^metanorma-collection /, "")
|
196
|
-
end
|
197
|
-
|
198
|
-
def keys
|
199
|
-
@files.keys
|
200
|
-
end
|
201
|
-
|
202
|
-
def get(ident, attr = nil)
|
203
|
-
if attr then @files[key(ident)][attr]
|
204
|
-
else @files[key(ident)]
|
205
|
-
end
|
206
|
-
end
|
207
|
-
|
208
|
-
def set(ident, attr, value)
|
209
|
-
@files[key(ident)][attr] = value
|
210
|
-
end
|
211
|
-
|
212
|
-
def each
|
213
|
-
@files.each
|
214
|
-
end
|
215
|
-
|
216
|
-
def each_with_index
|
217
|
-
@files.each_with_index
|
218
|
-
end
|
219
|
-
|
220
|
-
def ns(xpath)
|
221
|
-
@isodoc.ns(xpath)
|
222
|
-
end
|
223
|
-
end
|
224
|
-
end
|
@@ -1,84 +0,0 @@
|
|
1
|
-
module Metanorma
|
2
|
-
# XML collection renderer
|
3
|
-
class FileLookup
|
4
|
-
def add_section_split
|
5
|
-
ret = @files.keys.each_with_object({}) do |k, m|
|
6
|
-
if @files[k][:sectionsplit] == "true" && !@files[k]["attachment"]
|
7
|
-
process_section_split_instance(k, m)
|
8
|
-
cleanup_section_split_instance(k, m)
|
9
|
-
end
|
10
|
-
m[k] = @files[k]
|
11
|
-
end
|
12
|
-
@files = ret
|
13
|
-
end
|
14
|
-
|
15
|
-
def process_section_split_instance(key, manifest)
|
16
|
-
s, sectionsplit_manifest = sectionsplit(@files[key][:ref],
|
17
|
-
@files[key][:out_path], key)
|
18
|
-
s.each_with_index do |f1, i|
|
19
|
-
add_section_split_instance(f1, manifest, key, i)
|
20
|
-
end
|
21
|
-
manifest["#{key}:index.html"] =
|
22
|
-
add_section_split_cover(sectionsplit_manifest, key)
|
23
|
-
end
|
24
|
-
|
25
|
-
def cleanup_section_split_instance(key, manifest)
|
26
|
-
@files_to_delete << manifest["#{key}:index.html"][:ref]
|
27
|
-
#@files[key].delete(:ids).delete(:anchors)
|
28
|
-
@files[key][:indirect_key] = @sectionsplit.key
|
29
|
-
end
|
30
|
-
|
31
|
-
def add_section_split_cover(manifest, ident)
|
32
|
-
cover = @sectionsplit
|
33
|
-
.section_split_cover(manifest, @parent.dir_name_cleanse(ident),
|
34
|
-
one_doc_collection?)
|
35
|
-
@files[ident][:out_path] = cover
|
36
|
-
{ attachment: true, index: false, out_path: cover,
|
37
|
-
ref: File.join(File.dirname(manifest.file), cover) }
|
38
|
-
end
|
39
|
-
|
40
|
-
def one_doc_collection?
|
41
|
-
return false
|
42
|
-
docs = 0
|
43
|
-
@files.each_value do |v|
|
44
|
-
v[:attachment] and next
|
45
|
-
v[:presentationxml] and next
|
46
|
-
docs += 1
|
47
|
-
end
|
48
|
-
docs > 1
|
49
|
-
end
|
50
|
-
|
51
|
-
def add_section_split_instance(file, manifest, key, idx)
|
52
|
-
presfile, newkey, xml =
|
53
|
-
add_section_split_instance_prep(file, key)
|
54
|
-
manifest[newkey] =
|
55
|
-
{ parentid: key, presentationxml: true, type: "fileref",
|
56
|
-
rel_path: file[:url], out_path: File.basename(file[:url]),
|
57
|
-
anchors: read_anchors(xml), ids: read_ids(xml),
|
58
|
-
sectionsplit_output: true,
|
59
|
-
bibdata: @files[key][:bibdata], ref: presfile }
|
60
|
-
@files_to_delete << file[:url]
|
61
|
-
manifest[newkey][:bare] = true unless idx.zero?
|
62
|
-
end
|
63
|
-
|
64
|
-
def add_section_split_instance_prep(file, key)
|
65
|
-
presfile = File.join(File.dirname(@files[key][:ref]),
|
66
|
-
File.basename(file[:url]))
|
67
|
-
newkey = key("#{key.strip} #{file[:title]}")
|
68
|
-
xml = Nokogiri::XML(File.read(presfile), &:huge)
|
69
|
-
[presfile, newkey, xml]
|
70
|
-
end
|
71
|
-
|
72
|
-
def sectionsplit(file, outfile, ident)
|
73
|
-
@sectionsplit = Sectionsplit
|
74
|
-
.new(input: file, base: outfile, dir: File.dirname(file),
|
75
|
-
output: outfile, compile_opts: @parent.compile_options,
|
76
|
-
fileslookup: self, ident: ident, isodoc: @isodoc)
|
77
|
-
coll = @sectionsplit.sectionsplit.sort_by { |f| f[:order] }
|
78
|
-
xml = Nokogiri::XML(File.read(file, encoding: "UTF-8"), &:huge)
|
79
|
-
[coll, @sectionsplit
|
80
|
-
.collection_manifest(File.basename(file), coll, xml, nil,
|
81
|
-
File.dirname(file))]
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|