metanorma-standoc 2.1.0 → 2.1.3

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 (49) hide show
  1. checksums.yaml +4 -4
  2. data/lib/metanorma/standoc/base.rb +3 -1
  3. data/lib/metanorma/standoc/biblio.rng +134 -39
  4. data/lib/metanorma/standoc/blocks.rb +8 -6
  5. data/lib/metanorma/standoc/blocks_notes.rb +3 -0
  6. data/lib/metanorma/standoc/cleanup.rb +1 -0
  7. data/lib/metanorma/standoc/cleanup_footnotes.rb +14 -9
  8. data/lib/metanorma/standoc/cleanup_inline.rb +17 -0
  9. data/lib/metanorma/standoc/cleanup_reqt.rb +1 -1
  10. data/lib/metanorma/standoc/cleanup_terms.rb +3 -1
  11. data/lib/metanorma/standoc/cleanup_text.rb +9 -4
  12. data/lib/metanorma/standoc/cleanup_xref.rb +2 -1
  13. data/lib/metanorma/standoc/converter.rb +2 -0
  14. data/lib/metanorma/standoc/inline.rb +2 -1
  15. data/lib/metanorma/standoc/isodoc.rng +16 -0
  16. data/lib/metanorma/standoc/lists.rb +8 -3
  17. data/lib/metanorma/standoc/macros.rb +31 -4
  18. data/lib/metanorma/standoc/macros_form.rb +1 -1
  19. data/lib/metanorma/standoc/macros_note.rb +1 -6
  20. data/lib/metanorma/standoc/ref_sect.rb +2 -1
  21. data/lib/metanorma/standoc/reqt.rb +5 -3
  22. data/lib/metanorma/standoc/section.rb +1 -1
  23. data/lib/metanorma/standoc/version.rb +1 -1
  24. data/metanorma-standoc.gemspec +2 -2
  25. data/spec/metanorma/base_spec.rb +41 -5
  26. data/spec/metanorma/blocks_spec.rb +53 -1
  27. data/spec/metanorma/cleanup_sections_spec.rb +5 -5
  28. data/spec/metanorma/cleanup_spec.rb +6 -6
  29. data/spec/metanorma/cleanup_terms_spec.rb +1 -1
  30. data/spec/metanorma/inline_spec.rb +3 -3
  31. data/spec/metanorma/lists_spec.rb +10 -4
  32. data/spec/metanorma/macros_spec.rb +21 -12
  33. data/spec/metanorma/refs_spec.rb +112 -118
  34. data/spec/metanorma/table_spec.rb +24 -6
  35. data/spec/spec_helper.rb +1 -1
  36. data/spec/vcr_cassettes/bsi16341.yml +69 -69
  37. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec.yml +89 -89
  38. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec1.yml +12 -12
  39. data/spec/vcr_cassettes/hide_refs.yml +55 -55
  40. data/spec/vcr_cassettes/isobib_get_123.yml +14 -14
  41. data/spec/vcr_cassettes/isobib_get_123_1.yml +28 -28
  42. data/spec/vcr_cassettes/isobib_get_123_1_fr.yml +35 -35
  43. data/spec/vcr_cassettes/isobib_get_123_2001.yml +14 -14
  44. data/spec/vcr_cassettes/isobib_get_124.yml +12 -12
  45. data/spec/vcr_cassettes/rfcbib_get_rfc8341.yml +228 -52
  46. data/spec/vcr_cassettes/separates_iev_citations_by_top_level_clause.yml +56 -58
  47. data/spec/vcr_cassettes/std-link.yml +17 -17
  48. metadata +9 -10
  49. data/docs/quickstart.adoc +0 -375
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1e7285f74dd3b2b9ab155b8bf7e334aeb45f453a20f1d4eaf94f39f42b9251d3
4
- data.tar.gz: fdbad7c4cd96de56faacf360fdedaa0a0a5d24313c34b68ec2ab8e152db6a7c2
3
+ metadata.gz: 322efef58275c5330db01582e8ead5ea9c5c496e8a6c5e96aafd8c8413a4412f
4
+ data.tar.gz: f88ff574288ee6159fd0e4b05eb076767daede15afd3187d2de05dc1aae295bf
5
5
  SHA512:
