Module: Metanorma::Collection::XrefProcess

Defined in:
lib/metanorma/collection/xrefprocess/xrefprocess.rb

Class Method Summary collapse

Class Method Details

.copy_repo_items_biblio(ins, section, xml) ⇒ Object



191
192
193
194
195
196
197
198
199
200
# File 'lib/metanorma/collection/xrefprocess/xrefprocess.rb', line 191

def copy_repo_items_biblio(ins, section, xml)
  bibitems = ::Metanorma::Collection::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



117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/metanorma/collection/xrefprocess/xrefprocess.rb', line 117

def eref_to_internal_eref(section, xml, key)
  bibitems, indirect, bibids, lang =
    eref_to_internal_eref_prep(section, xml)
  eref_to_internal_eref_select(section, xml, bibitems)
    .each_with_object([]) do |x, m|
      url = select_citation_uri(bibitems[x], lang)
      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



140
141
142
143
144
145
146
147
148
149
150
# File 'lib/metanorma/collection/xrefprocess/xrefprocess.rb', line 140

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



152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/metanorma/collection/xrefprocess/xrefprocess.rb', line 152

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



130
131
132
133
134
135
136
137
138
# File 'lib/metanorma/collection/xrefprocess/xrefprocess.rb', line 130

def eref_to_internal_eref_prep(section, xml)
  bibitems = ::Metanorma::Collection::Util::gather_bibitems(xml)
    .delete_if { |_, v| internal_bib?(v) }
  indirect = ::Metanorma::Collection::Util::gather_bibitems(xml)
    .select { |_, v| indirect_bib?(v) }
  bibitemids = ::Metanorma::Collection::Util::gather_bibitemids(section)
  lang = xml.at(ns("//bibdata/language"))&.text || "en"
  [bibitems, indirect, bibitemids, lang]
end

.eref_to_internal_eref_select(section, _xml, bibitems) ⇒ Object



165
166
167
168
169
170
# File 'lib/metanorma/collection/xrefprocess/xrefprocess.rb', line 165

def eref_to_internal_eref_select(section, _xml, bibitems)
  refs = ::Metanorma::Collection::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)


177
178
179
180
181
182
# File 'lib/metanorma/collection/xrefprocess/xrefprocess.rb', line 177

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



202
203
204
205
206
207
208
209
210
211
212
213
# File 'lib/metanorma/collection/xrefprocess/xrefprocess.rb', line 202

def insert_indirect_biblio(ins, refs, key, xml)
  refs.empty? and return
  internal_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



215
216
217
218
219
220
# File 'lib/metanorma/collection/xrefprocess/xrefprocess.rb', line 215

def insert_indirect_biblio_prep(xml)
  bibitems = ::Metanorma::Collection::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)


172
173
174
175
# File 'lib/metanorma/collection/xrefprocess/xrefprocess.rb', line 172

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

.make_anchor(elem, anchor) ⇒ Object



60
61
62
63
64
65
66
# File 'lib/metanorma/collection/xrefprocess/xrefprocess.rb', line 60

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

.new_hidden_ref(xmldoc) ⇒ Object

from standoc



185
186
187
188
189
# File 'lib/metanorma/collection/xrefprocess/xrefprocess.rb', line 185

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



222
223
224
225
226
227
228
# File 'lib/metanorma/collection/xrefprocess/xrefprocess.rb', line 222

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



21
22
23
# File 'lib/metanorma/collection/xrefprocess/xrefprocess.rb', line 21

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

.select_citation_uri(bib, lang) ⇒ Object



109
110
111
112
113
114
115
# File 'lib/metanorma/collection/xrefprocess/xrefprocess.rb', line 109

def select_citation_uri(bib, lang)
  bib or return
  url = bib.at(ns("./uri[@type = 'citation']" \
                  "[@language = '#{lang}']")) ||
    bib.at(ns("./uri[@type = 'citation']"))
  url&.text
end

.svg_preprocess(xml, doc_suffix) ⇒ Object



35
36
37
38
39
40
41
42
# File 'lib/metanorma/collection/xrefprocess/xrefprocess.rb', line 35

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



51
52
53
54
55
56
57
58
# File 'lib/metanorma/collection/xrefprocess/xrefprocess.rb', line 51

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



44
45
46
47
48
49
# File 'lib/metanorma/collection/xrefprocess/xrefprocess.rb', line 44

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



99
100
101
102
103
104
105
106
107
# File 'lib/metanorma/collection/xrefprocess/xrefprocess.rb', line 99

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

xml.root = key # to force recognition of internal refs bookmarks etc as new id elements introduced in Presentation XML: add doc suffix



8
9
10
11
12
13
14
15
16
17
18
19
# File 'lib/metanorma/collection/xrefprocess/xrefprocess.rb', line 8

def xref_preprocess(xml, isodoc)
  @isodoc = isodoc
  key = (0...8).map { rand(65..90).chr }.join # random string
  xml.root["type"] = key
  Metanorma::Utils::anchor_attributes
    .each do |(tag_name, attr_name)|
    ::Metanorma::Collection::Util::add_suffix_to_attrs(
      xml, xml.root["document_suffix"], tag_name, attr_name, isodoc
    )
  end
  key
end

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



25
26
27
28
29
30
31
32
33
# File 'lib/metanorma/collection/xrefprocess/xrefprocess.rb', line 25

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



68
69
70
71
72
73
74
75
76
77
78
# File 'lib/metanorma/collection/xrefprocess/xrefprocess.rb', line 68

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



87
88
89
90
91
92
93
94
95
96
97
# File 'lib/metanorma/collection/xrefprocess/xrefprocess.rb', line 87

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



80
81
82
83
84
85
# File 'lib/metanorma/collection/xrefprocess/xrefprocess.rb', line 80

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