Module: Metanorma::XrefProcess

Defined in:
lib/metanorma/collection_xref_process.rb

Class Method Summary collapse

Class Method Details

.copy_repo_items_biblio(ins, section, xml) ⇒ Object



177
178
179
180
181
182
183
184
185
186
# File 'lib/metanorma/collection_xref_process.rb', line 177

def copy_repo_items_biblio(ins, section, xml)
  bibitems = Util::gather_bibitems(section)
  xml.xpath(ns("//references/bibitem[docidentifier/@type = 'repository']"))
    .each_with_object([]) do |b, m|
      bibitems[b["id"]] or next
      # section.at("//*[@bibitemid = '#{b['id']}']") or next
      ins << b.dup
      m << b["id"]
    end
end

.eref_to_internal_eref(section, xml, key) ⇒ Object



105
106
107
108
109
110
111
112
113
114
115
# File 'lib/metanorma/collection_xref_process.rb', line 105

def eref_to_internal_eref(section, xml, key)
  bibitems, indirect, bibids = eref_to_internal_eref_prep(section, xml)
  eref_to_internal_eref_select(section, xml, bibitems)
    .each_with_object([]) do |x, m|
      url = bibitems[x]&.at(ns("./uri[@type = 'citation']"))&.text
      bibids[x]&.each do |e|
        e.at(ns("./localityStack | ./locality")) and next
        id = eref_to_internal_eref1(e, key, url, indirect) and m << id
      end
    end
end

.eref_to_internal_eref1(elem, key, url, indirect) ⇒ Object



126
127
128
129
130
131
132
133
134
135
136
# File 'lib/metanorma/collection_xref_process.rb', line 126

def eref_to_internal_eref1(elem, key, url, indirect)
  if url
    elem.name = "link"
    elem["target"] = url
    nil
  elsif !indirect[elem["bibitemid"]]
    nil
  else
    eref_to_internal_eref1_internal(elem, key, indirect)
  end
end

.eref_to_internal_eref1_internal(elem, key, indirect) ⇒ Object



138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/metanorma/collection_xref_process.rb', line 138