6
- metadata.gz: ce9033847b44804a9ba150db5e4840e1d3dafef077a9c5af52defd74321333c66a3053abc589ae02ee3c28d6fe42afbd568cdef8b1a529e5b2a97ea46ec95ae0
7
- data.tar.gz: 6f498786e8222646f72fe88193797b0b0a23c30d1478cf78fad27862f19ece9c054ebe72c891ad671f5c03b4c8f06a659195cc77f359f517b1ffea02203ad22b
6
+ metadata.gz: f88c019751884a354f2217c7f67798365e4dfa4fdf15f573f8fa95d98b65abb483da40e6a5f8bd6c1fedb76a8d5d1fe72417cff24b94224bd5ecb625389dd926
7
+ data.tar.gz: 4eaa00800dc54f99af38e012923472d50215308e8ba96d2ebe8414ffb9e38c266a0de29e18fc80ba2536d82c7f47ea0df8bea8b892d7610c7d67b46d088bf430
@@ -171,7 +171,9 @@ module Metanorma
171
171
  end
172
172
 
173
173
  def doctype(node)
174
- node.attr("doctype")&.gsub(/\s+/, "-")&.downcase
174
+ ret = node.attr("doctype")&.gsub(/\s+/, "-")&.downcase || "standard"
175
+ ret = "standard" if ret == "article"
176
+ ret
175
177
  end
176
178
 
177
179
  def front(node, xml)
@@ -614,12 +614,103 @@
614
614
  <optional>
615
615
  <ref name="fetched"/>
616
616
  </optional>
617
- <choice>
618
- <oneOrMore>
619
- <ref name="btitle"/>
620
- </oneOrMore>
617
+ <optional>
621
618
  <ref name="formattedref"/>
622
- </choice>
619
+ </optional>
620
+ <oneOrMore>
621
+ <ref name="btitle"/>
622
+ </oneOrMore>
623
+ <zeroOrMore>
624
+ <ref name="bsource"/>
625
+ </zeroOrMore>
626
+ <oneOrMore>
627
+ <ref name="docidentifier"/>
628
+ </oneOrMore>
629
+ <optional>
630
+ <ref name="docnumber"/>
631
+ </optional>
632
+ <zeroOrMore>
633
+ <ref name="bdate"/>
634
+ </zeroOrMore>
635
+ <zeroOrMore>
636
+ <ref name="contributor"/>
637
+ </zeroOrMore>
638
+ <optional>
639
+ <ref name="edition"/>
640
+ </optional>
641
+ <zeroOrMore>
642
+ <ref name="version"/>
643
+ </zeroOrMore>
644
+ <zeroOrMore>
645
+ <ref name="biblionote"/>
646
+ </zeroOrMore>
647
+ <zeroOrMore>
648
+ <ref name="language"/>
649
+ </zeroOrMore>
650
+ <zeroOrMore>
651
+ <ref name="script"/>
652
+ </zeroOrMore>
653
+ <zeroOrMore>
654
+ <ref name="bibabstract"/>
655
+ </zeroOrMore>
656
+ <optional>
657
+ <ref name="status"/>
658
+ </optional>
659
+ <zeroOrMore>
660
+ <ref name="copyright"/>
661
+ </zeroOrMore>
662
+ <zeroOrMore>
663
+ <ref name="docrelation"/>
664
+ </zeroOrMore>
665
+ <zeroOrMore>
666
+ <ref name="series"/>
667
+ </zeroOrMore>
668
+ <optional>
669
+ <ref name="medium"/>
670
+ </optional>
671
+ <zeroOrMore>
672
+ <ref name="bplace"/>
673
+ </zeroOrMore>
674
+ <zeroOrMore>
675
+ <ref name="bprice"/>
676
+ </zeroOrMore>
677
+ <zeroOrMore>
678
+ <ref name="extent"/>
679
+ </zeroOrMore>
680
+ <optional>
681
+ <ref name="bibliographic_size"/>
682
+ </optional>
683
+ <zeroOrMore>
684
+ <ref name="accesslocation"/>
685
+ </zeroOrMore>
686
+ <zeroOrMore>
687
+ <ref name="license"/>
688
+ </zeroOrMore>
689
+ <zeroOrMore>
690
+ <ref name="bclassification"/>
691
+ </zeroOrMore>
692
+ <zeroOrMore>
693
+ <ref name="bkeyword"/>
694
+ </zeroOrMore>
695
+ <optional>
696
+ <ref name="validity"/>
697
+ </optional>
698
+ </define>
699
+ <define name="ReducedBibliographicItem">
700
+ <optional>
701
+ <attribute name="type">
702
+ <ref name="BibItemType"/>
703
+ </attribute>
704
+ </optional>
705
+ <optional>
706
+ <ref name="fetched"/>
707
+ </optional>
708
+ <optional>
709
+ <ref name="formattedref"/>
710
+ </optional>
711
+ <zeroOrMore>
712
+ <ref name="btitle"/>
713
+ </zeroOrMore>
623
714
  <zeroOrMore>
