metanorma 1.7.6 → 1.7.7

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f574203232cd03cda37b838dadb48b3c1b6a8f5c77e014baa361d520c7849690
4
- data.tar.gz: d13191d73999401fc80e40eac105a1561d7275e423e86eb61a1c6bb29b660145
3
+ metadata.gz: 5d25e0a641fe7ce0087e3d06ebb5851e52a3c85924259e6cf39f731f378d7212
4
+ data.tar.gz: 5ae477f5ad66882bf1b22ee0f9511636c14f937d4f50eb9defa7c8122c874f7c
5
5
  SHA512:
6
- metadata.gz: 128ccdcbb3366e183dce6e0e2de0a6b68be1275fd5d159ac4c6326daa3be1ceba039e810a65f569260d2315f8e1f295c0a524717b43acc88bafc02b076edf3f9
7
- data.tar.gz: 01562ff056874fb738098f843952a80de45aa71d9bfac65b61209233b8942bb77ab3bc43fbc2572a74e87d68b8e8f9b0002f4a1643853be10d19ecc39206cce4
6
+ metadata.gz: 8375fbebae7cb30ae9775b5329c567274ad47cdfc40652f7cf35f00b3691629198dc3ee56c95f0c332b7edf63788ad0f2586ecb4305c18737bdbeed8c16bff91
7
+ data.tar.gz: 6e6f57ff7e26d519cfeea98daf8a027ff27fb39f02f0ac8928f2bfab01030fa866992172ef8f8f9ca7f666783afa2e878f412a4a79b7b9d62fbe86d9a2c8c2e7
@@ -39,7 +39,8 @@ module Metanorma
39
39
  @coverpage_style)
40
40
  @documents = args[:documents] || {}
41
41
  @bibdatas = args[:documents] || {}
42
- if @documents.any? && !@directives.include?("documents-inline")
42
+ if (@documents.any? || @manifest) &&
43
+ (%w(documents-inline documents-external) & @directives).empty?
43
44
  @directives << "documents-inline"
44
45
  end
45
46
  @documents.merge! @manifest.documents(@dirname)
@@ -1,18 +1,6 @@
1
1
  module Metanorma
2
2
  # XML collection renderer
3
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
4
  # Resolves references to other files in the collection. Three routines:
17
5
  # 1. Eref to a document that has been split into multiple documents
18
6
  # (sectionsplit) are resolved to direct eref to the split document
@@ -27,16 +15,23 @@ module Metanorma
27
15
  # anchor to filename
28
16
  # @return [String] XML content
29
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)
30
31
  docxml = file.is_a?(String) ? Nokogiri::XML(file, &:huge) : file
31
32
  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
33
+ sso = @files.get(docid, :sectionsplit_output)
34
+ [docxml, sso]
40
35
  end
41
36
 
42
37
  def update_sectionsplit_refs_to_docs(docxml, internal_refs)
@@ -72,7 +67,7 @@ module Metanorma
72
67
  def add_hidden_bibliography(xmldoc, refs)
73
68
  ins = new_hidden_ref(xmldoc)
74
69
  refs.each do |k, v|
75
- _, url = @files.targetfile_id(v, {})
70
+ url = @files.url(v, {})
76
71
  ins << <<~XML
77
72
  <bibitem id="#{k}">
78
73
  <docidentifier type="repository">current-metanorma-collection/#{v}</docidentifier>
@@ -88,11 +83,11 @@ module Metanorma
88
83
  isodoc.eref2link(docxml)
89
84
  end
90
85
 
86
+ BIBITEM_NOT_REPO_XPATH = "//bibitem[not(ancestor::bibitem)]" \
87
+ "[not(./docidentifier[@type = 'repository'])]".freeze
88
+
91
89
  def supply_repo_ids(doc)
92
- doc.xpath(
93
- ns("//bibitem[not(ancestor::bibitem)]" \
94
- "[not(./docidentifier[@type = 'repository'])]"),
95
- ).each do |b|
90
+ doc.xpath(ns(BIBITEM_NOT_REPO_XPATH)).each do |b|
96
91
  b.xpath(ns("./docidentifier")).each do |docid|
