metanorma 1.7.6 → 1.7.7

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