Module: Metanorma::Standoc::Cleanup

Included in:
Converter
Defined in:
lib/metanorma/standoc/cleanup.rb,
lib/metanorma/standoc/cleanup_ref.rb,
lib/metanorma/standoc/cleanup_toc.rb,
lib/metanorma/standoc/cleanup_reqt.rb,
lib/metanorma/standoc/cleanup_text.rb,
lib/metanorma/standoc/cleanup_xref.rb,
lib/metanorma/standoc/cleanup_amend.rb,
lib/metanorma/standoc/cleanup_block.rb,
lib/metanorma/standoc/cleanup_image.rb,
lib/metanorma/standoc/cleanup_maths.rb,
lib/metanorma/standoc/cleanup_table.rb,
lib/metanorma/standoc/cleanup_terms.rb,
lib/metanorma/standoc/cleanup_inline.rb,
lib/metanorma/standoc/merge_bibitems.rb,
lib/metanorma/standoc/cleanup_bibdata.rb,
lib/metanorma/standoc/cleanup_bibitem.rb,
lib/metanorma/standoc/cleanup_section.rb,
lib/metanorma/standoc/cleanup_symbols.rb,
lib/metanorma/standoc/cleanup_asciibib.rb,
lib/metanorma/standoc/spans_to_bibitem.rb,
lib/metanorma/standoc/cleanup_footnotes.rb,
lib/metanorma/standoc/cleanup_dochistory.rb,
lib/metanorma/standoc/cleanup_boilerplate.rb,
lib/metanorma/standoc/cleanup_mathvariant.rb,
lib/metanorma/standoc/cleanup_section_names.rb,
lib/metanorma/standoc/cleanup_terms_boilerplate.rb,
lib/metanorma/standoc/cleanup_terms_designations.rb,
lib/metanorma/standoc/spans_to_bibitem_preprocessing.rb

Defined Under Namespace

Classes: MergeBibitems, SpansToBibitem

Constant Summary collapse

RELATON_SEVERITIES =
{ "INFO": 3, "WARN": 2, "ERROR": 1, "FATAL": 0,
"UNKNOWN": 3 }.freeze
TEXT_ELEMS =
%w{status language script version author name callout phone email
street city state country postcode identifier referenceFrom surname
referenceTo docidentifier docnumber prefix initial addition forename
title draft secretariat title-main title-intro title-part
verbal-definition non-verbal-representation}.freeze
IGNORE_QUOTES_ELEMENTS =
%w(pre tt sourcecode stem asciimath figure bibdata passthrough
identifier metanorma-extension).freeze
PRESERVE_LINEBREAK_ELEMENTS =
%w(pre sourcecode passthrough metanorma-extension).freeze
STRIP_LINEBREAK_ELEMENTS =
%w(title name variant-title figure example review admonition
note li th td dt dd p quote label annotation
preferred admitted related deprecates field-of-application
usage-info expression pronunciation grammar-value domain
definition termnote termexample modification description
newcontent floating-title).freeze
IGNORE_TEXT_ELEMENTS =
%w(index fn).freeze
CONN_REGEX_STR =

extending localities to cover ISO referencing

