metanorma-standoc 1.10.0 → 1.10.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/lib/asciidoctor/standoc/base.rb +0 -1
  3. data/lib/asciidoctor/standoc/blocks.rb +1 -1
  4. data/lib/asciidoctor/standoc/cleanup.rb +62 -2
  5. data/lib/asciidoctor/standoc/cleanup_block.rb +0 -1
  6. data/lib/asciidoctor/standoc/cleanup_boilerplate.rb +2 -2
  7. data/lib/asciidoctor/standoc/cleanup_footnotes.rb +0 -1
  8. data/lib/asciidoctor/standoc/cleanup_maths.rb +0 -1
  9. data/lib/asciidoctor/standoc/cleanup_section.rb +0 -1
  10. data/lib/asciidoctor/standoc/converter.rb +3 -0
  11. data/lib/asciidoctor/standoc/datamodel/diagram_preprocessor.rb +22 -21
  12. data/lib/asciidoctor/standoc/front.rb +0 -1
  13. data/lib/asciidoctor/standoc/front_contributor.rb +0 -1
  14. data/lib/asciidoctor/standoc/isodoc.rng +44 -7
  15. data/lib/asciidoctor/standoc/macros.rb +25 -5
  16. data/lib/asciidoctor/standoc/macros_plantuml.rb +3 -3
  17. data/lib/asciidoctor/standoc/macros_terms.rb +34 -7
  18. data/lib/asciidoctor/standoc/ref.rb +60 -56
  19. data/lib/asciidoctor/standoc/section.rb +19 -12
  20. data/lib/asciidoctor/standoc/term_lookup_cleanup.rb +59 -18
  21. data/lib/asciidoctor/standoc/utils.rb +0 -1
  22. data/lib/asciidoctor/standoc/validate.rb +4 -3
  23. data/lib/isodoc/html/html_titlepage.html +81 -0
  24. data/lib/isodoc/html/htmlstyle.css +983 -0
  25. data/lib/isodoc/html/htmlstyle.scss +714 -0
  26. data/lib/isodoc/html/scripts.html +71 -0
  27. data/lib/metanorma/standoc/processor.rb +16 -7
  28. data/lib/metanorma/standoc/version.rb +1 -1
  29. data/metanorma-standoc.gemspec +1 -1
  30. data/spec/asciidoctor/blocks_spec.rb +2 -2
  31. data/spec/asciidoctor/cleanup_sections_spec.rb +899 -864
  32. data/spec/asciidoctor/cleanup_spec.rb +64 -14
  33. data/spec/asciidoctor/macros_json2text_spec.rb +1 -1
  34. data/spec/asciidoctor/macros_plantuml_spec.rb +165 -104
  35. data/spec/asciidoctor/macros_spec.rb +396 -75
  36. data/spec/asciidoctor/validate_spec.rb +12 -2
  37. data/spec/support/shared_examples/structured_data_2_text_preprocessor.rb +34 -34
  38. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec.yml +50 -50
  39. data/spec/vcr_cassettes/isobib_get_123.yml +12 -12
  40. data/spec/vcr_cassettes/isobib_get_123_1.yml +23 -23
  41. data/spec/vcr_cassettes/isobib_get_123_1_fr.yml +34 -34
  42. data/spec/vcr_cassettes/isobib_get_123_2001.yml +13 -13
  43. data/spec/vcr_cassettes/isobib_get_124.yml +12 -12
  44. data/spec/vcr_cassettes/rfcbib_get_rfc8341.yml +14 -14
  45. data/spec/vcr_cassettes/separates_iev_citations_by_top_level_clause.yml +46 -46
  46. metadata +8 -4
@@ -12,7 +12,6 @@ module Asciidoctor
12
12
  end
13
13
  end
14
14
  raise "PlantUML not installed"
15
- nil
16
15
  end
17
16
 
18
17
  def self.run(umlfile, outfile)
@@ -59,7 +58,7 @@ module Asciidoctor
59
58
  Tempfile.open(["plantuml", ".pml"], encoding: "utf-8") do |f|
60
59
  f.write(src)
