metanorma-standoc 1.5.1 → 1.5.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/lib/asciidoctor/standoc/base.rb +1 -1
  3. data/lib/asciidoctor/standoc/cleanup.rb +1 -0
  4. data/lib/asciidoctor/standoc/cleanup_inline.rb +57 -1
  5. data/lib/asciidoctor/standoc/cleanup_ref.rb +3 -1
  6. data/lib/asciidoctor/standoc/cleanup_section.rb +18 -1
  7. data/lib/asciidoctor/standoc/cleanup_terms.rb +2 -2
  8. data/lib/asciidoctor/standoc/isodoc.rng +4 -1
  9. data/lib/asciidoctor/standoc/log.rb +10 -1
  10. data/lib/asciidoctor/standoc/utils.rb +2 -1
  11. data/lib/asciidoctor/standoc/validate.rb +30 -18
  12. data/lib/asciidoctor/standoc/validate_section.rb +1 -1
  13. data/lib/metanorma/standoc/version.rb +1 -1
  14. data/metanorma-standoc.gemspec +1 -1
  15. data/spec/asciidoctor-standoc/base_spec.rb +2 -1
  16. data/spec/asciidoctor-standoc/blocks_spec.rb +8 -1
  17. data/spec/asciidoctor-standoc/cleanup_spec.rb +121 -11
  18. data/spec/asciidoctor-standoc/inline_spec.rb +4 -1
  19. data/spec/asciidoctor-standoc/macros_spec.rb +41 -23
  20. data/spec/asciidoctor-standoc/refs_dl_spec.rb +3 -1
  21. data/spec/asciidoctor-standoc/table_spec.rb +7 -1
  22. data/spec/asciidoctor-standoc/validate_spec.rb +22 -0
  23. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec.yml +66 -66
  24. data/spec/vcr_cassettes/isobib_get_123.yml +16 -16
  25. data/spec/vcr_cassettes/isobib_get_123_1.yml +33 -33
  26. data/spec/vcr_cassettes/isobib_get_123_2001.yml +19 -19
  27. data/spec/vcr_cassettes/isobib_get_124.yml +19 -19
  28. data/spec/vcr_cassettes/rfcbib_get_rfc8341.yml +8 -8
  29. data/spec/vcr_cassettes/separates_iev_citations_by_top_level_clause.yml +28 -28
  30. metadata +4 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2b4ec9dd5050345506b6b416eaad6b57865cb3c0b9e57e00e3b52f625fe87a48
4
- data.tar.gz: 4e53f6a44684a9694104f74c7560040893a47c70c5c8292810e9349a32c1e151
3
+ metadata.gz: 910ada4e6d4f62c6106391e3ec0de46a7ba4a9d5362bb103cd80ee0b2acef9dc
4
+ data.tar.gz: de8546c035da0236faa4a6ca5df9b0f54f16806d09386793f359e55b69884212
5
5
  SHA512:
6
- metadata.gz: 8d437d0619e0da4931009f2f92db0778bdd0eccb9bd15f81a7e38edc66a89474cecaa4099bd55bf8178a13a9551d533378068730231e2ed13d2ead794da7cb3a
7
- data.tar.gz: c5a606e3c94a341a6ce19bf5e77df8bf49eeae5d68cf6143d7050190a29f7213a34d74ab7743b87f54d7766fd17606cfb05f05b51a63f7a85ae113b9a23e98fd
6
+ metadata.gz: 422e64b66f95fa4c49727687c446bd3f79bc09aa0609b352bd68cc659ff06bf57243ed410e4baa8f0cb501f101212d305a756b41548fcee7e877135aea22e1f3
7
+ data.tar.gz: 97d6e164975997ecc396376abdaf2edad43c1f4fbfa601dbbc5f2f4d465747164350f500aaadc05f9fd6ed1e499925df7d74626fcde21a0578feeb50d607b84e
@@ -170,7 +170,7 @@ module Asciidoctor
170
170
  end
171
171
 
172
172
  def doctype(node)
173
- node.attr("doctype")
173
+ node.attr("doctype")&.gsub(/\s+/, "-")&.downcase
174
174
  end
175
175
 
176
176
  def front(node, xml)
@@ -71,6 +71,7 @@ module Asciidoctor
71
71
  para_cleanup(xmldoc)
72
72
  empty_element_cleanup(xmldoc)
73
73
  img_cleanup(xmldoc)