624
715
  <ref name="bsource"/>
625
716
  </zeroOrMore>
@@ -638,9 +729,9 @@
638
729
  <optional>
639
730
  <ref name="edition"/>
640
731
  </optional>
641
- <optional>
732
+ <zeroOrMore>
642
733
  <ref name="version"/>
643
- </optional>
734
+ </zeroOrMore>
644
735
  <zeroOrMore>
645
736
  <ref name="biblionote"/>
646
737
  </zeroOrMore>
@@ -833,6 +924,12 @@
833
924
  <data type="boolean"/>
834
925
  </attribute>
835
926
  </optional>
927
+ <optional>
928
+ <attribute name="language"/>
929
+ </optional>
930
+ <optional>
931
+ <attribute name="script"/>
932
+ </optional>
836
933
  <text/>
837
934
  </element>
838
935
  </define>
@@ -986,36 +1083,34 @@
986
1083
  <ref name="SeriesType"/>
987
1084
  </attribute>
988
1085
  </optional>
989
- <choice>
1086
+ <optional>
990
1087
  <ref name="formattedref"/>
991
- <group>
992
- <ref name="btitle"/>
993
- <optional>
994
- <ref name="bplace"/>
995
- </optional>
996
- <optional>
997
- <ref name="seriesorganization"/>
998
- </optional>
999
- <optional>
1000
- <ref name="abbreviation"/>
1001
- </optional>
1002
- <optional>
1003
- <ref name="seriesfrom"/>
1004
- </optional>
1005
- <optional>
1006
- <ref name="seriesto"/>
1007
- </optional>
1008
- <optional>
1009
- <ref name="seriesnumber"/>
1010
- </optional>
1011
- <optional>
1012
- <ref name="seriespartnumber"/>
1013
- </optional>
1014
- <optional>
1015
- <ref name="seriesrun"/>
1016
- </optional>
1017
- </group>
1018
- </choice>
1088
+ </optional>
1089
+ <ref name="btitle"/>
1090
+ <optional>
1091
+ <ref name="bplace"/>
1092
+ </optional>
1093
+ <optional>
1094
+ <ref name="seriesorganization"/>
1095
+ </optional>
1096
+ <optional>
1097
+ <ref name="abbreviation"/>
1098
+ </optional>
1099
+ <optional>
1100
+ <ref name="seriesfrom"/>
1101
+ </optional>
1102
+ <optional>
1103
+ <ref name="seriesto"/>
1104
+ </optional>
1105
+ <optional>
1106
+ <ref name="seriesnumber"/>
1107
+ </optional>
1108
+ <optional>
1109
+ <ref name="seriespartnumber"/>
1110
+ </optional>
1111
+ <optional>
1112
+ <ref name="seriesrun"/>
1113
+ </optional>
1019
1114
  </element>