61
60
  [f, File.join(File.dirname(f.path),
62
- (fn || File.basename(f.path, ".pml")) + ".png")]
61
+ "#{fn || File.basename(f.path, '.pml')}.png")]
63
62
  end
64
63
  end
65
64
 
@@ -81,7 +80,8 @@ module Asciidoctor
81
80
  def abort(parent, reader, attrs, msg)
82
81
  warn msg
83
82
  attrs["language"] = "plantuml"
84
- create_listing_block parent, reader.source, attrs.reject { |k, _v| k == 1 }
83
+ create_listing_block parent, reader.source,
84
+ (attrs.reject { |k, _v| k == 1 })
85
85
  end
86
86
 
87
87
  def process(parent, reader, attrs)
@@ -46,7 +46,20 @@ module Asciidoctor
46
46
 
47
47
  def process(_parent, _target, attrs)
48
48
  termref = attrs["termxref"] || attrs["name"]
49
- "<concept><termxref>#{attrs['name']}</termxref>"\
49
+ "<concept type='term'><termxref>#{attrs['name']}</termxref>"\
50
+ "<renderterm>#{termref}</renderterm><xrefrender/></concept>"
51
+ end
52
+ end
53
+
54
+ class SymbolRefInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
55
+ use_dsl
56
+ named :symbol
57
+ name_positional_attributes "name", "termxref"
58
+ using_format :short
59
+
60
+ def process(_parent, _target, attrs)
61
+ termref = attrs["termxref"] || attrs["name"]
62
+ "<concept type='symbol'><termxref>#{attrs['name']}</termxref>"\
50
63
  "<renderterm>#{termref}</renderterm><xrefrender/></concept>"
51
64
  end
52
65
  end
@@ -68,24 +81,38 @@ module Asciidoctor
68
81
  def preprocess_attrs(target)
69
82
  m = /^(?<id>&lt;&lt;.+?&gt;&gt;)?(?<rest>.*)$/.match(target)
70
83
  ret = { id: m[:id]&.sub(/^&lt;&lt;/, "")&.sub(/&gt;&gt;$/, "") }
71
- m2 = /^(?<rest>.*)(?<opt>,option=.+)?$/.match(m[:rest].sub(/^,/, ""))
72
- ret[:opt] = m2[:opt]&.sub(/^,option=/, "")
73
- attrs = CSV.parse_line(m2[:rest]) || []
84
+ if m2 = /^(?<rest>.*?)(?<opt>,option=.+)$/.match(m[:rest].sub(/^,/, ""))
85
+ ret[:opt] = CSV.parse_line(m2[:opt].sub(/^,option=/, "")
86
+ .sub(/^"(.+)"$/, "\\1").sub(/^'(.+)'$/, "\\1"))
87
+ attrs = CSV.parse_line(m2[:rest]) || []
88
+ else
89
+ attrs = CSV.parse_line(m[:rest].sub(/^,/, "")) || []
90
+ end
74
91
  ret.merge(term: attrs[0], word: attrs[1] || attrs[0],
75
92
  xrefrender: attrs[2])
76
93
  end
77
94
 
95
+ def generate_attrs(opts)
96
+ ret = ""
97
+ opts.include?("noital") and ret += " ital='false'"
98
+ opts.include?("noref") and ret += " ref='false'"
99
+ opts.include?("ital") and ret += " ital='true'"
100
+ opts.include?("ref") and ret += " ref='true'"
101
+ ret
102
+ end
103
+
78
104
  def process(parent, target, _attrs)
79
105
  attrs = preprocess_attrs(target)
80
106
  termout = Asciidoctor::Inline.new(parent, :quoted, attrs[:term]).convert
81
107
  wordout = Asciidoctor::Inline.new(parent, :quoted, attrs[:word]).convert
82
108
  xrefout = Asciidoctor::Inline.new(parent, :quoted,
83
109
  attrs[:xrefrender]).convert
84
- attrs[:id] and return "<concept key='#{attrs[:id]}'><refterm>"\
110
+ optout = generate_attrs(attrs[:opt] || [])
111
+ attrs[:id] and return "<concept#{optout} key='#{attrs[:id]}'><refterm>"\
85
112
  "#{termout}</refterm><renderterm>#{wordout}</renderterm>"\