"(?<conn>and|or|from|to)!".freeze
LOCALITIES =
"section|clause|part|paragraph|chapter|page|line|" \
"table|annex|figure|example|note|formula|list|time|anchor|" \
"locality:[^ \\t\\n\\r:,;=]+".freeze
LOCALITY_REGEX_STR =
<<~REGEXP.freeze
  ^((#{CONN_REGEX_STR})?
      (?<locality>#{LOCALITIES})(\\s+|=)
         (?<ref>[^"][^ \\t\\n,:;-]*|"[^"]+")
           (-(?<to>[^"][^ \\t\\n,:;-]*|"[^"]"))?|
    (?<locality2>whole|title|locality:[^ \\t\\n\\r:,;=]+))(?<punct>[,:;]?)\\s*
   (?<text>.*)$
REGEXP
LOCALITY_REGEX_VALUE_ONLY_STR =
<<~REGEXP.freeze
  ^(?<conn0>(#{CONN_REGEX_STR}))
    (?!whole|title|locality:)
    (?<value>[^=,;:\\t\\n\\r]+)
    (?<punct>[,;\\t\\n\\r]|$)
REGEXP
LOCALITY_REGEX_STR_TRIPLEDASH =
<<~REGEXP.freeze
  ^(?<locality>(#{CONN_REGEX_STR})?
      (#{LOCALITIES})(\\s+|=))
         (?<ref>[^"][^ \\t\\n,:;-]*
           -[^ \\t\\n,:;"-]+
           -[^ \\t\\n,:;"]+)
    (?<text>[,:;]?\\s*
   .*)$
REGEXP
ELEMS_ALLOW_NOTES =
%w[p formula ul ol dl figure].freeze
IRI_TAG_PROPERTIES_MAP =
{
  clipPath: ["clip-path"],
  "color-profile": nil,
  cursor: nil,
  filter: nil,
  linearGradient: ["fill", "stroke"],
  marker: ["marker", "marker-end", "marker-mid", "marker-start"],
  mask: nil,
  pattern: ["fill", "stroke"],
  radialGradient: ["fill", "stroke"],
}.freeze
SVG_NS =
"http://www.w3.org/2000/svg".freeze
NUMERIC_REGEX =
%r{^((\+|-)?\d*\.?\d+)([eE](\+|-){1}\d+)?$}
MATHML_NS =
"http://www.w3.org/1998/Math/MathML".freeze
UNITSML_NS =
"https://schema.unitsml.org/unitsml/1.0".freeze
TERMDEF_BLOCKS =
"./p | ./ol | ./dl[not(@metadata = 'true')] | ./ul | ./figure | " \
"./formula | ./table".freeze
IDREF =
"//*/@id | //review/@from | //review/@to | " \
"//callout/@target | //citation/@bibitemid | " \
"//eref/@bibitemid".freeze
FIGURE_FN_XPATH =
"//figure/following-sibling::*[1][self::p and *[1][self::fn]]".freeze
NORM_REF =
"//bibliography/references[@normative = 'true'][not(@hidden)] | " \
"//bibliography/clause[.//references[@normative = 'true']]".freeze
MATHVARIANT_OVERRIDE =
{
  bold: { normal: "bold", italic: "bold-italic", fraktur: "bold-fraktur",
          script: "bold-script", "sans-serif": "bold-sans-serif",
          "sans-serif-italic": "sans-serif-bold-italic" },
  italic: { normal: "italic", bod: "bold-italic",
            "sans-serif": "sans-serif-italic",
            "bold-sans-serif": "sans-serif-bold-italic" },
  "bold-italic": { normal: "bold-italic", bold: "bold-italic",
                   italic: "bold-italic",
                   "sans-serif": "sans-serif-bold-italic",
                   "bold-sans-serif": "sans-serif-bold-italic",
                   "sans-serif-italic": "sans-serif-bold-italic" },
  fraktur: { normal: "fraktur", bold: "bold-fraktur" },
  "bold-fraktur": { normal: "bold-fraktur", fraktur: "bold-fraktur" },
  script: { normal: "script", bold: "bold-script" },
  "bold-script": { normal: "script", script: "bold-script" },
  "sans-serif": { normal: "sans-serif", bold: "bold-sans-serif",
                  italic: "sans-serif-italic",
                  "bold-italic": "sans-serif-bold-italic" },
  "bold-sans-serif": { normal: "bold-sans-serif", bold: "bold-sans-serif",
                       "sans-serif": "bold-sans-serif",
                       italic: "sans-serif-bold-italic",
                       "bold-italic": "sans-serif-bold-italic",
                       "sans-serif-italic": "sans-serif-bold-italic" },
  "sans-serif-italic": { normal: "sans-serif-italic",
                         italic: "sans-serif-italic",
                         "sans-serif": "sans-serif-italic",
                         bold: "sans-serif-bold-italic",
                         "bold-italic": "sans-serif-bold-italic",
                         "sans-serif-bold": "sans-serif-bold-italic" },
  "sans-serif-bold-italic": { normal: "sans-serif-bold-italic",
                              italic: "sans-serif-bold-italic",
                              "sans-serif": "sans-serif-bold-italic",
                              "sans-serif-italic": "sans-serif-bold-italic",
                              bold: "sans-serif-bold-italic",
                              "bold-italic": "sans-serif-bold-italic",
                              "sans-serif-bold": "sans-serif-bold-italic" },
}.freeze
NO_SYMABBR =
"[.//definitions[not(@type)]]".freeze
SYMABBR =
"[.//definitions[@type = 'symbols']]" \
"[.//definitions[@type = 'abbreviated_terms']]".freeze
SYMnoABBR =
"[.//definitions[@type = 'symbols']]" \
"[not(.//definitions[@type = 'abbreviated_terms'])]".freeze
ABBRnoSYM =
"[.//definitions[@type = 'abbreviated_terms']]" \
"[not(.//definitions[@type = 'symbols'])]".freeze
SECTION_CONTAINERS =
%w(foreword introduction acknowledgements abstract
clause clause references terms definitions annex
appendix).freeze
TERM_CLAUSE =
"//sections//terms[not(.//ancestor::clause[@type = 'terms'])] | " \
"//sections/clause[descendant::terms][@type = 'terms'] | " \
"//sections/clause[not(@type = 'terms')]//terms".freeze
DESIGNATOR =
%w(preferred admitted deprecates related).freeze

Instance Method Summary collapse

Instance Method Details

#add_locality(stack, match) ⇒ Object



84
85
86
87
88
89
90
91
92
# File 'lib/metanorma/standoc/cleanup_xref.rb', line 84

def add_locality(stack, match)
  stack.children.empty? && match[:conn] and
    stack["connective"] = match[:conn]
  ref =
    match[:ref] ? "<referenceFrom>#{tq match[:ref]}</referenceFrom>" : ""
  refto = match[:to] ? "<referenceTo>#{tq match[:to]}</referenceTo>" : ""
  stack.add_child("<locality type='#{locality_label(match)}'>#{ref}" \
                  "#{refto}</locality>")
end

#add_misc_container(xmldoc) ⇒ Object



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

def add_misc_container(xmldoc)
  unless ins = xmldoc.at("//metanorma-extension")
    a = xmldoc.xpath("//termdocsource")&.last || xmldoc.at("//bibdata")
    a.next = "<metanorma-extension/>"
    ins = xmldoc.at("//metanorma-extension")
  end
  ins
end

#add_to_hash(bib, key, val) ⇒ Object



72
73
74
# File 'lib/metanorma/standoc/cleanup_asciibib.rb', line 72

def add_to_hash(bib, key, val)
  Metanorma::Utils::set_nested_value(bib, key.split("."), val)
end

#align_callouts_to_annotations(xmldoc) ⇒ Object



120
121
122
123
124
125
126
127
# File 'lib/metanorma/standoc/cleanup_block.rb', line 120

def align_callouts_to_annotations(xmldoc)
  xmldoc.xpath("//sourcecode").each do |x|
    callouts = x.elements.select { |e| e.name == "callout" }
    annotations = x.elements.select { |e| e.name == "annotation" }
    callouts.size == annotations.size and
      link_callouts_to_annotations(callouts, annotations)
  end
end

#alternate_termdefinitions(xmldoc) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/metanorma/standoc/cleanup_terms.rb', line 56

def alternate_termdefinitions(xmldoc)
  xmldoc.xpath("//term").each do |t|
    t.xpath("./definition").each do |d|
      d1 = d.next_element or next
      if (v = d.at("./verbal-definition")) &&
          !d.at("./non-verbal-representation") &&
          !d1.at("./verbal-definition") &&
          nv = d1.at("./non-verbal-representation")
        v.next = nv.remove
        d1.remove
      end
    end
  end
end

#amend_attrs(yaml) ⇒ Object



41
42
43
44
45
46
47
48
# File 'lib/metanorma/standoc/cleanup_dochistory.rb', line 41

def amend_attrs(yaml)
  ret = ""
  yaml["change"] ||= "modify"
  %w(change path path_end title).each do |x|
    a = yaml[x] and ret += " #{x}='#{a}'"
  end
  ret = "<amend#{ret}>"
end

#amend_classification(yaml) ⇒ Object



75
76
77
78
79
# File 'lib/metanorma/standoc/cleanup_dochistory.rb', line 75

def amend_classification(yaml)
  a = yaml["classification"] or return ""
  a.is_a?(Array) or a = [a]
  a.map { |x| amend_classification1(x) }.join("\n")
end

#amend_classification1(yaml) ⇒ Object



81
82
83
84
85
86
# File 'lib/metanorma/standoc/cleanup_dochistory.rb', line 81

def amend_classification1(yaml)
  yaml.is_a?(Hash) or yaml = { "tag" => "default", "value" => yaml }
  <<~OUT
    <classification><tag>#{yaml['tag']}</tag><value>#{yaml['value']}</value></classification>
  OUT
end

#amend_description(yaml) ⇒ Object



69
70
71
72
73
# File 'lib/metanorma/standoc/cleanup_dochistory.rb', line 69

def amend_description(yaml)
  a = yaml["description"] or return ""
  out = adoc2xml(a, backend.to_sym)
  "<description>#{out.children.to_xml}</description>"
end

#amend_hash2mn(yaml) ⇒ Object



35
36
37
38
39
# File 'lib/metanorma/standoc/cleanup_dochistory.rb', line 35

def amend_hash2mn(yaml)
  yaml.nil? and return ""
  yaml.is_a?(Hash) and yaml = [yaml]
  yaml.map { |x| amend_hash2mn1(x) }.join("\n")
end

#amend_hash2mn1(yaml) ⇒ Object



50
51
52
53
54
55
56
# File 'lib/metanorma/standoc/cleanup_dochistory.rb', line 50

def amend_hash2mn1(yaml)
  ret = amend_attrs(yaml)
  ret += amend_description(yaml)
  ret += amend_location(yaml)
  ret += amend_classification(yaml)
  "#{ret}</amend>"
end

#amend_location(yaml) ⇒ Object



58
59
60
61
62
63
64
65
66
67
# File 'lib/metanorma/standoc/cleanup_dochistory.rb', line 58

def amend_location(yaml)
  a = yaml["location"] or return ""
  a.is_a?(Array) or a = [a]
  ret = a.map do |x|
    elem = Nokogiri::XML("<location>#{x}</location>").root
    extract_localities(elem)
    elem.children.to_xml
  end.join("\n")
  "<location>#{ret}</location>"
end

#ancestor_include?(elem, ancestors) ⇒ Boolean

Returns:

  • (Boolean)


14
15
16
17
# File 'lib/metanorma/standoc/cleanup_text.rb', line 14

def ancestor_include?(elem, ancestors)
  path = elem.path.gsub(/\[\d+\]/, "").split(%r{/})[1..-2]
  !path.intersection(ancestors).empty?
end

#anchor_alias(xmldoc) ⇒ Object



147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/metanorma/standoc/cleanup_xref.rb', line 147

def anchor_alias(xmldoc)
  t = xmldoc.at("//metanorma-extension/table[@id = " \
                "'_misccontainer_anchor_aliases']") or return
  key = ""
  t.xpath("./tbody/tr").each do |tr|
    tr.xpath("./td | ./th").each_with_index do |td, i|
      if i.zero? then key = td.text
      else anchor_alias1(key, td)
      end
    end
  end
end

#anchor_alias1(key, elem) ⇒ Object



160
161
162
163
164
165
166
# File 'lib/metanorma/standoc/cleanup_xref.rb', line 160

def anchor_alias1(key, elem)
  id = elem.text.strip
  id.empty? and elem.at("./link") and
    id = elem.at("./link/@target")&.text
  (key && !id.empty?) or return
  @anchor_alias[id] = key
end

#anchor_cleanup(elem) ⇒ Object



138
139
140
141
142
# File 'lib/metanorma/standoc/cleanup_inline.rb', line 138

def anchor_cleanup(elem)
  anchor_cleanup1(elem)
  xreftarget_cleanup(elem)
  contenthash_id_cleanup(elem)
end

#anchor_cleanup1(elem) ⇒ Object



144
145
146
147
148
149
150
151
152
153
154
# File 'lib/metanorma/standoc/cleanup_inline.rb', line 144

def anchor_cleanup1(elem)
  elem.xpath(IDREF).each do |s|
    if (ret = Metanorma::Utils::to_ncname(s.value)) != (orig = s.value)
      s.value = ret
      output = s.parent.dup
      output.children.remove
      @log.add("Anchors", s.parent,
               "normalised identifier in #{output} from #{orig}")
    end
  end
end

#asciimath2mathml(xml) ⇒ Object



11
12
13
14
15
16
17
18
# File 'lib/metanorma/standoc/cleanup_maths.rb', line 11

def asciimath2mathml(xml)
  xpath = xml.xpath("//stem[@type = 'AsciiMath']")
  xpath.each_with_index do |x, i|
    progress_conv(i, 500, xpath.size, 1000, "AsciiMath")
    asciimath2mathml_indiv(x)
  end
  asciimath2mathml_wrap(xml)
end

#asciimath2mathml_err(text, expr) ⇒ Object



47
48
49
50
# File 'lib/metanorma/standoc/cleanup_maths.rb', line 47

def asciimath2mathml_err(text, expr)
  err = "Malformed MathML: #{expr}\n#{text}"
  @log.add("Maths", nil, err, severity: 0)
end

#asciimath2mathml_indiv(elem) ⇒ Object



20
21
22
23
24
25
26
27
28
# File 'lib/metanorma/standoc/cleanup_maths.rb', line 20

def asciimath2mathml_indiv(elem)
  elem["type"] = "MathML"
  expr = @c.decode(elem.text)
  ret = asciimath_parse(expr, elem)&.strip
  ret += "<asciimath>#{@c.encode(expr, :basic)}</asciimath>"
  elem.children = ret
rescue StandardError => e
  asciimath2mathml_err(elem.to_xml, e)
end

#asciimath2mathml_wrap(xml) ⇒ Object



52
53
54
55
56
57
58
59
60
# File 'lib/metanorma/standoc/cleanup_maths.rb', line 52

def asciimath2mathml_wrap(xml)
  xml.xpath("//*[local-name() = 'math'][@display]").each do |y|
    y.delete("display")
  end
  # x.xpath("//stem").each do |y|
  # y.next_element&.name == "asciimath" and y << y.next_element
  # end
  xml
end

#asciimath2unitsml_optionsObject



124
125
126
# File 'lib/metanorma/standoc/cleanup_maths.rb', line 124

def asciimath2unitsml_options
  { multiplier: :space }
end

#asciimath_cleanup(xml) ⇒ Object



7
8
9
# File 'lib/metanorma/standoc/cleanup_maths.rb', line 7

def asciimath_cleanup(xml)
  !@keepasciimath and asciimath2mathml(xml)
end

#asciimath_parse(expr, elem) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
# File 'lib/metanorma/standoc/cleanup_maths.rb', line 35

def asciimath_parse(expr, elem)
  if NUMERIC_REGEX.match?(expr)
    @novalid or elem["validate"] = "false"
    <<~MATH
      <math xmlns='#{MATHML_NS}'><mstyle displaystyle='false'><mn>#{expr}</mn></mstyle></math>
    MATH
  else
    Plurimath::Math.parse(expr, "asciimath")
      .to_mathml(display_style: elem["block"])
  end
end

#attachment_cleanup(xmldoc) ⇒ Object



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

def attachment_cleanup(xmldoc)
  xmldoc.xpath("//bibitem[uri/@type = 'attachment']").each do |b|
    b["hidden"] = "true"
    u = b.at("./uri[@type = 'attachment']")
    c = b.at("./uri[@type = 'citation']") ||
      u.after("<uri type='citation'/>")
    uri = attachment_uri(u.text, b)
    u.children = uri
    c.children = uri
  end
end

#attachment_location(path) ⇒ Object



169
170
171
172
173
174
175
# File 'lib/metanorma/standoc/cleanup_bibitem.rb', line 169

def attachment_location(path)
  f = path
  @datauriattachment and
    f = File.join(@attachmentsdir, File.basename(path))
  Pathname.new(File.expand_path(f))
    .relative_path_from(Pathname.new(File.expand_path(@localdir))).to_s
end

#attachment_uri(path, bib) ⇒ Object



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

def attachment_uri(path, bib)
  init_attachments
  path = File.join(@localdir, path)
  valid_attachment?(path, bib) or return ""
  @datauriattachment or return attachment_location(path)
  save_attachment(path, bib)
end

#auto_name_definitions(xml) ⇒ Object



77
78
79
80
81
82
83
# File 'lib/metanorma/standoc/cleanup_section_names.rb', line 77

def auto_name_definitions(xml)
  xml.xpath("//definitions[@type = 'symbols']").size > 1 and return false
  xml.xpath("//definitions[@type = 'abbreviated_terms']").size > 1 and
    return false
  xml.xpath("//definitions[not(@type)]").size > 1 and return false
  true
end

#auto_name_terms(xml) ⇒ Object

do not auto-name terms sections if there are terms subclauses not covered by the auto titles, or if more than one title is covered by an auto title



102
103
104
105
106
107
108
109
110
111
112
# File 'lib/metanorma/standoc/cleanup_section_names.rb', line 102

def auto_name_terms(xml)
  n = xml.at("//terms | //clause[.//terms]")
  out = terms_subclauses(n)
    .each_with_object({ term: 0, sna: 0, ans: 0, sa: 0, nsa: 0,
                        tsna: 0, tans: 0, tsa: 0, tnsa: 0,
                        termdef: 0, other: 0 }) do |x, m|
    terms_subclause_type_tally(x, m, n)
  end
  out.delete(:parent)
  !out.values.detect { |x| x > 1 } && out[:other].zero?
end

#bib_relation_insert_pt(xmldoc) ⇒ Object



4
5
6
7
8
9
10
11
# File 'lib/metanorma/standoc/cleanup_dochistory.rb', line 4

def bib_relation_insert_pt(xmldoc)
  ins = nil
  %w(relation copyright status abstract script language note version
     edition contributor).each do |x|
    ins = xmldoc.at("//bibdata/#{x}[last()]") and break
  end
  ins
end

#bibabstract_location(xml) ⇒ Object



56
57
58
59
60
61
62
63
64
65
# File 'lib/metanorma/standoc/cleanup_section.rb', line 56

def bibabstract_location(xml)
  xml.at("//bibdata/script") || xml.at("//bibdata/language") ||
    xml.at("//bibdata/contributor[not(following-sibling::contributor)]") ||
    xml.at("//bibdata/date[not(following-sibling::date)]") ||
    xml.at("//docnumber") ||
    xml.at("//bibdata/docidentifier" \
           "[not(following-sibling::docidentifier)]") ||
    xml.at("//bibdata/uri[not(following-sibling::uri)]") ||
    xml.at("//bibdata/title[not(following-sibling::title)]")
end

#bibdata_anchor_cleanup(xmldoc) ⇒ Object



12
13
14
15
16
# File 'lib/metanorma/standoc/cleanup_bibdata.rb', line 12

def bibdata_anchor_cleanup(xmldoc)
  xmldoc.xpath("//bibdata//bibitem | //bibdata//note").each do |b|
    b.delete("id")
  end
end

#bibdata_cleanup(xmldoc) ⇒ Object



4
5
6
7
8
9
10
# File 'lib/metanorma/standoc/cleanup_bibdata.rb', line 4

def bibdata_cleanup(xmldoc)
  bibdata_anchor_cleanup(xmldoc)
  bibdata_docidentifier_cleanup(xmldoc)
  bibdata_embed_hdr_cleanup(xmldoc) # feeds bibdata_embed_id_cleanup
  bibdata_embed_id_cleanup(xmldoc)
  biblio_indirect_erefs(xmldoc, @internal_eref_namespaces&.uniq)
end

#bibdata_docidentifier_cleanup(xmldoc) ⇒ Object



18
19
20
21
22
23
24
25
# File 'lib/metanorma/standoc/cleanup_bibdata.rb', line 18

def bibdata_docidentifier_cleanup(xmldoc)
  ins = xmldoc.at("//bibdata/docidentifier")
  xmldoc.xpath("//bibdata/docidentifier").each_with_index do |b, i|
    i.zero? and next
    ins.next = b.remove
    ins = ins.next
  end
end

#bibdata_embed_hdr_cleanup(xmldoc) ⇒ Object



83
84
85
86
87
# File 'lib/metanorma/standoc/cleanup_bibdata.rb', line 83

def bibdata_embed_hdr_cleanup(xmldoc)
  (@embed_hdr.nil? || @embed_hdr.empty?) and return
  xmldoc.at("//bibdata") << "<relation type='derivedFrom'>" \
                            "#{hdr2bibitem(@embed_hdr.first)}</relation>"
end

#bibdata_embed_id_cleanup(xmldoc) ⇒ Object



113
114
115
116
117
118
119
120
121
122
123
# File 'lib/metanorma/standoc/cleanup_bibdata.rb', line 113

def bibdata_embed_id_cleanup(xmldoc)
  @embed_id.nil? and return
  bibdata = xmldoc.at("//bibdata")
  @embed_id.each do |d|
    bibdata = bibdata.at("./relation[@type = 'derivedFrom']/bibitem")
    ident = bibdata.at("./docidentifier[@primary = 'true']") ||
      bibdata.at("./docidentifier")
    xmldoc.xpath("//xref[@target = '#{d}'][normalize-space(text()) = '']")
      .each { |x| x << ident.text }
  end
end

#bibitem_cleanup(xmldoc) ⇒ Object



222
223
224
225
226
227
228
229
# File 'lib/metanorma/standoc/cleanup_bibitem.rb', line 222

def bibitem_cleanup(xmldoc)
  bibitem_nested_id(xmldoc) # feeds remove_dup_bibtem_id
  remove_dup_bibtem_id(xmldoc)
  ref_dl_cleanup(xmldoc)
  formattedref_spans(xmldoc)
  fetch_local_bibitem(xmldoc)
  attachment_cleanup(xmldoc)
end

#bibitem_id_docid_hash(xmldoc) ⇒ Object



213
214
215
216
217
218
219
220
# File 'lib/metanorma/standoc/cleanup_bibitem.rb', line 213

def bibitem_id_docid_hash(xmldoc)
  xmldoc.xpath("//bibitem[@id]").each_with_object({}) do |b, m|
    m[b["id"]] ||= {}
    docid = b.at("./docidentifier")&.text || "NO ID"
    m[b["id"]][docid] ||= []
    m[b["id"]][docid] << b
  end
end

#bibitem_nested_id(xmldoc) ⇒ Object



130
131
132
133
134
135
136
137
# File 'lib/metanorma/standoc/cleanup_bibitem.rb', line 130

def bibitem_nested_id(xmldoc)
  xmldoc.xpath("//bibitem//bibitem").each do |b|
    b.delete("id")
  end
  xmldoc.xpath("//bibdata//bibitem").each do |b|
    b.delete("id")
  end
end

#biblio_annex(xmldoc) ⇒ Object



93
94
95
96
97
98
99
100
# File 'lib/metanorma/standoc/cleanup_ref.rb', line 93

def biblio_annex(xmldoc)
  xmldoc.xpath("//annex[references/references]").each do |t|
    t.xpath("./clause | ./references | ./terms").size == 1 or next
    r = t.at("./references")
    r.xpath("./references").each { |b| b["normative"] = r["normative"] }
    r.replace(r.elements)
  end
end

#biblio_cleanup(xmldoc) ⇒ Object



64
65
66
67
68
69
70
71
72
# File 'lib/metanorma/standoc/cleanup_ref.rb', line 64

def biblio_cleanup(xmldoc)
  biblio_reorder(xmldoc)
  biblio_annex(xmldoc)
  biblio_nested(xmldoc)
  biblio_renumber(xmldoc)
  biblio_linkonly(xmldoc)
  biblio_hidden_inherit(xmldoc)
  biblio_no_ext(xmldoc)
end

#biblio_hidden_inherit(xmldoc) ⇒ Object



46
47
48
49
50
# File 'lib/metanorma/standoc/cleanup_bibitem.rb', line 46

def biblio_hidden_inherit(xmldoc)
  xmldoc.xpath("//references[@hidden = 'true']").each do |r|
    r.xpath("./bibitem").each { |b| b["hidden"] = true }
  end
end

#biblio_indirect_erefs(xmldoc, prefixes) ⇒ Object



74
75
76
77
78
79
80
81
# File 'lib/metanorma/standoc/cleanup_bibdata.rb', line 74

def biblio_indirect_erefs(xmldoc, prefixes)
  prefixes&.each do |prefix|
    refs = gather_indirect_erefs(xmldoc, prefix)
    refs = resolve_local_indirect_erefs(xmldoc, refs, prefix)
    refs.empty? and next
    insert_indirect_biblio(xmldoc, refs, prefix)
  end
end

#biblio_linkonly(xmldoc) ⇒ Object



74
75
76
77
78
79
80
81
82
83
84
# File 'lib/metanorma/standoc/cleanup_ref.rb', line 74

def biblio_linkonly(xmldoc)
  xmldoc.at("//xref[@hidden]") or return
  ins = xmldoc.at("//bibliography")
    .add_child("<references hidden='true' normative='true'/>").first
  refs = xmldoc.xpath("//xref[@hidden]").each_with_object([]) do |x, m|
    @refids << x["target"]
    m << { id: x["target"], ref: x["hidden"] }
    x.delete("hidden")
  end
  ins << insert_hidden_bibitems(refs)
end

#biblio_nested(xmldoc) ⇒ Object



102
103
104
105
# File 'lib/metanorma/standoc/cleanup_ref.rb', line 102

def biblio_nested(xmldoc)
  biblio_nested_initial_items(xmldoc)
  biblio_nested_sections(xmldoc)
end

#biblio_nested_initial_items(xmldoc) ⇒ Object



107
108
109
110
111
112
113
114
115
116
117
# File 'lib/metanorma/standoc/cleanup_ref.rb', line 107

def biblio_nested_initial_items(xmldoc)
  xmldoc.xpath("//references[references][bibitem]").each do |t|
    r = t.at("./references")
    ref = t.at("./bibitem")
      .before("<references unnumbered='true'></references>").previous
    (ref.xpath("./following-sibling::*") &
     r.xpath("./preceding-sibling::*")).each do |x|
      ref << x
    end
  end
end

#biblio_nested_sections(xmldoc) ⇒ Object



119
120
121
122
123
124
125
# File 'lib/metanorma/standoc/cleanup_ref.rb', line 119

def biblio_nested_sections(xmldoc)
  xmldoc.xpath("//references[references]").each do |t|
    t.name = "clause"
    t.xpath("./references").each { |r| r["normative"] = t["normative"] }
    t.delete("normative")
  end
end

#biblio_no_ext(xmldoc) ⇒ Object



52
53
54
# File 'lib/metanorma/standoc/cleanup_bibitem.rb', line 52

def biblio_no_ext(xmldoc)
  xmldoc.xpath("//bibitem/ext").each(&:remove)
end

#biblio_renumber(xmldoc) ⇒ Object

default presuppose that all citations in biblio numbered consecutively, but that standards codes are preserved as is: only numeric references are renumbered



35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/metanorma/standoc/cleanup_ref.rb', line 35

def biblio_renumber(xmldoc)
  i = 0
  xmldoc.xpath("//references[not(@normative = 'true')]" \
               "[not(@hidden = 'true')]").each do |r|
    r.xpath("./bibitem[not(@hidden = 'true')]").each do |b|
      i += 1
      docid = b.at("./docidentifier[@type = 'metanorma']") or next
      /^\[\d+\]$/.match?(docid.text) or next
      docid.children = "[#{i}]"
    end
  end
end

#biblio_reorder(xmldoc) ⇒ Object



9
10
11
12
13
# File 'lib/metanorma/standoc/cleanup_ref.rb', line 9

def biblio_reorder(xmldoc)
  xmldoc.xpath("//references[@normative = 'false']").each do |r|
    biblio_reorder1(r)
  end
end

#biblio_reorder1(refs) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/metanorma/standoc/cleanup_ref.rb', line 15

def biblio_reorder1(refs)
  fold_notes_into_biblio(refs)
  bib = sort_biblio(refs.xpath("./bibitem"))
  insert = refs.at("./bibitem")&.previous_element
  refs.xpath("./bibitem").each(&:remove)
  bib.reverse_each do |b|
    (insert and insert.next = b.to_xml) or
      refs.children.first.add_previous_sibling b.to_xml
  end
  extract_notes_from_biblio(refs)
  refs.xpath("./references").each { |r| biblio_reorder1(r) }
end

#block?(elem) ⇒ Boolean

Returns:

  • (Boolean)


132
133
134
135
136
137
138
139
# File 'lib/metanorma/standoc/cleanup_text.rb', line 132

def block?(elem)
  %w(title name variant-title clause figure annex example introduction
     foreword acknowledgements note li th td dt dd p quote label
     abstract preferred admitted related deprecates field-of-application
     usage-info expression pronunciation grammar-value domain
     definition termnote termexample modification description
     newcontent floating-title tab review admonition annotation).include? elem.name
end

#block_index_cleanup(xmldoc) ⇒ Object



179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/metanorma/standoc/cleanup_block.rb', line 179

def block_index_cleanup(xmldoc)
  xmldoc.xpath("//quote | //td | //th | //formula | //li | //dt | " \
               "//dd | //example | //note | //figure | //sourcecode | " \
               "//admonition | //termnote | //termexample | //form  | " \
               "//requirement | //recommendation | //permission | " \
               "//imagemap | //svgmap").each do |b|
    b.xpath("./p[indexterm]").each do |p|
      indexterm_para?(p) or next
      p.replace(p.children)
    end
  end
end

#blocksource_cleanup(xmldoc) ⇒ Object



226
227
228
229
230
231
# File 'lib/metanorma/standoc/cleanup_block.rb', line 226

def blocksource_cleanup(xmldoc)
  xmldoc.xpath("//figure//termsource | //table//termsource").each do |s|
    s.name = "source"
    s.delete("type")
  end
end

#boilerplate(xml, conv) ⇒ Object



90
91
92
93
94
95
96
97
98
99
# File 'lib/metanorma/standoc/cleanup_boilerplate.rb', line 90

def boilerplate(xml, conv)
  # prevent infinite recursion of asciidoc boilerplate processing
  xml.at("//metanorma-extension/semantic-metadata/" \
         "headless[text() = 'true']") and return nil
  file = boilerplate_file(xml)
  @boilerplateauthority and
    file2 = File.join(@localdir, @boilerplateauthority)
  resolve_boilerplate_files(process_boilerplate_file(file, conv),
                            process_boilerplate_file(file2, conv))
end

#boilerplate_cleanup(xmldoc) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
# File 'lib/metanorma/standoc/cleanup_boilerplate.rb', line 66

def boilerplate_cleanup(xmldoc)
  isodoc = boilerplate_isodoc(xmldoc) or return
  termdef_boilerplate_cleanup(xmldoc)
  termdef_boilerplate_insert(xmldoc, isodoc)
  unwrap_boilerplate_clauses(xmldoc, self.class::TERM_CLAUSE)
  if f = xmldoc.at(self.class::NORM_REF)
    norm_ref_preface(f)
    unwrap_boilerplate_clauses(f, ".")
  end
  initial_boilerplate(xmldoc, isodoc)
end

#boilerplate_file(_xmldoc) ⇒ Object



86
87
88
# File 'lib/metanorma/standoc/cleanup_boilerplate.rb', line 86

def boilerplate_file(_xmldoc)
  File.join(@libdir, "boilerplate.xml")
end

#boilerplate_file_convert(file) ⇒ Object

If Asciidoctor, convert top clauses to tags and wrap in <boilerplate>



137
138
139
140
# File 'lib/metanorma/standoc/cleanup_boilerplate.rb', line 137

def boilerplate_file_convert(file)
  ret = Nokogiri::XML(file).root and return ret
  boilerplate_file_restructure(file)
end

#boilerplate_file_restructure(file) ⇒ Object

If Asciidoctor, convert top clauses to tags and wrap in <boilerplate>



143
144
145
146
147
148
149
# File 'lib/metanorma/standoc/cleanup_boilerplate.rb', line 143

def boilerplate_file_restructure(file)
  ret = adoc2xml(file, backend.to_sym)
  boilerplate_xml_cleanup(ret)
  ret.name = "boilerplate"
  boilerplate_top_elements(ret)
  ret
end

#boilerplate_isodoc(xmldoc) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/metanorma/standoc/cleanup_boilerplate.rb', line 43

def boilerplate_isodoc(xmldoc)
  # prevent infinite recursion of asciidoc boilerplate processing
  # in termdef_boilerplate_insert and initial_boilerplate
  xmldoc.at("//metanorma-extension/semantic-metadata/" \
            "headless[text() = 'true']") and return nil
  x = xmldoc.dup
  x.root.add_namespace(nil, self.class::XML_NAMESPACE)
  xml = Nokogiri::XML(x.to_xml)
  @isodoc ||= isodoc(@lang, @script, @locale)
  @isodoc.info(xml, nil)
  @isodoc
end

#boilerplate_read(file) ⇒ Object



129
130
131
132
133
134
# File 'lib/metanorma/standoc/cleanup_boilerplate.rb', line 129

def boilerplate_read(file)
  ret = File.read(file, encoding: "UTF-8")
  /\.adoc$/.match?(file) and
    ret.gsub!(/(?<!\{)(\{\{[^{}]+\}\})(?!\})/, "pass:[\\1]")
  ret
end

#boilerplate_snippet_convert(adoc) ⇒ Object



14
15
16
17
# File 'lib/metanorma/standoc/cleanup_terms_boilerplate.rb', line 14

def boilerplate_snippet_convert(adoc)
  ret = boilerplate_xml_cleanup(adoc2xml(adoc, backend.to_sym))
  @i18n.l10n(ret.children.to_xml, @lang, @script)
end

#boilerplate_top_elements(xml) ⇒ Object



166
167
168
169
170
171
172
# File 'lib/metanorma/standoc/cleanup_boilerplate.rb', line 166

def boilerplate_top_elements(xml)
  xml.elements.each do |e|
    (t = e.at("./title") and /-statement$/.match?(t.text)) or next
    e.name = t.remove.text
    e.keys.each { |a| e.delete(a) } # rubocop:disable Style/HashEachMethods
  end
end

#boilerplate_xml_cleanup(xml) ⇒ Object

remove Metanorma namespace, so generated doc containing boilerplate can be queried consistently _d+ anchor is assigned to titleless clauses, will clash with main doc instances of same



155
156
157
158
159
160
161
162
163
164
# File 'lib/metanorma/standoc/cleanup_boilerplate.rb', line 155

def boilerplate_xml_cleanup(xml)
  ns = xml.namespace.href
  xml.traverse do |n|
    n.element? or next
    n.namespace.href == ns and n.namespace = nil
    /^_\d+$/.match?(n["id"]) and
      n["id"] = "_#{UUIDTools::UUID.random_create}"
  end
  xml
end

#bookmark_cleanup(xmldoc) ⇒ Object



26
27
28
29
30
# File 'lib/metanorma/standoc/cleanup_inline.rb', line 26

def bookmark_cleanup(xmldoc)
  redundant_bookmark_cleanup(xmldoc)
  li_bookmark_cleanup(xmldoc)
  dt_bookmark_cleanup(xmldoc)
end

#bookmark_to_id(elem, bookmark) ⇒ Object



43
44
45
46
47
# File 'lib/metanorma/standoc/cleanup_inline.rb', line 43

def bookmark_to_id(elem, bookmark)
  parent = bookmark.parent
  elem["id"] = bookmark.remove["id"]
  strip_initial_space(parent)
end

#bpart_cleanup(xmldoc) ⇒ Object

allows us to deal with doc relation localities, temporarily stashed to “bpart”



148
149
150
151
152
153
# File 'lib/metanorma/standoc/cleanup.rb', line 148

def bpart_cleanup(xmldoc)
  xmldoc.xpath("//relation/bpart").each do |x|
    extract_localities(x)
    x.replace(x.children)
  end
end

#callout_cleanup(xmldoc) ⇒ Object



137
138
139
140
# File 'lib/metanorma/standoc/cleanup_block.rb', line 137

def callout_cleanup(xmldoc)
  merge_annotations_into_sourcecode(xmldoc)
  align_callouts_to_annotations(xmldoc)
end

#change_clauses(docxml) ⇒ Object



4
5
6
7
8
# File 'lib/metanorma/standoc/cleanup_amend.rb', line 4

def change_clauses(docxml)
  docxml.xpath("//clause[@change]").each do |c|
    create_amend(c)
  end
end

#clausebefore_cleanup(xmldoc) ⇒ Object



174
175
176
177
# File 'lib/metanorma/standoc/cleanup_section.rb', line 174

def clausebefore_cleanup(xmldoc)
  sections_clausebefore_cleanup(xmldoc)
  preface_clausebefore_cleanup(xmldoc)
end

#clean_abstract(dupabstract) ⇒ Object



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

def clean_abstract(dupabstract)
  dupabstract.traverse { |n| n.remove_attribute("id") }
  %w(language script unnumbered).each do |w|
    dupabstract.remove_attribute(w)
  end
  dupabstract.at("./title")&.remove
  dupabstract
end

#cleanup(xmldoc) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/metanorma/standoc/cleanup.rb', line 28

def cleanup(xmldoc)
  @doctype = xmldoc.at("//bibdata/ext/doctype")&.text
  element_name_cleanup(xmldoc)
  passthrough_cleanup(xmldoc)
  unnumbered_blocks_cleanup(xmldoc)
  termdocsource_cleanup(xmldoc) # feeds: metadata_cleanup
  (xmldoc) # feeds: boilerplate_cleanup
  sections_cleanup(xmldoc) # feeds: obligations_cleanup, toc_cleanup,
  # floatingtitle_cleanup
  obligations_cleanup(xmldoc)
  para_index_cleanup(xmldoc)
  block_index_cleanup(xmldoc)
  table_cleanup(xmldoc) # feeds: blocksource_cleanup
  formula_cleanup(xmldoc)
  form_cleanup(xmldoc)
  sourcecode_cleanup(xmldoc) # feeds: callout_cleanup
  figure_cleanup(xmldoc)
  blocksource_cleanup(xmldoc)
  requirement_cleanup(xmldoc) # feeds: xref_cleanup
  element_name_cleanup(xmldoc)
  ref_cleanup(xmldoc) # feeds: bibitem_cleanup
  note_cleanup(xmldoc)
  clausebefore_cleanup(xmldoc) # feeeds: floatingtitle_cleanup
  floatingtitle_cleanup(xmldoc)
  bibitem_cleanup(xmldoc) # feeds: normref_cleanup, biblio_cleanup,
  # reference_names, bpart_cleanup
  normref_cleanup(xmldoc)
  biblio_cleanup(xmldoc)
  reference_names(xmldoc)
  terms_terms_cleanup(xmldoc) # feeds: boilerplate_cleanup
  asciimath_cleanup(xmldoc) # feeds: mathml_cleanup, termdef_cleanup,
  # symbols_cleanup
  symbols_cleanup(xmldoc) # feeds: termdef_cleanup
  xref_cleanup(xmldoc) # feeds: concept_cleanup, origin_cleanup
  concept_cleanup(xmldoc) # feeds: related_cleanup, termdef_cleanup
  related_cleanup(xmldoc) # feeds: termdef_cleanup
  origin_cleanup(xmldoc) # feeds: termdef_cleanup
  bookmark_cleanup(xmldoc)
  termdef_cleanup(xmldoc) # feeds: relaton_iev_cleanup, term_index_cleanup
  relaton_iev_cleanup(xmldoc)
  relaton_log_cleanup(xmldoc)
  element_name_cleanup(xmldoc)
  term_index_cleanup(xmldoc)
  bpart_cleanup(xmldoc)
  quotesource_cleanup(xmldoc)
  callout_cleanup(xmldoc)
  footnote_cleanup(xmldoc)
  ol_cleanup(xmldoc)
  mathml_cleanup(xmldoc)
  script_cleanup(xmldoc)
  docidentifier_cleanup(xmldoc) # feeds: bibdata_cleanup
  ext_contributor_cleanup(xmldoc) # feeds: bibdata_cleanup
  ext_dochistory_cleanup(xmldoc) # feeds: bibdata_cleanup
  bibdata_cleanup(xmldoc) # feeds: boilerplate_cleanup
  boilerplate_cleanup(xmldoc) # feeds: xref_cleanup for new <<>> introduced
  xref_cleanup(xmldoc)
  svgmap_cleanup(xmldoc) # feeds: img_cleanup
  toc_cleanup(xmldoc)
  smartquotes_cleanup(xmldoc)
  linebreak_cleanup(xmldoc)
  variant_cleanup(xmldoc)
  para_cleanup(xmldoc)
  empty_element_cleanup(xmldoc)
  img_cleanup(xmldoc)
  anchor_cleanup(xmldoc)
  link_cleanup(xmldoc)
  xmldoc
end

#concept_cleanup(xmldoc) ⇒ Object



72
73
74
75
76
77
78
# File 'lib/metanorma/standoc/cleanup_inline.rb', line 72

def concept_cleanup(xmldoc)
  xmldoc.xpath("//concept[not(termxref)]").each do |x|
    term = x.at("./refterm")
    term&.remove if term&.text&.empty?
    concept_cleanup1(x)
  end
end

#concept_cleanup1(elem) ⇒ Object



80
81
82
83
84
85
86
87
88
# File 'lib/metanorma/standoc/cleanup_inline.rb', line 80

def concept_cleanup1(elem)
  elem.children.remove if elem&.children&.text&.strip&.empty?
  key_extract_locality(elem)
  if elem["key"].include?(":") then concept_termbase_cleanup(elem)
  elsif refid? elem["key"] then concept_eref_cleanup(elem)
  else concept_xref_cleanup(elem)
  end
  elem.delete("key")
end

#concept_eref_cleanup(elem) ⇒ Object



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

def concept_eref_cleanup(elem)
  t = elem.at("./xrefrender")&.remove&.children&.to_xml
  l = elem.at("./locality")&.remove&.children&.to_xml
  elem.add_child "<eref bibitemid='#{elem['key']}'>#{l}</eref>"
  extract_localities(elem.elements[-1])
  elem.elements[-1].add_child(t) if t
end

#concept_termbase_cleanup(elem) ⇒ Object



105
106
107
108
109
110
# File 'lib/metanorma/standoc/cleanup_inline.rb', line 105

def concept_termbase_cleanup(elem)
  t = elem&.at("./xrefrender")&.remove&.children
  termbase, key = elem["key"].split(":", 2)
  elem.add_child(%(<termref base="#{termbase}" target="#{key}">) +
                 "#{t&.to_xml}</termref>")
end

#concept_xref_cleanup(elem) ⇒ Object



112
113
114
115
# File 'lib/metanorma/standoc/cleanup_inline.rb', line 112

def concept_xref_cleanup(elem)
  t = elem&.at("./xrefrender")&.remove&.children
  elem.add_child(%(<xref target="#{elem['key']}">#{t&.to_xml}</xref>))
end

#contenthash(elem) ⇒ Object



191
192
193
194
# File 'lib/metanorma/standoc/cleanup_inline.rb', line 191

def contenthash(elem)
  Digest::MD5.hexdigest("#{elem.path}////#{elem.text}")
    .sub(/^(.{8})(.{4})(.{4})(.{4})(.{12})$/, "_\\1-\\2-\\3-\\4-\\5")
end

#contenthash_id_cleanup(doc) ⇒ Object



168
169
170
171
# File 'lib/metanorma/standoc/cleanup_inline.rb', line 168

def contenthash_id_cleanup(doc)
  ids = contenthash_id_make(doc)
  contenthash_id_update_refs(doc, ids)
end

#contenthash_id_make(doc) ⇒ Object



173
174
175
176
177
178
179
180
# File 'lib/metanorma/standoc/cleanup_inline.rb', line 173

def contenthash_id_make(doc)
  doc.xpath("//*[@id]").each_with_object({}) do |x, m|
    next unless Metanorma::Utils::guid_anchor?(x["id"])

    m[x["id"]] = contenthash(x)
    x["id"] = m[x["id"]]
  end
end

#contenthash_id_update_refs(doc, ids) ⇒ Object



182
183
184
185
186
187
188
189
# File 'lib/metanorma/standoc/cleanup_inline.rb', line 182

def contenthash_id_update_refs(doc, ids)
  [%w(review from), %w(review to), %w(callout target), %w(eref bibitemid),
   %w(citation bibitemid), %w(xref target), %w(xref to)].each do |a|
    doc.xpath("//#{a[0]}").each do |x|
      ids[x[a[1]]] and x[a[1]] = ids[x[a[1]]]
    end
  end
end

#create_amend(clause) ⇒ Object



10
11
12
13
14
15
16
17
# File 'lib/metanorma/standoc/cleanup_amend.rb', line 10

def create_amend(clause)
  a = clause.add_child("<amend id='_#{UUIDTools::UUID.random_create}'/>")
    .first
  clause.elements.each do |e|
    e.parent = a unless %w(amend title).include? e.name
  end
  create_amend1(clause, a)
end

#create_amend1(clause, amend) ⇒ Object



19
20
21
22
23
24
25
26
27
# File 'lib/metanorma/standoc/cleanup_amend.rb', line 19

def create_amend1(clause, amend)
  create_amend2(clause, amend)
  d = amend.at("./description")
  autonum = d.xpath(".//autonumber").map(&:remove)
  d.xpath(".//p[normalize-space(.)='']").each(&:remove)
  move_attrs_to_amend(clause, amend)
  autonum.each { |a| amend << a }
  amend
end

#create_amend2(_clause, amend) ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/metanorma/standoc/cleanup_amend.rb', line 29

def create_amend2(_clause, amend)
  q = amend.at("./quote") and q.name = "newcontent"
  if q.nil?
    amend.children = "<description>#{amend.children.to_xml}</description>"
    return
  end
  pre = q.xpath("./preceding-sibling::*")&.remove
  post = q.xpath("./following-sibling::*")&.remove
  pre.empty? or amend << "<description>#{pre.to_xml}</description>"
  amend << q.remove
  post.empty? or amend << "<description>#{post.to_xml}</description>"
end

#datauri_attachment(path, doc) ⇒ Object



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

def datauri_attachment(path, doc)
  @datauriattachment or return
  m = add_misc_container(doc)
  f = attachment_location(path)
  e = (m << "<attachment name='#{f}'/>").last_element_child
  Vectory::Utils::datauri(path, @localdir).scan(/.{1,60}/)
    .each { |dd| e << "#{dd}\n" }
  f
end

#dd_bib_extract(dtd) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/metanorma/standoc/cleanup_asciibib.rb', line 59

def dd_bib_extract(dtd)
  return nil if dtd.children.empty?

  dtd.at("./dl") and return dl_bib_extract(dtd)
  elems = dtd.remove.elements
  return p_unwrap(dtd) unless elems.size == 1 &&
    %w(ol ul).include?(elems[0].name)

  elems[0].xpath("./li").each_with_object([]) do |li, ret|
    ret << p_unwrap(li)
  end
end

#dl1_table_cleanup(xmldoc) ⇒ Object



4
5
6
7
8
9
# File 'lib/metanorma/standoc/cleanup_table.rb', line 4

def dl1_table_cleanup(xmldoc)
  q = "//table/following-sibling::*[1][self::dl]"
  xmldoc.xpath(q).each do |s|
    s["key"] == "true" and s.previous_element << s.remove
  end
end

#dl2_table_cleanup(xmldoc) ⇒ Object

move Key dl after table footer



12
13
14
15
16
17
18
19
20
21
# File 'lib/metanorma/standoc/cleanup_table.rb', line 12

def dl2_table_cleanup(xmldoc)
  q = "//table/following-sibling::*[1][self::p]"
  xmldoc.xpath(q).each do |s|
    if s.text =~ /^\s*key[^a-z]*$/i && s&.next_element&.name == "dl"
      s.next_element["key"] = "true"
      s.previous_element << s.next_element.remove
      s.remove
    end
  end
end

#dl_bib_extract(clause, nested = false) ⇒ Object

definition list, with at most one level of unordered lists



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/metanorma/standoc/cleanup_asciibib.rb', line 77

def dl_bib_extract(clause, nested = false)
  dl = clause.at("./dl") or return
  key = ""
  bib = dl.xpath("./dt | ./dd").each_with_object({}) do |dtd, m|
    (dtd.name == "dt" and key = dtd.text.sub(/:+$/, "")) and next
    add_to_hash(m, key, dd_bib_extract(dtd))
  end
  clause.xpath("./clause").each do |c1|
    key = c1&.at("./title")&.text&.downcase&.strip
    next unless %w(contributor relation series).include? key

    add_to_hash(bib, key, dl_bib_extract(c1, true))
  end
  dl_bib_extract_title(bib, clause, nested)
end

#dl_bib_extract_title(bib, clause, nested) ⇒ Object



93
94
95
96
97
98
99
100
101
# File 'lib/metanorma/standoc/cleanup_asciibib.rb', line 93

def dl_bib_extract_title(bib, clause, nested)
  (!nested && clause.at("./title")) or return bib
  title = clause.at("./title").remove.children.to_xml
  bib["title"] = [bib["title"]] if bib["title"].is_a?(Hash) ||
    bib["title"].is_a?(String)
  bib["title"] ||= []
  bib["title"] << title if !title.empty?
  bib
end

#dl_to_designation(dlist) ⇒ Object



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

def dl_to_designation(dlist)
  prev = dlist.previous_element
  unless %w(preferred admitted deprecates related).include? prev&.name
    @log.add("AsciiDoc Input", dlist, "Metadata definition list does " \
                                      "not follow a term designation")
    return nil
  end
  prev
end

#docidentifier_cleanup(xmldoc) ⇒ Object



118
# File 'lib/metanorma/standoc/cleanup.rb', line 118

def docidentifier_cleanup(xmldoc); end

#dt_bookmark_cleanup(xmldoc) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/metanorma/standoc/cleanup_inline.rb', line 59

def dt_bookmark_cleanup(xmldoc)
  xmldoc.xpath("//dt[descendant::bookmark]").each do |x|
    if x.at("./*[1][local-name() = 'p']/" \
            "*[1][local-name() = 'bookmark']") &&
        empty_text_before_first_element(x.elements[0])
      bookmark_to_id(x, x.elements[0].elements[0])
    elsif x.at("./*[1][local-name() = 'bookmark']") &&
        empty_text_before_first_element(x)
      bookmark_to_id(x, x.elements[0])
    end
  end
end

#dumb2smart_quotes(xmldoc) ⇒ Object



145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/metanorma/standoc/cleanup_text.rb', line 145

def dumb2smart_quotes(xmldoc)
  prev = ""
  xmldoc.traverse do |x|
    block?(x) and prev = ""
    empty_tag_with_text_content?(x) and prev = "dummy"
    x.text? or next

    # ancestors = x.path.gsub(/\[\d+\]/, "").split(%r{/})[1..-2]
    # ancestors.intersection(IGNORE_QUOTES_ELEMENTS).empty? or next
    ancestor_include?(x, IGNORE_QUOTES_ELEMENTS) and next
    dumb2smart_quotes1(x, prev)
    prev = x.text
  end
end

#dumb2smart_quotes1(curr, prev) ⇒ Object



160
161
162
163
164
165
166
# File 'lib/metanorma/standoc/cleanup_text.rb', line 160

def dumb2smart_quotes1(curr, prev)
  /[-'"(<>]|\.\.|\dx/.match?(curr.text) or return

  /\A["']/.match?(curr.text) && prev.match?(/\S\Z/) and
    curr.content = curr.text.sub(/\A"/, "").sub(/\A'/, "")
  curr.replace(Metanorma::Utils::smartformat(curr.text))
end

#dumbquote_cleanup(xmldoc) ⇒ Object



168
169
170
171
172
173
174
175
176
177
178
# File 'lib/metanorma/standoc/cleanup_text.rb', line 168

def dumbquote_cleanup(xmldoc)
  xmldoc.traverse do |n|
    next unless n.text? && /\u2019/.match?(n.text)

    n.replace(@c.encode(
                @c.decode(n.text)
      .gsub(/(?<=\p{Alnum})\u2019(?=\p{Alpha})/, "'"),
                :basic, :hexadecimal
              ))
  end
end

#element_name_cleanup(xmldoc) ⇒ Object



142
143
144
# File 'lib/metanorma/standoc/cleanup.rb', line 142

def element_name_cleanup(xmldoc)
  xmldoc.traverse { |n| n.name = n.name.tr("_", "-") }
end

#embed_recurse(bibitem, node) ⇒ Object



107
108
109
110
111
# File 'lib/metanorma/standoc/cleanup_bibdata.rb', line 107

def embed_recurse(bibitem, node)
  node[:child].map { |x| hdr2bibitem(x) }.each do |x|
    bibitem << "<relation type='derivedFrom'>#{x}</relation>"
  end
end

#empty_element_cleanup(xmldoc) ⇒ Object



134
135
136
137
138
139
140
# File 'lib/metanorma/standoc/cleanup.rb', line 134

def empty_element_cleanup(xmldoc)
  xmldoc.xpath("//#{TEXT_ELEMS.join(' | //')}").each do |x|
    next if x.name == "name" && x.parent.name == "expression"

    x.remove if x.children.empty?
  end
end

#empty_tag_with_text_content?(elem) ⇒ Boolean

Returns:

  • (Boolean)


141
142
143
# File 'lib/metanorma/standoc/cleanup_text.rb', line 141

def empty_tag_with_text_content?(elem)
  %w(eref xref termref link).include? elem.name
end

#empty_text_before_first_element(elem) ⇒ Object



8
9
10
11
12
13
14
# File 'lib/metanorma/standoc/cleanup_inline.rb', line 8

def empty_text_before_first_element(elem)
  elem.children.each do |c|
    return false if c.text? && /\S/.match(c.text)
    return true if c.element?
  end
  true
end

#endofpreface_clausebefore(xml, ins) ⇒ Object

only move clausebefore notes at the very end of preface



203
204
205
206
207
208
209
210
# File 'lib/metanorma/standoc/cleanup_section.rb', line 203

def endofpreface_clausebefore(xml, ins)
  xml.xpath("//preface//*[@beforeclauses = 'true']").reverse.each do |x|
    textafter = xml.xpath("//preface//*") & x.xpath("./following::*")
    textafter.text.strip.empty? or break
    x.delete("beforeclauses")
    ins.previous = x.remove
  end
end

#eref_stack(xmldoc) ⇒ Object



137
138
139
140
141
142
143
144
145
# File 'lib/metanorma/standoc/cleanup_xref.rb', line 137

def eref_stack(xmldoc)
  xmldoc.xpath("//eref[eref]").each do |e|
    e.name = "erefstack"
    e.delete("bibitemid")
    e.delete("citeas")
    e.xpath("./eref").each { |e1| e1["type"] = e["type"] }
    e.delete("type")
  end
end

#ext_contributor_cleanup(xmldoc) ⇒ Object



125
126
127
128
129
130
131
132
133
# File 'lib/metanorma/standoc/cleanup_bibdata.rb', line 125

def ext_contributor_cleanup(xmldoc)
  t = xmldoc.xpath("//metanorma-extension/clause/title").detect do |x|
    x.text.strip.casecmp("contributor metadata").zero?
  end or return
  a = t.at("../sourcecode") or return
  ins = xmldoc.at("//bibdata/contributor[last()]")
  yaml = YAML.safe_load(a.text, permitted_classes: [Date])
  ext_contributors_process(yaml, ins)
end

#ext_contributors_process(yaml, ins) ⇒ Object



143
144
145
146
147
148
149
150
# File 'lib/metanorma/standoc/cleanup_bibdata.rb', line 143

def ext_contributors_process(yaml, ins)
  yaml.is_a?(Hash) && !yaml["contributor"] and yaml = [yaml]
  yaml.is_a?(Array) and yaml = { "contributor" => yaml }
  r = yaml2relaton(yaml)
  Nokogiri::XML(r).xpath("//contributor").reverse_each do |c|
    ins.next = c
  end
end

#ext_dochistory_cleanup(xmldoc) ⇒ Object



13
14
15
16
17
18
19
20
21
22
# File 'lib/metanorma/standoc/cleanup_dochistory.rb', line 13

def ext_dochistory_cleanup(xmldoc)
  t = xmldoc.xpath("//metanorma-extension/clause/title").detect do |x|
    x.text.strip.casecmp("document history").zero?
  end or return
  a = t.at("../sourcecode") or return
  ins = bib_relation_insert_pt(xmldoc) or return
  docid = xmldoc.at("//bibdata/docidentifier")
  yaml = YAML.safe_load(a.text, permitted_classes: [Date])
  ext_dochistory_process(yaml, ins, docid)
end

#ext_dochistory_process(yaml, ins, docid) ⇒ Object



24
25
26
27
28
29
30
31
32
33
# File 'lib/metanorma/standoc/cleanup_dochistory.rb', line 24

def ext_dochistory_process(yaml, ins, docid)
  yaml.is_a?(Hash) and yaml = [yaml]
  yaml.reverse.each do |y|
    type = y["relation.type"] || "updatedBy"
    docid and
      y["docid"] ||= [{ "type" => docid["type"], "id" => docid.text }]
    r = yaml2relaton(y, amend_hash2mn(y["amend"]))
    ins.next = "<relation type='#{type}'>#{r}</relation>"
  end
end

#external_terms_boilerplate(sources) ⇒ Object



4
5
6
7
# File 'lib/metanorma/standoc/cleanup_terms_boilerplate.rb', line 4

def external_terms_boilerplate(sources)
  e = @i18n.external_terms_boilerplate
  e.gsub(/%(?=\p{P}|\p{Z}|$)/, sources || "???")
end

#extract_from_p(tag, bib, key) ⇒ Object



42
43
44
45
46
# File 'lib/metanorma/standoc/cleanup_asciibib.rb', line 42

def extract_from_p(tag, bib, key)
  return unless bib[tag]

  "<#{key}>#{bib[tag].at('p').children}</#{key}>"
end

#extract_localities(elem) ⇒ Object



35
36
37
38
39
40
41
42
43
# File 'lib/metanorma/standoc/cleanup_xref.rb', line 35

def extract_localities(elem)
  elem.children.empty? and return
  f = elem.children.first
  f.text? or return
  head = f.remove.text
  tail = elem.children.remove
  extract_localities1(elem, head)
  tail and elem << tail
end

#extract_localities1(elem, text) ⇒ Object



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

def extract_localities1(elem, text)
  re = to_regex(LOCALITY_REGEX_STR)
  b = elem.add_child("<localityStack/>").first if re.match text
  while (m = re.match locality_normalise(text))
    add_locality(b, m)
    text = extract_localities_update_text(m)
    b = elem.add_child("<localityStack/>").first if m[:punct] == ";"
  end
  fill_in_eref_connectives(elem)
  elem.add_child(text) if text
end

#extract_localities_update_text(match) ⇒ Object

clause=3;and!5 => clause=3;and!clause=5



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

def extract_localities_update_text(match)
  ret = match[:text]
  re = to_regex(LOCALITY_REGEX_VALUE_ONLY_STR)
  re.match?(ret) && match[:punct] == ";" and
    ret.sub!(%r{^(#{CONN_REGEX_STR})}o, "\\1#{match[:locality]}=")
  ret
end

#extract_notes_from_biblio(refs) ⇒ Object



37
38
39
40
41
42
43
44
# File 'lib/metanorma/standoc/cleanup_bibitem.rb', line 37

def extract_notes_from_biblio(refs)
  refs.xpath("./bibitem").each do |r|
    r.xpath("./note[@appended]").reverse_each do |n|
      n.delete("appended")
      r.next = n
    end
  end
end

#extract_symbols_list(dlist) ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
# File 'lib/metanorma/standoc/cleanup_symbols.rb', line 19

def extract_symbols_list(dlist)
  dl_out = []
  dlist.xpath("./dt | ./dd").each do |dtd|
    if dtd.name == "dt"
      dl_out << { dt: dtd.remove, key: symbol_key(dtd) }
    else
      dl_out.last[:dd] = dtd.remove
    end
  end
  dl_out
end

#fetch_local_bibitem(xmldoc) ⇒ Object

if citation uri points to local file, get bibitem from it



120
121
122
123
124
125
126
127
128
# File 'lib/metanorma/standoc/cleanup_bibitem.rb', line 120

def fetch_local_bibitem(xmldoc)
  xmldoc.xpath("//bibitem[formattedref][uri[@type = 'citation']]")
    .each do |b|
    uri = b&.at("./uri[@type = 'citation']")&.text
    bibitem = read_local_bibitem(uri) or next
    bibitem["id"] = b["id"]
    b.replace(bibitem)
  end
end

#fetch_termbase(_termbase, _id) ⇒ Object



95
96
97
# File 'lib/metanorma/standoc/cleanup_bibitem.rb', line 95

def fetch_termbase(_termbase, _id)
  ""
end

#figure_cleanup(xmldoc) ⇒ Object



87
88
89
90
91
92
93
# File 'lib/metanorma/standoc/cleanup_block.rb', line 87

def figure_cleanup(xmldoc)
  figure_footnote_cleanup(xmldoc)
  subfigure_cleanup(xmldoc)
  figure_dl_cleanup1(xmldoc)
  figure_dl_cleanup2(xmldoc)
  single_subfigure_cleanup(xmldoc)
end

#figure_dl_cleanup1(xmldoc) ⇒ Object



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

def figure_dl_cleanup1(xmldoc)
  q = "//figure/following-sibling::*[self::dl]"
  q1 = "//figure/figure/following-sibling::*[self::dl]"
  (xmldoc.xpath(q) - xmldoc.xpath(q1)).each do |s|
    s["key"] == "true" and s.previous_element << s.remove
  end
end

#figure_dl_cleanup2(xmldoc) ⇒ Object

include key definition list inside figure



57
58
59
60
61
62
63
64
65
66
# File 'lib/metanorma/standoc/cleanup_block.rb', line 57

def figure_dl_cleanup2(xmldoc)
  q = "//figure/following-sibling::*[self::p]"
  xmldoc.xpath(q).each do |s|
    if s.text =~ /^\s*key[^a-z]*$/i && s&.next_element&.name == "dl"
      s.next_element["key"] = "true"
      s.previous_element << s.next_element.remove
      s.remove
    end
  end
end

#figure_footnote_cleanup(xmldoc) ⇒ Object

include footnotes inside figure if they are the only content of the paras following



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/metanorma/standoc/cleanup_footnotes.rb', line 21

def figure_footnote_cleanup(xmldoc)
  nomatches = false
  until nomatches
    nomatches = true
    xmldoc.xpath(FIGURE_FN_XPATH).each do |s|
      next if s.children.map do |c|
                c.text? && /[[:alpha:]]/.match(c.text)
              end.any?

      s.previous_element << s.first_element_child.remove
      s.remove
      nomatches = false
    end
  end
end

#fill_in_eref_connectives(elem) ⇒ Object



94
95
96
97
98
99
100
101
102
# File 'lib/metanorma/standoc/cleanup_xref.rb', line 94

def fill_in_eref_connectives(elem)
  elem.xpath("./localityStack").size < 2 and return
  elem.xpath("./localityStack[not(@connective)]").each do |l|
    n = l.next_element
    l["connective"] = "and"
    n && n.name == "localityStack" && n["connective"] == "to" and
      l["connective"] = "from"
  end
end

#floating_title_preface2sections(xmldoc) ⇒ Object



238
239
240
241
242
243
# File 'lib/metanorma/standoc/cleanup_section.rb', line 238

def floating_title_preface2sections(xmldoc)
  t = xmldoc.at("//preface/floating-title") or return
  s = xmldoc.at("//sections")
  t.next_element or
    s.children.first.previous = t.remove
end

#floatingtitle_cleanup(xmldoc) ⇒ Object



220
221
222
223
# File 'lib/metanorma/standoc/cleanup_section.rb', line 220

def floatingtitle_cleanup(xmldoc)
  pop_floating_title(xmldoc) # done again, after endofpreface_clausebefore
  floating_title_preface2sections(xmldoc)
end

#fold_notes_into_biblio(refs) ⇒ Object



28
29
30
31
32
33
34
35
# File 'lib/metanorma/standoc/cleanup_bibitem.rb', line 28

def fold_notes_into_biblio(refs)
  refs.xpath("./bibitem").each do |r|
    while r&.next_element&.name == "note"
      r.next_element["appended"] = true
      r << r.next_element.remove
    end
  end
end

#footnote_block_cleanup(xmldoc) ⇒ Object



96
97
98
99
100
101
102
103
104
105
106
# File 'lib/metanorma/standoc/cleanup_footnotes.rb', line 96

def footnote_block_cleanup(xmldoc)
  ids = xmldoc.xpath("//footnoteblock").each_with_object([]) do |f, m|
    f.name = "fn"
    m << f.text
    if id = xmldoc.at("//*[@id = '#{f.text}']")
      f.children = id.dup.children
    else footnote_block_error(f)
    end
  end
  footnote_block_remove(xmldoc, ids)
end

#footnote_block_error(fnote) ⇒ Object



115
116
117
118
119
# File 'lib/metanorma/standoc/cleanup_footnotes.rb', line 115

def footnote_block_error(fnote)
  @log.add("Crossreferences", fnote,
           "Could not resolve footnoteblock:[#{fnote.text}]", severity: 1)
  fnote.children = "[ERROR]"
end

#footnote_block_remove(xmldoc, ids) ⇒ Object



108
109
110
111
112
113
# File 'lib/metanorma/standoc/cleanup_footnotes.rb', line 108

def footnote_block_remove(xmldoc, ids)
  ids.each do |id|
    n = xmldoc.at("//*[@id = '#{id}']") and
      n.remove
  end
end

#footnote_cleanup(xmldoc) ⇒ Object



121
122
123
124
125
126
127
128
129
# File 'lib/metanorma/standoc/cleanup_footnotes.rb', line 121

def footnote_cleanup(xmldoc)
  footnote_block_cleanup(xmldoc)
  title_footnote_move(xmldoc)
  table_footnote_renumber(xmldoc)
  other_footnote_renumber(xmldoc)
  xmldoc.xpath("//fn").each do |fn|
    fn.delete("table")
  end
end

#footnote_content(fnote) ⇒ Object



8
9
10
11
12
13
14
# File 'lib/metanorma/standoc/cleanup_footnotes.rb', line 8

def footnote_content(fnote)
  c = if fnote.children.respond_to?(:to_xml)
        fnote.children.to_xml
      else fn.children
      end
  c.gsub(/ id="[^"]+"/, "")
end

#form_cleanup(xmldoc) ⇒ Object



171
172
173
174
175
176
177
# File 'lib/metanorma/standoc/cleanup_block.rb', line 171

def form_cleanup(xmldoc)
  xmldoc.xpath("//select").each do |s|
    while s.next_element&.name == "option"
      s << s.next_element
    end
  end
end

#format_ref(ref, type) ⇒ Object



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

def format_ref(ref, type)
  ret = Nokogiri::XML.fragment(ref)
  ret.traverse { |x| x.remove if x.name == "fn" }
  ref = to_xml(ret)
  type != "metanorma" and return @isodoc.docid_prefix(type, ref)
  /^\d+$/.match(ref) && !/^\[.*\]$/.match(ref) and return "[#{ref}]"
  ref
end

#formattedref_spans(xmldoc) ⇒ Object



4
5
6
7
8
9
# File 'lib/metanorma/standoc/cleanup_bibitem.rb', line 4

def formattedref_spans(xmldoc)
  xmldoc.xpath("//bibitem[formattedref//span]").each do |b|
    ret = new_bibitem_from_formattedref_spans(b)
    merge_bibitem_from_formattedref_spans(b, ret)
  end
end

#formula_cleanup(formula) ⇒ Object

include where definition list inside stem block



25
26
27
28
# File 'lib/metanorma/standoc/cleanup_block.rb', line 25

def formula_cleanup(formula)
  formula_cleanup_where1(formula)
  formula_cleanup_where2(formula)
end

#formula_cleanup_where1(formula) ⇒ Object



30
31
32
33
34
35
# File 'lib/metanorma/standoc/cleanup_block.rb', line 30

def formula_cleanup_where1(formula)
  q = "//formula/following-sibling::*[1][self::dl]"
  formula.xpath(q).each do |s|
    s["key"] == "true" and s.previous_element << s.remove
  end
end

#formula_cleanup_where2(formula) ⇒ Object



37
38
39
40
41
42
43
44
45
46
# File 'lib/metanorma/standoc/cleanup_block.rb', line 37

def formula_cleanup_where2(formula)
  q = "//formula/following-sibling::*[1][self::p]"
  formula.xpath(q).each do |s|
    if s.text =~ /^\s*where[^a-z]*$/i && s&.next_element&.name == "dl"
      s.next_element["key"] = "true"
      s.previous_element << s.next_element.remove
      s.remove
    end
  end
end

#gather_indirect_erefs(xmldoc, prefix) ⇒ Object



27
28
29
30
31
32
33
# File 'lib/metanorma/standoc/cleanup_bibdata.rb', line 27

def gather_indirect_erefs(xmldoc, prefix)
  xmldoc.xpath("//eref[@type = '#{prefix}']")
    .each_with_object({}) do |e, m|
    e.delete("type")
    m[e["bibitemid"]] = true
  end.keys
end

#gather_text_for_linebreak_cleanup(block) ⇒ Object



58
59
60
61
62
63
64
65
66
67
# File 'lib/metanorma/standoc/cleanup_text.rb', line 58

def gather_text_for_linebreak_cleanup(block)
  x = block.xpath(".//text()").map do |e|
    { elem: e, text: e.text,
      skip: ancestor_include?(e, PRESERVE_LINEBREAK_ELEMENTS) }
  end
  x.empty? and return x
  x.each { |e| e[:skip] ||= !e[:text].include?("\n") }
  x[-1][:last] = true
  x
end

#gather_unitsml(unitsml, xmldoc, tag) ⇒ Object



114
115
116
117
118
119
120
121
122
# File 'lib/metanorma/standoc/cleanup_maths.rb', line 114

def gather_unitsml(unitsml, xmldoc, tag)
  tags = xmldoc.xpath(".//m:#{tag}", "m" => UNITSML_NS)
    .each_with_object({}) do |x, m|
    m[x["xml:id"]] = x.remove
  end
  tags.empty? and return
  set = unitsml.add_child("<#{tag}Set/>").first
  tags.each_value { |v| set << v }
end

#generate_termdefinitions(xmldoc) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
# File 'lib/metanorma/standoc/cleanup_terms.rb', line 33

def generate_termdefinitions(xmldoc)
  xmldoc.xpath("//term[not(definition)]").each do |d|
    first_child = d.at(TERMDEF_BLOCKS) || next
    t = Nokogiri::XML::Element.new("definition", xmldoc)
    first_child.replace(t)
    t << first_child.remove
    d.xpath(TERMDEF_BLOCKS).each do |n|
      t << n.remove
    end
  end
end

#get_or_make_title(node) ⇒ Object



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

def get_or_make_title(node)
  unless node.at("./title")
    if node.children.empty?
      node << "<title/>"
    else
      node.children.first.previous = "<title/>"
    end
  end
  node.at("./title")
end

#hdr2bibitem(hdr) ⇒ Object



89
90
91
92
93
94
95
96
97
98
# File 'lib/metanorma/standoc/cleanup_bibdata.rb', line 89

def hdr2bibitem(hdr)
  xml = Asciidoctor
    .convert(hdr[:text], backend: hdr2bibitem_type(hdr),
                         header_footer: true)
  b = Nokogiri::XML(xml).at("//xmlns:bibdata")
  b.name = "bibitem"
  b.delete("type")
  embed_recurse(b, hdr)
  b.to_xml
end

#hdr2bibitem_type(hdr) ⇒ Object



100
101
102
103
104
105
# File 'lib/metanorma/standoc/cleanup_bibdata.rb', line 100

def hdr2bibitem_type(hdr)
  m = /:mn-document-class: (\S+)/.match(hdr[:text])
  if m then m[1].to_sym
  else Processor.new.asciidoctor_backend
  end
end

#header_rows_cleanup(xmldoc) ⇒ Object



33
34
35
36
37
38
39
40
41
42
# File 'lib/metanorma/standoc/cleanup_table.rb', line 33

def header_rows_cleanup(xmldoc)
  xmldoc.xpath("//table[@headerrows]").each do |s|
    thead = insert_thead(s)
    (thead.xpath("./tr").size...s["headerrows"].to_i).each do
      s.at("./tbody/tr").parent = thead
    end
    thead.xpath(".//td").each { |n| n.name = "th" }
    s.delete("headerrows")
  end
end

#idtype2cit(ref) ⇒ Object



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

def idtype2cit(ref)
  ref.xpath("./docidentifier/@type").each_with_object({}) do |t, m|
    m[t.text] and next
    docid = select_docid(ref, t.text) or next
    m[t.text] = format_ref(docid.children.to_xml, docid["type"])
  end
end

#ignoretext?(elem) ⇒ Boolean

Returns:

  • (Boolean)


128
129
130
# File 'lib/metanorma/standoc/cleanup_text.rb', line 128

def ignoretext?(elem)
  IGNORE_TEXT_ELEMENTS.include? elem.name
end

#img_cleanup(xmldoc) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/metanorma/standoc/cleanup_image.rb', line 57

def img_cleanup(xmldoc)
  if @datauriimage
    xmldoc.xpath("//image").each do |i|
      # do not datauri encode SVG, we need to deduplicate its IDs
      unless read_in_if_svg(i, @localdir)
        i["src"] = Vectory::Utils::datauri(i["src"], @localdir)
      end
    end
  end
  svg_cleanup(xmldoc)
  xmldoc
end

#include_indexterm?(elem) ⇒ Boolean

Returns:

  • (Boolean)


198
199
200
201
# File 'lib/metanorma/standoc/cleanup_block.rb', line 198

def include_indexterm?(elem)
  elem.nil? and return false
  !%w(image literal sourcecode).include?(elem.name)
end

#index_cleanup1(term, fieldofappl) ⇒ Object



142
143
144
145
146
147
# File 'lib/metanorma/standoc/cleanup_terms.rb', line 142

def index_cleanup1(term, fieldofappl)
  term or return
  idx = term.children.dup
  fieldofappl.empty? or idx << ", &#x3c;#{fieldofappl}&#x3e;"
  term << "<index><primary>#{idx.to_xml}</primary></index>"
end

#indexterm_para?(para) ⇒ Boolean

Returns:

  • (Boolean)


192
193
194
195
196
# File 'lib/metanorma/standoc/cleanup_block.rb', line 192

def indexterm_para?(para)
  p = para.dup
  p.xpath("./index").each(&:remove)
  p.text.strip.empty?
end

#indirect_eref_to_xref(eref, ident) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/metanorma/standoc/cleanup_bibdata.rb', line 48

def indirect_eref_to_xref(eref, ident)
  loc = eref.at("./localityStack[locality[@type = 'anchor']]") ||
    eref.at("./locality[@type = 'anchor']")
  loc = loc&.remove&.text || ident
  eref.name = "xref"
  eref.delete("bibitemid")
  eref.delete("citeas")
  eref["target"] = loc
  eref.document.at("//*[@id = '#{loc}']") and return
  eref.children = %(** Missing target #{loc})
  eref["target"] = ident
end

#init_attachmentsObject



195
196
197
198
199
200
201
# File 'lib/metanorma/standoc/cleanup_bibitem.rb', line 195

def init_attachments
  @attachmentsdir and return
  @attachmentsfld = "_#{@filename}_attachments"
  @attachmentsdir = File.join(@output_dir, @attachmentsfld)
  FileUtils.rm_rf(@attachmentsdir)
  FileUtils.mkdir_p(@attachmentsdir)
end

#initial_boilerplate(xml, isodoc) ⇒ Object



78
79
80
81
82
83
84
# File 'lib/metanorma/standoc/cleanup_boilerplate.rb', line 78

def initial_boilerplate(xml, isodoc)
  xml.at("//boilerplate") and return
  preface = xml.at("//preface | //sections | //annex | //references") or
    return
  b = boilerplate(xml, isodoc) or return
  preface.previous = b
end

#inject_id(xmldoc, path) ⇒ Object



18
19
20
21
22
# File 'lib/metanorma/standoc/cleanup_block.rb', line 18

def inject_id(xmldoc, path)
  xmldoc.xpath(path).each do |x|
    x["id"] ||= Metanorma::Utils::anchor_or_uuid
  end
end

#insert_before(xmldoc, xpath) ⇒ Object



212
213
214
215
216
217
218
# File 'lib/metanorma/standoc/cleanup_section.rb', line 212

def insert_before(xmldoc, xpath)
  unless ins = xmldoc.at(xpath).children.first
    xmldoc.at(xpath) << " "
    ins = xmldoc.at(xpath).children.first
  end
  ins
end

#insert_hidden_bibitems(bib) ⇒ Object



86
87
88
89
90
91
# File 'lib/metanorma/standoc/cleanup_ref.rb', line 86

def insert_hidden_bibitems(bib)
  refs = bib.each_with_object([]) do |b, m|
    m << reference1code(%(<ref id="#{b[:id]}">[#{b[:ref]}]</ref>), nil)
  end
  reference_populate(refs)
end

#insert_indirect_biblio(xmldoc, refs, prefix) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/metanorma/standoc/cleanup_bibdata.rb', line 35

def insert_indirect_biblio(xmldoc, refs, prefix)
  i = xmldoc.at("bibliography") or
    xmldoc.root << "<bibliography/>" and i = xmldoc.at("bibliography")
  i = i.add_child("<references hidden='true' normative='false'/>").first
  refs.each do |x|
    i << <<~BIB
      <bibitem id="#{x}" type="internal">
      <docidentifier type="repository">#{x.sub(/^#{prefix}_/, "#{prefix}/")}</docidentifier>
      </bibitem>
    BIB
  end
end

#insert_thead(table) ⇒ Object



23
24
25
26
27
28
29
30
31
# File 'lib/metanorma/standoc/cleanup_table.rb', line 23

def insert_thead(table)
  thead = table.at("./thead")
  thead.nil? or return thead
  if tname = table.at("./name")
    thead = tname.add_next_sibling("<thead/>").first
    return thead
  end
  table.children.first.add_previous_sibling("<thead/>").first
end

#internal_external_terms_boilerplate(sources) ⇒ Object



9
10
11
12
# File 'lib/metanorma/standoc/cleanup_terms_boilerplate.rb', line 9

def internal_external_terms_boilerplate(sources)
  e = @i18n.internal_external_terms_boilerplate
  e.gsub(/%(?=\p{P}|\p{Z}|$)/, sources || "??")
end

#key_extract_locality(elem) ⇒ Object



99
100
101
102
103
# File 'lib/metanorma/standoc/cleanup_inline.rb', line 99

def key_extract_locality(elem)
  elem["key"].include?(",") or return
  elem.add_child("<locality>#{elem['key'].sub(/^[^,]+,/, '')}</locality>")
  elem["key"] = elem["key"].sub(/(^[^,]+),.*$/, "\\1")
end

#li_bookmark_cleanup(xmldoc) ⇒ Object



49
50
51
52
53
54
55
56
57
# File 'lib/metanorma/standoc/cleanup_inline.rb', line 49

def li_bookmark_cleanup(xmldoc)
  xmldoc.xpath("//li[descendant::bookmark]").each do |x|
    if x.at("./*[1][local-name() = 'p']/" \
            "*[1][local-name() = 'bookmark']") &&
        empty_text_before_first_element(x.elements[0])
      bookmark_to_id(x, x.elements[0].elements[0])
    end
  end
end

#linebreak_cleanup(xmldoc) ⇒ Object

process example/p, example/sourcecode, not example on its own: this is about stripping lines for blocks containing inline elems & text



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

def linebreak_cleanup(xmldoc)
  xmldoc.traverse do |x|
    x.text? && x.text.include?("\n") or next
    ancestor_include?(x, PRESERVE_LINEBREAK_ELEMENTS) and next
    ancestor_include?(x, STRIP_LINEBREAK_ELEMENTS) or next
    x.replace(Metanorma::Utils
      .line_sanitise(x.text.lines.map(&:rstrip)).join)
  end
end

#linebreak_cleanup_block(block) ⇒ Object



40
41
42
43
44
45
46
47
48
# File 'lib/metanorma/standoc/cleanup_text.rb', line 40

def linebreak_cleanup_block(block)
  block.each_with_index do |e, i|
    e[:skip] and next
    lines = lines_strip_textspan(e, block[i + 1])
    out = Metanorma::Utils.line_sanitise(lines)
    e[:last] or out.pop
    e[:elem].replace(out.join)
  end
end

#lines_strip_textspan(span, nextspan) ⇒ Object



50
51
52
53
54
55
56
# File 'lib/metanorma/standoc/cleanup_text.rb', line 50

def lines_strip_textspan(span, nextspan)
  lines = span[:text].lines[0..-2].map(&:rstrip) <<
    span[:text].lines[-1]&.sub(/\n$/, "")
  # no final line rstrip: can be space linking to next line
  span[:last] or lines << nextspan[:text].lines.first # next token context
  lines
end


113
114
115
116
117
118
# File 'lib/metanorma/standoc/cleanup_block.rb', line 113

def link_callouts_to_annotations(callouts, annotations)
  callouts.each_with_index do |c, i|
    c["target"] = "_#{UUIDTools::UUID.random_create}"
    annotations[i]["id"] = c["target"]
  end
end


206
207
208
# File 'lib/metanorma/standoc/cleanup_inline.rb', line 206

def link_cleanup(xmldoc)
  uri_cleanup(xmldoc)
end

#locality_label(match) ⇒ Object



104
105
106
107
# File 'lib/metanorma/standoc/cleanup_xref.rb', line 104

def locality_label(match)
  loc = match[:locality] || match[:locality2]
  /^locality:/.match?(loc) ? loc : loc&.downcase
end

#locality_normalise(text) ⇒ Object

treat n-n-n locality as “n-n-n”, do not parse as a range



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

def locality_normalise(text)
  re = to_regex(LOCALITY_REGEX_STR_TRIPLEDASH)
  m = re.match(text) and
    text = %(#{m[:locality]}"#{m[:ref]}"#{m[:text]})
  text
end

#make_abstract(xml, sect) ⇒ Object



36
37
38
39
40
41
42
43
44
45
# File 'lib/metanorma/standoc/cleanup_section.rb', line 36

def make_abstract(xml, sect)
  if xml.at("//abstract[not(ancestor::bibitem)]")
    preface = sect.at("//preface") ||
      sect.add_previous_sibling("<preface/>").first
    abstract = xml.at("//abstract[not(ancestor::bibitem)]").remove
    preface.prepend_child abstract.remove
    bibabstract = bibabstract_location(xml)
    bibabstract.next = clean_abstract(abstract.dup)
  end
end

#make_annexes(xml) ⇒ Object



93
94
95
96
97
98
99
100
101
102
103
# File 'lib/metanorma/standoc/cleanup_section.rb', line 93

def make_annexes(xml)
  xml.xpath("//*[@annex]").each do |y|
    y.delete("annex")
    y.name == "annex" || !y.ancestors("annex").empty? and next
    y.wrap("<annex/>")
    y.parent["id"] = "_#{UUIDTools::UUID.random_create}"
    %w(obligation language script).each do |w|
      y.parent[w] = y[w]
    end
  end
end

#make_bibliography(xml, sect) ⇒ Object



67
68
69
70
71
72
73
74
# File 'lib/metanorma/standoc/cleanup_section.rb', line 67

def make_bibliography(xml, sect)
  if xml.at("//sections/references | //xref[@hidden]")
    biblio = sect.add_next_sibling("<bibliography/>").first
    xml.xpath("//sections/references").each do |r|
      biblio.add_child r.remove
    end
  end
end

#make_colophon(xml) ⇒ Object



27
28
29
30
31
32
33
34
# File 'lib/metanorma/standoc/cleanup_section.rb', line 27

def make_colophon(xml)
  xml.at("//clause[@colophon]") or return
  colophon = xml.root.add_child("<colophon/>").first
  xml.xpath("//*[@colophon]").each do |c|
    c.delete("colophon")
    colophon.add_child c.remove
  end
end

#make_indexsect(xml, sect) ⇒ Object



76
77
78
79
80
# File 'lib/metanorma/standoc/cleanup_section.rb', line 76

def make_indexsect(xml, sect)
  xml.xpath("//sections/indexsect").reverse_each do |r|
    sect.next = r.remove
  end
end

#make_preface(xml, sect) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
# File 'lib/metanorma/standoc/cleanup_section.rb', line 6

def make_preface(xml, sect)
  if xml.at("//foreword | //introduction | //acknowledgements | " \
            "//*[@preface]")
    preface = sect.add_previous_sibling("<preface/>").first
    f = xml.at("//foreword") and to_preface(preface, f)
    f = xml.at("//introduction") and to_preface(preface, f)
    move_clauses_into_preface(xml, preface)
    f = xml.at("//acknowledgements") and to_preface(preface, f)
  end
  make_abstract(xml, sect)
end

#mathml_cleanup(xmldoc) ⇒ Object



181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/metanorma/standoc/cleanup_maths.rb', line 181

def mathml_cleanup(xmldoc)
  a2u = Asciimath2UnitsML::Conv.new(asciimath2unitsml_options)
  xmldoc.xpath("//stem[@type = 'MathML'][not(@validate = 'false')]")
    .each do |x|
    mathml_xml_cleanup(x)
    a2u.MathML2UnitsML(x)
    mathml_mathvariant(x)
  end
  xmldoc.xpath("//stem[@type = 'MathML']")
    .each { |x| mathml_number_format(x) }
  mathml_unitsml(xmldoc)
end

#mathml_italicise(xml) ⇒ Object

presuppose multichar mi upright, singlechar mi MathML default italic



10
11
12
13
14
15
16
# File 'lib/metanorma/standoc/cleanup_mathvariant.rb', line 10

def mathml_italicise(xml)
  xml.xpath(".//m:mi[not(ancestor::*[@mathvariant])]",
            "m" => MATHML_NS).each do |i|
    char = @c.decode(i.text)
    i["mathvariant"] = "normal" if mi_italicise?(char)
  end
end

#mathml_mathvariant(math) ⇒ Object



77
78
79
80
81
82
83
84
85
# File 'lib/metanorma/standoc/cleanup_mathvariant.rb', line 77

def mathml_mathvariant(math)
  math.xpath(".//*[@mathvariant]").each do |outer|
    outer.xpath(".//*[@mathvariant]").each do |inner|
      inner["mathvariant"] =
        mathvariant_override(inner["mathvariant"], outer["mathvariant"])
    end
  end
  mathml_italicise(math)
end

#mathml_mi_italicsObject



4
5
6
7
# File 'lib/metanorma/standoc/cleanup_mathvariant.rb', line 4

def mathml_mi_italics
  { uppergreek: true, upperroman: true,
    lowergreek: true, lowerroman: true }
end

#mathml_mn_format(math) ⇒ Object



128
129
130
131
132
133
134
135
136
137
138
# File 'lib/metanorma/standoc/cleanup_maths.rb', line 128

def mathml_mn_format(math)
  math["number-format"] or return
  math.xpath(".//m:mn", "m" => MATHML_NS).each do |m|
    profile = mathml_mn_profile(m)
    attr = profile.each_with_object([]) do |(k, v), acc|
      v == "nil" and next
      acc << "#{k}='#{@c.decode v}'"
    end.join(",")
    attr.empty? or m["data-metanorma-numberformat"] = attr
  end
end

#mathml_mn_profile(mnum) ⇒ Object



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

def mathml_mn_profile(mnum)
  fmt = @numberfmt_default&.dup || {}
  fmt1 = {}
  fmt2 = kv_parse(mnum["data-metanorma-numberformat"] || "")
  if fmt2["profile"]
    fmt1 = @numberfmt_prof[fmt2["profile"]] || {}
    fmt2.delete("profile")
  end
  fmt.merge(fmt1).merge(fmt2)
end

#mathml_namespace(stem) ⇒ Object



88
89
90
91
92
# File 'lib/metanorma/standoc/cleanup_maths.rb', line 88

def mathml_namespace(stem)
  stem.xpath("./*[local-name() = 'math']").each do |x|
    x.default_namespace = MATHML_NS
  end
end

#mathml_number_format(stem) ⇒ Object



175
176
177
178
179
# File 'lib/metanorma/standoc/cleanup_maths.rb', line 175

def mathml_number_format(stem)
  mathml_stem_format(stem)
  mathml_mn_format(stem)
  stem.delete("number-format")
end

#mathml_preserve_space(math) ⇒ Object



81
82
83
84
85
86
# File 'lib/metanorma/standoc/cleanup_maths.rb', line 81

def mathml_preserve_space(math)
  math.xpath(".//m:mtext", "m" => MATHML_NS).each do |x|
    x.children = x.children.to_xml
      .gsub(/^\s/, "&#xA0;").gsub(/\s$/, "&#xA0;")
  end
end

#mathml_stem_format(stem) ⇒ Object



151
152
153
154
155
156
157
158
159
160
# File 'lib/metanorma/standoc/cleanup_maths.rb', line 151

def mathml_stem_format(stem)
  f = mathml_stem_format_attr(stem) or return
  attr = quoted_csv_split(f, ",").map do |x|
    m = /^(.+?)=(.+)?$/.match(x) or next
    "#{m[1]}='#{@c.decode m[2]}'"
  end.join(",")
  stem.xpath(".//m:mn", "m" => MATHML_NS).each do |m|
    attr.empty? or m["data-metanorma-numberformat"] = attr
  end
end

#mathml_stem_format_attr(stem) ⇒ Object



162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/metanorma/standoc/cleanup_maths.rb', line 162

def mathml_stem_format_attr(stem)
  f = stem["number-format"] || @numberfmt_formula or return
  if f == "nil"
    stem.delete("number-format")
    return
  end
  f == "default" or return f
  if @numberfmt_default.empty?
    "notation='basic'"
  else @numberfmt_default&.map { |k, v| "#{k}='#{v}'" }&.join(",")
  end
end

#mathml_unitsml(xmldoc) ⇒ Object



105
106
107
108
109
110
111
112
# File 'lib/metanorma/standoc/cleanup_maths.rb', line 105

def mathml_unitsml(xmldoc)
  xmldoc.at(".//m:*", "m" => UNITSML_NS) or return
  misc = add_misc_container(xmldoc)
  unitsml = misc.add_child("<UnitsML xmlns='#{UNITSML_NS}'/>").first
  %w(Unit CountedItem Quantity Dimension Prefix).each do |t|
    gather_unitsml(unitsml, xmldoc, t)
  end
end

#mathml_xml_cleanup(stem) ⇒ Object



62
63
64
65
66
# File 'lib/metanorma/standoc/cleanup_maths.rb', line 62

def mathml_xml_cleanup(stem)
  xml_unescape_mathml(stem)
  mathml_namespace(stem)
  mathml_preserve_space(stem)
end

#mathvariant_override(inner, outer) ⇒ Object



70
71
72
73
74
75
# File 'lib/metanorma/standoc/cleanup_mathvariant.rb', line 70

def mathvariant_override(inner, outer)
  o = outer.to_sym
  i = inner.to_sym
  MATHVARIANT_OVERRIDE[o] or return inner
  MATHVARIANT_OVERRIDE[o][i] || inner
end

#maxlevel(xml) ⇒ Object



105
106
107
108
109
110
111
# File 'lib/metanorma/standoc/cleanup_section.rb', line 105

def maxlevel(xml)
  max = 5
  xml.xpath("//clause[@level]").each do |c|
    max = c["level"].to_i if max < c["level"].to_i
  end
  max
end

#merge_annotations_into_sourcecode(xmldoc) ⇒ Object



129
130
131
132
133
134
135
# File 'lib/metanorma/standoc/cleanup_block.rb', line 129

def merge_annotations_into_sourcecode(xmldoc)
  xmldoc.xpath("//sourcecode").each do |x|
    while x.next_element&.name == "annotation"
      x.next_element.parent = x
    end
  end
end

#merge_bibitem_from_formattedref_spans(bib, new) ⇒ Object



19
20
21
22
23
24
25
26
# File 'lib/metanorma/standoc/cleanup_bibitem.rb', line 19

def merge_bibitem_from_formattedref_spans(bib, new)
  new["type"] and bib["type"] = new["type"]
  if bib.at("./title") # there already is a fetched record here: merge
    bib.children = MergeBibitems
      .new(bib.to_xml, new.to_xml).merge.to_noko.children
  else bib << new.children.to_xml
  end
end

#merge_boilerplate_files(built_in, user_add) ⇒ Object



113
114
115
116
117
118
# File 'lib/metanorma/standoc/cleanup_boilerplate.rb', line 113

def merge_boilerplate_files(built_in, user_add)
  %w(copyright license legal feedback).each do |w|
    resolve_boilerplate_statement(built_in, user_add, w)
  end
  to_xml(built_in)
end

#metadata_cleanup(xmldoc) ⇒ Object



190
191
192
193
194
# File 'lib/metanorma/standoc/cleanup.rb', line 190

def (xmldoc)
  (@metadata_attrs.nil? || @metadata_attrs.empty?) and return
  ins = add_misc_container(xmldoc)
  ins << @metadata_attrs
end

#mi_italicise?(char) ⇒ Boolean

Returns:

  • (Boolean)


18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/metanorma/standoc/cleanup_mathvariant.rb', line 18

def mi_italicise?(char)
  char.length > 1 and return false
  case char
  when /\p{Greek}/
    (/\p{Lower}/.match(char) && !mathml_mi_italics[:lowergreek]) ||
      (/\p{Upper}/.match(char) && !mathml_mi_italics[:uppergreek])
  when /\p{Latin}/
    (/\p{Lower}/.match(char) && !mathml_mi_italics[:lowerroman]) ||
      (/\p{Upper}/.match(char) && !mathml_mi_italics[:upperroman])
  else false
  end
end

#misccontainer_cleanup(xml) ⇒ Object



133
134
135
136
137
# File 'lib/metanorma/standoc/cleanup_section.rb', line 133

def misccontainer_cleanup(xml)
  m = xml.at("//misc-container-clause") or return
  ins = add_misc_container(xml)
  ins << m.remove.children
end

#move_attrs_to_amend(clause, amend) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/metanorma/standoc/cleanup_amend.rb', line 42

def move_attrs_to_amend(clause, amend)
  %w(change path path_end title).each do |e|
    next unless clause[e]

    amend[e] = clause[e]
    clause.delete(e)
  end
  return unless amend["locality"]

  loc = amend.children.add_previous_sibling("<location/>")
  extract_localities1(loc, amend["locality"])
  loc1 = loc.at("./localityStack") and loc.replace(loc1.elements)
  amend.delete("locality")
end

#move_clauses_into_preface(xml, preface) ⇒ Object



18
19
20
# File 'lib/metanorma/standoc/cleanup_section.rb', line 18

def move_clauses_into_preface(xml, preface)
  xml.xpath("//*[@preface]").each { |c| to_preface(preface, c) }
end

#new_bibitem_from_formattedref_spans(bib) ⇒ Object



11
12
13
14
15
16
17
# File 'lib/metanorma/standoc/cleanup_bibitem.rb', line 11

def new_bibitem_from_formattedref_spans(bib)
  ret = SpansToBibitem.new(bib).convert
  ret.err.each do |e|
    @log.add("Bibliography", bib, e[:msg], severity: e[:fatal] ? 0 : 1)
  end
  ret.out
end

#norm_ref_boilerplate_insert_location(ref) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
# File 'lib/metanorma/standoc/cleanup_boilerplate.rb', line 27

def norm_ref_boilerplate_insert_location(ref)
  while (n = ref.parent) && %w(clause references).include?(n&.name)
    n.elements.detect do |e|
      !%(title references).include?(e.name) &&
        !e.at("./self::clause[@type = 'boilerplate']") &&
        !e.at("./self::clause[.//references][not(.//clause[not(.//bibitem)])]")
    end and break
    ref = n
  end
  ref.at("./title")
end

#norm_ref_preface(ref) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
# File 'lib/metanorma/standoc/cleanup_boilerplate.rb', line 6

def norm_ref_preface(ref)
  ins = norm_ref_boilerplate_insert_location(ref)
  ins2 = norm_ref_process_boilerplate_note(ref)
  ins2 == :populated and return
  ins2 == :missing or ins = ins2
  refs = ref.elements.select do |e|
    %w(references bibitem).include? e.name
  end
  pref = refs.empty? ? @i18n.norm_empty_pref : @i18n.norm_with_refs_pref
  ins.next = boilerplate_snippet_convert(pref)
end

#norm_ref_process_boilerplate_note(ref) ⇒ Object



18
19
20
21
22
23
24
25
# File 'lib/metanorma/standoc/cleanup_boilerplate.rb', line 18

def norm_ref_process_boilerplate_note(ref)
  ins2 = ref.at("./note[@type = 'boilerplate']") or return :missing
  if ins2 && ins2.text.strip.downcase == "(default)"
    ins2.children = " "
    ins2.children.first
  else :populated
  end
end

#normref_cleanup(xmldoc) ⇒ Object



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

def normref_cleanup(xmldoc)
  r = xmldoc.at(self.class::NORM_REF) || return
  preface = ((r.xpath("./title/following-sibling::*") & # intersection
              r.xpath("./bibitem[1]/preceding-sibling::*")) -
  r.xpath("./note[@type = 'boilerplate']/descendant-or-self::*"))
  preface.each(&:remove)
end

#note_cleanup(xmldoc) ⇒ Object

if a note is at the end of a section, it is left alone if a note is followed by a non-note block, it is moved inside its preceding block if it is not delimited (so there was no way of making that block include the note)



101
102
103
104
105
106
107
108
109
110
111
# File 'lib/metanorma/standoc/cleanup_block.rb', line 101

def note_cleanup(xmldoc)
  xmldoc.xpath("//note").each do |n|
    n["keep-separate"] == "true" || !n.ancestors("table").empty? and next
    prev = n.previous_element || next
    n.parent = prev if ELEMS_ALLOW_NOTES.include? prev.name
  end
  xmldoc.xpath("//note[@keep-separate] | " \
               "//termnote[@keep-separate]").each do |n|
    n.delete("keep-separate")
  end
end

#notes_table_cleanup(xmldoc) ⇒ Object

move notes into table



66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/metanorma/standoc/cleanup_table.rb', line 66

def notes_table_cleanup(xmldoc)
  nomatches = false
  until nomatches
    nomatches = true
    xmldoc.xpath("//table/following-sibling::*[1]" \
                 "[self::note[not(@keep-separate = 'true')]]").each do |n|
      n.delete("keep-separate")
      n.previous_element << n.remove
      nomatches = false
    end
  end
end

#obligations_cleanup(xml) ⇒ Object



145
146
147
148
149
# File 'lib/metanorma/standoc/cleanup_section.rb', line 145

def obligations_cleanup(xml)
  obligations_cleanup_info(xml)
  obligations_cleanup_norm(xml)
  obligations_cleanup_inherit(xml)
end

#obligations_cleanup_info(xml) ⇒ Object



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

def obligations_cleanup_info(xml)
  xml.xpath("//foreword | //introduction | //acknowledgements | " \
            "//references | //preface//clause").each do |r|
    r["obligation"] = "informative"
  end
end

#obligations_cleanup_inherit(xml) ⇒ Object



165
166
167
168
169
170
171
172
# File 'lib/metanorma/standoc/cleanup_section.rb', line 165

def obligations_cleanup_inherit(xml)
  xml.xpath("//annex | //clause[not(ancestor::boilerplate)]").each do |r|
    r["obligation"] = "normative" unless r["obligation"]
  end
  xml.xpath(Utils::SUBCLAUSE_XPATH).each do |r|
    o = r.at("./ancestor::*/@obligation")&.text and r["obligation"] = o
  end
end

#obligations_cleanup_norm(xml) ⇒ Object



158
159
160
161
162
163
# File 'lib/metanorma/standoc/cleanup_section.rb', line 158

def obligations_cleanup_norm(xml)
  s = xml.at("//clause[@type = 'scope']") and
    s["obligation"] = "normative"
  xml.xpath("//terms").each { |r| r["obligation"] = "normative" }
  xml.xpath("//definitions").each { |r| r["obligation"] = "normative" }
end

#ol_cleanup(doc) ⇒ Object



218
219
220
221
222
223
224
# File 'lib/metanorma/standoc/cleanup_block.rb', line 218

def ol_cleanup(doc)
  doc.xpath("//ol[@explicit-type]").each do |x|
    x.delete("explicit-type")
    @log.add("Style", x,
             "Style override set for ordered list")
  end
end

#origin_cleanup(xmldoc) ⇒ Object



237
238
239
240
241
242
243
244
245
246
247
248
# File 'lib/metanorma/standoc/cleanup_xref.rb', line 237

def origin_cleanup(xmldoc)
  xmldoc.xpath("//origin/concept[termref]").each do |x|
    x.replace(x.at("./termref"))
  end
  xmldoc.xpath("//origin").each do |x|
    x["citeas"] = @anchors&.dig(x["bibitemid"], :xref) or
      @log.add("Crossreferences", x,
               "#{x['bibitemid']} does not have a corresponding anchor " \
               "ID in the bibliography!")
    extract_localities(x)
  end
end

#other_footnote_renumber(xmldoc) ⇒ Object



78
79
80
81
82
83
84
# File 'lib/metanorma/standoc/cleanup_footnotes.rb', line 78

def other_footnote_renumber(xmldoc)
  seen = {}
  i = 0
  xmldoc.xpath("//fn").each do |fn|
    i, seen = other_footnote_renumber1(fn, i, seen)
  end
end

#other_footnote_renumber1(fnote, idx, seen) ⇒ Object



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

def other_footnote_renumber1(fnote, idx, seen)
  return [idx, seen] if fnote["table"]

  content = footnote_content(fnote)
  if seen[content] then outnum = seen[content]
  else
    idx += 1
    outnum = idx
    seen[content] = outnum
  end
  fnote["reference"] = outnum.to_s
  [idx, seen]
end

#p_unwrap(para) ⇒ Object

if the content is a single paragraph, replace it with its children single links replaced with uri



50
51
52
53
54
55
56
57
# File 'lib/metanorma/standoc/cleanup_asciibib.rb', line 50

def p_unwrap(para)
  elems = para.elements
  if elems.size == 1 && elems[0].name == "p"
    link_unwrap(elems[0]).children.to_xml.strip
  else
    para.to_xml.strip
  end
end

#para_cleanup(xmldoc) ⇒ Object



7
8
9
10
11
12
13
14
15
16
# File 'lib/metanorma/standoc/cleanup_block.rb', line 7

def para_cleanup(xmldoc)
  ["//p[not(ancestor::bibdata)]", "//ol[not(ancestor::bibdata)]",
   "//ul[not(ancestor::bibdata)]", "//quote[not(ancestor::bibdata)]",
   "//dl[not(ancestor::bibdata)]",
   "//note[not(ancestor::bibitem or " \
   "ancestor::table or ancestor::bibdata)]"].each do |w|
    inject_id(xmldoc, w)
  end
  xmldoc.xpath("//p[not(text()) and not(node())]").each(&:remove)
end

#para_index_cleanup(xmldoc) ⇒ Object



203
204
205
206
207
208
# File 'lib/metanorma/standoc/cleanup_block.rb', line 203

def para_index_cleanup(xmldoc)
  xmldoc.xpath("//p[index]").select { |p| indexterm_para?(p) }
    .each do |p|
      para_index_cleanup1(p, p.previous_element, p.next_element)
    end
end

#para_index_cleanup1(para, prev, foll) ⇒ Object



210
211
212
213
214
215
216
# File 'lib/metanorma/standoc/cleanup_block.rb', line 210

def para_index_cleanup1(para, prev, foll)
  if include_indexterm?(prev)
    prev << para.remove.children
  elsif include_indexterm?(foll) && !foll.children.empty?
    foll.children.first.previous = para.remove.children
  end
end

#passthrough_cleanup(doc) ⇒ Object



196
197
198
199
200
201
202
203
204
# File 'lib/metanorma/standoc/cleanup_inline.rb', line 196

def passthrough_cleanup(doc)
  doc.xpath("//passthrough-inline").each do |p|
    p.name = "passthrough"
    p.children = select_odd_chars(p.children.to_xml)
  end
  doc.xpath("//identifier").each do |p|
    p.children = select_odd_chars(p.children.to_xml)
  end
end

#pop_floating_title(xmldoc) ⇒ Object



225
226
227
228
229
230
231
232
233
234
235
236
# File 'lib/metanorma/standoc/cleanup_section.rb', line 225

def pop_floating_title(xmldoc)
  loop do
    found = false
    xmldoc.xpath("//floating-title").each do |t|
      t.next_element.nil? or next
      %w(sections annex preface).include? t.parent.name and next
      t.parent.next = t
      found = true
    end
    break unless found
  end
end

#preface_clausebefore_cleanup(xmldoc) ⇒ Object



179
180
181
182
183
184
185
186
187
188
189
# File 'lib/metanorma/standoc/cleanup_section.rb', line 179

def preface_clausebefore_cleanup(xmldoc)
  xmldoc.at("//preface") or return
  ins = insert_before(xmldoc, "//preface")
  xmldoc.xpath("//preface//*[@beforeclauses = 'true']").each do |x|
    x.delete("beforeclauses")
    ins.previous = x.remove
  end
  xmldoc.xpath("//*[@coverpage = 'true']").each do |x|
    ins.previous = x.remove
  end
end

#process_boilerplate_file(filename, conv) ⇒ Object



101
102
103
104
105
# File 'lib/metanorma/standoc/cleanup_boilerplate.rb', line 101

def process_boilerplate_file(filename, conv)
  (!filename.nil? and File.exist?(filename)) or return
  b = conv.populate_template(boilerplate_read(filename), nil)
  boilerplate_file_convert(b)
end

#progress_conv(idx, step, total, threshold, msg) ⇒ Object



68
69
70
71
# File 'lib/metanorma/standoc/cleanup_maths.rb', line 68

def progress_conv(idx, step, total, threshold, msg)
  (idx % step).zero? && total > threshold && idx.positive? or return
  warn "#{msg} #{idx} of #{total}"
end

#quotesource_cleanup(xmldoc) ⇒ Object



231
232
233
234
235
# File 'lib/metanorma/standoc/cleanup_xref.rb', line 231

def quotesource_cleanup(xmldoc)
  xmldoc.xpath("//quote/source | //terms/source").each do |x|
    xref_to_eref(x, "source")
  end
end

#read_in_if_svg(img, localdir) ⇒ Object



75
76
77
78
79
80
81
82
83
84
# File 'lib/metanorma/standoc/cleanup_image.rb', line 75

def read_in_if_svg(img, localdir)
  img["src"] or return false
  path = Vectory::Utils.svgmap_rewrite0_path(img["src"], localdir)
  File.file?(path) or return false
  types = MIME::Types.type_for(path) or return false
  types.first == "image/svg+xml" or return false
  svg = File.read(path, encoding: "utf-8") or return false
  img.children = (Nokogiri::XML(svg).root)
  true
end

#read_local_bibitem(uri) ⇒ Object



99
100
101
102
103
104
105
106
107
108
109
# File 'lib/metanorma/standoc/cleanup_bibitem.rb', line 99

def read_local_bibitem(uri)
  xml = read_local_bibitem_file(uri) or return nil
  ret = xml.at("//*[local-name() = 'bibdata']") or return nil
  ret = Nokogiri::XML(ret.to_xml
    .sub(%r{(<bibdata[^>]*?) xmlns=("[^"]+"|'[^']+')}, "\\1")).root
  ret.name = "bibitem"
  ins = ret.at("./*[local-name() = 'docidentifier']") or return nil
  ins.previous = %{<uri type="citation">#{uri}</uri>}
  ret&.at("./*[local-name() = 'ext']")&.remove
  ret
end

#read_local_bibitem_file(uri) ⇒ Object



111
112
113
114
115
116
117
# File 'lib/metanorma/standoc/cleanup_bibitem.rb', line 111

def read_local_bibitem_file(uri)
  %r{^https?://}.match?(uri) and return nil
  file = "#{@localdir}#{uri}.rxl"
  File.file?(file) or file = "#{@localdir}#{uri}.xml"
  File.file?(file) or return nil
  Nokogiri::XML(File.read(file, encoding: "utf-8"))
end

#redundant_bookmark_cleanup(xmldoc) ⇒ Object



32
33
34
35
36
37
38
39
40
41
# File 'lib/metanorma/standoc/cleanup_inline.rb', line 32

def redundant_bookmark_cleanup(xmldoc)
  xmldoc.xpath("//bookmark").each do |b|
    p = b
    while !p.xml? && p = p.parent
      p["id"] == b["id"] or next
      b.remove
      break
    end
  end
end

#ref_cleanup(xmldoc) ⇒ Object

move ref before p



49
50
51
52
53
54
# File 'lib/metanorma/standoc/cleanup_ref.rb', line 49

def ref_cleanup(xmldoc)
  xmldoc.xpath("//p/ref").each do |r|
    parent = r.parent
    parent.previous = r.remove
  end
end

#ref_dl_cleanup(xmldoc) ⇒ Object



7
8
9
10
11
12
13
14
15
16
# File 'lib/metanorma/standoc/cleanup_asciibib.rb', line 7

def ref_dl_cleanup(xmldoc)
  xmldoc.xpath("//clause[@bibitem = 'true']").each do |c|
    bib = dl_bib_extract(c) or next
    validate_ref_dl(bib, c)
    bibitemxml = RelatonBib::BibliographicItem.from_hash(bib).to_xml or next
    bibitem = Nokogiri::XML(bibitemxml)
    bibitem.root["id"] = c["id"] if c["id"] && !/^_/.match(c["id"])
    c.replace(bibitem.root)
  end
end

#reference_names(xmldoc) ⇒ Object



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

def reference_names(xmldoc)
  xmldoc.xpath("//bibitem[not(ancestor::bibitem)]").each do |ref|
    @anchors[ref["id"]] =
      if docid = select_docid(ref)
        reference = format_ref(docid.children.to_xml, docid["type"])
        { xref: reference, id: idtype2cit(ref) }
      else { xref: ref["id"], id: { "" => ref["id"] } }
      end
  end
end

#related2pref(elem) ⇒ Object



176
177
178
# File 'lib/metanorma/standoc/cleanup_terms_designations.rb', line 176

def related2pref(elem)
  elem&.name == "related" ? elem.at("./preferred") : elem
end


90
91
92
93
94
95
96
97
# File 'lib/metanorma/standoc/cleanup_inline.rb', line 90

def related_cleanup(xmldoc)
  xmldoc.xpath("//related[not(termxref)]").each do |x|
    term = x.at("./refterm")
    term.replace("<preferred>#{term_expr(term.children.to_xml)}" \
                 "</preferred>")
    concept_cleanup1(x)
  end
end

#relaton_iev_cleanup(xmldoc) ⇒ Object



97
98
99
100
101
102
# File 'lib/metanorma/standoc/cleanup.rb', line 97

def relaton_iev_cleanup(xmldoc)
  _, err = RelatonIev::iev_cleanup(xmldoc, @bibdb)
  err.each do |e|
    @log.add("Bibliography", nil, e, severity: 0)
  end
end

#relaton_log_cleanup(_xmldoc) ⇒ Object



108
109
110
111
112
113
114
115
116
# File 'lib/metanorma/standoc/cleanup.rb', line 108

def relaton_log_cleanup(_xmldoc)
  @relaton_log or return
  @relaton_log.rewind
  @relaton_log.string.split(/(?<=})\n(?={)/).each do |l|
    e = JSON.parse(l)
    @log.add("Relaton", e["key"], e["message"],
             severity: RELATON_SEVERITIES[e["severity"].to_sym])
  end
end

#remove_dup_bibtem_id(xmldoc) ⇒ Object

remove dupes if both same ID and same docid, in case dupes introduced through termbases



205
206
207
208
209
210
211
# File 'lib/metanorma/standoc/cleanup_bibitem.rb', line 205

def remove_dup_bibtem_id(xmldoc)
  bibitem_id_docid_hash(xmldoc).each_value do |v|
    v.each_value do |v1|
      v1[1..].each(&:remove)
    end
  end
end

#replace_title(doc, xpath, text, first = false) ⇒ Object



15
16
17
18
19
20
21
22
23
# File 'lib/metanorma/standoc/cleanup_section_names.rb', line 15

def replace_title(doc, xpath, text, first = false)
  text or return
  doc.xpath(xpath).each_with_index do |node, i|
    first && !i.zero? and next
    node["keeptitle"] == "true" and next
    title = get_or_make_title(node)
    set_title_with_footnotes(title, text)
  end
end

#requirement_cleanup(xmldoc) ⇒ Object



4
5
6
7
8
# File 'lib/metanorma/standoc/cleanup_reqt.rb', line 4

def requirement_cleanup(xmldoc)
  @reqt_models ||=
    requirements_processor.new({ default: @default_requirement_model })
  @reqt_models.requirement_cleanup(xmldoc)
end

#resolve_boilerplate_files(built_in, user_add) ⇒ Object



107
108
109
110
111
# File 'lib/metanorma/standoc/cleanup_boilerplate.rb', line 107

def resolve_boilerplate_files(built_in, user_add)
  built_in || user_add or return
  built_in && user_add or return to_xml(built_in || user_add)
  merge_boilerplate_files(built_in, user_add)
end

#resolve_boilerplate_statement(built_in, user_add, statement) ⇒ Object



120
121
122
123
124
125
126
127
# File 'lib/metanorma/standoc/cleanup_boilerplate.rb', line 120

def resolve_boilerplate_statement(built_in, user_add, statement)
  b = user_add.at("./#{statement}-statement") or return
  if a = built_in.at("./#{statement}-statement")
    b.text.strip.empty? and a.remove or a.replace(b)
  else
    built_in << b
  end
end

#resolve_local_indirect_erefs(xmldoc, refs, prefix) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/metanorma/standoc/cleanup_bibdata.rb', line 61

def resolve_local_indirect_erefs(xmldoc, refs, prefix)
  refs.each_with_object([]) do |r, m|
    id = r.sub(/^#{prefix}_/, "")
    n = xmldoc.at("//*[@id = '#{id}']")
    if n&.at("./ancestor-or-self::*[@type = '#{prefix}']")
      xmldoc.xpath("//eref[@bibitemid = '#{r}']").each do |e|
        indirect_eref_to_xref(e, id)
      end
    else m << r
    end
  end
end

#safe_noko(text, doc) ⇒ Object



152
153
154
155
156
157
# File 'lib/metanorma/standoc/cleanup_block.rb', line 152

def safe_noko(text, doc)
  Nokogiri::XML::Text.new(text, doc).to_xml(
    encoding: "US-ASCII",
    save_with: Nokogiri::XML::Node::SaveOptions::NO_DECLARATION,
  )
end

#save_attachment(path, bib) ⇒ Object



159
160
161
162
163
164
165
166
167
# File 'lib/metanorma/standoc/cleanup_bibitem.rb', line 159

def save_attachment(path, bib)
  init_attachments
  f = File.basename(path)
  File.exist?(File.join(@attachmentsdir, f)) and
    f += "_#{UUIDTools::UUID.random_create}"
  out_fld = File.join(@attachmentsdir, f)
  FileUtils.cp(path, out_fld)
  datauri_attachment(out_fld, bib.document)
end

#script_cleanup(xmldoc) ⇒ Object

it seems Nokogiri::XML is treating the content of <script> as cdata, because of its use in HTML. Bad nokogiri. Undoing that, since we use script as a normal tag



130
131
132
# File 'lib/metanorma/standoc/cleanup.rb', line 130

def script_cleanup(xmldoc)
  xmldoc.xpath("//script").each { |x| x.content = x.to_str }
end

#section_names_definitions(xml) ⇒ Object



67
68
69
70
71
72
73
74
75
# File 'lib/metanorma/standoc/cleanup_section_names.rb', line 67

def section_names_definitions(xml)
  auto_name_definitions(xml) or return
  replace_title(xml, "//definitions[@type = 'symbols']",
                @i18n&.symbols)
  replace_title(xml, "//definitions[@type = 'abbreviated_terms']",
                @i18n&.abbrev)
  replace_title(xml, "//definitions[not(@type)]",
                @i18n&.symbolsabbrev)
end

#section_names_refs_cleanup(xml) ⇒ Object



47
48
49
50
51
52
# File 'lib/metanorma/standoc/cleanup_section_names.rb', line 47

def section_names_refs_cleanup(xml)
  replace_title(xml, "//bibliography/references[@normative = 'true']",
                @i18n&.normref, true)
  replace_title(xml, "//bibliography/references[@normative = 'false']",
                @i18n&.bibliography, true)
end

#section_names_terms1_cleanup(xml) ⇒ Object



85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/metanorma/standoc/cleanup_section_names.rb', line 85

def section_names_terms1_cleanup(xml)
  auto_name_terms(xml) or return
  replace_title(xml, "//terms#{SYMnoABBR} | //clause[@type = 'terms']#{SYMnoABBR}",
                @i18n&.termsdefsymbols, true)
  replace_title(xml, "//terms#{ABBRnoSYM} | //clause[@type = 'terms']#{ABBRnoSYM}",
                @i18n&.termsdefabbrev, true)
  replace_title(xml, "//terms#{SYMABBR} | //clause[@type = 'terms']#{SYMABBR}",
                @i18n&.termsdefsymbolsabbrev, true)
  replace_title(xml, "//terms#{NO_SYMABBR} | //clause[@type = 'terms']#{NO_SYMABBR}",
                @i18n&.termsdefsymbolsabbrev, true)
  replace_title(xml, "//terms[not(.//definitions)] | //clause[@type = 'terms'][not(.//definitions)]",
                @i18n&.termsdef, true)
end

#section_names_terms_cleanup(xml) ⇒ Object



62
63
64
65
# File 'lib/metanorma/standoc/cleanup_section_names.rb', line 62

def section_names_terms_cleanup(xml)
  section_names_definitions(xml)
  section_names_terms1_cleanup(xml)
end

#sections_clausebefore_cleanup(xmldoc) ⇒ Object



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

def sections_clausebefore_cleanup(xmldoc)
  xmldoc.at("//sections") or return
  ins = insert_before(xmldoc, "//sections")
  xmldoc.xpath("//sections//*[@beforeclauses = 'true']")
    .reverse.each do |x|
    x.delete("beforeclauses")
    ins.previous = x.remove
  end
  endofpreface_clausebefore(xmldoc, ins)
end

#sections_cleanup(xml) ⇒ Object



124
125
126
127
128
129
130
131
# File 'lib/metanorma/standoc/cleanup_section.rb', line 124

def sections_cleanup(xml)
  misccontainer_cleanup(xml)
  sections_order_cleanup(xml)
  sections_level_cleanup(xml)
  sections_names_cleanup(xml)
  sections_variant_title_cleanup(xml)
  change_clauses(xml)
end

#sections_level_cleanup(xml) ⇒ Object



113
114
115
116
117
118
119
120
121
122
# File 'lib/metanorma/standoc/cleanup_section.rb', line 113

def sections_level_cleanup(xml)
  m = maxlevel(xml)
  m < 6 and return
  m.downto(6).each do |l|
    xml.xpath("//clause[@level = '#{l}']").each do |c|
      c.delete("level")
      c.previous_element << c.remove
    end
  end
end

#sections_names_cleanup(xml) ⇒ Object



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

def sections_names_cleanup(xml)
  replace_title(xml, "//clause[@type = 'scope']", @i18n&.scope)
  sections_names_pref_cleanup(xml)
  section_names_refs_cleanup(xml)
  section_names_terms_cleanup(xml)
  xml.xpath("//*[@keeptitle]").each { |s| s.delete("keeptitle") }
end

#sections_names_pref_cleanup(xml) ⇒ Object



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

def sections_names_pref_cleanup(xml)
  replace_title(xml, "//preface//abstract", @i18n&.abstract)
  replace_title(xml, "//foreword", @i18n&.foreword)
  replace_title(xml, "//introduction", @i18n&.introduction)
  replace_title(xml, "//acknowledgements", @i18n&.acknowledgements)
end

#sections_order_cleanup(xml) ⇒ Object



82
83
84
85
86
87
88
89
90
91
# File 'lib/metanorma/standoc/cleanup_section.rb', line 82

def sections_order_cleanup(xml)
  s = xml.at("//sections")
  pop_floating_title(xml)
  make_preface(xml, s)
  make_annexes(xml)
  make_indexsect(xml, s)
  make_bibliography(xml, s)
  make_colophon(xml)
  xml.xpath("//sections/annex").reverse_each { |r| s.next = r.remove }
end

#sections_variant_title_cleanup(xml) ⇒ Object



151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/metanorma/standoc/cleanup_section_names.rb', line 151

def sections_variant_title_cleanup(xml)
  path = SECTION_CONTAINERS.map { |x| "./ancestor::#{x}" }.join(" | ")
  xml.xpath("//p[@variant_title]").each do |p|
    p.name = "variant-title"
    p.delete("id")
    p.delete("variant_title")
    p.xpath("(#{path})[last()]").each do |sect|
      (ins = sect.at("./title") and ins.next = p) or
        sect.children.first.previous = p
    end
  end
end

#select_docid(ref, type = nil) ⇒ Object



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

def select_docid(ref, type = nil)
  type and t = "[@type = '#{type}']"
  ref.at("./docidentifier[@type = 'metanorma']#{t}") ||
    ref.at("./docidentifier[@primary = 'true'][@language = '#{@lang}']#{t}") ||
    ref.at("./docidentifier[@primary = 'true'][not(@language)]#{t}") ||
    ref.at("./docidentifier[@primary = 'true']#{t}") ||
    ref.at("./docidentifier[not(@type = 'DOI')][@language = '#{@lang}']#{t}") ||
    ref.at("./docidentifier[not(@type = 'DOI')][not(@language)]#{t}") ||
    ref.at("./docidentifier[not(@type = 'DOI')]#{t}")
end

#set_title_with_footnotes(title, text) ⇒ Object



25
26
27
28
29
30
# File 'lib/metanorma/standoc/cleanup_section_names.rb', line 25

def set_title_with_footnotes(title, text)
  fn = title.xpath("./fn | ./bookmark | ./index")
  fn.each(&:remove)
  title.children = text
  fn.each { |n| title << n }
end

#single_clause_annex(xml) ⇒ Object



139
140
141
142
143
# File 'lib/metanorma/standoc/cleanup_section.rb', line 139

def single_clause_annex(xml)
  xml.xpath("//annex").each do |a|
    single_clause_annex1(a)
  end
end

#single_subfigure_cleanup(xmldoc) ⇒ Object



79
80
81
82
83
84
85
# File 'lib/metanorma/standoc/cleanup_block.rb', line 79

def single_subfigure_cleanup(xmldoc)
  xmldoc.xpath("//figure[figure]").each do |e|
    s = e.xpath("./figure")
    s.size == 1 or next
    s[0].replace(s[0].children)
  end
end

#smartquotes_cleanup(xmldoc) ⇒ Object



69
70
71
72
73
74
# File 'lib/metanorma/standoc/cleanup_text.rb', line 69

def smartquotes_cleanup(xmldoc)
  xmldoc.xpath("//date").each { |d| Metanorma::Utils::endash_date(d) }
  if @smartquotes then smartquotes_cleanup1(xmldoc)
  else dumbquote_cleanup(xmldoc)
  end
end

#smartquotes_cleanup1(xmldoc) ⇒ Object



76
77
78
79
# File 'lib/metanorma/standoc/cleanup_text.rb', line 76

def smartquotes_cleanup1(xmldoc)
  uninterrupt_quotes_around_xml(xmldoc)
  dumb2smart_quotes(xmldoc)
end

#sort_biblio(bib) ⇒ Object



28
29
30
# File 'lib/metanorma/standoc/cleanup_ref.rb', line 28

def sort_biblio(bib)
  bib
end

#sourcecode_cleanup(xmldoc) ⇒ Object



142
143
144
145
146
147
148
149
150
# File 'lib/metanorma/standoc/cleanup_block.rb', line 142

def sourcecode_cleanup(xmldoc)
  xmldoc.xpath("//sourcecode").each do |x|
    x.traverse do |n|
      n.text? or next
      /#{Regexp.escape(@sourcecode_markup_start)}/.match?(n.text) or next
      n.replace(sourcecode_markup(n))
    end
  end
end

#sourcecode_markup(node) ⇒ Object



159
160
161
162
163
164
165
166
167
168
169
# File 'lib/metanorma/standoc/cleanup_block.rb', line 159

def sourcecode_markup(node)
  node.text.split(/(#{Regexp.escape(@sourcecode_markup_start)}|
                    #{Regexp.escape(@sourcecode_markup_end)})/x)
    .each_slice(4).map.with_object([]) do |a, acc|
    acc << safe_noko(a[0], node.document)
    a.size == 4 or next
    acc << Asciidoctor.convert(
      a[2], doctype: :inline, backend: self&.backend&.to_sym || :standoc
    )
  end.join
end

#sources_table_cleanup(xmldoc) ⇒ Object



52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/metanorma/standoc/cleanup_table.rb', line 52

def sources_table_cleanup(xmldoc)
  nomatches = false
  until nomatches
    nomatches = true
    xmldoc.xpath("//table/following-sibling::*[1]" \
                 "[self::termsource]").each do |n|
      n.previous_element << n.remove
      nomatches = false
      # will be renamed source from termsource later
    end
  end
end

#split_termdefinitions(xmldoc) ⇒ Object



45
46
47
48
49
50
51
52
53
54
# File 'lib/metanorma/standoc/cleanup_terms.rb', line 45

def split_termdefinitions(xmldoc)
  xmldoc.xpath("//definition").each do |d|
    if d.at("./p | ./ol | ./dl | ./ul")
      d.children = "<verbal-definition>#{d.children}</verbal-definition>"
    else
      d.children = "<non-verbal-representation>" \
                   "#{d.children}</non-verbal-representation>"
    end
  end
end

#strip_initial_space(elem) ⇒ Object



16
17
18
19
20
21
22
23
24
# File 'lib/metanorma/standoc/cleanup_inline.rb', line 16

def strip_initial_space(elem)
  a = elem.children[0]
  a.text? or return
  if /\S/.match?(a.text)
    a.content = a.text.lstrip
  else
    a.remove
  end
end

#subfigure_cleanup(xmldoc) ⇒ Object

examples containing only figures become subfigures of figures



69
70
71
72
73
74
75
76
77
# File 'lib/metanorma/standoc/cleanup_block.rb', line 69

def subfigure_cleanup(xmldoc)
  xmldoc.xpath("//example[figure]").each do |e|
    e.elements.reject do |m|
      %w(name figure index note).include?(m.name) ||
        (m.name == "dl" && m["key"] == "true")
    end.empty? or next
    e.name = "figure"
  end
end

#svg_attrupdate(elem, iri_properties, idx, ids) ⇒ Object



180
181
182
183
184
185
# File 'lib/metanorma/standoc/cleanup_image.rb', line 180

def svg_attrupdate(elem, iri_properties, idx, ids)
  iri_properties.each do |p|
    elem[p] or next
    elem[p] = svg_update_url(elem[p], idx, ids)
  end
end

#svg_classupdate(xmldoc) ⇒ Object



86
87
88
89
90
91
# File 'lib/metanorma/standoc/cleanup_image.rb', line 86

def svg_classupdate(xmldoc)
  xmldoc.xpath("//m:svg[m:style]", "m" => SVG_NS)
    .each_with_index do |s, i|
    svg_classupdate1(s, s.at("./m:style", "m" => SVG_NS), i)
  end
end

#svg_classupdate1(svg, style, idx) ⇒ Object



93
94
95
96
97
98
99
100
101
# File 'lib/metanorma/standoc/cleanup_image.rb', line 93

def svg_classupdate1(svg, style, idx)
  tree = Crass.parse(style.text)
  tree.each { |n| svg_suffix_css_style(n, idx) }
  style.children = Crass::Parser.stringify(tree)
  svg.xpath(".//*[@class]").each do |n|
    n["class"] = n["class"].split(/\s+/)
      .map { |x| "#{x}_inject_#{idx}" }.join(" ")
  end
end

#svg_cleanup(xmldoc) ⇒ Object



70
71
72
73
# File 'lib/metanorma/standoc/cleanup_image.rb', line 70

def svg_cleanup(xmldoc)
  svg_uniqueids(xmldoc)
  svg_classupdate(xmldoc)
end

#svg_idupdate(elem, idx, ids) ⇒ Object



196
197
198
199
200
# File 'lib/metanorma/standoc/cleanup_image.rb', line 196

def svg_idupdate(elem, idx, ids)
  elem["id"] or return
  ids[elem["id"]] or return
  elem["id"] += "_inject_#{idx}"
end

#svg_iri_properties(id_elems) ⇒ Object



135
136
137
138
139
140
141
142
143
144
# File 'lib/metanorma/standoc/cleanup_image.rb', line 135

def svg_iri_properties(id_elems)
  iri_tag_names = id_elems.each_with_object([]) do |e, m|
    IRI_TAG_PROPERTIES_MAP.key?(e.name.to_sym) and m << e.name
  end.uniq
  iri_properties = iri_tag_names.each_with_object([]) do |t, m|
    (IRI_TAG_PROPERTIES_MAP[t.to_sym] || [t]).each { |t1| m = m << t1 }
  end.uniq
  iri_properties.empty? and return []
  iri_properties << "style"
end

#svg_linkupdate(elem, idx, ids) ⇒ Object



187
188
189
190
191
192
193
194
# File 'lib/metanorma/standoc/cleanup_image.rb', line 187

def svg_linkupdate(elem, idx, ids)
  %w(xlink:href href).each do |ref|
    iri = elem[ref]&.strip
    /^#/.match?(iri) or next
    ids[iri.sub(/^#/, "")] or next
    elem[ref] += "_inject_#{idx}"
  end
end

#svg_styleupdate(elem, idx, ids) ⇒ Object



176
177
178
# File 'lib/metanorma/standoc/cleanup_image.rb', line 176

def svg_styleupdate(elem, idx, ids)
  elem.children = svg_update_url(elem.text, idx, ids)
end

#svg_suffix_css_style(node, idx) ⇒ Object



103
104
105
106
107
108
109
# File 'lib/metanorma/standoc/cleanup_image.rb', line 103

def svg_suffix_css_style(node, idx)
  node[:node] == :style_rule && /\./.match?(node[:selector][:value]) or
    return
  v = node[:selector][:value]
    .gsub(/([^.\s]*\.\S+)/, "\\1_inject_#{idx}")
  node[:selector] = Crass.parse("#{v} {}").first[:selector]
end

#svg_uniqueids(xmldoc) ⇒ Object



125
126
127
128
129
130
131
132
133
# File 'lib/metanorma/standoc/cleanup_image.rb', line 125

def svg_uniqueids(xmldoc)
  # only keep non-unique identifiers
  ids = xmldoc.xpath("//m:svg//*/@id | //svg/@id", "m" => SVG_NS)
    .map(&:text).group_by(&:itself).transform_values(&:count)
    .delete_if { |_, v| v < 2 }
  xmldoc.xpath("//m:svg", "m" => SVG_NS).each_with_index do |s, i|
    ids = svg_uniqueids1(s, i, ids)
  end
end

#svg_uniqueids1(svg, idx, ids) ⇒ Object



146
147
148
149
150
151
152
153
# File 'lib/metanorma/standoc/cleanup_image.rb', line 146

def svg_uniqueids1(svg, idx, ids)
  id_elems = svg.xpath(".//*[@id] | ./@id/..")
  iri_properties = svg_iri_properties(id_elems)
  svg_uniqueids2(svg, iri_properties, idx, ids)
  new_ids = id_elems.map { |x| x["id"] }
    .map { |x| x + (ids[x] ? "_inject_#{idx}" : "") }
  ids.merge(new_ids.each.map { |value| [value, true] }.to_h)
end

#svg_uniqueids2(svg, iri_properties, idx, ids) ⇒ Object



155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/metanorma/standoc/cleanup_image.rb', line 155

def svg_uniqueids2(svg, iri_properties, idx, ids)
  svg.traverse do |e|
    e.element? or next
    if e.name == "style"
      svg_styleupdate(e, idx, ids)
    elsif !e.attributes.empty?
      svg_attrupdate(e, iri_properties, idx, ids)
    end
    svg_linkupdate(e, idx, ids)
    svg_idupdate(e, idx, ids)
  end
end

#svg_update_url(text, idx, ids) ⇒ Object



168
169
170
171
172
173
174
# File 'lib/metanorma/standoc/cleanup_image.rb', line 168

def svg_update_url(text, idx, ids)
  text.gsub(/url\("?#([a-zA-Z][\w:.-]*)"?\)/) do |x|
    if ids[$1] then "url(##{$1}_inject_#{idx})"
    else x
    end
  end
end

#svgmap_cleanup(xmldoc) ⇒ Object



7
8
9
10
11
# File 'lib/metanorma/standoc/cleanup_image.rb', line 7

def svgmap_cleanup(xmldoc)
  svgmap_moveattrs(xmldoc)
  svgmap_populate(xmldoc)
  Vectory::SvgMapping.new(xmldoc, @localdir).call
end

#svgmap_moveattrs(xmldoc) ⇒ Object



13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/metanorma/standoc/cleanup_image.rb', line 13

def svgmap_moveattrs(xmldoc)
  xmldoc.xpath("//svgmap").each do |s|
    f = s.at(".//figure") or next
    (t = s.at("./name")) && !f.at("./name") and
      f.children.first.previous = t.remove
    if s["id"] && Metanorma::Utils::guid_anchor?(f["id"])
      f["id"] = s["id"]
      s.delete("id")
    end
    svgmap_moveattrs1(s, f)
  end
end

#svgmap_moveattrs1(svgmap, figure) ⇒ Object



26
27
28
29
30
31
32
33
# File 'lib/metanorma/standoc/cleanup_image.rb', line 26

def svgmap_moveattrs1(svgmap, figure)
  %w(unnumbered number subsequence keep-with-next
     keep-lines-together tag multilingual-rendering).each do |a|
    figure[a] || !svgmap[a] and next
    figure[a] = svgmap[a]
    svgmap.delete(a)
  end
end

#svgmap_populate(xmldoc) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/metanorma/standoc/cleanup_image.rb', line 35

def svgmap_populate(xmldoc)
  xmldoc.xpath("//svgmap").each do |s|
    s1 = s.dup
    s.children.remove
    f = s1.at(".//figure") and s << f
    s1.xpath(".//li").each do |li|
      t = li.at(".//eref | .//link | .//xref") or next
      href = t.xpath("./following-sibling::node()")
      href.empty? or
        s << %[<target href="#{svgmap_target(href)}">#{t.to_xml}</target>]
    end
  end
end

#svgmap_target(nodeset) ⇒ Object



49
50
51
52
53
54
55
# File 'lib/metanorma/standoc/cleanup_image.rb', line 49

def svgmap_target(nodeset)
  nodeset.each do |n|
    n.name == "link" or next
    n.children = n["target"]
  end
  nodeset.text.sub(/^[,; ]/, "").strip
end

#symbol_key(sym) ⇒ Object

Indices sort after letter but before any following letter (x, x_m, x_1, xa); we use colon to force that sort order. Numbers sort after letters; we use thorn to force that sort order. Capitals sort before their corresponding lowercase.



10
11
12
13
14
15
16
17
# File 'lib/metanorma/standoc/cleanup_symbols.rb', line 10

def symbol_key(sym)
  @c.decode(asciimath_key(sym).text)
    .gsub(/[\[\]{}<>()]/, "").gsub(/\s/m, "")
    .gsub(/[[:punct:]]|[_^]/, ":\\0").delete("`")
    .gsub(/[0-9]+/, "þ\\0")
    .tr("AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz",
        "ABCFEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
end

#symbols_cleanup(docxml) ⇒ Object



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

def symbols_cleanup(docxml)
  docxml.xpath("//definitions/dl").each do |dl|
    dl_out = extract_symbols_list(dl)
    dl_out.sort! { |a, b| a[:key] <=> b[:key] || a[:dt] <=> b[:dt] }
    dl.children = dl_out.map { |d| d[:dt].to_s + d[:dd].to_s }.join("\n")
  end
  docxml
end

#table_cleanup(xmldoc) ⇒ Object



44
45
46
47
48
49
50
# File 'lib/metanorma/standoc/cleanup_table.rb', line 44

def table_cleanup(xmldoc)
  dl1_table_cleanup(xmldoc)
  dl2_table_cleanup(xmldoc)
  sources_table_cleanup(xmldoc)
  notes_table_cleanup(xmldoc)
  header_rows_cleanup(xmldoc)
end

#table_footnote_number(outnum) ⇒ Object



50
51
52
# File 'lib/metanorma/standoc/cleanup_footnotes.rb', line 50

def table_footnote_number(outnum)
  (outnum - 1 + "a".ord).chr
end

#table_footnote_renumber(xmldoc) ⇒ Object



54
55
56
57
58
59
60
61
62
# File 'lib/metanorma/standoc/cleanup_footnotes.rb', line 54

def table_footnote_renumber(xmldoc)
  xmldoc.xpath("//table | //figure").each do |t|
    seen = {}
    i = 0
    t.xpath(".//fn[not(ancestor::name)]").each do |fn|
      i, seen = table_footnote_renumber1(fn, i, seen)
    end
  end
end

#table_footnote_renumber1(fnote, idx, seen) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/metanorma/standoc/cleanup_footnotes.rb', line 37

def table_footnote_renumber1(fnote, idx, seen)
  content = footnote_content(fnote)
  if seen[content] then outnum = seen[content]
  else
    idx += 1
    outnum = idx
    seen[content] = outnum
  end
  fnote["reference"] = table_footnote_number(outnum)
  fnote["table"] = true
  [idx, seen]
end

#term_children_cleanup(xmldoc) ⇒ Object



83
84
85
86
87
88
89
# File 'lib/metanorma/standoc/cleanup_terms.rb', line 83

def term_children_cleanup(xmldoc)
  xmldoc.xpath("//term").each do |t|
    %w(termnote termexample termsource term).each do |w|
      t.xpath("./#{w}").each { |n| t << n.remove }
    end
  end
end

#term_defs_boilerplate(div, source, term, _preface, isodoc) ⇒ Object



19
20
21
22
23
24
25
26
27
# File 'lib/metanorma/standoc/cleanup_terms_boilerplate.rb', line 19

def term_defs_boilerplate(div, source, term, _preface, isodoc)
  verify_term_defs_source(source)
  a = @i18n.term_def_boilerplate and
    div.next = boilerplate_snippet_convert(a)
  a = if source.empty? && term.nil? then @i18n.no_terms_boilerplate
      else term_defs_boilerplate_cont(source, term, isodoc)
      end
  a and div.next = boilerplate_snippet_convert(a)
end

#term_defs_boilerplate_cont(src, term, isodoc) ⇒ Object



38
39
40
41
42
43
44
45
46
47
# File 'lib/metanorma/standoc/cleanup_terms_boilerplate.rb', line 38

def term_defs_boilerplate_cont(src, term, isodoc)
  sources = isodoc.sentence_join(src.map do |s|
    %{<<#{s['bibitemid']}>>}
  end)
  if src.empty? then @i18n.internal_terms_boilerplate
  elsif term.nil? then external_terms_boilerplate(sources)
  else
    internal_external_terms_boilerplate(sources)
  end
end

#term_designation_redundant(xmldoc) ⇒ Object



180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/metanorma/standoc/cleanup_terms_designations.rb', line 180

def term_designation_redundant(xmldoc)
  xmldoc.xpath("//term").each do |t|
    DESIGNATOR.each do |n|
      t.xpath("./#{n}/expression/name").each_with_object([]) do |d, m|
        if m.include?(d.text)
          @log.add("Terms", t, "Removed duplicate designation #{d.text}")
          d.parent.parent.remove
        end
        m << d.text
      end
    end
  end
end

#term_designation_reorder(xmldoc) ⇒ Object



164
165
166
167
168
169
170
171
172
173
174
# File 'lib/metanorma/standoc/cleanup_terms_designations.rb', line 164

def term_designation_reorder(xmldoc)
  xmldoc.xpath("//term").each do |t|
    des = DESIGNATOR.each_with_object([]) do |tag, m|
      t.xpath("./#{tag}").each { |x| m << x.remove }
    end.reverse
    t << " "
    des.each do |x|
      t.children.first.previous = x
    end
  end
end

#term_dl_to_designation_category(prev, category) ⇒ Object



101
102
103
104
105
106
# File 'lib/metanorma/standoc/cleanup_terms_designations.rb', line 101

def term_dl_to_designation_category(prev, category)
  cat = prev.at(".//expression/grammar/#{category}")
  cat&.text&.include?(",") and
    cat.replace(cat.text.split(/,\s*/)
      .map { |x| "<#{category}>#{x}</#{category}>" }.join)
end

#term_dl_to_designation_metadata(prev, dlist) ⇒ Object



45
46
47
48
49
50
51
52
# File 'lib/metanorma/standoc/cleanup_terms_designations.rb', line 45

def (prev, dlist)
  %w(absent geographic-area).each do |a|
    dl_to_attrs(prev, dlist, a)
  end
  %w(field-of-application usage-info).reverse_each do |a|
    dl_to_elems(prev.at("./expression"), prev, dlist, a)
  end
end

#term_dl_to_expression_grammar(prev, dlist) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/metanorma/standoc/cleanup_terms_designations.rb', line 88

def term_dl_to_expression_grammar(prev, dlist)
  prev.at(".//expression") or return
  prev.at(".//expression") << "<grammar><sentinel/></grammar>"
  %w(gender number isPreposition isParticiple isAdjective isAdverb isNoun
     grammar-value).reverse_each do |a|
    dl_to_elems(prev.at(".//expression/grammar/*"), prev.elements.last,
                dlist, a)
  end
  term_dl_to_designation_category(prev, "gender")
  term_dl_to_designation_category(prev, "number")
  prev.at(".//expression/grammar/sentinel").remove
end

#term_dl_to_expression_metadata(prev, dlist) ⇒ Object



63
64
65
66
67
# File 'lib/metanorma/standoc/cleanup_terms_designations.rb', line 63

def (prev, dlist)
  (prev, dlist)
  (prev, dlist)
  term_to_letter_symbol(prev, dlist)
end

#term_dl_to_expression_name_metadata(prev, dlist) ⇒ Object



80
81
82
83
84
85
86
# File 'lib/metanorma/standoc/cleanup_terms_designations.rb', line 80

def (prev, dlist)
  %w(abbreviation-type pronunciation).reverse_each do |a|
    dl_to_elems(prev.at("./expression/name"), prev, dlist, a)
  end
  g = dlist.at("./dt[text()='grammar']/following::dd//dl") and
    term_dl_to_expression_grammar(prev, g)
end

#term_dl_to_expression_root_metadata(prev, dlist) ⇒ Object



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

def (prev, dlist)
  %w(isInternational).each do |a|
    p = prev.at("./expression | ./letter-symbol | ./graphical-symbol")
    dl_to_attrs(p, dlist, a)
  end
  %w(language script type).each do |a|
    p = prev.at("./expression") or next
    dl_to_attrs(p, dlist, a)
  end
end

#term_dl_to_metadata(xmldoc) ⇒ Object



23
24
25
26
27
28
29
30
31
32
33
# File 'lib/metanorma/standoc/cleanup_terms_designations.rb', line 23

def (xmldoc)
  xmldoc.xpath("//term[dl[@metadata = 'true']]").each do |t|
    t.xpath("./dl[@metadata = 'true']").each do |dl|
      prev = related2pref(dl_to_designation(dl)) or next
      (prev, dl)
      (prev, dl)
      (prev, dl)
      dl.remove
    end
  end
end

#term_dl_to_term_metadata(prev, dlist) ⇒ Object



35
36
37
38
39
40
41
42
43
# File 'lib/metanorma/standoc/cleanup_terms_designations.rb', line 35

def (prev, dlist)
  return unless prev.name == "preferred" &&
    prev.at("./preceding-sibling::preferred").nil?

  ins = term_element_insert_point(prev)
  %w(domain subject).each do |a|
    ins = dl_to_elems(ins, prev.parent, dlist, a)
  end
end

#term_element_insert_point(prev) ⇒ Object



54
55
56
57
58
59
60
61
# File 'lib/metanorma/standoc/cleanup_terms_designations.rb', line 54

def term_element_insert_point(prev)
  ins = prev
  while %w(preferred admitted deprecates related domain dl)
      .include? ins&.next_element&.name
    ins = ins.next_element
  end
  ins
end

#term_index_cleanup(xmldoc) ⇒ Object



130
131
132
133
134
135
136
137
138
139
140
# File 'lib/metanorma/standoc/cleanup_terms.rb', line 130

def term_index_cleanup(xmldoc)
  @index_terms or return
  xmldoc.xpath("//preferred").each do |p|
    index_cleanup1(p.at("./expression/name | ./letter-symbol/name"),
                   p.xpath("./field-of-application | ./usage-info")
      &.map(&:text)&.join(", "))
  end
  xmldoc.xpath("//definitions/dl/dt").each do |p|
    index_cleanup1(p, "")
  end
end

#term_nonverbal_designations(xmldoc) ⇒ Object



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

def term_nonverbal_designations(xmldoc)
  xmldoc.xpath("//term/preferred | //term/admitted | //term/deprecates")
    .each do |d|
    d.text.strip.empty? or next
    n = d.next_element
    if %w(formula figure).include?(n&.name)
      term_nonverbal_designations1(d, n)
    else d.at("./expression/name") or
      d.children = term_expr("")
    end
  end
end

#term_nonverbal_designations1(desgn, elem) ⇒ Object



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

def term_nonverbal_designations1(desgn, elem)
  desgn = related2pref(desgn)
  if elem.name == "figure"
    elem.at("./name").remove
    desgn.children =
      "<graphical-symbol>#{elem.remove.to_xml}</graphical-symbol>"
  else
    desgn.children = term_expr(elem.at("./stem").to_xml)
    elem.remove
  end
end

#term_termsource_to_designation(xmldoc) ⇒ Object



153
154
155
156
157
158
159
160
161
162
# File 'lib/metanorma/standoc/cleanup_terms_designations.rb', line 153

def term_termsource_to_designation(xmldoc)
  xmldoc.xpath("//term/termsource").each do |t|
    p = t.previous_element
    while %w(domain subject).include? p&.name
      p = p.previous_element
    end
    DESIGNATOR.include?(p&.name) or next
    related2pref(p) << t.remove
  end
end

#term_to_letter_symbol(prev, dlist) ⇒ Object



108
109
110
111
112
113
114
# File 'lib/metanorma/standoc/cleanup_terms_designations.rb', line 108

def term_to_letter_symbol(prev, dlist)
  ls = dlist.at("./dt[text()='letter-symbol']/following::dd/p")&.text
  !ls || ls == "false" and return
  e = prev.at(".//expression")
  e.name = "letter-symbol"
  ls != "true" and e["type"] = ls
end

#termdef_boilerplate_cleanup(xmldoc) ⇒ Object



54
55
56
# File 'lib/metanorma/standoc/cleanup_terms_boilerplate.rb', line 54

def termdef_boilerplate_cleanup(xmldoc)
  # termdef_remove_initial_paras(xmldoc)
end

#termdef_boilerplate_climb_up(clause, container) ⇒ Object



83
84
85
86
87
88
89
90
91
# File 'lib/metanorma/standoc/cleanup_terms_boilerplate.rb', line 83

def termdef_boilerplate_climb_up(clause, container)
  container.at(".//*[@id = '#{clause['id']}']") or return clause
  while (n = clause.parent)
    n.at(".//definitions") and break
    clause = n
    n["id"] == container["id"] and break
  end
  clause
end

#termdef_boilerplate_insert(xmldoc, isodoc, once = false) ⇒ Object



62
63
64
65
66
67
68
69
70
71
# File 'lib/metanorma/standoc/cleanup_terms_boilerplate.rb', line 62

def termdef_boilerplate_insert(xmldoc, isodoc, once = false)
  if once
    f = termdef_boilerplate_insert_location(xmldoc) and
      termdef_boilerplate_insert1(f, xmldoc, isodoc)
  else
    xmldoc.xpath(self.class::TERM_CLAUSE).each do |f|
      termdef_boilerplate_insert1(f, xmldoc, isodoc)
    end
  end
end

#termdef_boilerplate_insert1(sect, xmldoc, isodoc) ⇒ Object



93
94
95
96
97
98
99
100
101
102
103
# File 'lib/metanorma/standoc/cleanup_terms_boilerplate.rb', line 93

def termdef_boilerplate_insert1(sect, xmldoc, isodoc)
  ins = sect.at("./title")
  if (ins2 = sect.at("./clause[@type = 'boilerplate'] | " \
          "./note[@type = 'boilerplate']"))
    ins2.text.strip.downcase == "(default)" or return
    ins2.children = " "
    ins = ins2.children.first
  end
  term_defs_boilerplate(ins, xmldoc.xpath(".//termdocsource"),
                        sect.at(".//term"), sect.at(".//p"), isodoc)
end

#termdef_boilerplate_insert_location(xmldoc) ⇒ Object



73
74
75
76
77
78
79
80
81
# File 'lib/metanorma/standoc/cleanup_terms_boilerplate.rb', line 73

def termdef_boilerplate_insert_location(xmldoc)
  f = xmldoc.at(self.class::TERM_CLAUSE)
  root = xmldoc.at("//sections/terms | //sections/clause[@type = 'terms']")
  if f && root && f["id"] != root["id"]
    f = termdef_boilerplate_climb_up(f, root)
  elsif !f && root then f = root
  end
  f
end

#termdef_cleanup(xmldoc) ⇒ Object



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/metanorma/standoc/cleanup_terms.rb', line 113

def termdef_cleanup(xmldoc)
  termdef_unnest_cleanup(xmldoc)
  termlookup_cleanup(xmldoc)
  term_nonverbal_designations(xmldoc)
  (xmldoc)
  term_termsource_to_designation(xmldoc)
  term_designation_reorder(xmldoc)
  term_designation_redundant(xmldoc)
  termdef_from_termbase(xmldoc)
  termdomain_cleanup(xmldoc)
  termdef_stem_cleanup(xmldoc)
  termdefinition_cleanup(xmldoc)
  termdomain1_cleanup(xmldoc)
  termnote_example_cleanup(xmldoc)
  term_children_cleanup(xmldoc)
end

#termdef_from_termbase(xmldoc) ⇒ Object



91
92
93
94
95
96
97
# File 'lib/metanorma/standoc/cleanup_terms.rb', line 91

def termdef_from_termbase(xmldoc)
  xmldoc.xpath("//term").each do |x|
    if (c = x.at("./origin/termref")) && !x.at("./definition")
      x.at("./origin").previous = fetch_termbase(c["base"], c.text)
    end
  end
end

#termdef_remove_initial_paras(xmldoc) ⇒ Object



58
59
60
# File 'lib/metanorma/standoc/cleanup_terms_boilerplate.rb', line 58

def termdef_remove_initial_paras(xmldoc)
  xmldoc.xpath("//terms/p | //terms/ul").each(&:remove)
end

#termdef_stem_cleanup(xmldoc) ⇒ Object



4
5
6
7
8
9
10
11
# File 'lib/metanorma/standoc/cleanup_terms_designations.rb', line 4

def termdef_stem_cleanup(xmldoc)
  xmldoc.xpath("//term//expression/name[stem]").each do |n|
    test = n.dup
    test.at("./stem").remove
    test.text.strip.empty? or next
    n.parent.name = "letter-symbol"
  end
end

#termdef_unnest_cleanup(xmldoc) ⇒ Object

release termdef tags from surrounding paras



14
15
16
17
18
19
20
21
# File 'lib/metanorma/standoc/cleanup_terms_designations.rb', line 14

def termdef_unnest_cleanup(xmldoc)
  desgn = "//p/admitted | //p/deprecates | //p/preferred | //p//related"
  nodes = xmldoc.xpath(desgn)
  while !nodes.empty?
    nodes[0].parent.replace(nodes[0].parent.children)
    nodes = xmldoc.xpath(desgn)
  end
end

#termdefinition_cleanup(xmldoc) ⇒ Object



23
24
25
26
27
# File 'lib/metanorma/standoc/cleanup_terms.rb', line 23

def termdefinition_cleanup(xmldoc)
  generate_termdefinitions(xmldoc)
  split_termdefinitions(xmldoc)
  alternate_termdefinitions(xmldoc)
end

#termdocsource_cleanup(xmldoc) ⇒ Object



71
72
73
74
# File 'lib/metanorma/standoc/cleanup_terms.rb', line 71

def termdocsource_cleanup(xmldoc)
  f = xmldoc.at("//preface | //sections")
  xmldoc.xpath("//termdocsource").each { |s| f.previous = s.remove }
end

#termdomain1_cleanup(xmldoc) ⇒ Object



16
17
18
19
20
21
# File 'lib/metanorma/standoc/cleanup_terms.rb', line 16

def termdomain1_cleanup(xmldoc)
  xmldoc.xpath("//term").each do |t|
    d = t.xpath("./domain | ./subject").last or next
    defn = d.at("../definition") and defn.previous = d.remove
  end
end

#termdomain_cleanup(xmldoc) ⇒ Object



7
8
9
10
11
12
13
14
# File 'lib/metanorma/standoc/cleanup_terms.rb', line 7

def termdomain_cleanup(xmldoc)
  xmldoc.xpath("//p/domain").each do |a|
    parent = a.parent
    prev = parent.previous
    prev.next = a.remove
    parent.text.strip.empty? and parent.remove
  end
end

#termlookup_cleanup(xmldoc) ⇒ Object



109
110
111
# File 'lib/metanorma/standoc/cleanup_terms.rb', line 109

def termlookup_cleanup(xmldoc)
  Metanorma::Standoc::TermLookupCleanup.new(xmldoc, @log).call
end

#termnote_example_cleanup(xmldoc) ⇒ Object



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

def termnote_example_cleanup(xmldoc)
  %w(note example).each do |w|
    xmldoc.xpath("//term#{w}[not(ancestor::term)]").each do |x|
      if x["keepasterm"] then x.delete("keepasterm")
      else x.name = w
      end
    end
  end
end

#terms_subclause_type_tally(node, m, parent) ⇒ Object



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/metanorma/standoc/cleanup_section_names.rb', line 123

def terms_subclause_type_tally(node, m, parent)
  sym = if (node.at(".//term") && !node.at(".//definitions")) ||
      (node.name == "terms" && !node.at(".//term"))
          unless m[:parent] == :term # don't count Term > Term twice
            :term
          end
        elsif node.at(".//term") && node.at("./self::*#{SYMnoABBR}") then :tsna
        elsif node.at(".//term") && node.at("./self::*#{ABBRnoSYM}") then :tans
        elsif node.at(".//term") && node.at("./self::*#{SYMABBR}") then :tsa
        elsif node.at(".//term") && node.at("./self::*#{NO_SYMABBR}") then :tnsa
        elsif node.at("./self::*#{SYMnoABBR}") then :sna
        elsif node.at("./self::*#{ABBRnoSYM}") then :ans
        elsif node.at("./self::*#{SYMABBR}") then :sa
        elsif node.at("./self::*#{NO_SYMABBR}") then :nsa
        elsif node.name == "definitions" # ignore
        elsif node == parent && node.at(".//term") &&
            node.at(".//definitions")
          :termdef
        else :other
        end
  node == parent and m[:parent] = sym
  sym and m[sym] += 1
end

#terms_subclauses(node) ⇒ Object



114
115
116
117
118
119
120
121
# File 'lib/metanorma/standoc/cleanup_section_names.rb', line 114

def terms_subclauses(node)
  legal = %w(terms definitions clause)
  [node, node&.elements].compact.flatten
    .select do |x|
      legal.include?(x.name) &&
        !(x.name == "clause" && x["type"] == "boilerplate")
    end
end

#terms_terms_cleanup(xmldoc) ⇒ Object



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

def terms_terms_cleanup(xmldoc)
  xmldoc.xpath("//terms[terms][not(term)]").each do |t|
    t.name = "clause"
    t["type"] = "terms"
  end
end

#textcleanup(result) ⇒ Object



4
5
6
7
8
9
10
11
12
# File 'lib/metanorma/standoc/cleanup_text.rb', line 4

def textcleanup(result)
  text = result.flatten.map(&:rstrip) * "\n"
  text = text.gsub(/(?<!\s)\s+<fn /, "<fn ")
  %w(passthrough passthrough-inline).each do |v|
    text.gsub!(%r{<#{v}\s+formats="metanorma">([^<]*)
              </#{v}>}mx) { @c.decode($1) }
  end
  text
end

#title_footnote_move(xmldoc) ⇒ Object



86
87
88
89
90
91
92
93
94
# File 'lib/metanorma/standoc/cleanup_footnotes.rb', line 86

def title_footnote_move(xmldoc)
  ins = xmldoc.at("//bibdata/language")
  xmldoc.xpath("//bibdata/title//fn").each do |f|
    f.name = "note"
    f["type"] = "title-footnote"
    f.delete("reference")
    ins.previous = f.remove
  end
end

#to_preface(preface, clause) ⇒ Object



22
23
24
25
# File 'lib/metanorma/standoc/cleanup_section.rb', line 22

def to_preface(preface, clause)
  clause.delete("preface")
  preface.add_child clause.remove
end

#to_regex(str) ⇒ Object



20
21
22
# File 'lib/metanorma/standoc/cleanup_xref.rb', line 20

def to_regex(str)
  Regexp.new(str.gsub(/\s/, ""), Regexp::IGNORECASE | Regexp::MULTILINE)
end

#to_xreftarget(str) ⇒ Object



125
126
127
128
129
130
131
132
# File 'lib/metanorma/standoc/cleanup_inline.rb', line 125

def to_xreftarget(str)
  return Metanorma::Utils::to_ncname(str) unless /^[^#]+#.+$/.match?(str)

  /^(?<pref>[^#]+)#(?<suff>.+)$/ =~ str
  pref = pref.gsub(%r([#{Metanorma::Utils::NAMECHAR}])o, "_")
  suff = suff.gsub(%r([#{Metanorma::Utils::NAMECHAR}])o, "_")
  "#{pref}##{suff}"
end

#toc_cleanup(xmldoc) ⇒ Object



4
5
6
7
8
9
# File 'lib/metanorma/standoc/cleanup_toc.rb', line 4

def toc_cleanup(xmldoc)
  toc_cleanup_para(xmldoc)
  xmldoc.xpath("//toc").each { |t| toc_cleanup1(t, xmldoc) }
  toc_cleanup_clause(xmldoc)
  (xmldoc)
end

#toc_cleanup1(toc, xmldoc) ⇒ Object



43
44
45
46
47
48
49
50
51
# File 'lib/metanorma/standoc/cleanup_toc.rb', line 43

def toc_cleanup1(toc, xmldoc)
  depth = 1
  ret = ""
  toc_index(toc, xmldoc).each do |x|
    ret = toc_cleanup1_entry(x, depth, ret)
    depth = x[:depth]
  end
  toc.children = "<ul>#{ret}</ul>"
end

#toc_cleanup1_entry(entry, depth, ret) ⇒ Object



53
54
55
56
57
58
59
60
# File 'lib/metanorma/standoc/cleanup_toc.rb', line 53

def toc_cleanup1_entry(entry, depth, ret)
  if depth > entry[:depth]
    ret += "</ul></li>" * (depth - entry[:depth])
  elsif depth < entry[:depth]
    ret += "<li><ul>" * (entry[:depth] - depth)
  end
  ret + "<li><xref target='#{entry[:target]}'>#{entry[:text]}</xref></li>"
end

#toc_cleanup_clause(xmldoc) ⇒ Object



62
63
64
65
66
67
68
69
70
# File 'lib/metanorma/standoc/cleanup_toc.rb', line 62

def toc_cleanup_clause(xmldoc)
  xmldoc
    .xpath("//clause[@type = 'toc'] | //annex[@type = 'toc']").each do |c|
    c.xpath(".//ul[not(ancestor::ul)]").each do |ul|
      toc_cleanup_clause_entry(xmldoc, ul)
      ul.replace("<toc>#{ul.to_xml}</toc>")
    end
  end
end

#toc_cleanup_clause_entry(xmldoc, list) ⇒ Object



72
73
74
75
76
77
78
# File 'lib/metanorma/standoc/cleanup_toc.rb', line 72

def toc_cleanup_clause_entry(xmldoc, list)
  list.xpath(".//xref[not(text())]").each do |x|
    c1 = xmldoc.at("//*[@id = '#{x['target']}']")
    t = c1.at("./variant-title[@type = 'toc']") || c1.at("./title")
    x << t.dup.children
  end
end

#toc_cleanup_para(xmldoc) ⇒ Object



11
12
13
14
15
16
17
18
# File 'lib/metanorma/standoc/cleanup_toc.rb', line 11

def toc_cleanup_para(xmldoc)
  xmldoc.xpath("//p[toc]").each do |x|
    x.xpath("./toc").reverse_each do |t|
      x.next = t
    end
    x.remove if x.text.strip.empty?
  end
end

#toc_index(toc, xmldoc) ⇒ Object



20
21
22
23
24
25
26
27
# File 'lib/metanorma/standoc/cleanup_toc.rb', line 20

def toc_index(toc, xmldoc)
  depths = toc_index_depths(toc)
  depths.keys.each_with_object([]) do |key, arr|
    xmldoc.xpath(key).each do |x|
      arr << toc_index1(key, x, depths)
    end
  end.sort_by { |a| a[:line] }
end

#toc_index1(key, entry, depths) ⇒ Object



29
30
31
32
33
34
35
# File 'lib/metanorma/standoc/cleanup_toc.rb', line 29

def toc_index1(key, entry, depths)
  t = entry.at("./following-sibling::variant-title[@type = 'toc']") and
    entry = t
  { text: entry.children.to_xml, depth: depths[key].to_i,
    target: entry.xpath("(./ancestor-or-self::*/@id)[last()]")[0].text,
    line: entry.line }
end

#toc_index_depths(toc) ⇒ Object



37
38
39
40
41
# File 'lib/metanorma/standoc/cleanup_toc.rb', line 37

def toc_index_depths(toc)
  toc.xpath("./toc-xpath").each_with_object({}) do |x, m|
    m[x.text] = x["depth"]
  end
end

#toc_metadata(xmldoc) ⇒ Object



80
81
82
83
84
# File 'lib/metanorma/standoc/cleanup_toc.rb', line 80

def (xmldoc)
  @htmltoclevels || @doctoclevels || @pdftoclevels || @toclevels or return
  ins = add_misc_container(xmldoc)
  toc_metadata1(ins)
end

#toc_metadata1(ins) ⇒ Object



86
87
88
89
90
91
92
93
94
# File 'lib/metanorma/standoc/cleanup_toc.rb', line 86

def toc_metadata1(ins)
  [[@toclevels, "TOC Heading Levels"],
   [@htmltoclevels, "HTML TOC Heading Levels"],
   [@doctoclevels, "DOC TOC Heading Levels"],
   [@pdftoclevels, "PDF TOC Heading Levels"]].each do |n|
    n[0] and ins << "<presentation-metadata><name>#{n[1]}</name>" \
                    "<value>#{n[0]}</value></presentation-metadata>"
  end
end

#tq(text) ⇒ Object



31
32
33
# File 'lib/metanorma/standoc/cleanup_xref.rb', line 31

def tq(text)
  text.sub(/^"/, "").sub(/"$/, "")
end

#uninterrupt_quotes_around_xml(xmldoc) ⇒ Object

“abc<tag/>”, def => “abc”,<tag/> def



82
83
84
85
86
87
88
89
# File 'lib/metanorma/standoc/cleanup_text.rb', line 82

def uninterrupt_quotes_around_xml(xmldoc)
  xmldoc.traverse do |n|
    next unless n.text? && n&.previous&.element?
    next if uninterrupt_quotes_around_xml_skip(n)

    uninterrupt_quotes_around_xml1(n.previous)
  end
end

#uninterrupt_quotes_around_xml1(elem) ⇒ Object



114
115
116
117
118
119
120
121
122
123
# File 'lib/metanorma/standoc/cleanup_text.rb', line 114

def uninterrupt_quotes_around_xml1(elem)
  prev = elem.at(".//preceding::text()[1]") or return
  /\S\Z/.match?(prev.text) or return
  foll = elem.at(".//following::text()[1]")
  /"$/.match?(prev.text) and /^"/.match?(foll&.text) and return # "<tag/>"
  m = /\A(["'][[:punct:]]*)(\s|\Z)/
    .match(@c.decode(foll&.text)) or return
  foll.content = foll.text.sub(/\A(["'][[:punct:]]*)/, "")
  prev.content = "#{prev.text}#{m[1]}"
end

#uninterrupt_quotes_around_xml_skip(elem) ⇒ Object



106
107
108
109
110
111
112
# File 'lib/metanorma/standoc/cleanup_text.rb', line 106

def uninterrupt_quotes_around_xml_skip(elem)
  !(/\A['"]/.match?(elem.text) &&
  !ancestor_include?(elem.previous, IGNORE_QUOTES_ELEMENTS) &&
    ((elem.previous.text.strip.empty? &&
      !empty_tag_with_text_content?(elem.previous)) ||
     ignoretext?(elem.previous)))
end

#unnumbered_blocks_cleanup(xmldoc) ⇒ Object



233
234
235
236
237
238
239
240
# File 'lib/metanorma/standoc/cleanup_block.rb', line 233

def unnumbered_blocks_cleanup(xmldoc)
  @blockunnumbered&.each do |b|
    xmldoc.xpath("//#{b}").each do |e|
      /^[^_]/.match?(e["id"]) and e["unnumbered"] = "false"
      e["unnumbered"] ||= "true"
    end
  end
end

#unwrap_boilerplate_clauses(xmldoc, xpath) ⇒ Object



56
57
58
59
60
61
62
63
64
# File 'lib/metanorma/standoc/cleanup_boilerplate.rb', line 56

def unwrap_boilerplate_clauses(xmldoc, xpath)
  xmldoc.xpath(xpath).each do |f|
    f.xpath(".//clause[@type = 'boilerplate'] | " \
            ".//note[@type = 'boilerplate']").each do |c|
      c.at("./title")&.remove
      c.replace(c.children)
    end
  end
end

#uri_cleanup(xmldoc) ⇒ Object



210
211
212
213
214
215
216
217
# File 'lib/metanorma/standoc/cleanup_inline.rb', line 210

def uri_cleanup(xmldoc)
  xmldoc.xpath("//link[@target]").each do |l|
    l["target"] = Addressable::URI.parse(l["target"]).to_s
  rescue Addressable::URI::InvalidURIError
    err = "Malformed URI: #{l['target']}"
    @log.add("Anchors", l, err, severity: 0)
  end
end

#uri_component_encode(comp) ⇒ Object



219
220
221
# File 'lib/metanorma/standoc/cleanup_inline.rb', line 219

def uri_component_encode(comp)
  CGI.escape(comp).gsub("+", "%20")
end

#valid_attachment?(path, bib) ⇒ Boolean

Returns:

  • (Boolean)


187
188
189
190
191
192
193
# File 'lib/metanorma/standoc/cleanup_bibitem.rb', line 187

def valid_attachment?(path, bib)
  File.exist?(path) and return true
  p = Pathname.new(path).cleanpath
  @log.add("Bibliography", bib, "Attachment #{p} does not exist",
           severity: 0)
  false
end

#validate_ref_dl(bib, clause) ⇒ Object

do not accept implicit id



19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/metanorma/standoc/cleanup_asciibib.rb', line 19

def validate_ref_dl(bib, clause)
  id = bib["id"]
  id ||= clause["id"] unless /^_/.match?(clause["id"])
  unless id
    @log.add("Anchors", clause,
             "The following reference is missing an anchor:\n" \
             "#{clause.to_xml}", severity: 1)
    return
  end
  @refids << id
  validate_ref_dl1(bib, id, clause)
end

#validate_ref_dl1(bib, id, clause) ⇒ Object



32
33
34
35
36
37
38
39
40
# File 'lib/metanorma/standoc/cleanup_asciibib.rb', line 32

def validate_ref_dl1(bib, id, clause)
  bib["title"] or
    @log.add("Bibliography", clause, "Reference #{id} is missing a title",
             severity: 1)
  bib["docid"] or
    @log.add("Bibliography", clause,
             "Reference #{id} is missing a document identifier (docid)",
             severity: 1)
end

#variant_cleanup(xmldoc) ⇒ Object



155
156
157
158
159
160
161
162
163
164
165
# File 'lib/metanorma/standoc/cleanup.rb', line 155

def variant_cleanup(xmldoc)
  variant_space_cleanup(xmldoc)
  xmldoc.xpath("//*[variant]").each do |c|
    next unless c.children.any? do |n|
      n.name != "variant" && (!n.text? || !n.text.gsub(/\s/, "").empty?)
    end

    variant_cleanup1(c)
  end
  xmldoc.xpath("//variantwrap").each { |n| n.name = "variant" }
end

#variant_cleanup1(elem) ⇒ Object



167
168
169
170
171
172
173
174
175
176
177
# File 'lib/metanorma/standoc/cleanup.rb', line 167

def variant_cleanup1(elem)
  elem.xpath("./variant").each do |n|
    if n.at_xpath("preceding-sibling::node()" \
                  "[not(self::text()[not(normalize-space())])][1]" \
                  "[self::variantwrap]")
      n.previous_element << n
    else
      n.replace("<variantwrap/>").first << n
    end
  end
end

#variant_space_cleanup(xmldoc) ⇒ Object



179
180
181
182
183
184
185
186
187
188
# File 'lib/metanorma/standoc/cleanup.rb', line 179

def variant_space_cleanup(xmldoc)
  xmldoc.xpath("//*[variant]").each do |c|
    next if c.next.nil? || c.next.next.nil?

    if c.next.text? && c.next.next.name == "variant"
      c.next.text.gsub(/\s/, "").empty? and
        c.next.remove
    end
  end
end

#verify_term_defs_source(source) ⇒ Object



29
30
31
32
33
34
35
36
# File 'lib/metanorma/standoc/cleanup_terms_boilerplate.rb', line 29

def verify_term_defs_source(source)
  source.each do |s|
    @anchors[s["bibitemid"]] or
      @log.add("Crossreferences", nil,
               "term source #{s['bibitemid']} not referenced",
               severity: 1)
  end
end

#xml_unescape_mathml(xml) ⇒ Object



73
74
75
76
77
78
79
# File 'lib/metanorma/standoc/cleanup_maths.rb', line 73

def xml_unescape_mathml(xml)
  xml.children.any?(&:element?) and return
  math = xml.text.gsub("&lt;", "<").gsub("&gt;", ">")
    .gsub("&quot;", '"').gsub("&apos;", "'").gsub("&amp;", "&")
    .gsub(/<[^: \r\n\t\/]+:/, "<").gsub(/<\/[^ \r\n\t:]+:/, "</")
  xml.children = math
end

#xref_alias(elem) ⇒ Object



225
226
227
228
229
# File 'lib/metanorma/standoc/cleanup_xref.rb', line 225

def xref_alias(elem)
  elem["style"] == "id" && elem.text.strip.empty? and
    elem << elem["target"]
  elem["target"] = @anchor_alias[elem["target"]]
end

#xref_cleanup(xmldoc) ⇒ Object



129
130
131
132
133
134
135
# File 'lib/metanorma/standoc/cleanup_xref.rb', line 129

def xref_cleanup(xmldoc)
  anchor_alias(xmldoc)
  xref_compound_cleanup(xmldoc)
  xref_cleanup1(xmldoc)
  xref_compound_wrapup(xmldoc)
  eref_stack(xmldoc)
end

#xref_cleanup1(xmldoc) ⇒ Object



201
202
203
204
205
206
207
208
209
210
211
# File 'lib/metanorma/standoc/cleanup_xref.rb', line 201

def xref_cleanup1(xmldoc)
  xmldoc.xpath("//xref").each do |x|
    %r{:(?!//)}.match?(x["target"]) and xref_to_internal_eref(x)
    x.name == "xref" or next
    if refid? x["target"]
      xref_to_eref(x, "eref")
    elsif @anchor_alias[x["target"]] then xref_alias(x)
    else x.delete("type")
    end
  end
end

#xref_compound_cleanup(xmldoc) ⇒ Object



168
169
170
171
172
173
174
175
# File 'lib/metanorma/standoc/cleanup_xref.rb', line 168

def xref_compound_cleanup(xmldoc)
  xmldoc.xpath("//xref").each do |x|
    x["target"].include?(";") or next
    locations = x["target"].split(";")
    x["target"] = locations.first.sub(/^[^!]*!/, "")
    xref_compound_cleanup1(x, locations)
  end
end

#xref_compound_cleanup1(xref, locations) ⇒ Object



177
178
179
180
181
182
183
184
# File 'lib/metanorma/standoc/cleanup_xref.rb', line 177

def xref_compound_cleanup1(xref, locations)
  xref.children.empty? and xref.children = "<sentinel/>"
  xref_parse_compound_locations(locations).reverse_each do |y|
    xref.children.first.previous =
      "<xref target='#{y[1]}' connective='#{y[0]}'/>"
  end
  xref&.at("./sentinel")&.remove
end

#xref_compound_wrapup(xmldoc) ⇒ Object



195
196
197
198
199
# File 'lib/metanorma/standoc/cleanup_xref.rb', line 195

def xref_compound_wrapup(xmldoc)
  xmldoc.xpath("//xref//xref").each do |x|
    x.name = "location"
  end
end

#xref_parse_compound_locations(locations) ⇒ Object



186
187
188
189
190
191
192
193
# File 'lib/metanorma/standoc/cleanup_xref.rb', line 186

def xref_parse_compound_locations(locations)
  l = locations.map { |y| y.split("!", 2) }
  l.map.with_index do |y, i|
    y.size == 1 and
      y.unshift(l.dig(i + 1, 0) == "to" ? "from" : "and")
    y
  end
end

#xref_to_eref(elem, name) ⇒ Object



109
110
111
112
113
114
115
116
117
118
119
# File 'lib/metanorma/standoc/cleanup_xref.rb', line 109

def xref_to_eref(elem, name)
  elem.name = name
  elem["bibitemid"] = elem["target"]
  if ref = @anchors&.dig(elem["target"], :xref)
    t = @anchors.dig(elem["target"], :id, elem["style"]) and ref = t
    elem["citeas"] = @c.decode(ref)
  else xref_to_eref1(elem)
  end
  elem.delete("target")
  extract_localities(elem)
end

#xref_to_eref1(elem) ⇒ Object



121
122
123
124
125
126
127
# File 'lib/metanorma/standoc/cleanup_xref.rb', line 121

def xref_to_eref1(elem)
  elem["citeas"] = ""
  @internal_eref_namespaces.include?(elem["type"]) or
    @log.add("Crossreferences", elem,
             "#{elem['target']} does not have a corresponding " \
             "anchor ID in the bibliography!")
end

#xref_to_internal_eref(elem) ⇒ Object



213
214
215
216
217
218
219
220
221
222
223
# File 'lib/metanorma/standoc/cleanup_xref.rb', line 213

def xref_to_internal_eref(elem)
  a = elem["target"].split(":", 3)
  unless a.size < 2 || a[0].empty? || a[1].empty?
    elem["target"] = "#{a[0]}_#{a[1]}"
    a.size > 2 and
      elem.children = %{anchor="#{a[2..].join}",#{elem.children&.text}}
    elem["type"] = a[0]
    @internal_eref_namespaces << a[0]
    xref_to_eref(elem, "eref")
  end
end

#xreftarget_cleanup(elem) ⇒ Object



156
157
158
159
160
161
162
163
164
165
166
# File 'lib/metanorma/standoc/cleanup_inline.rb', line 156

def xreftarget_cleanup(elem)
  elem.xpath("//xref/@target").each do |s|
    if (ret = to_xreftarget(s.value)) != (orig = s.value)
      s.value = ret
      output = s.parent.dup
      output.children.remove
      @log.add("Anchors", s.parent,
               "normalised identifier in #{output} from #{orig}")
    end
  end
end

#yaml2relaton(yaml, amend = nil) ⇒ Object



135
136
137
138
139
140
141
# File 'lib/metanorma/standoc/cleanup_bibdata.rb', line 135

def yaml2relaton(yaml, amend = nil)
  r = RelatonBib.parse_yaml(yaml.to_yaml, [Date], symbolize_names: true)
  h = RelatonBib::HashConverter.hash_to_bib(r)
  b = RelatonBib::BibliographicItem.new(**h).to_xml
  amend and b.sub!("</bibitem>", "#{amend}</bibitem>")
  b
end