1020
1115
  </define>
1021
1116
  <define name="SeriesType">
@@ -1174,7 +1269,7 @@
1174
1269
  </element>
1175
1270
  </optional>
1176
1271
  <element name="bibitem">
1177
- <ref name="BibliographicItem"/>
1272
+ <ref name="ReducedBibliographicItem"/>
1178
1273
  </element>
1179
1274
  <choice>
1180
1275
  <zeroOrMore>
@@ -1199,9 +1294,9 @@
1199
1294
  <optional>
1200
1295
  <ref name="revision-date"/>
1201
1296
  </optional>
1202
- <zeroOrMore>
1297
+ <optional>
1203
1298
  <ref name="draft"/>
1204
- </zeroOrMore>
1299
+ </optional>
1205
1300
  </element>
1206
1301
  </define>
1207
1302
  <define name="vedition">
@@ -38,9 +38,7 @@ module Metanorma
38
38
  role == "form" and return form(node)
39
39
  role == "definition" and return termdefinition(node)
40
40
  result = []
41
- node.blocks.each do |b|
42
- result << send(b.context, b)
43
- end
41
+ node.blocks.each { |b| result << send(b.context, b) }
44
42
  result
45
43
  end
46
44
 
@@ -80,14 +78,17 @@ module Metanorma
80
78
 
81
79
  def term_example(node)
82
80
  noko do |xml|
83
- xml.termexample **attr_code(id_attr(node)) do |ex|
81
+ xml.termexample **attr_code(id_attr(node)
82
+ .merge(
83
+ keepasterm: node.option?("termexample") || nil,
84
+ )) do |ex|
84
85
  wrap_in_para(node, ex)
85
86
  end
86
87
  end.join("\n")
87
88
  end
88
89
 
89
90
  def example(node)
90
- return term_example(node) if in_terms?
91
+ return term_example(node) if in_terms? || node.option?("termexample")
91
92
 
92
93
  role = node.role || node.attr("style")
93
94
  %w(recommendation requirement permission).include?(role) and
@@ -237,10 +238,11 @@ module Metanorma
237
238
  end
238
239
 
239
240
  def pass(node)
241
+ c = HTMLEntities.new
240
242
  noko do |xml|
241
243
  xml.passthrough **attr_code(formats:
242
244
  node.attr("format") || "metanorma") do |p|
243
- p << HTMLEntities.new.encode(node.content, :basic, :hexadecimal)
245
+ p << c.encode(c.decode(node.content), :basic, :hexadecimal)
244
246
  end
245
247
  end
246
248
  end
@@ -8,6 +8,7 @@ module Metanorma
8
8
  number: node.attr("number"),
9
9
  subsequence: node.attr("subsequence"),
10
10
  "keep-separate": node.attr("keep-separate"),
11
+ keepasterm: node.option?("termnote") ? "true" : nil,
11
12
  )))
12
13
  end
13
14
 
@@ -61,6 +62,8 @@ module Metanorma
61
62
  end
62
63
 
63
64
  def note(node)
65
+ return termnote(node) if node.option?("termnote")
66
+
64
67
  noko do |xml|
65
68
  xml.note **note_attrs(node) do |c|
66
69
  wrap_in_para(node, c)
@@ -25,6 +25,7 @@ module Metanorma
25
25
  module Cleanup
26
26
  def cleanup(xmldoc)
27
27
  element_name_cleanup(xmldoc)
28
+ passthrough_cleanup(xmldoc)
28
29
  sections_cleanup(xmldoc)
29
30
  obligations_cleanup(xmldoc)