86
113
  "<xrefrender>#{xrefout}</xrefrender></concept>"
87
- "<concept><termxref>#{termout}</termxref><renderterm>#{wordout}"\
88
- "</renderterm><xrefrender>#{xrefout}</xrefrender></concept>"
114
+ "<concept#{optout}><termxref>#{termout}</termxref><renderterm>"\
115
+ "#{wordout}</renderterm><xrefrender>#{xrefout}</xrefrender></concept>"
89
116
  end
90
117
  end
91
118
  end
@@ -4,7 +4,7 @@ module Asciidoctor
4
4
  module Standoc
5
5
  module Refs
6
6
  def iso_publisher(bib, code)
7
- code.sub(/ .*$/, "").split(/\//).each do |abbrev|
7
+ code.sub(/ .*$/, "").split("/").each do |abbrev|
8
8
  bib.contributor do |c|
9
9
  c.role **{ type: "publisher" }
10
10
  c.organization do |org|
@@ -18,75 +18,78 @@ module Asciidoctor
18
18
  { format: "text/plain" }
19
19
  end
20
20
 
21
- def ref_attributes(m)
22
- { id: m[:anchor], type: "standard" }
21
+ def ref_attributes(match)
22
+ { id: match[:anchor], type: "standard" }
23
23
  end
24
24
 
25
- def isorefrender1(bib, m, yr, allp = "")
26
- bib.title(**plaintxt) { |i| i << ref_normalise(m[:text]) }
27
- docid(bib, m[:usrlbl]) if m[:usrlbl]
28
- docid(bib, id_and_year(m[:code], yr) + allp)
29
- docnumber(bib, m[:code])
25
+ def isorefrender1(bib, match, yr, allp = "")
26
+ bib.title(**plaintxt) { |i| i << ref_normalise(match[:text]) }
27
+ docid(bib, match[:usrlbl]) if match[:usrlbl]
28
+ docid(bib, id_and_year(match[:code], yr) + allp)
29
+ docnumber(bib, match[:code])
30
30
  end
31
31
 
32
- def isorefmatches(xml, m)
33
- yr = norm_year(m[:year])
34
- ref = fetch_ref xml, m[:code], yr, title: m[:text], usrlbl: m[:usrlbl],
35
- lang: (@lang || :all)
36
- return use_my_anchor(ref, m[:anchor]) if ref
32
+ def isorefmatches(xml, match)
33
+ yr = norm_year(match[:year])
34
+ ref = fetch_ref xml, match[:code], yr,
35
+ title: match[:text], usrlbl: match[:usrlbl],
36
+ lang: (@lang || :all)
37
+ return use_my_anchor(ref, match[:anchor]) if ref
37
38
 
38
- xml.bibitem **attr_code(ref_attributes(m)) do |t|
39
- isorefrender1(t, m, yr)
39
+ xml.bibitem **attr_code(ref_attributes(match)) do |t|
40
+ isorefrender1(t, match, yr)
40
41
  yr and t.date **{ type: "published" } do |d|
41
42
  set_date_range(d, yr)
42
43
  end
43
- iso_publisher(t, m[:code])
44
+ iso_publisher(t, match[:code])
44
45
  end
45
46
  end
46
47
 
47
- def isorefmatches2(xml, m)
48
- ref = fetch_ref xml, m[:code], nil, no_year: true, note: m[:fn],
49
- title: m[:text], usrlbl: m[:usrlbl], lang: (@lang || :all)
50
- return use_my_anchor(ref, m[:anchor]) if ref
48
+ def isorefmatches2(xml, match)
49
+ ref = fetch_ref xml, match[:code], nil,
50
+ no_year: true, note: match[:fn],
51
+ title: match[:text], usrlbl: match[:usrlbl],
52
+ lang: (@lang || :all)
53
+ return use_my_anchor(ref, match[:anchor]) if ref
51
54
 
52
- isorefmatches2_1(xml, m)
55
+ isorefmatches2_1(xml, match)
53
56
  end
54
57
 
55
- def isorefmatches2_1(xml, m)
56
- xml.bibitem **attr_code(ref_attributes(m)) do |t|
57
- isorefrender1(t, m, "--")
58
+ def isorefmatches2_1(xml, match)
59
+ xml.bibitem **attr_code(ref_attributes(match)) do |t|
60
+ isorefrender1(t, match, "--")
58
61
  t.date **{ type: "published" } do |d|
59
62
  d.on "--"
60
63
  end
61
- iso_publisher(t, m[:code])
62
- unless m[:fn].nil?
64
+ iso_publisher(t, match[:code])
65
+ unless match[:fn].nil?
63
66
  t.note(**plaintxt.merge(type: "Unpublished-Status")) do |p|
64
- p << (m[:fn]).to_s
67
+ p << (match[:fn]).to_s
65
68
  end
66
69
  end
67
70
  end
68
71
  end
69
72
 
70
- def isorefmatches3(xml, m)
71
- yr = norm_year(m[:year])
73
+ def isorefmatches3(xml, match)
74
+ yr = norm_year(match[:year])
72
75
  hasyr = !yr.nil? && yr != "--"
73
- ref = fetch_ref(xml, m[:code], hasyr ? yr : nil,
74
- all_parts: true,
75
- no_year: yr == "--", text: m[:text], usrlbl: m[:usrlbl],
76
+ ref = fetch_ref(xml, match[:code], hasyr ? yr : nil,
77
+ all_parts: true, no_year: yr == "--",
78
+ text: match[:text], usrlbl: match[:usrlbl],
76
79
  lang: (@lang || :all))
77
- return use_my_anchor(ref, m[:anchor]) if ref
80
+ return use_my_anchor(ref, match[:anchor]) if ref
78
81
 
79
- isorefmatches3_1(xml, m, yr, hasyr, ref)
82
+ isorefmatches3_1(xml, match, yr, hasyr, ref)
80
83
  end
81
84
 
82
- def isorefmatches3_1(xml, m, yr, _hasyr, _ref)
83
- xml.bibitem(**attr_code(ref_attributes(m))) do |t|
84
- isorefrender1(t, m, yr, " (all parts)")
85
- conditional_date(t, m, yr == "--")
86
- iso_publisher(t, m[:code])
87
- if m.names.include?("fn") && m[:fn]
85
+ def isorefmatches3_1(xml, match, yr, _hasyr, _ref)
86
+ xml.bibitem(**attr_code(ref_attributes(match))) do |t|
87
+ isorefrender1(t, match, yr, " (all parts)")
88
+ conditional_date(t, match, yr == "--")
89
+ iso_publisher(t, match[:code])
90
+ if match.names.include?("fn") && match[:fn]
88
91
  t.note(**plaintxt.merge(type: "Unpublished-Status")) do |p|
89
- p << (m[:fn]).to_s
92
+ p << (match[:fn]).to_s
90
93
  end
91
94
  end
92
95
  t.extent **{ type: "part" } do |e|
@@ -95,23 +98,23 @@ module Asciidoctor
95
98
  end
96
99
  end
97
100
 
98
- def refitem_render1(m, code, bib)
101
+ def refitem_render1(match, code, bib)
99
102
  if code[:type] == "path"
100
103
  bib.uri code[:key].sub(/\.[a-zA-Z0-9]+$/, ""), **{ type: "URI" }
101
104
  bib.uri code[:key].sub(/\.[a-zA-Z0-9]+$/, ""), **{ type: "citation" }
102
105
  end
103
- docid(bib, m[:usrlbl]) if m[:usrlbl]
106
+ docid(bib, match[:usrlbl]) if match[:usrlbl]
104
107
  docid(bib, /^\d+$/.match?(code[:id]) ? "[#{code[:id]}]" : code[:id])
105
108
  code[:type] == "repo" and
106
109
  bib.docidentifier code[:key], **{ type: "repository" }
107
110
  end
108
111
 
109
- def refitem_render(xml, m, code)
110
- xml.bibitem **attr_code(id: m[:anchor]) do |t|
112
+ def refitem_render(xml, match, code)
113
+ xml.bibitem **attr_code(id: match[:anchor]) do |t|
111
114
  t.formattedref **{ format: "application/x-isodoc+xml" } do |i|
112
- i << ref_normalise_no_format(m[:text])
115
+ i << ref_normalise_no_format(match[:text])
113
116
  end
114
- refitem_render1(m, code, t)
117
+ refitem_render1(match, code, t)
115
118
  docnumber(t, code[:id]) unless /^\d+$|^\(.+\)$/.match?(code[:id])
116
119
  end
117
120
  end
@@ -128,7 +131,7 @@ module Asciidoctor
128
131
 
129
132
  def analyse_ref_repo_path(ret)
130
133
  return ret unless m =
131
- /^(?<type>repo|path):\((?<key>[^,]+),?(?<id>.*)\)$/.match(ret[:id])
134
+ /^(?<type>repo|path):\((?<key>[^,]+),?(?<id>.*)\)$/.match(ret[:id])
132
135
 
133
136
  id = m[:id].empty? ? m[:key].sub(%r{^[^/]+/}, "") : m[:id]
134
137
  ret.merge(id: id, type: m[:type], key: m[:key], nofetch: true)
@@ -156,16 +159,17 @@ module Asciidoctor
156
159
  nil
157
160
  end
158
161
 
159
- def refitem1(xml, _item, m)
160
- code = analyse_ref_code(m[:code])
162
+ def refitem1(xml, _item, match)
163
+ code = analyse_ref_code(match[:code])
161
164
  unless code[:id] && code[:numeric] || code[:nofetch]
162
165
  ref = fetch_ref(xml, code[:id],
163
- m.names.include?("year") ? m[:year] : nil,
164
- title: m[:text],
165
- usrlbl: m[:usrlbl], lang: (@lang || :all))
166
- return use_my_anchor(ref, m[:anchor]) if ref
166
+ match.names.include?("year") ? match[:year] : nil,
167
+ title: match[:text],
168
+ usrlbl: match[:usrlbl], lang: (@lang || :all)) and
169
+ return use_my_anchor(ref, match[:anchor])
167
170
  end
168
- refitem_render(xml, m, code)
171
+
172
+ refitem_render(xml, match, code)
169
173
  end
170
174
 
171
175
  def ref_normalise(ref)
@@ -186,7 +190,7 @@ module Asciidoctor
186
190
  \[(?<usrlbl>\([^)]+\))?(?<code>(ISO|IEC)[^0-9]*\s[0-9-]+):
187
191
  (--|&\#821[12];)\]</ref>,?\s*
188
192
  (<fn[^>]*>\s*<p>(?<fn>[^\]]+)</p>\s*</fn>)?,?\s?(?<text>.*)$}xm