74
+ anchor_cleanup(xmldoc)
74
75
  xmldoc
75
76
  end
76
77
 
@@ -117,7 +117,8 @@ module Asciidoctor
117
117
  def concept_termbase_cleanup(x)
118
118
  text = x&.children&.first&.remove&.text
119
119
  termbase, key = x["key"].split(/:/, 2)
120
- x.add_child(%(<termref base="#{termbase}" target="#{key}">#{text}</termref>))
120
+ x.add_child(%(<termref base="#{termbase}" target="#{key}">) +
121
+ "#{text}</termref>")
121
122
  end
122
123
 
123
124
  def concept_xref_cleanup(x)
@@ -129,6 +130,61 @@ module Asciidoctor
129
130
  x.children = "<eref>#{x.children.to_xml}</eref>"
130
131
  extract_localities(x.first_element_child)
131
132
  end
133
+
134
+ NAMECHAR = "\u0000-\u0022\u0024\u002c\u002f\u003a-\u0040\\u005b-\u005e"\
135
+ "\u0060\u007b-\u00b6\u00b8-\u00bf\u00d7\u00f7\u037e\u2000-\u200b"\
136
+ "\u200e-\u203e\u2041-\u206f\u2190-\u2bff\u2ff0-\u3000".freeze
137
+ #"\ud800-\uf8ff\ufdd0-\ufdef\ufffe-\uffff".freeze
138
+ NAMESTARTCHAR = "\\u002d\u002e\u0030-\u0039\u00b7\u0300-\u036f"\
139
+ "\u203f-\u2040".freeze
140
+
141
+ def to_ncname(s)
142
+ start = s[0]
143
+ ret1 = %r([#{NAMECHAR}#]).match(start) ? "_" :
144
+ (%r([#{NAMESTARTCHAR}#]).match(start) ? "_#{start}" : start)
145
+ ret = ret1 + s[1..-1].gsub(%r([#{NAMECHAR}#]), "_")
146
+ ret
147
+ end
148
+
149
+ def to_xreftarget(s)
150
+ return to_ncname(s) unless /^[^#]+#.+$/.match(s)
151
+ /^(?<pref>[^#]+)#(?<suff>.+)$/ =~ s
152
+ pref = pref.gsub(%r([#{NAMECHAR}]), "_")
153
+ suff = suff.gsub(%r([#{NAMECHAR}]), "_")
154
+ "#{pref}##{suff}"
155
+ end
156
+
157
+ IDREF = "//*/@id | //review/@from | //review/@to | "\
158
+ "//callout/@target | //citation/@bibitemid | //eref/@bibitemid".freeze
159
+
160
+ def anchor_cleanup(x)
161
+ anchor_cleanup1(x)
162
+ xreftarget_cleanup(x)
163
+ end
164
+
165
+ def anchor_cleanup1(x)
166
+ x.xpath(IDREF).each do |s|
167
+ if (ret = to_ncname(s.value)) != (orig = s.value)
168
+ s.value = ret
169
+ output = s.parent.dup
170
+ output.children.remove
171
+ @log.add("Anchors", s.parent, "normalised identifier in #{output} "\
172
+ "from #{orig}")
173
+ end
174
+ end
175
+ end
176
+
177
+ def xreftarget_cleanup(x)
178
+ x.xpath("//xref/@target").each do |s|
179
+ if (ret = to_xreftarget(s.value)) != (orig = s.value)
180
+ s.value = ret
181
+ output = s.parent.dup
182
+ output.children.remove
183
+ @log.add("Anchors", s.parent, "normalised identifier in #{output} "\
184
+ "from #{orig}")
185
+ end
186
+ end
187
+ end
132
188
  end
133
189
  end
134
190
  end
@@ -203,7 +203,9 @@ module Asciidoctor
203
203
  end
204
204
  if !nested and c.at("./title")
205
205
  title = c.at("./title").remove.children.to_xml
206
- bib["title"] = bib["title"] ? Array(bib["title"]) : []
206
+ bib["title"] = [bib["title"]] if bib["title"].is_a? Hash
207
+ bib["title"] = [bib["title"]] if bib["title"].is_a? String
208
+ bib["title"] = [] unless bib["title"]
207
209
  bib["title"] << title if !title.empty?
208
210
  end
209
211
  bib
@@ -141,12 +141,29 @@ module Asciidoctor
141
141
  end
142
142
 
143
143
  def clausebefore_cleanup(xmldoc)
144
+ preface_clausebefore_cleanup(xmldoc)
145
+ sections_clausebefore_cleanup(xmldoc)
146
+ end
147
+
148
+ def preface_clausebefore_cleanup(xmldoc)
149
+ return unless xmldoc.at("//preface")
150
+ unless ins = xmldoc.at("//preface").children.first
151
+ xmldoc.at("//preface") << " "
152
+ ins = xmldoc.at("//preface").children.first
153
+ end
154
+ xmldoc.xpath("//preface//*[@beforeclauses = 'true']").each do |x|
155
+ x.delete("beforeclauses")
156
+ ins.previous = x.remove
157
+ end
158
+ end
159
+
160
+ def sections_clausebefore_cleanup(xmldoc)
144
161
  return unless xmldoc.at("//sections")
145
162
  unless ins = xmldoc.at("//sections").children.first
146
163
  xmldoc.at("//sections") << " "
147
164
  ins = xmldoc.at("//sections").children.first
148
165
  end
149
- xmldoc.xpath("//*[@beforeclauses = 'true']").each do |x|
166
+ xmldoc.xpath("//sections//*[@beforeclauses = 'true']").each do |x|
150
167
  x.delete("beforeclauses")
151
168
  ins.previous = x.remove
152
169
  end
@@ -110,8 +110,8 @@ module Asciidoctor
110
110
  end
111
111
  ret = Nokogiri::XML(key.to_xml)
112
112
  HTMLEntities.new.decode(ret.text).
113
- gsub(/[\[\]\{\}<>\(\)]/, "").strip.
114
- gsub(/[[:punct]]|[_^]/, ":\\0").gsub(/`/, "").
113
+ gsub(/[\[\]\{\}<>\(\)]/, "").gsub(/\s/m, "").
114
+ gsub(/[[:punct:]]|[_^]/, ":\\0").gsub(/`/, "").
115
115
  gsub(/[0-9]+/, "þ\\0")
116
116
  end
117
117
 
@@ -42,8 +42,11 @@
42
42
  </define>
43
43
  <define name="xref">
44
44
  <element name="xref">
45
+ <!-- attribute target { xsd:IDREF }, -->
45
46
  <attribute name="target">
46
- <data type="IDREF"/>
47
+ <data type="string">
48
+ <param name="pattern">\i\c*|\c+#\c+</param>
49
+ </data>
47
50
  </attribute>
48
51
  <optional>
49
52
  <attribute name="type">
@@ -8,7 +8,8 @@ module Asciidoctor
8
8
  def add(category, loc, msg)
9
9
  return if @novalid
10
10
  @log[category] = [] unless @log[category]
11
- @log[category] << { location: current_location(loc), message: msg }
11
+ @log[category] << { location: current_location(loc), message: msg,
12
+ context: context(loc) }
12
13
  loc = loc.nil? ? "" : "(#{current_location(loc)}): "
13
14
  warn "#{category}: #{loc}#{msg}"
14
15
  end
@@ -31,6 +32,13 @@ module Asciidoctor
31
32
  "??"
32
33
  end
33
34
 
35
+ def context(n)
36
+ return nil if n.is_a? String
37
+ n.respond_to?(:to_xml) and return n.to_xml
38
+ n.respond_to?(:to_s) and return n.to_s
39
+ nil
40
+ end
41
+
34
42
  def write(file)
35
43
  File.open(file, "w:UTF-8") do |f|
36
44
  f.puts "#{file} errors"
@@ -41,6 +49,7 @@ module Asciidoctor
41
49
  end.each do |n|
42
50
  loc = n[:location] ? "(#{n[:location]}): " : ""
43
51
  f.puts "#{loc}#{n[:message]}"
52
+ n[:context]&.split(/\n/)&.first(5)&.each { |l| f.puts "\t#{l}" }
44
53
  end
45
54
  end
46
55
  end
@@ -128,7 +128,8 @@ module Asciidoctor
128
128
  ::Nokogiri::XML::Builder.with fragment, &block
129
129
  fragment.to_xml(encoding: "US-ASCII", indent: 0).lines.map do |l|
130
130
  l.gsub(/>\n$/, ">").gsub(/\s*\n$/m, " ").gsub("&#150;", "\u0096").
131
- gsub("&#151;", "\u0097")
131
+ gsub("&#151;", "\u0097").gsub("&#x96;", "\u0096").
132
+ gsub("&#x97;", "\u0097")
132
133
  end
133
134
  end
134
135
 
@@ -8,7 +8,8 @@ module Asciidoctor
8
8
  module Standoc
9
9
  module Validate
10
10
 
11
- SOURCELOCALITY = "./termsource/origin//locality[@type = 'clause']/referenceFrom".freeze
11
+ SOURCELOCALITY = "./termsource/origin//locality[@type = 'clause']/"\
12
+ "referenceFrom".freeze
12
13
 
13
14
  def init_iev
14
15
  return nil if @no_isobib
@@ -19,13 +20,16 @@ module Asciidoctor
19
20
 
20
21
  def iev_validate(xmldoc)
21
22
  xmldoc.xpath("//term").each do |t|
22
- /^IEC 60050-/.match(t&.at("./termsource/origin/@citeas")&.text) or next
23
- pref = t.xpath("./preferred").inject([]) { |m, x| m << x&.text&.downcase }
24
- locality = t.xpath(SOURCELOCALITY)&.text or next
23
+ /^IEC 60050-/.match(t&.at("./termsource/origin/@citeas")&.text) &&
24
+ loc = t.xpath(SOURCELOCALITY)&.text or next
25
25
  @iev = init_iev or return
26
- iev = @iev.fetch(locality, xmldoc&.at("//language")&.text || "en") or next
26
+ iev = @iev.fetch(loc, xmldoc&.at("//language")&.text || "en") or next
27
+ pref = t.xpath("./preferred").inject([]) do |m, x|
28
+ m << x&.text&.downcase
29
+ end
27
30
  pref.include?(iev.downcase) or
28
- @log.add("Bibliography", t, %(Term "#{pref[0]}" does not match IEV #{locality} "#{iev}"))
31
+ @log.add("Bibliography", t, %(Term "#{pref[0]}" does not match ) +
32
+ %(IEV #{loc} "#{iev}"))
29
33
  end
30
34
  end
31
35
 
@@ -35,20 +39,26 @@ module Asciidoctor
35
39
  iev_validate(doc.root)
36
40
  end
37
41
 
42
+ def repeat_id_validate1(ids, x)
43
+ if ids[x["id"]]
44
+ @log.add("Anchors", x, "Anchor #{x['id']} has already been used "\
45
+ "at line #{ids[x['id']]}")
46
+ raise StandardError.new "Error: multiple instances of same ID"
47
+ else
48
+ ids[x["id"]] = x.line
49
+ end
50
+ ids
51
+ end
52
+
38
53
  def repeat_id_validate(doc)
39
54
  ids = {}
40
- crash = false
41
- doc.xpath("//*[@id]").each do |x|
42
- if ids[x["id"]]
43
- @log.add("Anchors", x, "Anchor #{x['id']} has already been used at line #{ids[x['id']]}")
44
- crash = true
45
- else
46
- ids[x["id"]] = x.line
55
+ begin
56
+ doc.xpath("//*[@id]").each do |x|
57
+ ids = repeat_id_validate1(ids, x)
47
58
  end
48
- end
49
- if crash
59
+ rescue StandardError => e
50
60
  clean_exit
51
- abort("Cannot deal with multiple instances of same ID")
61
+ abort(e.message)
52
62
  end
53
63
  end
54
64
 
@@ -59,8 +69,10 @@ module Asciidoctor
59
69
  f.close
60
70
  errors = Jing.new(schema).validate(f.path)
61
71
  warn "Syntax Valid!" if errors.none?
62
- errors.each do |error|
63
- @log.add("Syntax", "XML Line #{"%06d" % error[:line]}:#{error[:column]}", error[:message])
72
+ errors.each do |e|
73
+ @log.add("Metanorma XML Syntax",
74
+ "XML Line #{"%06d" % e[:line]}:#{e[:column]}",
75
+ e[:message])
64
76
  end
65
77
  rescue Jing::Error => e
66
78
  clean_exit
@@ -22,7 +22,7 @@ module Asciidoctor
22
22
  def style_warning(node, msg, text = nil)
23
23
  w = msg
24
24
  w += ": #{text}" if text
25
- @log.add("Style Warning", node, w)
25
+ @log.add("Metanorma XML Style Warning", node, w)
26
26
  end
27
27
 
28
28
  def asset_title_style(root)
@@ -1,5 +1,5 @@
1
1
  module Metanorma
2
2
  module Standoc
3
- VERSION = "1.5.1".freeze
3
+ VERSION = "1.5.2".freeze
4
4
  end
5
5
  end
@@ -30,7 +30,7 @@ Gem::Specification.new do |spec|
30
30
  spec.add_dependency "ruby-jing"
31
31
  spec.add_dependency "isodoc", "~> 1.2.0"
32
32
  spec.add_dependency "iev", "~> 0.2.1"
33
- spec.add_dependency "relaton", "~> 1.2.0"
33
+ spec.add_dependency "relaton", "~> 1.3.0"
34
34
  spec.add_dependency "relaton-iev", "~> 1.0.0"
35
35
  spec.add_dependency "sterile", "~> 1.0.14"
36
36
  spec.add_dependency "concurrent-ruby"
@@ -327,6 +327,7 @@ RSpec.describe Asciidoctor::Standoc do
327
327
  :doc-uri: E
328
328
  :relaton-uri: F
329
329
  :title-eo: Dokumenttitolo
330
+ :doctype: This is a DocType
330
331
 
331
332
  [abstract]
332
333
  == Abstract
@@ -422,7 +423,7 @@ RSpec.describe Asciidoctor::Standoc do
422
423
  </owner>
423
424
  </copyright>
424
425
  <ext>
425
- <doctype>article</doctype>
426
+ <doctype>this-is-a-doctype</doctype>
426
427
  </ext>
427
428
  </bibdata>
428
429
  <preface>
@@ -1255,7 +1255,14 @@ RSpec.describe Asciidoctor::Standoc do
1255
1255
  <description><p id="_">I recommend <em>this</em>.</p>
1256
1256
  </description><specification exclude="false" type="tabular" keep-with-next="true" keep-lines-together="true"><p id="_">This is the object of the recommendation:</p><table id="_"> <tbody> <tr> <td align="left">Object</td> <td align="left">Value</td> </tr> <tr> <td align="left">Mission</td> <td align="left">Accomplished</td> </tr> </tbody></table></specification><description>
1257
1257
  <p id="_">As for the measurement targets,</p>
1258
- </description><measurement-target exclude="false"><p id="_">The measurement target shall be measured as:</p><formula id="_"> <stem type="MathML"><math xmlns="http://www.w3.org/1998/Math/MathML"><mfrac><mi>r</mi><mn>1</mn></mfrac><mo>=</mo><mn>0</mn></math></stem></formula></measurement-target>
1258
+ </description><measurement-target exclude="false"><p id="_">The measurement target shall be measured as:</p><formula id="_"> <stem type="MathML"><math xmlns="http://www.w3.org/1998/Math/MathML"><mfrac>
1259
+ <mrow>
1260
+ <mi>r</mi>
1261
+ </mrow>
1262
+ <mrow>
1263
+ <mn>1</mn>
1264
+ </mrow>
1265
+ </mfrac><mo>=</mo><mn>0</mn></math></stem></formula></measurement-target>
1259
1266
  <verification exclude="false"><p id="_">The following code will be run for verification:</p><sourcecode lang="CoreRoot" id="_">CoreRoot(success): HttpResponse
1260
1267
  if (success)
1261
1268
  recommendation(label: success-response)
@@ -158,7 +158,21 @@ RSpec.describe Asciidoctor::Standoc do
158
158
  <terms id="_" obligation="normative">
159
159
  <title>Terms and definitions</title>
160
160
  <p id="_">For the purposes of this document, the following terms and definitions apply.</p>
161
- <term id="_"><preferred><stem type="MathML"><math xmlns="http://www.w3.org/1998/Math/MathML"><msub><mi>t</mi><mn>90</mn></msub></math></stem></preferred><admitted><stem type="MathML"><math xmlns="http://www.w3.org/1998/Math/MathML"><msub><mi>t</mi><mn>91</mn></msub></math></stem></admitted>
161
+ <term id="_"><preferred><stem type="MathML"><math xmlns="http://www.w3.org/1998/Math/MathML"><msub>
162
+ <mrow>
163
+ <mi>t</mi>
164
+ </mrow>
165
+ <mrow>
166
+ <mn>90</mn>
167
+ </mrow>
168
+ </msub></math></stem></preferred><admitted><stem type="MathML"><math xmlns="http://www.w3.org/1998/Math/MathML"><msub>
169
+ <mrow>
170
+ <mi>t</mi>
171
+ </mrow>
172
+ <mrow>
173
+ <mn>91</mn>
174
+ </mrow>
175
+ </msub></math></stem></admitted>
162
176
  <definition><p id="_">Time</p></definition></term>
163
177
  </terms>
164
178
  </sections>
@@ -229,8 +243,22 @@ RSpec.describe Asciidoctor::Standoc do
229
243
  <terms id="_" obligation="normative">
230
244
  <title>Terms and definitions</title>
231
245
  <p id="_">For the purposes of this document, the following terms and definitions apply.</p>
232
- <term id="_"><preferred><stem type="MathML"><math xmlns="http://www.w3.org/1998/Math/MathML"><msub><mi>t</mi><mn>90</mn></msub></math></stem></preferred><definition><formula id="_">
233
- <stem type="MathML"><math xmlns="http://www.w3.org/1998/Math/MathML"><msub><mi>t</mi><mi>A</mi></msub></math></stem>
246
+ <term id="_"><preferred><stem type="MathML"><math xmlns="http://www.w3.org/1998/Math/MathML"><msub>
247
+ <mrow>
248
+ <mi>t</mi>
249
+ </mrow>
250
+ <mrow>
251
+ <mn>90</mn>
252
+ </mrow>
253
+ </msub></math></stem></preferred><definition><formula id="_">
254
+ <stem type="MathML"><math xmlns="http://www.w3.org/1998/Math/MathML"><msub>
255
+ <mrow>
256
+ <mi>t</mi>
257
+ </mrow>
258
+ <mrow>
259
+ <mi>A</mi>
260
+ </mrow>
261
+ </msub></math></stem>
234
262
  </formula>
235
263
  <p id="_">This paragraph is extraneous</p></definition>
236
264
  </term>
@@ -1359,7 +1387,14 @@ end
1359
1387
  #{BLANK_HDR}
1360
1388
  <sections>
1361
1389
  <p id="_">
1362
- <stem type="MathML"><math xmlns="http://www.w3.org/1998/Math/MathML"><mfrac><mn>1</mn><mi>r</mi></mfrac></math></stem>
1390
+ <stem type="MathML"><math xmlns="http://www.w3.org/1998/Math/MathML"><mfrac>
1391
+ <mrow>
1392
+ <mn>1</mn>
1393
+ </mrow>
1394
+ <mrow>
1395
+ <mi>r</mi>
1396
+ </mrow>
1397
+ </mfrac></math></stem>
1363
1398
  </p>
1364
1399
  </sections>
1365
1400
  </standard-document>
@@ -1669,12 +1704,28 @@ it "sorts symbols lists" do
1669
1704
  x_1_:: Definition 3
1670
1705
  x_m_:: Definition 4
1671
1706
  x:: Definition 5
1707
+ stem:[n]:: Definition 6
1708
+ m:: Definition 7
1672
1709
  INPUT
1673
1710
  #{BLANK_HDR}
1674
1711
  <sections>
1675
1712
  <definitions id='L' obligation="normative">
1676
1713
  <title>Symbols and abbreviated terms</title>
1677
1714
  <dl id='_'>
1715
+ <dt>m</dt>
1716
+ <dd>
1717
+ <p id='_'>Definition 7</p>
1718
+ </dd>
1719
+ <dt>
1720
+ <stem type='MathML'>
1721
+ <math xmlns='http://www.w3.org/1998/Math/MathML'>
1722
+ <mi>n</mi>
1723
+ </math>
1724
+ </stem>
1725
+ </dt>
1726
+ <dd>
1727
+ <p id='_'>Definition 6</p>
1728
+ </dd>
1678
1729
  <dt>x</dt>
1679
1730
  <dd>
1680
1731
  <p id='_'>Definition 5</p>
@@ -1727,8 +1778,12 @@ it "sorts symbols lists" do
1727
1778
  <dt><stem type='MathML'>
1728
1779
  <math xmlns='http://www.w3.org/1998/Math/MathML'>
1729
1780
  <msub>
1730
- <mi>x</mi>
1731
- <mi>m</mi>
1781
+ <mrow>
1782
+ <mi>x</mi>
1783
+ </mrow>
1784
+ <mrow>
1785
+ <mi>m</mi>
1786
+ </mrow>
1732
1787
  </msub>
1733
1788
  </math>
1734
1789
  </stem></dt>
@@ -1738,8 +1793,12 @@ it "sorts symbols lists" do
1738
1793
  <dt><stem type='MathML'>
1739
1794
  <math xmlns='http://www.w3.org/1998/Math/MathML'>
1740
1795
  <msub>
1741
- <mi>x</mi>
1742
- <mn>1</mn>
1796
+ <mrow>
1797
+ <mi>x</mi>
1798
+ </mrow>
1799
+ <mrow>
1800
+ <mn>1</mn>
1801
+ </mrow>
1743
1802
  </msub>
1744
1803
  </math>
1745
1804
  </stem></dt>
@@ -1872,6 +1931,9 @@ it "moves %beforeclause admonitions to right position" do
1872
1931
  INPUT
1873
1932
  #{BLANK_HDR}
1874
1933
  <preface>
1934
+ <note id='_'>
1935
+ <p id='_'>Note which is very important</p>
1936
+ </note>
1875
1937
  <foreword id='_' obligation='informative'>
1876
1938
  <title>Foreword</title>
1877
1939
  <p id='_'>Foreword</p>
@@ -1882,9 +1944,6 @@ INPUT
1882
1944
  </introduction>
1883
1945
  </preface>
1884
1946
  <sections>
1885
- <note id='_'>
1886
- <p id='_'>Note which is very important</p>
1887
- </note>
1888
1947
  <admonition id='_' type='important'>
1889
1948
  <p id='_'>Notice which is very important</p>
1890
1949
  </admonition>
@@ -3102,6 +3161,57 @@ INPUT
3102
3161
  OUTPUT
3103
3162
  end
3104
3163
 
3164
+ it "fixes illegal anchors" do
3165
+ input = <<~INPUT
3166
+ #{ASCIIDOC_BLANK_HDR}
3167
+
3168
+ [[a:b]]
3169
+ == A
3170
+ <</:ab>>
3171
+ <<:>>
3172
+ <<1>>
3173
+ <<1:>>
3174
+ <<1#b>>
3175
+ <<:a#b:>>
3176
+
3177
+ INPUT
3178
+ expect(xmlpp(Asciidoctor.convert(input, backend: :standoc, header_footer: true).gsub(/<p id="_[^"]+">/, "").gsub('</p>', ""))).to be_equivalent_to (<<~"OUTPUT")
3179
+ <standard-document xmlns='https://www.metanorma.org/ns/standoc'>
3180
+ <bibdata type='standard'>
3181
+ <title language='en' format='text/plain'>Document title</title>
3182
+ <language>en</language>
3183
+ <script>Latn</script>
3184
+ <status>
3185
+ <stage>published</stage>
3186
+ </status>
3187
+ <copyright>
3188
+ <from>2020</from>
3189
+ </copyright>
3190
+ <ext>
3191
+ <doctype>article</doctype>
3192
+ </ext>
3193
+ </bibdata>
3194
+ <sections>
3195
+ <clause id='a_b' inline-header='false' obligation='normative'>
3196
+ <title>A</title>
3197
+ <xref target='__ab'/>
3198
+ <xref target='_'/>
3199
+ <xref target='_1'/>
3200
+ <xref target='_1_'/>
3201
+ <xref target='1#b'/>
3202
+ <xref target='_a#b_'/>
3203
+ </clause>
3204
+ </sections>
3205
+ </standard-document>
3206
+ OUTPUT
3207
+ expect{Asciidoctor.convert(input, backend: :standoc, header_footer: true)}.to output(%r{normalised identifier in <clause id="a_b" inline-header="false" obligation="normative"/> from a:b}).to_stderr
3208
+ expect{Asciidoctor.convert(input, backend: :standoc, header_footer: true)}.to output(%r{normalised identifier in <xref target="__ab"/> from /:ab}).to_stderr
3209
+ expect{Asciidoctor.convert(input, backend: :standoc, header_footer: true)}.to output(%r{normalised identifier in <xref target="_"/> from :}).to_stderr
3210
+ expect{Asciidoctor.convert(input, backend: :standoc, header_footer: true)}.to output(%r{normalised identifier in <xref target="_1"/> from 1}).to_stderr
3211
+ expect{Asciidoctor.convert(input, backend: :standoc, header_footer: true)}.to output(%r{normalised identifier in <xref target="_1_"/> from 1:}).to_stderr
3212
+ expect{Asciidoctor.convert(input, backend: :standoc, header_footer: true)}.to output(%r{normalised identifier in <xref target="_a#b_"/> from :a#b:}).to_stderr
3213
+ end
3214
+
3105
3215
 
3106
3216
  private
3107
3217