30
31
  table_cleanup(xmldoc)
@@ -5,12 +5,15 @@ require "json"
5
5
  module Metanorma
6
6
  module Standoc
7
7
  module Cleanup
8
- def footnote_content(fn)
9
- c = fn.children.respond_to?(:to_xml) ? fn.children.to_xml : fn.children
8
+ def footnote_content(fnote)
9
+ c = if fnote.children.respond_to?(:to_xml)
10
+ fnote.children.to_xml
11
+ else fn.children
12
+ end
10
13
  c.gsub(/ id="[^"]+"/, "")
11
14
  end
12
15
 
13
- # include footnotes inside figure if they are the only content
16
+ # include footnotes inside figure if they are the only content
14
17
  # of the paras following
15
18
  def figure_footnote_cleanup(xmldoc)
16
19
  nomatches = false
@@ -18,7 +21,9 @@ module Metanorma
18
21
  q = "//figure/following-sibling::*[1][self::p and *[1][self::fn]]"
19
22
  nomatches = true
20
23
  xmldoc.xpath(q).each do |s|
21
- next if s.children.map { |c| c.text? && /[[:alpha:]]/.match(c.text) }.any?
24
+ next if s.children.map do |c|
25
+ c.text? && /[[:alpha:]]/.match(c.text)
26
+ end.any?
22
27
 
23
28
  s.previous_element << s.first_element_child.remove
24
29
  s.remove
@@ -27,16 +32,16 @@ module Metanorma
27
32
  end
28
33
  end
29
34
 
30
- def table_footnote_renumber1(fn, i, seen)
31
- content = footnote_content(fn)
35
+ def table_footnote_renumber1(fnote, i, seen)
36
+ content = footnote_content(fnote)
32
37
  if seen[content] then outnum = seen[content]
33
38
  else
34
39
  i += 1
35
40
  outnum = i
36
41
  seen[content] = outnum
37
42
  end
38
- fn["reference"] = (outnum - 1 + "a".ord).chr
39
- fn["table"] = true
43
+ fnote["reference"] = (outnum - 1 + "a".ord).chr
44
+ fnote["table"] = true
40
45
  [i, seen]
41
46
  end
42
47
 
@@ -84,7 +89,7 @@ module Metanorma
84
89
 
85
90
  def footnote_block_cleanup(xmldoc)
86
91
  xmldoc.xpath("//footnoteblock").each do |f|
87
- f.name = 'fn'
92
+ f.name = "fn"
88
93
  if id = xmldoc.at("//*[@id = '#{f.text}']")
89
94
  f.children = id.remove.children
90
95
  else
@@ -185,6 +185,23 @@ module Metanorma
185
185
  Digest::MD5.hexdigest("#{elem.path}////#{elem.text}")
186
186
  .sub(/^(.{8})(.{4})(.{4})(.{4})(.{12})$/, "_\\1-\\2-\\3-\\4-\\5")
187
187
  end
188
+
189
+ def passthrough_cleanup(doc)
190
+ doc.xpath("//passthrough-inline").each do |p|
191
+ p.name = "passthrough"
192
+ p.children = select_odd_chars(p.children.to_xml)
193
+ end
194
+ doc.xpath("//identifier").each do |p|
195
+ p.children = select_odd_chars(p.children.to_xml)
196
+ end
197
+ end
198
+
199
+ private
200
+
201
+ # skip ZWNJ inserted to prevent regexes operating in asciidoctor
202
+ def select_odd_chars(text)
203
+ text.gsub(/(?!&)([[:punct:]])\u200c/, "\\1")
204
+ end
188
205
  end
189
206
  end
190
207
  end
@@ -53,7 +53,7 @@ module Metanorma
53
53
  permission).include?(text.name))) ||
54
54
  (text.text.strip.empty? && !text.at(".//xref | .//eref | .//link"))
55
55
 