def eref_to_internal_eref1_internal(elem, key, indirect)
  t = elem["bibitemid"]
  if key
    t = "#{key}_#{t}"
    elem["type"] = key
  elsif d = indirect[t]&.at(ns("./docidentifier[@type = 'repository']"))
    m = %r{^([^/]+)}.match(d.text) and
      t.sub!(%r(#{m[0]}_), "")
  end
  make_anchor(elem, t)
  elem["bibitemid"]
end

.eref_to_internal_eref_prep(section, xml) ⇒ Object



117
118
119
120
121
122
123
124
# File 'lib/metanorma/collection_xref_process.rb', line 117

def eref_to_internal_eref_prep(section, xml)
  bibitems = Util::gather_bibitems(xml)
    .delete_if { |_, v| internal_bib?(v) }
  indirect = Util::gather_bibitems(xml)
    .select { |_, v| indirect_bib?(v) }
  bibitemids = Util::gather_bibitemids(section)
  [bibitems, indirect, bibitemids]
end

.eref_to_internal_eref_select(section, _xml, bibitems) ⇒ Object



151
152
153
154
155
156
# File 'lib/metanorma/collection_xref_process.rb', line 151

def eref_to_internal_eref_select(section, _xml, bibitems)
  refs = Util::gather_bibitemids(section).keys
  refs.uniq.reject do |x|
    b = bibitems[x] and (indirect_bib?(b) || internal_bib?(b))
  end
end

.indirect_bib?(bibitem) ⇒ Boolean

Returns:

  • (Boolean)


163
164
165
166
167
168
# File 'lib/metanorma/collection_xref_process.rb', line 163

def indirect_bib?(bibitem)
  a = bibitem.at(ns("./docidentifier[@type = 'repository']")) or
    return false
  %r{^current-metanorma-collection/}.match?(a.text) and return false
  a.text.include?("/")
end

.insert_indirect_biblio(ins, refs, key, xml) ⇒ Object



188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/metanorma/collection_xref_process.rb', line 188

def insert_indirect_biblio(ins, refs, key, xml)
  refs.empty? and return
  internal_bibitems, external_bibitems = insert_indirect_biblio_prep(xml)
  refs.compact.reject do |x|
    # external_bibitems[x.sub(/^#{key}_/, "")]
  end.each do |x|
    ins << if b = internal_bibitems[x.sub(/^#{key}_/, "")]
             b.dup.tap { |m| m["id"] = x }
           else new_indirect_bibitem(x, key)
           end
  end
end

.insert_indirect_biblio_prep(xml) ⇒ Object



201
202
203
204
205
206
# File 'lib/metanorma/collection_xref_process.rb', line 201

def insert_indirect_biblio_prep(xml)
  bibitems = Util::gather_bibitems(xml)
  internal_bibitems = bibitems.select { |_, v| internal_bib?(v) }
  external_bibitems = bibitems.reject { |_, v| internal_bib?(v) }
  [internal_bibitems, external_bibitems]
end

.internal_bib?(bibitem) ⇒ Boolean

Returns:

  • (Boolean)


158
159
160
161
# File 'lib/metanorma/collection_xref_process.rb', line 158

def internal_bib?(bibitem)
  bibitem["type"] == "internal" ||
    bibitem.at(ns("./docidentifier[@type = 'repository']"))
end

.make_anchor(elem, anchor) ⇒ Object



56
57
58
59
60
61
62
# File 'lib/metanorma/collection_xref_process.rb', line 56

def make_anchor(elem, anchor)
  elem.at(ns("./localityStack | ./locality")) and return
  elem.text.strip.empty? and elem << anchor
  elem <<
    "<localityStack><locality type='anchor'><referenceFrom>" \
      "#{anchor}</referenceFrom></locality></localityStack>"
end

.new_hidden_ref(xmldoc) ⇒ Object

from standoc



171
172
173
174
175
# File 'lib/metanorma/collection_xref_process.rb', line 171

def new_hidden_ref(xmldoc)
  ins = xmldoc.at("bibliography") or
    xmldoc.root << "<bibliography/>" and ins = xmldoc.at("bibliography")
  ins.add_child("<references hidden='true' normative='false'/>").first
end

.new_indirect_bibitem(ident, prefix) ⇒ Object



208
209
210
211
212
213
214
# File 'lib/metanorma/collection_xref_process.rb', line 208

def new_indirect_bibitem(ident, prefix)
  <<~BIBENTRY
    <bibitem id="#{ident}" type="internal">
    <docidentifier type="repository">#{ident.sub(/^#{prefix}_/, "#{prefix}/")}</docidentifier>
    </bibitem>
  BIBENTRY
end

.ns(xpath) ⇒ Object



17
18
19
# File 'lib/metanorma/collection_xref_process.rb', line 17

def ns(xpath)
  @isodoc.ns(xpath)
end

.svg_preprocess(xml, doc_suffix) ⇒ Object



31
32
33
34
35
36
37
38
# File 'lib/metanorma/collection_xref_process.rb', line 31

def svg_preprocess(xml, doc_suffix)
  suffix = doc_suffix.nil? || doc_suffix.blank? ? "" : "_#{doc_suffix}"
  xml.xpath("//m:svg", "m" => "http://www.w3.org/2000/svg").each do |s|
    m = svgmap_wrap(s)
    svg_xrefs(s, m, suffix)
  end
  xml
end

.svg_xrefs(svg, svgmap, suffix) ⇒ Object



47
48
49
50
51
52
53
54
# File 'lib/metanorma/collection_xref_process.rb', line 47

def svg_xrefs(svg, svgmap, suffix)
  svg.xpath(".//m:a", "m" => "http://www.w3.org/2000/svg").each do |a|
    /^#/.match? a["href"] or next
    a["href"] = a["href"].sub(/^#/, "")
    svgmap << "<target href='#{a['href']}'>" \
      "<xref target='#{a['href']}#{suffix}'/></target>"
  end
end

.svgmap_wrap(svg) ⇒ Object



40
41
42
43
44
45
# File 'lib/metanorma/collection_xref_process.rb', line 40

def svgmap_wrap(svg)
  ret = svg.at("./ancestor::xmlns:svgmap") and return ret
  ret = svg.at("./ancestor::xmlns:figure")
  ret.wrap("<svgmap/>")
  svg.at("./ancestor::xmlns:svgmap")
end

.xref_prefix_key(xref, key, indirect) ⇒ Object



95
96
97
98
99
100
101
102
103
# File 'lib/metanorma/collection_xref_process.rb', line 95

def xref_prefix_key(xref, key, indirect)
  if b = indirect[xref["target"]]
    t = b.at(ns("./docidentifier[@type = 'repository']"))
    xref["type"] = t.text.sub(%r{/.*$}, "")
  elsif key
    xref["target"] = "#{key}_#{xref['target']}"
    xref["type"] = key
  end
end

.xref_preprocess(xml, isodoc) ⇒ Object



4
5
6
7
8
9
10
11
12
13
14
15
# File 'lib/metanorma/collection_xref_process.rb', line 4

def xref_preprocess(xml, isodoc)
  @isodoc = isodoc
  key = (0...8).map { rand(65..90).chr }.join # random string
  xml.root["type"] = key # to force recognition of internal refs
  # bookmarks etc as new id elements introduced in Presentation XML:
  # add doc suffix
  Metanorma::Utils::anchor_attributes.each do |(tag_name, attribute_name)|
    Util::add_suffix_to_attributes(xml, xml.root["document_suffix"],
                                   tag_name, attribute_name, isodoc)
  end
  key
end

.xref_process(section, xml, key, ident, isodoc) ⇒ Object



21
22
23
24
25
26
27
28
29
# File 'lib/metanorma/collection_xref_process.rb', line 21

def xref_process(section, xml, key, ident, isodoc)
  @isodoc ||= isodoc
  svg_preprocess(section, Metanorma::Utils::to_ncname(ident))
  refs = eref_to_internal_eref(section, xml, key)
  refs += xref_to_internal_eref(section, xml, key)
  ins = new_hidden_ref(section)
  copied_refs = copy_repo_items_biblio(ins, section, xml)
  insert_indirect_biblio(ins, refs - copied_refs, key, xml)
end

.xref_to_internal_eref(section, xml, key) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
# File 'lib/metanorma/collection_xref_process.rb', line 64

def xref_to_internal_eref(section, xml, key)
  key or return [] # no sectionsplit, no playing with xrefs
  bibitems, indirect = xref_to_internal_eref_prep(section, xml)
  section.xpath(ns("//xref")).each_with_object({}) do |x, m|
    xref_prefix_key(x, key, indirect)
    x["bibitemid"] = x["target"]
    m[x["bibitemid"]] = true
    xref_to_internal_eref_anchor(x, key, bibitems,
                                 xml.root["document_suffix"])
  end.keys
end

.xref_to_internal_eref_anchor(xref, key, bibitems, document_suffix) ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
# File 'lib/metanorma/collection_xref_process.rb', line 83

def xref_to_internal_eref_anchor(xref, key, bibitems, document_suffix)
  t = xref["target"]
  if d = bibitems[t]&.at(ns("./docidentifier[@type = 'repository']"))
    m = %r{^([^/]+)}.match(d.text) and
      t.sub!(%r(#{m[0]}_), "")
  end
  key and t.sub!(%r{^#{key}_}, "")
  make_anchor(xref, t.sub(%r(_#{document_suffix}$), ""))
  xref.delete("target")
  xref.name = "eref"
end

.xref_to_internal_eref_prep(section, xml) ⇒ Object



76
77
78
79
80
81
# File 'lib/metanorma/collection_xref_process.rb', line 76

def xref_to_internal_eref_prep(section, xml)
  bibitems = Util::gather_bibitems(section)
  indirect_bibitems = Util::gather_bibitems(xml)
    .select { |_, v| indirect_bib?(v) }
  [bibitems, indirect_bibitems]
end