97
92
  id = @isodoc.docid_prefix(docid["type"], docid.children.to_xml)
98
93
  @files.get(id) or next
@@ -163,8 +158,7 @@ module Metanorma
163
158
  internal_refs.each do |schema, ids|
164
159
  ids.each do |id, file|
165
160
  k = indirect_ref_key(schema, id, docxml)
166
- update_indirect_refs_to_docs1(docxml, k,
167
- file, bibitems, erefs)
161
+ update_indirect_refs_to_docs1(docxml, k, file, bibitems, erefs)
168
162
  end
169
163
  end
170
164
  end
@@ -179,8 +173,8 @@ module Metanorma
179
173
  def indirect_ref_key(schema, id, docxml)
180
174
  /^#{schema}_/.match?(id) and return id
181
175
  ret = "#{schema}_#{id}"
182
- suffix = docxml.root['document_suffix']
183
- (k = docxml.root["type"]) && k != schema && suffix and
176
+ suffix = docxml.root["document_suffix"]
177
+ (k = docxml.root["type"]) && k != schema && suffix and
184
178
  ret = "#{ret}_#{suffix}"
185
179
  ret
186
180
  end
@@ -199,7 +193,9 @@ module Metanorma
199
193
  @files.get(file) && p = @files.get(file, :parentid) and
200
194
  suffix = "#{p}_#{suffix}"
201
195
  existing = a.text
202
- anchor = Metanorma::Utils::to_ncname("#{existing}_#{suffix}")
196
+ anchor = existing
197
+ @files.url?(file) or
198
+ anchor = Metanorma::Utils::to_ncname("#{anchor}_#{suffix}")
203
199
  @updated_anchors[existing] or a.children = anchor
204
200
  @updated_anchors[anchor] = true
205
201
  end
@@ -230,15 +226,22 @@ module Metanorma
230
226
  def update_anchor_loc(bib, eref, docid)
231
227
  loc = eref.at(".//xmlns:locality[@type = 'anchor']") or
232
228
  return update_anchor_create_loc(bib, eref, docid)
233
- @ncnames[docid] ||= Metanorma::Utils::to_ncname(docid)
234
229
  ref = loc.at("./xmlns:referenceFrom") or return
235
- anchor = "#{ref.text}_#{@ncnames[docid]}"
236
- @files.get(docid, :anchors).inject([]) do |m, (_, x)|
230
+ anchor = suffix_anchor(ref, docid)
231
+ a = @files.get(docid, :anchors) or return
232
+ a.inject([]) do |m, (_, x)|
237
233
  m += x.values
238
234
  end.include?(anchor) or return
239
235
  ref.content = anchor
240
236
  end
241
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
+
242
245
  # if there is a crossref to another document, with no anchor, retrieve the
243
246
  # anchor given the locality, and insert it into the crossref
244
247
  def update_anchor_create_loc(_bib, eref, docid)
@@ -134,7 +134,8 @@ module Metanorma
134
134
  end
135
135
 
136
136
  def locate_internal_refs1(refs, identifier, ident)
137
- t = locate_internal_refs1_prep(ident)
137
+ file, = @files.targetfile_id(ident, read: true)
138
+ t = locate_internal_refs1_prep(file)
138
139
  refs.each do |schema, ids|
139
140
  ids.keys.select { |id| t[id] }.each do |id|
140
141
  t[id].at("./ancestor-or-self::*[@type = '#{schema}']") and
@@ -143,8 +144,7 @@ module Metanorma
143
144
  end
144
145
  end
145
146
 
146
- def locate_internal_refs1_prep(ident)
147
- file, = @files.targetfile_id(ident, read: true)
147
+ def locate_internal_refs1_prep(file)
148
148
  xml = Nokogiri::XML(file, &:huge)
149
149
  r = xml.root["document_suffix"]
150
150
  xml.xpath("//*[@id]").each_with_object({}) do |i, x|