56
- t = Nokogiri::XML::Element.new("description", reqt)
56
+ t = Nokogiri::XML::Element.new("description", reqt.document)
57
57
  text.before(t)
58
58
  t.children = text.remove
59
59
  end
@@ -93,7 +93,9 @@ module Metanorma
93
93
  def termnote_example_cleanup(xmldoc)
94
94
  %w(note example).each do |w|
95
95
  xmldoc.xpath("//term#{w}[not(ancestor::term)]").each do |x|
96
- x.name = w
96
+ if x["keepasterm"] then x.delete("keepasterm")
97
+ else x.name = w
98
+ end
97
99
  end
98
100
  end
99
101
  end
@@ -5,8 +5,11 @@ module Metanorma
5
5
  text = result.flatten.map { |l| l.sub(/\s*\Z/, "") } * "\n"
6
6
  !@keepasciimath and text = asciimath2mathml(text)
7
7
  text = text.gsub(/\s+<fn /, "<fn ")
8
- text.gsub(%r{<passthrough\s+formats="metanorma">([^<]*)
9
- </passthrough>}mx) { HTMLEntities.new.decode($1) }
8
+ %w(passthrough passthrough-inline).each do |v|
9
+ text.gsub!(%r{<#{v}\s+formats="metanorma">([^<]*)
10
+ </#{v}>}mx) { HTMLEntities.new.decode($1) }
11
+ end
12
+ text
10
13
  end
11
14
 
12
15
  def smartquotes_cleanup(xmldoc)
@@ -33,7 +36,8 @@ module Metanorma
33
36
 
34
37
  def uninterrupt_quotes_around_xml_skip(elem)
35
38
  !(/\A['"]/.match?(elem.text) &&
36
- elem.previous.ancestors("pre, tt, sourcecode, stem, figure, bibdata")
39
+ elem.previous.ancestors("pre, tt, sourcecode, stem, figure, bibdata,
40
+ passthrough, identifer")
37
41
  .empty? &&
38
42
  ((elem.previous.text.strip.empty? &&
39
43
  !empty_tag_with_text_content?(elem.previous)) ||
@@ -70,7 +74,8 @@ module Metanorma
70
74
  empty_tag_with_text_content?(x) and prev = "dummy"
71
75
  next unless x.text?
72
76
 
73
- x.ancestors("pre, tt, sourcecode, stem, figure, bibdata").empty? and
77
+ x.ancestors("pre, tt, sourcecode, stem, figure, bibdata, passthrough,
78
+ identifier").empty? and
74
79
  dumb2smart_quotes1(x, prev)
75
80
  prev = x.text if x.ancestors("index").empty?
76
81
  end
@@ -68,9 +68,10 @@ module Metanorma
68
68
  end
69
69
 
70
70
  def xref_to_eref(elem)
71
+ c = HTMLEntities.new
71
72
  elem["bibitemid"] = elem["target"]
72
73
  if ref = @anchors&.dig(elem["target"], :xref)
73
- elem["citeas"] = HTMLEntities.new.encode(ref, :hexadecimal)
74
+ elem["citeas"] = c.decode(ref)
74
75
  else
75
76
  elem["citeas"] = ""
76
77
  xref_to_eref1(elem)
@@ -36,6 +36,7 @@ module Metanorma
36
36
  inline_macro Metanorma::Standoc::DomainTermInlineMacro
37
37
  inline_macro Metanorma::Standoc::InheritInlineMacro
38
38
  inline_macro Metanorma::Standoc::HTML5RubyMacro
39
+ inline_macro Metanorma::Standoc::IdentifierInlineMacro
39
40
  inline_macro Metanorma::Standoc::ConceptInlineMacro
40
41
  inline_macro Metanorma::Standoc::AutonumberInlineMacro
41
42
  inline_macro Metanorma::Standoc::VariantInlineMacro
@@ -63,6 +64,7 @@ module Metanorma
63
64
  block Metanorma::Plugin::Lutaml::LutamlDiagramBlock
64
65
  block Metanorma::Standoc::PseudocodeBlockMacro
65
66
  preprocessor Metanorma::Standoc::EmbedIncludeProcessor
67
+ preprocessor Metanorma::Standoc::NamedEscapePreprocessor
66
68
  end
67
69
 
68
70
  include ::Asciidoctor::Converter
@@ -79,7 +79,8 @@ module Metanorma
79
79
  end
80
80
 
81
81
  def inline_anchor_bibref(node)
82
- eref_contents = (node.text || node.target || node.id)
82
+ eref_contents = HTMLEntities.new
83
+ .decode(node.text || node.target || node.id)
83
84
  &.sub(/^\[?([^\[\]]+?)\]?$/, "[\\1]")
84
85
  @refids << (node.target || node.id)
85
86
  noko do |xml|
@@ -282,6 +282,9 @@
282
282
  <ref name="MultilingualRenderingType"/>
283
283
  </attribute>
284
284
  </optional>
285
+ <optional>
286
+ <ref name="tname"/>
287
+ </optional>
285
288
  <oneOrMore>
286
289
  <ref name="ul_li"/>
287
290
  </oneOrMore>
@@ -324,6 +327,9 @@
324
327
  </choice>
325
328
  </attribute>
326
329
  </optional>
330
+ <optional>
331
+ <ref name="tname"/>
332
+ </optional>
327
333
  <oneOrMore>
328
334
  <ref name="li"/>
329
335
  </oneOrMore>
@@ -360,6 +366,9 @@
360
366
  <ref name="MultilingualRenderingType"/>
361
367
  </attribute>
362
368
  </optional>
369
+ <optional>
370
+ <ref name="tname"/>
371
+ </optional>
363
372
  <oneOrMore>
364
373
  <ref name="dt"/>
365
374
  <ref name="dd"/>
@@ -694,6 +703,9 @@
694
703
  <optional>
695
704
  <attribute name="tag"/>
696
705
  </optional>
706
+ <optional>
707
+ <attribute name="type"/>
708
+ </optional>
697
709
  <optional>
698
710
  <attribute name="multilingual-rendering">
699
711
  <ref name="MultilingualRenderingType"/>
@@ -729,6 +741,9 @@
729
741
  <optional>
730
742
  <attribute name="tag"/>
731
743
  </optional>
744
+ <optional>
745
+ <attribute name="type"/>
746
+ </optional>
732
747
  <optional>
733
748
  <attribute name="multilingual-rendering">
734
749
  <ref name="MultilingualRenderingType"/>
@@ -2050,6 +2065,7 @@
2050
2065
  <value>compare</value>
2051
2066
  <value>contrast</value>
2052
2067
  <value>see</value>
2068
+ <value>seealso</value>
2053
2069
  </choice>
2054
2070
  </define>
2055
2071
  <define name="deprecates">
@@ -38,9 +38,8 @@ module Metanorma
38
38
 
39
39
  noko do |xml|
40
40
  xml.ul **ul_attrs(node) do |xml_ul|
41
- node.items.each do |item|
42
- ul_li(xml_ul, item)
43
- end
41
+ list_caption(node, xml_ul)
42
+ node.items.each { |item| ul_li(xml_ul, item) }
44
43
  end
45
44
  end.join("\n")
46
45
  end
@@ -62,6 +61,7 @@ module Metanorma
62
61
  def olist(node)
63
62
  noko do |xml|
64
63
  xml.ol **ol_attrs(node) do |xml_ol|
64
+ list_caption(node, xml_ol)
65
65
  node.items.each { |item| li(xml_ol, item) }
66
66
  end
67
67
  end.join("\n")
@@ -98,6 +98,7 @@ module Metanorma
98
98
  def dlist(node)
99
99
  noko do |xml|
100
100
  xml.dl **dl_attrs(node) do |xml_dl|
101
+ list_caption(node, xml_dl)
101
102
  node.items.each do |terms, dd|
102
103
  dt(terms, xml_dl)
103
104
  dd(dd, xml_dl)
@@ -115,6 +116,10 @@ module Metanorma
115
116
  end
116
117
  end.join("\n")
117
118
  end
119
+
120
+ def list_caption(node, out)
121
+ a = node.title and out.name { |n| n << a }
122
+ end
118
123
  end
119
124
  end
120
125
  end
@@ -130,7 +130,7 @@ module Metanorma
130
130
 
131
131
  def process(parent, target, attrs)
132
132
  out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
133
- %{<autonumber type=#{target}>#{out}</autonumber>}
133
+ %{<autonumber type='#{target}'>#{out}</autonumber>}
134
134
  end
135
135
  end
136
136
 
@@ -143,9 +143,9 @@ module Metanorma
143
143
  /^(?<lang>[^-]*)(?:-(?<script>.*))?$/ =~ target
144
144
  out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
145
145
  if script
146
- %{<variant lang=#{lang} script=#{script}>#{out}</variant>}
146
+ %{<variant lang='#{lang}' script='#{script}'>#{out}</variant>}
147
147
  else
148
- %{<variant lang=#{lang}>#{out}</variant>}
148
+ %{<variant lang='#{lang}'>#{out}</variant>}
149
149
  end
150
150
  end
151
151
  end
@@ -191,6 +191,7 @@ module Metanorma
191
191
  end
192
192
  end
193
193
 
194
+ # inject ZWNJ to prevent Asciidoctor from attempting regex substitutions
194
195
  class PassInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
195
196
  use_dsl
196
197
  named :"pass-format"
@@ -198,7 +199,21 @@ module Metanorma
198
199
  def process(parent, target, attrs)
199
200
  format = target || "metanorma"
200
201
  out = Asciidoctor::Inline.new(parent, :quoted, attrs[1]).convert
201
- %{<passthrough formats="#{format}">#{out}</passthrough>}
202
+ .gsub(/((?![<>&])[[:punct:]])/, "\\1&#x200c;")
203
+ %{<passthrough-inline formats="#{format}">#{out}</passthrough-inline>}
204
+ end
205
+ end
206
+
207
+ class IdentifierInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
208
+ use_dsl
209
+ named :identifier
210
+ parse_content_as :raw
211
+ using_format :short
212
+
213
+ def process(parent, _target, attrs)
214
+ out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
215
+ .gsub(/((?![<>&])[[:punct:]])/, "\\1&#x200c;")
216
+ %{<identifier>#{out}</identifier>}
202
217
  end
203
218
  end
204
219
 
@@ -213,5 +228,17 @@ module Metanorma
213
228
  type: :xref, target: "_#{UUIDTools::UUID.random_create}")
214
229
  end
215
230
  end
231
+
232
+ class NamedEscapePreprocessor < Asciidoctor::Extensions::Preprocessor
233
+ def process(_document, reader)
234
+ c = HTMLEntities.new
235
+ lines = reader.readlines.map do |l|
236
+ l.split(/(&[A-Za-z][^;]*;)/).map do |s|
237
+ /^&[A-Za-z]/.match?(s) ? c.encode(c.decode(s), :hexadecimal) : s
238
+ end.join
239
+ end
240
+ ::Asciidoctor::Reader.new lines
241
+ end
242
+ end
216
243
  end
217
244
  end
@@ -56,7 +56,7 @@ module Metanorma
56
56
  m = %w(disabled value)
57
57
  .map { |a| attr[a] ? " #{a}='#{attr[a]}'" : nil }.compact
58
58
  out = Asciidoctor::Inline.new(parent, :quoted, attr["text"]).convert
59
- %{<option #{m.join}">#{out}</option>}
59
+ %{<option #{m.join}>#{out}</option>}
60
60
  end
61
61
  end
62
62
  end