metanorma-standoc 1.10.0 → 1.10.3.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 (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