189
- .freeze
193
+ .freeze
190
194
 
191
195
  ISO_REF_ALL_PARTS =
192
196
  %r{^<ref\sid="(?<anchor>[^"]+)">
@@ -12,7 +12,7 @@ module Asciidoctor
12
12
  def sectiontype1(node)
13
13
  node&.attr("heading")&.downcase ||
14
14
  node.title.gsub(%r{<index>.*?</index>}m, "").gsub(/<[^>]+>/, "")
15
- .strip.downcase
15
+ .strip.downcase
16
16
  end
17
17
 
18
18
  def sectiontype(node, level = true)
@@ -21,6 +21,7 @@ module Asciidoctor
21
21
  return ret1 if "symbols and abbreviated terms" == ret1
22
22
  return nil unless !level || node.level == 1
23
23
  return nil if @seen_headers.include? ret
24
+
24
25
  @seen_headers << ret
25
26
  ret1
26
27
  end
@@ -48,11 +49,14 @@ module Asciidoctor
48
49
  script: node.attributes["script"],
49
50
  number: node.attributes["number"],
50
51
  type: node.attributes["type"],
51
- annex: ( ((node.attr("style") == "appendix" || node.role == "appendix") &&
52
- node.level == 1) ? true : nil),
53
- preface: (
54
- (node.role == "preface" || node.attr("style") == "preface") ? true : nil) }
52
+ annex: (if (node.attr("style") == "appendix" || node.role == "appendix") &&
53
+ node.level == 1
54
+ true
55
+ end),
56
+ preface: (
57
+ node.role == "preface" || node.attr("style") == "preface" ? true : nil) }
55
58
  return ret unless node.attributes["change"]
