metanorma-standoc 2.0.3 → 2.0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/lib/metanorma/standoc/base.rb +73 -23
  3. data/lib/metanorma/standoc/blocks.rb +1 -1
  4. data/lib/metanorma/standoc/blocks_notes.rb +2 -2
  5. data/lib/metanorma/standoc/cleanup_amend.rb +33 -30
  6. data/lib/metanorma/standoc/cleanup_boilerplate.rb +29 -5
  7. data/lib/metanorma/standoc/cleanup_ref.rb +31 -2
  8. data/lib/metanorma/standoc/cleanup_ref_dl.rb +25 -16
  9. data/lib/metanorma/standoc/cleanup_section.rb +1 -1
  10. data/lib/metanorma/standoc/cleanup_terms_designations.rb +4 -2
  11. data/lib/metanorma/standoc/cleanup_text.rb +39 -17
  12. data/lib/metanorma/standoc/cleanup_xref.rb +70 -8
  13. data/lib/metanorma/standoc/converter.rb +2 -1
  14. data/lib/metanorma/standoc/inline.rb +21 -12
  15. data/lib/metanorma/standoc/isodoc.rng +63 -3
  16. data/lib/metanorma/standoc/macros.rb +14 -2
  17. data/lib/metanorma/standoc/macros_embed.rb +35 -14
  18. data/lib/metanorma/standoc/macros_note.rb +4 -3
  19. data/lib/metanorma/standoc/processor.rb +6 -1
  20. data/lib/metanorma/standoc/ref.rb +14 -15
  21. data/lib/metanorma/standoc/ref_utility.rb +6 -5
  22. data/lib/metanorma/standoc/render.rb +7 -3
  23. data/lib/metanorma/standoc/table.rb +8 -10
  24. data/lib/metanorma/standoc/term_lookup_cleanup.rb +10 -6
  25. data/lib/metanorma/standoc/utils.rb +3 -1
  26. data/lib/metanorma/standoc/validate.rb +79 -10
  27. data/lib/metanorma/standoc/version.rb +1 -1
  28. data/metanorma-standoc.gemspec +2 -2
  29. data/spec/assets/a2.adoc +4 -2
  30. data/spec/assets/a3.adoc +2 -2
  31. data/spec/assets/a3a.adoc +7 -0
  32. data/spec/metanorma/base_spec.rb +1 -1
  33. data/spec/metanorma/cleanup_spec.rb +31 -20
  34. data/spec/metanorma/cleanup_terms_spec.rb +16 -4
  35. data/spec/metanorma/inline_spec.rb +31 -0
  36. data/spec/metanorma/macros_plantuml_spec.rb +41 -42
  37. data/spec/metanorma/macros_spec.rb +206 -4
  38. data/spec/metanorma/processor_spec.rb +17 -13
  39. data/spec/metanorma/refs_spec.rb +129 -2
  40. data/spec/metanorma/validate_spec.rb +108 -0
  41. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec.yml +45 -45
  42. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec1.yml +10 -10
  43. data/spec/vcr_cassettes/hide_refs.yml +39 -39
  44. data/spec/vcr_cassettes/isobib_get_123.yml +12 -12
  45. data/spec/vcr_cassettes/isobib_get_123_1.yml +23 -23
  46. data/spec/vcr_cassettes/isobib_get_123_1_fr.yml +28 -28
  47. data/spec/vcr_cassettes/isobib_get_123_2001.yml +11 -11
  48. data/spec/vcr_cassettes/isobib_get_124.yml +12 -12
  49. data/spec/vcr_cassettes/rfcbib_get_rfc8341.yml +18 -18
  50. data/spec/vcr_cassettes/separates_iev_citations_by_top_level_clause.yml +75 -65
  51. metadata +10 -9
@@ -3,11 +3,12 @@ module Metanorma
3
3
  module Cleanup
4
4
  # extending localities to cover ISO referencing
5
5
  LOCALITY_REGEX_STR = <<~REGEXP.freeze
