Module: Metanorma::Standoc::Index

Included in:
Cleanup
Defined in:
lib/metanorma/cleanup/index.rb

Constant Summary collapse

EMPTY_INDEX_XPATH =

normalize-space(.) rather than normalize-space(text()): index terms wrapped entirely in formatting (a priori, stem) have no direct text nodes but are not empty

"//index[not(.//primary[normalize-space(.)]) " \
"or .//secondary[. and not(normalize-space(.))] " \
"or .//tertiary[. and not(normalize-space(.))]]".freeze
DESIGNATIONS =
%w(preferred admitted deprecates).freeze

Instance Method Summary collapse

Instance Method Details

#block_index_cleanup(xmldoc) ⇒ Object



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

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

#designation?(elem) ⇒ Boolean

Returns:

  • (Boolean)


79
80
81
# File 'lib/metanorma/cleanup/index.rb', line 79

def designation?(elem)
  DESIGNATIONS.include?(elem&.name)
end

#empty_index_context(node) ⇒ Object



24
25
26
27
# File 'lib/metanorma/cleanup/index.rb', line 24

def empty_index_context(node)
  ctx = node.ancestors.find { |a| a["id"] || a["anchor"] }
  ctx ? (ctx["id"] || ctx["anchor"]) : "(unknown location)"
end

#include_indexterm?(elem) ⇒ Boolean

Returns:

  • (Boolean)


48
49
50
51
# File 'lib/metanorma/cleanup/index.rb', line 48

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

#index_cleanup(xmldoc) ⇒ Object



12
13
14
15
16
# File 'lib/metanorma/cleanup/index.rb', line 12

def index_cleanup(xmldoc)
  para_index_cleanup(xmldoc)
  block_index_cleanup(xmldoc)
  index_empty_check(xmldoc)
end

#index_cleanup1(term, fieldofappl) ⇒ Object



122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/metanorma/cleanup/index.rb', line 122

def index_cleanup1(term, fieldofappl)
  term or return
  # The auto-index primary is the designation text; existing index /
  # index-xref children (e.g. folded in from term-adjacent index
  # paragraphs, metanorma/metanorma-standoc#1237) are themselves index
  # entries and must not be nested inside this new primary.
  idx = term.children
    .reject { |c| %w(index index-xref).include?(c.name) }
    .map(&:to_xml).join
  fieldofappl.empty? or idx += ", <#{fieldofappl}>"
  term << "<index><primary>#{idx}</primary></index>"
end

#index_empty_check(xmldoc) ⇒ Object



18
19
20
21
22
# File 'lib/metanorma/cleanup/index.rb', line 18

def index_empty_check(xmldoc)
  xmldoc.xpath(EMPTY_INDEX_XPATH).each do |i|
    @log.add("STANDOC_64", i, params: [empty_index_context(i)])
  end
end

#indexterm_para?(para) ⇒ Boolean

Returns:

  • (Boolean)


42
43
44
45
46
# File 'lib/metanorma/cleanup/index.rb', line 42

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

#para_index_cleanup(xmldoc) ⇒ Object



53
54
55
56
57
58
# File 'lib/metanorma/cleanup/index.rb', line 53

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



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

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

#preceding_designation(node) ⇒ Object



104
105
106
107
108
# File 'lib/metanorma/cleanup/index.rb', line 104

def preceding_designation(node)
  el = node.previous_element
  el = el.previous_element until el.nil? || designation?(el)
  el
end

#term_designation_name(elem) ⇒ Object

Inside a term, index elements must live within a designation's name, which admits (PureTextElement | index | index-xref)*; the term model does not admit them as bare children of a designation or the term. term_index_relocate moves any such misplaced index there afterwards. metanorma/metanorma-standoc#1237



73
74
75
# File 'lib/metanorma/cleanup/index.rb', line 73

def term_designation_name(elem)
  elem&.at("./expression/name | ./letter-symbol/name")
end

#term_index_cleanup(xmldoc) ⇒ Object



110
111
112
113
114
115
116
117
118
119
120
# File 'lib/metanorma/cleanup/index.rb', line 110

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_index_relocate(xmldoc) ⇒ Object

Relocate index / index-xref elements that ended up as bare children of a designation or a term -- positions the term model does not admit -- into a designation's name, which admits index / index-xref. This catches designation-adjacent index paragraphs whose designation was still macro-wrapped (e.g. after alt:[]) when para_index_cleanup ran, so it did not recognise the designation. metanorma/metanorma-standoc#1237



89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/metanorma/cleanup/index.rb', line 89

def term_index_relocate(xmldoc)
  xmldoc.xpath("//#{DESIGNATIONS.join(' | //')}").each do |d|
    name = term_designation_name(d) or next
    d.xpath("./index | ./index-xref").each { |i| name << i.remove }
  end
  xmldoc.xpath("//term").each do |term|
    term.xpath("./index | ./index-xref").each do |i|
      d = preceding_designation(i) ||
        term.at("./#{DESIGNATIONS.join(' | ./')}")
      name = term_designation_name(d) or next
      name << i.remove
    end
  end
end