59
+
56
60
  ret.merge(change: node.attributes["change"],
57
61
  path: node.attributes["path"],
58
62
  path_end: node.attributes["path_end"],
@@ -75,7 +79,7 @@ module Asciidoctor
75
79
  symbols_parse(symbols_attrs(node, a), xml, node)
76
80
  when "acknowledgements"
77
81
  acknowledgements_parse(a, xml, node)
78
- when "bibliography"
82
+ when "bibliography"
79
83
  bibliography_parse(a, xml, node)
80
84
  else
81
85
  if @term_def then term_def_subclause_parse(a, xml, node)
@@ -88,9 +92,9 @@ module Asciidoctor
88
92
  bibliography_parse(a, xml, node)
89
93
  elsif node.attr("style") == "bibliography"
90
94
  bibliography_parse(a, xml, node)
91
- elsif node.attr("style") == "abstract"
95
+ elsif node.attr("style") == "abstract"
92
96
  abstract_parse(a, xml, node)
93
- elsif node.attr("style") == "index"
97
+ elsif node.attr("style") == "index"
94
98
  indexsect_parse(a, xml, node)
95
99
  elsif node.attr("style") == "appendix" && node.level == 1
96
100
  annex_parse(a, xml, node)
@@ -102,10 +106,13 @@ module Asciidoctor
102
106
  end
103
107
 
104
108
  def set_obligation(attrs, node)
105
- attrs[:obligation] = node.attributes.has_key?("obligation") ?
106
- node.attr("obligation") :
107
- node.parent.attributes.has_key?("obligation") ?
108
- node.parent.attr("obligation") : "normative"
109
+ attrs[:obligation] = if node.attributes.has_key?("obligation")
110
+ node.attr("obligation")
111
+ elsif node.parent.attributes.has_key?("obligation")
112
+ node.parent.attr("obligation")
113
+ else
114
+ "normative"
115
+ end
109
116
  end
110
117
 
111
118
  def preamble(node)
@@ -6,13 +6,14 @@ module Asciidoctor
6
6
  class TermLookupCleanup
7
7
  AUTOMATIC_GENERATED_ID_REGEXP = /\A_/.freeze
8
8
  EXISTING_TERM_REGEXP = /\Aterm-/.freeze
9
+ EXISTING_SYMBOL_REGEXP = /\Asymbol-/.freeze
9
10
 
10
11
  attr_reader :xmldoc, :termlookup, :log
11
12
 
12
13
  def initialize(xmldoc, log)
13
14
  @xmldoc = xmldoc
14
15
  @log = log
15
- @termlookup = {}
16
+ @termlookup = { term: {}, symbol: {} }
16
17
  @idhash = {}
17
18
  end
18
19
 
@@ -20,13 +21,20 @@ module Asciidoctor
20
21
  @idhash = populate_idhash
21
22
  @termlookup = replace_automatic_generated_ids_terms
22
23
  set_termxref_tags_target
24
+ concept_cleanup
23
25
  end
24
26
 
25
27
  private
26
28
 
29
+ def concept_cleanup
30
+ xmldoc.xpath("//concept").each do |n|
31
+ n.delete("type")
32
+ end
33
+ end
34
+
27
35
  def populate_idhash
28
36
  xmldoc.xpath("//*[@id]").each_with_object({}) do |n, mem|
29
- next unless /^term-/.match?(n["id"])
37
+ next unless /^(term|symbol)-/.match?(n["id"])
30
38
 
31
39
  mem[n["id"]] = true
32
40
  end
@@ -35,7 +43,7 @@ module Asciidoctor
35
43
  def set_termxref_tags_target
36
44
  xmldoc.xpath("//termxref").each do |node|
37
45
  target = normalize_ref_id(node.text)
38
- if termlookup[target].nil?
46
+ if termlookup[:term][target].nil? && termlookup[:symbol][target].nil?
39
47
  remove_missing_ref(node, target)
40
48
  next
41
49
  end
@@ -46,6 +54,14 @@ module Asciidoctor
46
54
  end
47
55
 
48
56
  def remove_missing_ref(node, target)
57
+ if node.at("../concept[@type = 'symbol']")
58
+ remove_missing_ref_symbol(node, target)
59
+ else
60
+ remove_missing_ref_term(node, target)
61
+ end
62
+ end
63
+
64
+ def remove_missing_ref_term(node, target)
49
65
  log.add("AsciiDoc Input", node,
50
66
  %(Error: Term reference in `term[#{target}]` missing: \
51
67
  "#{target}" is not defined in document))
@@ -58,39 +74,64 @@ module Asciidoctor
58
74
  "not resolved via ID <tt>#{target}</tt>"
59
75
  end
60
76
 
77
+ def remove_missing_ref_symbol(node, target)
78
+ log.add("AsciiDoc Input", node,
79
+ %(Error: Symbol reference in `symbol[#{target}]` missing: \
80
+ "#{target}" is not defined in document))
81
+ node.name = "strong"
82
+ node.at("../xrefrender").remove
83
+ display = node&.at("../renderterm")&.remove&.children
84
+ display = [] if display.nil? || display&.to_xml == node.text
85
+ d = display.empty? ? "" : ", display <tt>#{display.to_xml}</tt>"
86
+ node.children = "symbol <tt>#{node.text}</tt>#{d} "\
87
+ "not resolved via ID <tt>#{target}</tt>"
88
+ end
89
+
61
90
  def modify_ref_node(node, target)
62
91
  node.name = "xref"
63
- node["target"] = termlookup[target]
92
+ s = termlookup[:symbol][target]
93
+ t = termlookup[:term][target]
94
+ type = node.parent["type"]
95
+ if type == "term" || !type && t
96
+ node["target"] = t
97
+ elsif type == "symbol" || !type && s
98
+ node["target"] = s
99
+ end
64
100
  end
65
101
 
66
102
  def replace_automatic_generated_ids_terms
67
- xmldoc.xpath("//term").each.with_object({}) do |term_node, res|
68
- normalize_id_and_memorize(term_node, res, "./preferred")
103
+ r = xmldoc.xpath("//term").each.with_object({}) do |n, res|
104
+ normalize_id_and_memorize(n, res, "./preferred", "term")
105
+ end
106
+ s = xmldoc.xpath("//definitions//dt").each.with_object({}) do |n, res|
107
+ normalize_id_and_memorize(n, res, ".", "symbol")
69
108
  end
109
+ { term: r, symbol: s }
70
110
  end
71
111
 
72
- def normalize_id_and_memorize(term_node, res_table, text_selector)
73
- term_text = normalize_ref_id(term_node.at(text_selector).text)
74
- unless AUTOMATIC_GENERATED_ID_REGEXP.match(term_node["id"]).nil?
75
- id = unique_text_id(term_text)
76
- term_node["id"] = id
112
+ def normalize_id_and_memorize(node, res_table, text_selector, prefix)
113
+ term_text = normalize_ref_id(node.at(text_selector).text)
114
+ unless AUTOMATIC_GENERATED_ID_REGEXP.match(node["id"]).nil? &&
115
+ !node["id"].nil?
116
+ id = unique_text_id(term_text, prefix)
117
+ node["id"] = id
77
118
  @idhash[id] = true
78
119
  end
79
- res_table[term_text] = term_node["id"]
120
+ res_table[term_text] = node["id"]
80
121
  end
81
122
 
82
123
  def normalize_ref_id(text)
83
- text.downcase.gsub(/[[:space:]]/, "-")
124
+ Metanorma::Utils::to_ncname(text.downcase.gsub(/[[:space:]]/, "-"))
84
125
  end
85
126
 
86
- def unique_text_id(text)
87
- unless @idhash["term-#{text}"]
88
- return "term-#{text}"
127
+ def unique_text_id(text, prefix)
128
+ unless @idhash["#{prefix}-#{text}"]
129
+ return "#{prefix}-#{text}"
89
130
  end
90
131
 
91
132
  (1..Float::INFINITY).lazy.each do |index|
92
- unless @idhash["term-#{text}-#{index}"]
93
- break("term-#{text}-#{index}")
133
+ unless @idhash["#{prefix}-#{text}-#{index}"]
134
+ break("#{prefix}-#{text}-#{index}")
94
135
  end
95
136
  end
96
137
  end