6
- ^((?<locality>section|clause|part|paragraph|chapter|page|
6
+ ^(((?<conn>and|or|from|to)!)?
7
+ (?<locality>section|clause|part|paragraph|chapter|page|
7
8
  table|annex|figure|example|note|formula|list|time|anchor|
8
9
  locality:[^ \\t\\n\\r:,;=]+)(\\s+|=)
9
- (?<ref>[^"][^ \\t\\n,:-]*|"[^"]+")
10
- (-(?<to>[^"][^ \\t\\n,:-]*|"[^"]"))?|
10
+ (?<ref>[^"][^ \\t\\n,:;-]*|"[^"]+")
11
+ (-(?<to>[^"][^ \\t\\n,:;-]*|"[^"]"))?|
11
12
  (?<locality2>whole|locality:[^ \\t\\n\\r:,;=]+))(?<punct>[,:;]?)\\s*
12
13
  (?<text>.*)$
13
14
  REGEXP
@@ -30,16 +31,37 @@ module Metanorma
30
31
  def extract_localities1(elem, text)
31
32
  b = elem.add_child("<localityStack/>").first if LOCALITY_RE.match text
32
33
  while (m = LOCALITY_RE.match text)
33
- ref = m[:ref] ? "<referenceFrom>#{tq m[:ref]}</referenceFrom>" : ""
34
- refto = m[:to] ? "<referenceTo>#{tq m[:to]}</referenceTo>" : ""
35
- b.add_child("<locality type='#{locality_label(m)}'>#{ref}#{refto}"\
36
- "</locality>")
34
+ add_locality(b, m)
37
35
  text = m[:text]
38
36
  b = elem.add_child("<localityStack/>").first if m[:punct] == ";"
39
37
  end
38
+ fill_in_eref_connectives(elem)
40
39
  elem.add_child(text) if text
41
40
  end
42
41
 
42
+ def add_locality(stack, match)
43
+ stack.children.empty? && match[:conn] and
44
+ stack["connective"] = match[:conn]
45
+ ref =
46
+ match[:ref] ? "<referenceFrom>#{tq match[:ref]}</referenceFrom>" : ""
47
+ refto = match[:to] ? "<referenceTo>#{tq match[:to]}</referenceTo>" : ""
48
+ stack.add_child("<locality type='#{locality_label(match)}'>#{ref}"\
49
+ "#{refto}</locality>")
50
+ end
51
+
52
+ def fill_in_eref_connectives(elem)
53
+ return if elem.xpath("./localityStack").size < 2
54
+
55
+ elem.xpath("./localityStack[not(@connective)]").each do |l|
56
+ n = l.next_element
57
+ l["connective"] = if n && n.name == "localityStack" &&
58
+ n["connective"] == "to"
59
+ "from"
60
+ else "and"
61
+ end
62
+ end
63
+ end
64
+
43
65
  def locality_label(match)
44
66
  loc = match[:locality] || match[:locality2]
45
67
  /^locality:/.match?(loc) ? loc : loc&.downcase
@@ -65,8 +87,48 @@ module Metanorma
65
87
  end
66
88
 
67
89
  def xref_cleanup(xmldoc)
90
+ xref_compound_cleanup(xmldoc)
91
+ xref_cleanup1(xmldoc)
92
+ xref_compound_wrapup(xmldoc)
93
+ end
94
+
95
+ def xref_compound_cleanup(xmldoc)
96
+ xmldoc.xpath("//xref").each do |x|
97
+ /;/.match?(x["target"]) or next
98
+ locations = x["target"].split(";")
99
+ x["target"] = locations.first.sub(/^[^!]*!/, "")
100
+ xref_compound_cleanup1(x, locations)
101
+ end
102
+ end
103
+
104
+ def xref_compound_cleanup1(xref, locations)
105
+ xref.children.empty? and xref.children = "<sentinel/>"
106
+ xref_parse_compound_locations(locations).reverse.each do |y|
107
+ xref.children.first.previous =
108
+ "<xref target='#{y[1]}' connective='#{y[0]}'/>"
109
+ end
110
+ xref&.at("./sentinel")&.remove
111
+ end
112
+
113
+ def xref_parse_compound_locations(locations)
114
+ l = locations.map { |y| y.split("!", 2) }
115
+ l.map.with_index do |y, i|
116
+ if y.size == 1
117
+ y.unshift(l.dig(i + 1, 0) == "to" ? "from" : "and")
118
+ end
119
+ y
120
+ end
121
+ end
122
+
123
+ def xref_compound_wrapup(xmldoc)
124
+ xmldoc.xpath("//xref//xref").each do |x|
125
+ x.name = "location"
126
+ end
127
+ end
128
+
129
+ def xref_cleanup1(xmldoc)
68
130
  xmldoc.xpath("//xref").each do |x|
69
- /:/.match(x["target"]) and xref_to_internal_eref(x)
131
+ /:/.match?(x["target"]) and xref_to_internal_eref(x)
70
132
  next unless x.name == "xref"
71
133
 
72
134
  if refid? x["target"]
@@ -53,6 +53,7 @@ module Metanorma
53
53
  inline_macro Metanorma::Standoc::FormOptionMacro
54
54
  inline_macro Metanorma::Standoc::ToCInlineMacro
55
55
  inline_macro Metanorma::Standoc::PassInlineMacro
56
+ inline_macro Metanorma::Standoc::StdLinkInlineMacro
56
57
  inline_macro Metanorma::Plugin::Lutaml::LutamlFigureInlineMacro
57
58
  inline_macro Metanorma::Plugin::Lutaml::LutamlTableInlineMacro
58
59
  block_macro Metanorma::Plugin::Lutaml::LutamlDiagramBlockMacro
@@ -91,7 +92,7 @@ module Metanorma
91
92
  end
92
93
 
93
94
  class << self
94
- attr_accessor :_file
95
+ attr_accessor :_file, :embed_hdr
95
96
  end
96
97
 
97
98
  def self.inherited(konv) # rubocop:disable Lint/MissingSuper
@@ -40,20 +40,29 @@ module Metanorma
40
40
  end
41
41
 
42
42
  def inline_anchor_xref_attrs(node)
43
- m = /^(?<drop>droploc%)?(?<case>capital%|lowercase%)?(?<drop2>droploc%)?
44
- (?<fn>fn:?\s*)?(?<text>.*)$/x.match node.text
43
+ m = inline_anchor_xref_match(node)
45
44
  t = node.target.gsub(/^#/, "").gsub(%r{(\.xml|\.adoc)(#.*$)}, "\\2")
46
45
  m.nil? and return { target: t, type: "inline", text: node.text }
47
- droploc = m[:drop].nil? && m[:drop2].nil? ? nil : true
48
- f = m[:fn].nil? ? "inline" : "footnote"
49
- c = if %i[case fn drop drop2].any? do |x|
50
- !m[x].nil?
51
- end
52
- m[:text]
53
- else node.text
54
- end
55
- { target: t, type: f, case: m[:case]&.sub(/%$/, ""), droploc: droploc,
56
- text: c }
46
+ { target: t, type: m[:fn].nil? ? "inline" : "footnote",
47
+ case: m[:case]&.sub(/%$/, ""),
48
+ droploc: m[:drop].nil? && m[:drop2].nil? ? nil : true,
49
+ text: inline_anchor_xref_text(m, node),
50
+ hidden: m[:hidden] }
51
+ end
52
+
53
+ def inline_anchor_xref_match(node)
54
+ /^(hidden%(?<hidden>[^,]+),?)?
55
+ (?<drop>droploc%)?(?<case>capital%|lowercase%)?(?<drop2>droploc%)?
56
+ (?<fn>fn:?\s*)?(?<text>.*)$/x.match node.text
57
+ end
58
+
59
+ def inline_anchor_xref_text(match, node)
60
+ if %i[case fn drop drop2 hidden].any? do |x|
61
+ !match[x].nil?
62
+ end
63
+ match[:text]
64
+ else node.text
65
+ end
57
66
  end
58
67
 
59
68
  def inline_anchor_link(node)
@@ -152,9 +152,7 @@
152
152
  <data type="boolean"/>
153
153
  </attribute>
154
154
  </optional>
155
- <oneOrMore>
156
- <ref name="PureTextElement"/>
157
- </oneOrMore>
155
+ <ref name="XrefBody"/>
158
156
  </element>
159
157
  </define>
160
158
  <define name="erefType">
@@ -188,6 +186,42 @@
188
186
  <ref name="PureTextElement"/>
189
187
  </oneOrMore>
190
188
  </define>
189
+ <define name="localityStack">
190
+ <element name="localityStack">
191
+ <optional>
192
+ <attribute name="connective">
193
+ <choice>
194
+ <value>and</value>
195
+ <value>or</value>
196
+ <value>from</value>
197
+ <value>to</value>
198
+ <value/>
199
+ </choice>
200
+ </attribute>
201
+ </optional>
202
+ <zeroOrMore>
203
+ <ref name="locality"/>
204
+ </zeroOrMore>
205
+ </element>
206
+ </define>
207
+ <define name="sourceLocalityStack">
208
+ <element name="sourceLocalityStack">
209
+ <optional>
210
+ <attribute name="connective">
211
+ <choice>
212
+ <value>and</value>
213
+ <value>or</value>
214
+ <value>from</value>
215
+ <value>to</value>
216
+ <value/>
217
+ </choice>
218
+ </attribute>
219
+ </optional>
220
+ <zeroOrMore>
221
+ <ref name="sourceLocality"/>
222
+ </zeroOrMore>
223
+ </element>
224
+ </define>
191
225
  <define name="ul">
192
226
  <element name="ul">
193
227
  <attribute name="id">
@@ -2641,4 +2675,30 @@
2641
2675
  </zeroOrMore>
2642
2676
  </element>
2643
2677
  </define>
2678
+ <define name="XrefBody">
2679
+ <zeroOrMore>
2680
+ <ref name="XrefTarget"/>
2681
+ </zeroOrMore>
2682
+ <oneOrMore>
2683
+ <ref name="PureTextElement"/>
2684
+ </oneOrMore>
2685
+ </define>
2686
+ <define name="XrefTarget">
2687
+ <element name="location">
2688
+ <attribute name="target">
2689
+ <data type="string">
2690
+ <param name="pattern">\i\c*|\c+#\c+</param>
2691
+ </data>
2692
+ </attribute>
2693
+ <attribute name="connective">
2694
+ <choice>
2695
+ <value>and</value>
2696
+ <value>or</value>
2697
+ <value>from</value>
2698
+ <value>to</value>
2699
+ <value/>
2700
+ </choice>
2701
+ </attribute>
2702
+ </element>
2703
+ </define>
2644
2704
  </grammar>
@@ -82,7 +82,7 @@ module Metanorma
82
82
  .match(l) && (ignore = !ignore)
83
83
  next if l.empty? || l.match(/ \+$/) || /^\[.*\]$/.match?(l) || ignore
84
84
  next if i == lines.size - 1 ||
85
- i < lines.size - 1 && lines[i + 1].empty?
85
+ (i < lines.size - 1 && lines[i + 1].empty?)
86
86
 
87
87
  lines[i] += " +"
88
88
  end
@@ -140,7 +140,7 @@ module Metanorma
140
140
  parse_content_as :text
141
141
 
142
142
  def process(parent, target, attrs)
143
- /^(?<lang>[^-]*)(-(?<script>.*))?$/ =~ target
143
+ /^(?<lang>[^-]*)(?:-(?<script>.*))?$/ =~ target
144
144
  out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
145
145
  if script
146
146
  %{<variant lang=#{lang} script=#{script}>#{out}</variant>}
@@ -201,5 +201,17 @@ module Metanorma
201
201
  %{<passthrough formats="#{format}">#{out}</passthrough>}
202
202
  end
203
203
  end
204
+
205
+ class StdLinkInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
206
+ use_dsl
207
+ named :"std-link"
208
+ parse_content_as :text
209
+ using_format :short
210
+
211
+ def process(parent, _target, attrs)
212
+ create_anchor(parent, "hidden%#{attrs['text']}",
213
+ type: :xref, target: "_#{UUIDTools::UUID.random_create}")
214
+ end
215
+ end
204
216
  end
205
217
  end
@@ -5,13 +5,24 @@ module Metanorma
5
5
  return reader if reader.eof?
6
6
 
7
7
  lines = reader.readlines
8
- while !lines.grep(/^embed::/).empty?
9
- headings = lines.grep(/^== /).map(&:strip)
10
- lines = lines.map do |line|
11
- /^embed::/.match?(line) ? embed(line, doc, reader, headings) : line
12
- end.flatten
8
+ headings = lines.grep(/^== /).map(&:strip)
9
+ ret = lines.each_with_object({ lines: [], hdr: [] }) do |line, m|
10
+ process1(line, m, doc, reader, headings)
13
11
  end
14
- ::Asciidoctor::Reader.new lines
12
+ #doc.converter.embed_hdr = ret[:hdr]
13
+ doc.attributes["embed_hdr"] = ret[:hdr]
14
+ ::Asciidoctor::Reader.new ret[:lines].flatten
15
+ end
16
+
17
+ def process1(line, acc, doc, reader, headings)
18
+ if /^embed::/.match?(line)
19
+ e = embed(line, doc, reader, headings)
20
+ acc[:lines] << e[:lines]
21
+ acc[:hdr] << e[:hdr]
22
+ else
23
+ acc[:lines] << line
24
+ end
25
+ acc
15
26
  end
16
27
 
17
28
  def filename(line, doc, reader)
@@ -27,26 +38,36 @@ module Metanorma
27
38
  end
28
39
  end
29
40
 
41
+ def read(inc_path)
42
+ ::File.open inc_path, "r" do |fd|
43
+ readlines_safe(fd).map(&:chomp)
44
+ end
45
+ end
46
+
30
47
  def embed(line, doc, reader, headings)
31
48
  inc_path = filename(line, doc, reader) or return line
32
49
  lines = filter_sections(read(inc_path), headings)
33
50
  doc = Asciidoctor::Document.new [], { safe: :safe }
34
51
  reader = ::Asciidoctor::PreprocessorReader.new doc, lines
35
- strip_header(reader.read_lines)
52
+ ret = strip_header(reader.read_lines)
53
+ embed_recurse(ret, doc, reader, headings)
36
54
  end
37
55
 
38
- def read(inc_path)
39
- ::File.open inc_path, "r" do |fd|
40
- readlines_safe(fd).map(&:chomp)
56
+ def embed_recurse(ret, doc, reader, headings)
57
+ ret1 = ret[:lines].each_with_object({ lines: [], hdr: [] }) do |line, m|
58
+ process1(line, m, doc, reader, headings)
41
59
  end
60
+ { lines: ret1[:lines],
61
+ hdr: { text: ret[:hdr].join("\n"), child: ret1[:hdr] } }
42
62
  end
43
63
 
44
64
  def strip_header(lines)
45
- return lines unless !lines.empty? && lines.first.start_with?("= ")
65
+ return { lines: lines, hdr: nil } unless !lines.empty? &&
66
+ lines.first.start_with?("= ")
46
67
 
47
68
  skip = true
48
- lines.each_with_object([]) do |l, m|
49
- m << l unless skip
69
+ lines.each_with_object({ hdr: [], lines: [] }) do |l, m|
70
+ m[skip ? :hdr : :lines] << l
50
71
  skip = false if !/\S/.match?(l)
51
72
  end
52
73
  end
@@ -56,7 +77,7 @@ module Metanorma
56
77
  lines.each_with_index.with_object([]) do |(l, i), m|
57
78
  if headings.include?(l.strip)
58
79
  skip = true
59
- m.unshift while !m.empty? && /^\S/.match?(m[-1])
80
+ m.pop while !m.empty? && /^\S/.match?(m[-1])
60
81
  elsif skip && /^== |^embed::|^include::/.match?(l)
61
82
  skip = false
62
83
  j = i
@@ -22,9 +22,10 @@ module Metanorma
22
22
  para.set_attr("name", "todo")
23
23
  para.set_attr("caption", "TODO")
24
24
  para.lines[0].sub!(/^TODO: /, "")
25
- todo = Asciidoctor::Block.new(parent, :admonition, attributes: para.attributes,
26
- source: para.lines,
27
- content_model: :compound)
25
+ todo = Asciidoctor::Block
26
+ .new(parent, :admonition, attributes: para.attributes,
27
+ source: para.lines,
28
+ content_model: :compound)
28
29
  parent.blocks[parent.blocks.index(para)] = todo
29
30
  end
30
31
  end
@@ -3,6 +3,10 @@ require "metanorma/processor"
3
3
  module Metanorma
4
4
  module Standoc
5
5
  class Processor < Metanorma::Processor
6
+ class << self
7
+ attr_reader :asciidoctor_backend
8
+ end
9
+
6
10
  def initialize # rubocop:disable Lint/MissingSuper
7
11
  @short = :standoc
8
12
  @input_format = :asciidoc
@@ -22,7 +26,8 @@ module Metanorma
22
26
  end
23
27
 
24
28
  def html_path(file)
25
- File.join(File.dirname(__FILE__), "..", "..", "isodoc", "html", file)
29
+ File.join(File.dirname(__FILE__), "..", "..", "isodoc", "html",
30
+ file)
26
31
  end
27
32
 
28
33
  def output(isodoc_node, inname, outname, format, options = {})
@@ -121,7 +121,7 @@ module Metanorma
121
121
  t.formattedref **{ format: "application/x-isodoc+xml" } do |i|
122
122
  i << ref_normalise_no_format(match[:text])
123
123
  end
124
- yr_match = /[:-](?<year>(19|20)[0-9][0-9])\b/.match(code[:id])
124
+ yr_match = /[:-](?<year>(?:19|20)[0-9][0-9])\b/.match(code[:id])
125
125
  refitem_render1(match, code, t)
126
126
  docnumber(t, code[:id]) unless /^\d+$|^\(.+\)$/.match?(code[:id])
127
127
  conditional_date(t, yr_match || match, false)
@@ -149,7 +149,7 @@ module Metanorma
149
149
  end
150
150
 
151
151
  def refitem1yr(code)
152
- yr_match = /[:-](?<year>(19|20)[0-9][0-9])\b/.match(code)
152
+ yr_match = /[:-](?<year>(?:19|20)[0-9][0-9])\b/.match(code)
153
153
  yr_match ? yr_match[:year] : nil
154
154
  end
155
155
 
@@ -163,20 +163,20 @@ module Metanorma
163
163
 
164
164
  ISO_REF =
165
165
  %r{^<ref\sid="(?<anchor>[^"]+)">
166
- \[(?<usrlbl>\([^)]+\))?(?<code>(ISO|IEC)[^0-9]*\s[0-9-]+|IEV)
167
- (:(?<year>[0-9][0-9-]+))?\]</ref>,?\s*(?<text>.*)$}xm.freeze
166
+ \[(?<usrlbl>\([^)]+\))?(?<code>(?:ISO|IEC)[^0-9]*\s[0-9-]+|IEV)
167
+ (?::(?<year>[0-9][0-9-]+))?\]</ref>,?\s*(?<text>.*)$}xm.freeze
168
168
 
169
169
  ISO_REF_NO_YEAR =
170
170
  %r{^<ref\sid="(?<anchor>[^"]+)">
171
- \[(?<usrlbl>\([^)]+\))?(?<code>(ISO|IEC)[^0-9]*\s[0-9-]+):
172
- (--|&\#821[12];)\]</ref>,?\s*
173
- (<fn[^>]*>\s*<p>(?<fn>[^\]]+)</p>\s*</fn>)?,?\s?(?<text>.*)$}xm
171
+ \[(?<usrlbl>\([^)]+\))?(?<code>(?:ISO|IEC)[^0-9]*\s[0-9-]+):
172
+ (?:--|&\#821[12];)\]</ref>,?\s*
173
+ (?:<fn[^>]*>\s*<p>(?<fn>[^\]]+)</p>\s*</fn>)?,?\s?(?<text>.*)$}xm
174
174
  .freeze
175
175
 
176
176
  ISO_REF_ALL_PARTS =
177
177
  %r{^<ref\sid="(?<anchor>[^"]+)">
178
- \[(?<usrlbl>\([^)]+\))?(?<code>(ISO|IEC)[^0-9]*\s[0-9]+)
179
- (:(?<year>--|&\#821[12];|[0-9][0-9-]+))?\s
178
+ \[(?<usrlbl>\([^)]+\))?(?<code>(?:ISO|IEC)[^0-9]*\s[0-9]+)
179
+ (?::(?<year>--|&\#821[12];|[0-9][0-9-]+))?\s
180
180
  \(all\sparts\)\]</ref>,?\s*
181
181
  (<fn[^>]*>\s*<p>(?<fn>[^\]]+)</p>\s*</fn>,?\s?)?(?<text>.*)$}xm.freeze
182
182
 
@@ -214,18 +214,17 @@ module Metanorma
214
214
  end
215
215
  end
216
216
 
217
- def reference_preproc(node)
217
+ def reference(node)
218
218
  refs = node.items.each_with_object([]) do |b, m|
219
219
  m << reference1code(b.text, node)
220
220
  end
221
+ reference_populate(refs)
222
+ end
223
+
224
+ def reference_populate(refs)
221
225
  results = refs.each_with_index.with_object(Queue.new) do |(ref, i), res|
222
226
  fetch_ref_async(ref.merge(ord: i), i, res)
223
227
  end
224
- [refs, results]
225
- end
226
-
227
- def reference(node)
228
- refs, results = reference_preproc(node)
229
228
  ret = reference_queue(refs, results)
230
229
  noko do |xml|
231
230
  ret.each { |b| reference1out(b, xml) }
@@ -2,7 +2,7 @@ module Metanorma
2
2
  module Standoc
3
3
  module Refs
4
4
  def set_date_range(date, text)
5
- matched = /^(?<from>[0-9]+)(-+(?<to>[0-9]+))?$/.match text
5
+ matched = /^(?<from>[0-9]+)(?:-+(?<to>[0-9]+))?$/.match text
6
6
  return unless matched[:from]
7
7
 
8
8
  if matched[:to]
@@ -113,10 +113,11 @@ module Metanorma
113
113
  { id: match[:anchor], type: "standard" }
114
114
  end
115
115
 
116
- MALFORMED_REF =
117
- "no anchor on reference, markup may be malformed: see "\
118
- "https://www.metanorma.com/author/topics/document-format/bibliography/ , "\
119
- "https://www.metanorma.com/author/iso/topics/markup/#bibliographies".freeze
116
+ MALFORMED_REF = <<~REF.freeze
117
+ no anchor on reference, markup may be malformed: see
118
+ https://www.metanorma.com/author/topics/document-format/bibliography/ ,
119
+ https://www.metanorma.com/author/iso/topics/markup/#bibliographies
120
+ REF
120
121
 
121
122
  def ref_normalise(ref)
122
123
  ref.gsub(/&amp;amp;/, "&amp;").gsub(%r{^<em>(.*)</em>}, "\\1")
@@ -25,6 +25,9 @@ module Metanorma
25
25
  sectionsplit: node.attr("sectionsplit"),
26
26
  baseassetpath: node.attr("base-asset-path"),
27
27
  aligncrosselements: node.attr("align-cross-elements"),
28
+ tocfigures: @tocfigures,
29
+ toctables: @toctables,
30
+ tocrecommendations: @tocrecommendations,
28
31
  }
29
32
  end
30
33
 
@@ -61,12 +64,13 @@ module Metanorma
61
64
  bare: node.attr("bare"),
62
65
  baseassetpath: node.attr("base-asset-path"),
63
66
  aligncrosselements: node.attr("align-cross-elements"),
67
+ tocfigures: @tocfigures,
68
+ toctables: @toctables,
69
+ tocrecommendations: @tocrecommendations,
64
70
  }
65
71
 
66
72
  if fonts_manifest = node.attr(FONTS_MANIFEST)
67
- attrs[IsoDoc::XslfoPdfConvert::MN2PDF_OPTIONS] = {
68
- IsoDoc::XslfoPdfConvert::MN2PDF_FONT_MANIFEST => fonts_manifest,
69
- }
73
+ attrs[IsoDoc::XslfoPdfConvert::MN2PDF_FONT_MANIFEST] = fonts_manifest
70
74
  end
71
75
 
72
76
  attrs
@@ -19,9 +19,7 @@ module Metanorma
19
19
  xml.table **attr_code(table_attrs(node)) do |xml_table|
20
20
  colgroup(node, xml_table)
21
21
  table_name(node, xml_table)
22
- %i(head body foot).reject do |tblsec|
23
- node.rows[tblsec].empty?
24
- end
22
+ %i(head body foot).reject { |tblsec| node.rows[tblsec].empty? }
25
23
  table_head_body_and_foot node, xml_table
26
24
  end
27
25
  end
@@ -50,12 +48,12 @@ module Metanorma
50
48
  end
51
49
  end
52
50
 
53
- def table_cell1(cell, thd)
54
- thd << if cell.style == :asciidoc
55
- cell.content
56
- else
57
- cell.text
58
- end
51
+ def table_cell1(cell)
52
+ if cell.style == :asciidoc
53
+ cell.content
54
+ else
55
+ cell.text
56
+ end
59
57
  end
60
58
 
61
59
  def table_cell(node, xml_tr, tblsec)
@@ -65,7 +63,7 @@ module Metanorma
65
63
  cell_tag = "td"
66
64
  cell_tag = "th" if tblsec == :head || node.style == :header
67
65
  xml_tr.send cell_tag, **attr_code(cell_attributes) do |thd|
68
- table_cell1(node, thd)
66
+ thd << table_cell1(node)
69
67
  end
70
68
  end
71
69
 
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true.
2
2
  require "metanorma/standoc/utils"
3
3
 
4
-
5
4
  module Metanorma
6
5
  module Standoc
7
6
  # Intelligent term lookup xml modifier
@@ -110,15 +109,15 @@ module Metanorma
110
109
  if type == "term" || ((!type || node.parent.name == "related") && t)
111
110
  node["target"] = t
112
111
  elsif type == "symbol" ||
113
- ((!type || node.parent.name == "related") && s)
112
+ ((!type || node.parent.name == "related") && s)
114
113
  node["target"] = s
115
114
  end
116
115
  end
117
116
 
118
117
  def replace_automatic_generated_ids_terms
119
118
  r = xmldoc.xpath("//term").each.with_object({}) do |n, res|
120
- normalize_id_and_memorize(n, res, "./preferred//name",
121
- "term")
119
+ normalize_id_and_memorize(n, res, "./preferred//name", "term")
120
+ normalize_id_and_memorize(n, res, "./admitted//name", "term")
122
121
  end
123
122
  s = xmldoc.xpath("//definitions//dt").each.with_object({}) do |n, res|
124
123
  normalize_id_and_memorize(n, res, ".", "symbol")
@@ -127,11 +126,13 @@ module Metanorma
127
126
  end
128
127
 
129
128
  def pref_secondary2primary
129
+ term = ""
130
130
  xmldoc.xpath("//term").each.with_object({}) do |n, res|
131
131
  n.xpath("./preferred//name").each_with_index do |p, i|
132
132
  i.zero? and term = p.text
133
133
  i.positive? and res[p.text] = term
134
134
  end
135
+ n.xpath("./admitted//name").each { |p| res[p.text] = term }
135
136
  end
136
137
  end
137
138
 
@@ -141,7 +142,7 @@ module Metanorma
141
142
  end
142
143
 
143
144
  def normalize_id_and_memorize_init(node, res_table, text_selector, prefix)
144
- term_text = normalize_ref_id(node.at(text_selector))
145
+ term_text = normalize_ref_id(node.at(text_selector)) or return
145
146
  unless AUTOMATIC_GENERATED_ID_REGEXP.match(node["id"]).nil? &&
146
147
  !node["id"].nil?
147
148
  id = unique_text_id(term_text, prefix)
@@ -160,9 +161,12 @@ module Metanorma
160
161
  end
161
162
 
162
163
  def normalize_ref_id(term)
164
+ return nil if term.nil?
165
+
163
166
  t = term.dup
164
167
  t.xpath(".//index").map(&:remove)
165
- Metanorma::Utils::to_ncname(t.text.downcase.gsub(/[[:space:]]/, "-"))
168
+ Metanorma::Utils::to_ncname(t.text.strip.downcase
169
+ .gsub(/[[:space:]]+/, "-"))
166
170
  end
167
171
 
168
172
  def unique_text_id(text, prefix)
@@ -32,7 +32,9 @@ module Metanorma
32
32
  doc = ::Nokogiri::XML.parse(NOKOHEAD)
33
33
  fragment = doc.fragment("")
34
34
  ::Nokogiri::XML::Builder.with fragment, &block
35
- fragment.to_xml(encoding: "US-ASCII", indent: 0).lines.map do |l|
35
+ fragment.to_xml(encoding: "US-ASCII", indent: 0,
36
+ save_with: Nokogiri::XML::Node::SaveOptions::AS_XML)
37
+ .lines.map do |l|
36
38
  l.gsub(/>\n$/, ">").gsub(/\s*\n$/m, " ").gsub("&#150;", "\u0096")
37
39
  .gsub("&#151;", "\u0097").gsub("&#x96;", "\u0096")
38
40
  .gsub("&#x97;", "\u0097")