@@ -153,5 +153,16 @@ module Metanorma
153
153
  r and x[i["id"].sub(/_#{r}$/, "")] = i
154
154
  end
155
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
156
167
  end
157
168
  end
@@ -28,7 +28,7 @@ module Metanorma
28
28
  from_yaml m
29
29
  end
30
30
  docref = RelatonBib.array mnf["docref"]
31
- new(mnf["level"], mnf["title"], docref, manifest)
31
+ new(mnf["level"], mnf["title"], parse_docrefs_yaml(docref), manifest)
32
32
  end
33
33
 
34
34
  # @param mnf [Nokogiri::XML::Element]
@@ -37,23 +37,44 @@ module Metanorma
37
37
  level = mnf.at("level").text
38
38
  title = mnf.at("title")&.text
39
39
  manifest = mnf.xpath("xmlns:manifest").map { |m| from_xml(m) }
40
- new(level, title, parse_docref(mnf), manifest)
40
+ new(level, title, parse_docrefs_xml(mnf), manifest)
41
41
  end
42
42
 
43
43
  private
44
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
+
45
58
  # @param mnf [Nokogiri::XML::Element]
46
59
  # @return [Hash{String=>String}]
47
- def parse_docref(mnf)
60
+ def parse_docrefs_xml(mnf)
48
61
  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|
62
+ h = { "identifier" => parse_docrefs_xml_id(dr) }
63
+ %i(fileref url attachment sectionsplit index).each do |s|
51
64
  h[s.to_s] = dr[s] if dr[s]
52
65
  end
66
+ m = dr.at("manifest") and h["manifest"] = from_xml(m)
53
67
  h["presentation-xml"] = dr[:presentationxml] if dr[:presentationxml]
54
68
  h
55
69
  end
56
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
57
78
  end
58
79
 
59
80
  # @param col [Metanorma::Collection]
@@ -66,23 +87,30 @@ module Metanorma
66
87
  # @return [Hash<String, Metanorma::Document>]
67
88
  def documents(dir = "")
68
89
  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
- )
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
74
95
  m
75
96
  end
76
97
  @manifest.reduce(docs) { |mem, mnf| mem.merge mnf.documents(dir) }
77
98
  end
78
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
+
79
107
  # @param builder [Nokogiri::XML::Builder]
80
108
  def to_xml(builder)
81
109
  builder.manifest do |b|
82
110
  b.level @level
83
111
  b.title @title if @title
84
112
  docref_to_xml b
85
- @manifest.each { |m| m.to_xml b }
113
+ @manifest&.each { |m| m.to_xml b }
86
114
  end
87
115
  end
88
116
 
@@ -97,7 +125,7 @@ module Metanorma
97
125
  def docref_by_id(docid)
98
126
  refs = docrefs
99
127
  dref = refs.detect { |k| k["identifier"] == docid }
100
- dref || docrefs.detect { |k| /^#{k["identifier"]}/ =~ docid }
128
+ dref || docrefs.detect { |k| /^#{k['identifier']}/ =~ docid }
101
129
  end
102
130
 
103
131
  private
@@ -108,17 +136,18 @@ module Metanorma
108
136
  @docref.each do |dr|
109
137
  drf = builder.docref do |b|
110
138
  b.identifier { |i| i << dr["identifier"] }
111
- !dr["attachment"] && !dr["sectionsplit"] &&
139
+ !dr["attachment"] && !dr["sectionsplit"] && @collection &&
112
140
  d = @collection.bibdatas[Util::key dr["identifier"]] and
113
141
  b.parent.add_child(d.bibitem.to_xml(bibdata: true))
142
+ m = dr["manifest"] and m.to_xml b
114
143
  end
115
144
  docref_to_xml_attrs(drf, dr)
116
145
  end
117
146
  end
118
147
 
119
148
  def docref_to_xml_attrs(elem, docref)
120
- elem[:fileref] = @disambig.strip_root(docref["fileref"])
121
- %i(attachment sectionsplit).each do |i|
149
+ f = docref["fileref"] and elem[:fileref] = @disambig.strip_root(f)
150
+ %i(attachment sectionsplit url).each do |i|
122
151
  elem[i] = docref[i.to_s] if docref[i.to_s]
123
152
  end
124
153
  elem[:index] = docref.has_key?("index") ? docref["index"] : "true"
@@ -128,11 +157,11 @@ module Metanorma
128
157
  end
129
158
 
130
159
  def docref_to_xml_attrs_id(elem, docref)
131
- if collection.directives.include?("documents-inline")
160
+ if collection&.directives&.include?("documents-inline")
132
161
  id = collection.documents.find_index do |k, _|
133
162
  k == docref["identifier"]
134
163
  end
135
- elem[:id] = format("doc%<index>09d", index: id)
164
+ id and elem[:id] = format("doc%<index>09d", index: id)
136
165
  end
137
166
  end
138
167
  end
@@ -162,6 +162,9 @@ module Metanorma
162
162
  # @param builder [Nokogiri::XML::Builder]
163
163
  def docrefs(elm, builder)
164
164
  elm.xpath(ns("./docref[@index = 'true']")).each do |d|
165
+ if m = d.at(ns("./manifest"))
166
+ builder << indexfile(m, ul: false)
167
+ else
165
168
  ident = docref_ident(d)
166
169
  builder.li do |li|
167
170
  li.a href: index_link(d, ident) do |a|
@@ -171,6 +174,7 @@ module Metanorma
171
174
  end
172
175
  end
173
176
  end
177
+ end
174
178
  end
175
179
 
176
180
  def docref_ident(docref)
@@ -189,8 +193,8 @@ module Metanorma
189
193
  #
190
194
  # @param elm [Nokogiri::XML::Element]
191
195
  # @return [String] XML
192
- def indexfile(elm)
193
- Nokogiri::HTML::Builder.new do |b|
196
+ def indexfile(elm, ul: true)
197
+ ret = Nokogiri::HTML::Builder.new do |b|
194
198
  b.ul do
195
199
  b.li indexfile_title(elm)
196
200
  indexfile_docref(elm, b)
@@ -198,7 +202,10 @@ module Metanorma
198
202
  b << indexfile(d)
199
203
  end
200
204
  end
201
- end.doc.root.to_html
205
+ end
206
+ ret = ret.doc.root
207
+ ul or ret = ret.children
208
+ ret.to_html
202
209
  end
203
210
 
204
211
  # object to construct navigation out of in Liquid
@@ -0,0 +1,217 @@
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
@@ -35,7 +35,7 @@ module Metanorma
35
35
 
36
36
  private
37
37
 
38
- STDTYPE2FLAVOR = { plateau: "jis" }.freeze
38
+ STDTYPE2FLAVOR = { }.freeze
39
39
 
40
40
  def stdtype2flavor(stdtype)
41
41
  flavor = STDTYPE2FLAVOR[stdtype] || stdtype
@@ -33,7 +33,7 @@ module Metanorma
33
33
  def read_file(docref)
34
34
  ident = docref.at(ns("./identifier"))
35
35
  i = key(@isodoc.docid_prefix(ident["type"], ident.children.to_xml))
36
- entry = file_entry(docref, ident.children.to_xml)
36
+ entry = file_entry(docref, ident.children.to_xml) or return
37
37
  bibdata_process(entry, i)
38
38
  bibitem_process(entry)
39
39
  @files[i] = entry
@@ -64,11 +64,12 @@ module Metanorma
64
64
  # the working directory (../../...) truncated
65
65
  # identifier is the id with only spaces, no nbsp
66
66
  def file_entry(ref, identifier)
67
+ ref["fileref"] or return
67
68
  out = ref["attachment"] ? ref["fileref"] : File.basename(ref["fileref"])
68
69
  out1 = @disambig.source2dest_filename(out)
69
70
  ret = if ref["fileref"]
70
71
  { type: "fileref", ref: @documents[Util::key identifier].file,
71
- rel_path: ref["fileref"],
72
+ rel_path: ref["fileref"], url: ref["url"],
72
73
  out_path: out1 } # @disambig.source2dest_filename(out) }
73
74
  else { type: "id", ref: ref["id"] }
74
75
  end
@@ -77,7 +78,7 @@ module Metanorma
77
78
  end
78
79
 
79
80
  def file_entry_copy(ref, ret)
80
- %w(attachment sectionsplit index presentation-xml
81
+ %w(attachment sectionsplit index presentation-xml url
81
82
  bare-after-first).each do |s|
82
83
  ret[s.gsub("-", "").to_sym] = ref[s] if ref[s]
83
84
  end
@@ -102,6 +103,21 @@ module Metanorma
102
103
  end
103
104
  end
104
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
+
105
121
  # return file contents + output filename for each file in the collection,
106
122
  # given a docref entry
107
123
  # @param data [Hash] docref entry
@@ -1,6 +1,6 @@
1
1
  require "yaml"
2
2
  require_relative "util"
3
- require_relative "sectionsplit_links"
3
+ require_relative "collection_xref_process"
4
4
 
5
5
  module Metanorma
6
6
  class Sectionsplit
@@ -68,7 +68,7 @@ module Metanorma
68
68
  # def sectionsplit(filename, basename, dir, compile_options, fileslookup = nil, ident = nil)
69
69
  def sectionsplit
70
70
  xml = sectionsplit_prep(File.read(@input_filename), @base, @dir)
71
- @key = xref_preprocess(xml, @fileslookup, @ident)
71
+ @key = Metanorma::XrefProcess::xref_preprocess(xml, @isodoc)
72
72
  SPLITSECTIONS.each_with_object([]) do |n, ret|
73
73
  conflate_floatingtitles(xml.xpath(ns(n[0]))).each do |s|
74
74
  ret << sectionfile(xml, emptydoc(xml), "#{@base}.#{ret.size}", s,
@@ -151,7 +151,7 @@ module Metanorma
151
151
  def create_sectionfile(xml, out, file, chunks, parentnode)
152
152
  ins = out.at(ns("//metanorma-extension")) || out.at(ns("//bibdata"))
153
153
  sectionfile_insert(ins, chunks, parentnode)
154
- xref_process(out, xml, @key)
154
+ Metanorma::XrefProcess::xref_process(out, xml, @key, @ident, @isodoc)
155
155
  outname = "#{file}.xml"
156
156
  File.open(File.join(@splitdir, outname), "w:UTF-8") do |f|
157
157
  f.write(out)
@@ -1,3 +1,3 @@
1
1
  module Metanorma
2
- VERSION = "1.7.6".freeze
2
+ VERSION = "1.7.7".freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metanorma
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.6
4
+ version: 1.7.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-04-22 00:00:00.000000000 Z
11
+ date: 2024-05-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asciidoctor
@@ -265,7 +265,6 @@ files:
265
265
  - CHANGELOG.adoc
266
266
  - CODE_OF_CONDUCT.md
267
267
  - Gemfile
268
- - Gemfile.devel
269
268
  - LICENSE.txt
270
269
  - README.adoc
271
270
  - lib/metanorma.rb
@@ -278,6 +277,7 @@ files:
278
277
  - lib/metanorma/collection_render_utils.rb
279
278
  - lib/metanorma/collection_render_word.rb
280
279
  - lib/metanorma/collection_renderer.rb
280
+ - lib/metanorma/collection_xref_process.rb
281
281
  - lib/metanorma/compile.rb
282
282
  - lib/metanorma/compile_options.rb
283
283
  - lib/metanorma/compile_validate.rb
@@ -293,7 +293,6 @@ files:
293
293
  - lib/metanorma/processor.rb
294
294
  - lib/metanorma/registry.rb
295
295
  - lib/metanorma/sectionsplit.rb
296
- - lib/metanorma/sectionsplit_links.rb
297
296
  - lib/metanorma/util.rb
298
297
  - lib/metanorma/version.rb
299
298
  - lib/metanorma/worker_pool.rb
@@ -317,7 +316,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
317
316
  - !ruby/object:Gem::Version
318
317
  version: '0'
319
318
  requirements: []
320
- rubygems_version: 3.3.26
319
+ rubygems_version: 3.3.27
321
320
  signing_key:
322
321
  specification_version: 4
323
322
  summary: Metanorma is the standard of standards; the metanorma gem allows you to create
data/Gemfile.devel DELETED
@@ -1,2 +0,0 @@
1
- gem "metanorma-cli"
2
- gem "isodoc", git: "https://github.com/metanorma/isodoc", branch: "main"
@@ -1,189 +0,0 @@
1
- module Metanorma
2
- class Sectionsplit
3
- def xref_preprocess(xml, _fileslookup, _identifier)
4
- key = (0...8).map { rand(65..90).chr }.join # random string
5
- xml.root["type"] = key # to force recognition of internal refs
6
- # bookmarks etc as new id elements introduced in Presentation XML:
7
- # add doc suffix
8
- Metanorma::Utils::anchor_attributes.each do |(tag_name, attribute_name)|
9
- Util::add_suffix_to_attributes(xml, xml.root["document_suffix"],
10
- tag_name, attribute_name, @isodoc)
11
- end
12
- key
13
- end
14
-
15
- def xref_process(section, xml, key)
16
- svg_preprocess(section, Metanorma::Utils::to_ncname(@ident))
17
- refs = eref_to_internal_eref(section, xml, key)
18
- refs += xref_to_internal_eref(section, xml, key)
19
- ins = new_hidden_ref(section)
20
- copied_refs = copy_repo_items_biblio(ins, section, xml)
21
- insert_indirect_biblio(ins, refs - copied_refs, key, xml)
22
- end
23
-
24
- def svg_preprocess(xml, doc_suffix)
25
- suffix = doc_suffix.nil? || doc_suffix.blank? ? "" : "_#{doc_suffix}"
26
- xml.xpath("//m:svg", "m" => "http://www.w3.org/2000/svg").each do |s|
27
- m = svgmap_wrap(s)
28
- svg_xrefs(s, m, suffix)
29
- end
30
- xml
31
- end
32
-
33
- def svgmap_wrap(svg)
34
- ret = svg.at("./ancestor::xmlns:svgmap") and return ret
35
- ret = svg.at("./ancestor::xmlns:figure")
36
- ret.wrap("<svgmap/>")
37
- svg.at("./ancestor::xmlns:svgmap")
38
- end
39
-
40
- def svg_xrefs(svg, svgmap, suffix)
41
- svg.xpath(".//m:a", "m" => "http://www.w3.org/2000/svg").each do |a|
42
- /^#/.match? a["href"] or next
43
- a["href"] = a["href"].sub(/^#/, "")
44
- svgmap << "<target href='#{a['href']}'>" \
45
- "<xref target='#{a['href']}#{suffix}'/></target>"
46
- end
47
- end
48
-
49
- def make_anchor(anchor)
50
- "<localityStack><locality type='anchor'><referenceFrom>" \
51
- "#{anchor}</referenceFrom></locality></localityStack>"
52
- end
53
-
54
- def xref_to_internal_eref(section, xml, key)
55
- bibitems, indirect = xref_to_internal_eref_prep(section, xml)
56
- section.xpath(ns("//xref")).each_with_object({}) do |x, m|
57
- xref_prefix_key(x, key, indirect)
58
- x["bibitemid"] = x["target"]
59
- m[x["bibitemid"]] = true
60
- xref_to_internal_eref_anchor(x, key, bibitems, xml.root["document_suffix"])
61
- end.keys
62
- end
63
-
64
- def xref_to_internal_eref_prep(section, xml)
65
- bibitems = Util::gather_bibitems(section)
66
- indirect_bibitems = Util::gather_bibitems(xml)
67
- .select { |_, v| indirect_bib?(v) }
68
- [bibitems, indirect_bibitems]
69
- end
70
-
71
- def xref_to_internal_eref_anchor(xref, key, bibitems, document_suffix)
72
- t = xref["target"]
73
- if d = bibitems[t]&.at(ns("./docidentifier[@type = 'repository']"))
74
- m = %r{^([^/]+)}.match(d.text) and
75
- t.sub!(%r(#{m[0]}_), "")
76
- end
77
- t.sub!(%r{^#{key}_}, "")
78
- xref << make_anchor(t.sub(%r(_#{document_suffix}$), ""))
79
- xref.delete("target")
80
- xref.name = "eref"
81
- end
82
-
83
- def xref_prefix_key(xref, key, indirect)
84
- if b = indirect[xref["target"]]
85
- t = b.at(ns("./docidentifier[@type = 'repository']"))
86
- xref["type"] = t.text.sub(%r{/.*$}, "")
87
- else
88
- xref["target"] = "#{key}_#{xref['target']}"
89
- xref["type"] = key
90
- end
91
- end
92
-
93
- def eref_to_internal_eref(section, xml, key)
94
- bibitems, bibitemids = eref_to_internal_eref_prep(section, xml)
95
- eref_to_internal_eref_select(section, xml, bibitems)
96
- .each_with_object([]) do |x, m|
97
- url = bibitems[x]&.at(ns("./uri[@type = 'citation']"))
98
- bibitemids[x]&.each do |e|
99
- id = eref_to_internal_eref1(e, key, url) and m << id
100
- end
101
- end
102
- end
103
-
104
- def eref_to_internal_eref_prep(section, xml)
105
- bibitems = Util::gather_bibitems(xml)
106
- .delete_if { |_, v| internal_bib?(v) }
107
- bibitemids = Util::gather_bibitemids(section)
108
- [bibitems, bibitemids]
109
- end
110
-
111
- def eref_to_internal_eref1(elem, key, url)
112
- if url
113
- elem.name = "link"
114
- elem["target"] = url
115
- nil
116
- else
117
- elem["bibitemid"] = "#{key}_#{elem['bibitemid']}"
118
- elem << make_anchor(elem["bibitemid"])
119
- elem["type"] = key
120
- elem["bibitemid"]
121
- end
122
- end
123
-
124
- def eref_to_internal_eref_select(section, _xml, bibitems)
125
- refs = Util::gather_bibitemids(section).keys
126
- refs.uniq.reject do |x|
127
- b = bibitems[x] and ( indirect_bib?(b) || internal_bib?(b) )
128
- end
129
- end
130
-
131
- def internal_bib?(bibitem)
132
- bibitem["type"] == "internal" ||
133
- bibitem.at(ns("./docidentifier[@type = 'repository']"))
134
- end
135
-
136
- def indirect_bib?(bibitem)
137
- a = bibitem.at(ns("./docidentifier[@type = 'repository']")) or
138
- return false
139
- %r{^current-metanorma-collection/}.match?(a.text) and return false
140
- a.text.include?("/")
141
- end
142
-
143
- # from standoc
144
- def new_hidden_ref(xmldoc)
145
- ins = xmldoc.at("bibliography") or
146
- xmldoc.root << "<bibliography/>" and ins = xmldoc.at("bibliography")
147
- ins.add_child("<references hidden='true' normative='false'/>").first
148
- end
149
-
150
- def copy_repo_items_biblio(ins, section, xml)
151
- bibitems = Util::gather_bibitems(section)
152
- xml.xpath(ns("//references/bibitem[docidentifier/@type = 'repository']"))
153
- .each_with_object([]) do |b, m|
154
- bibitems[b["id"]] or next
155
- # section.at("//*[@bibitemid = '#{b['id']}']") or next
156
- ins << b.dup
157
- m << b["id"]
158
- end
159
- end
160
-
161
- def insert_indirect_biblio(ins, refs, key, xml)
162
- refs.empty? and return
163
- internal_bibitems, external_bibitems = insert_indirect_biblio_prep(xml)
164
- refs.compact.reject do |x|
165
- #external_bibitems[x.sub(/^#{key}_/, "")]
166
- end.each do |x|
167
- ins << if b = internal_bibitems[x.sub(/^#{key}_/, "")]
168
- b.dup.tap { |m| m["id"] = x }
169
- else new_indirect_bibitem(x, key)
170
- end
171
- end
172
- end
173
-
174
- def insert_indirect_biblio_prep(xml)
175
- bibitems = Util::gather_bibitems(xml)
176
- internal_bibitems = bibitems.select { |_, v| internal_bib?(v) }
177
- external_bibitems = bibitems.reject { |_, v| internal_bib?(v) }
178
- [internal_bibitems, external_bibitems]
179
- end
180
-
181
- def new_indirect_bibitem(ident, prefix)
182
- <<~BIBENTRY
183
- <bibitem id="#{ident}" type="internal">
184
- <docidentifier type="repository">#{ident.sub(/^#{prefix}_/, "#{prefix}/")}</docidentifier>
185
- </bibitem>
186
- BIBENTRY
187
- end
188
- end
189
- end