metanorma-standoc 2.1.5 → 2.2.0

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 (44) hide show
  1. checksums.yaml +4 -4
  2. data/lib/metanorma/standoc/base.rb +1 -0
  3. data/lib/metanorma/standoc/blocks.rb +1 -2
  4. data/lib/metanorma/standoc/cleanup.rb +1 -1
  5. data/lib/metanorma/standoc/cleanup_biblio.rb +204 -0
  6. data/lib/metanorma/standoc/cleanup_block.rb +6 -4
  7. data/lib/metanorma/standoc/cleanup_maths.rb +2 -15
  8. data/lib/metanorma/standoc/cleanup_ref.rb +22 -13
  9. data/lib/metanorma/standoc/cleanup_reqt.rb +37 -4
  10. data/lib/metanorma/standoc/cleanup_symbols.rb +1 -1
  11. data/lib/metanorma/standoc/cleanup_text.rb +10 -8
  12. data/lib/metanorma/standoc/cleanup_xref.rb +1 -2
  13. data/lib/metanorma/standoc/converter.rb +2 -0
  14. data/lib/metanorma/standoc/front.rb +1 -1
  15. data/lib/metanorma/standoc/inline.rb +8 -4
  16. data/lib/metanorma/standoc/isodoc.rng +6 -1
  17. data/lib/metanorma/standoc/macros.rb +1 -180
  18. data/lib/metanorma/standoc/macros_inline.rb +194 -0
  19. data/lib/metanorma/standoc/ref_sect.rb +2 -2
  20. data/lib/metanorma/standoc/ref_utility.rb +1 -1
  21. data/lib/metanorma/standoc/reqt.rb +5 -5
  22. data/lib/metanorma/standoc/reqt.rng +1 -1
  23. data/lib/metanorma/standoc/version.rb +1 -1
  24. data/metanorma-standoc.gemspec +2 -3
  25. data/spec/metanorma/{refs_dl_spec.rb → biblio_spec.rb} +84 -1
  26. data/spec/metanorma/blocks_spec.rb +18 -8
  27. data/spec/metanorma/cleanup_blocks_spec.rb +24 -27
  28. data/spec/metanorma/inline_spec.rb +4 -0
  29. data/spec/metanorma/macros_spec.rb +2 -0
  30. data/spec/vcr_cassettes/bsi16341.yml +55 -55
  31. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec.yml +45 -45
  32. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec1.yml +12 -12
  33. data/spec/vcr_cassettes/hide_refs.yml +59 -59
  34. data/spec/vcr_cassettes/isobib_get_123.yml +12 -12
  35. data/spec/vcr_cassettes/isobib_get_123_1.yml +25 -25
  36. data/spec/vcr_cassettes/isobib_get_123_1_fr.yml +32 -32
  37. data/spec/vcr_cassettes/isobib_get_123_2.yml +22 -22
  38. data/spec/vcr_cassettes/isobib_get_123_2001.yml +13 -13
  39. data/spec/vcr_cassettes/isobib_get_124.yml +12 -12
  40. data/spec/vcr_cassettes/rfcbib_get_rfc8341.yml +24 -24
  41. data/spec/vcr_cassettes/separates_iev_citations_by_top_level_clause.yml +45 -45
  42. data/spec/vcr_cassettes/std-link.yml +11 -11
  43. metadata +7 -6
  44. data/lib/metanorma/standoc/cleanup_ref_dl.rb +0 -113
@@ -3,6 +3,7 @@ require "fileutils"
3
3
  require "uuidtools"
4
4
  require "yaml"
5
5
  require "csv"
6
+ require_relative "./macros_inline"
6
7
  require_relative "./macros_plantuml"
7
8
  require_relative "./macros_terms"
8
9
  require_relative "./macros_form"
@@ -15,54 +16,6 @@ require "metanorma-plugin-lutaml"
15
16
 
16
17
  module Metanorma
17
18
  module Standoc
18
- class InheritInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
19
- use_dsl
20
- named :inherit
21
- parse_content_as :text
22
- using_format :short
23
-
24
- def process(parent, _target, attrs)
25
- out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
26
- %{<inherit>#{out}</inherit>}
27
- end
28
- end
29
-
30
- class IndexXrefInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
31
- use_dsl
32
- named :index
33
-
34
- def preprocess_attrs(attrs)
35
- return unless attrs.size > 1 && attrs.size < 5
36
-
37
- ret = { primary: attrs[1], target: attrs[attrs.size] }
38
- ret[:secondary] = attrs[2] if attrs.size > 2
39
- ret[:tertiary] = attrs[3] if attrs.size > 3
40
- ret
41
- end
42
-
43
- def process(_parent, target, attr)
44
- args = preprocess_attrs(attr) or return
45
- ret = "<index-xref also='#{target == 'also'}'>"\
46
- "<primary>#{args[:primary]}</primary>"
47
- ret += "<secondary>#{args[:secondary]}</secondary>" if args[:secondary]
48
- ret += "<tertiary>#{args[:tertiary]}</tertiary>" if args[:tertiary]
49
- ret + "<target>#{args[:target]}</target></index-xref>"
50
- end
51
- end
52
-
53
- class IndexRangeInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
54
- use_dsl
55
- named :"index-range"
56
- parse_content_as :text
57
-
58
- def process(parent, target, attr)
59
- text = attr["text"]
60
- text = "((#{text}))" unless /^\(\(.+\)\)$/.match?(text)
61
- out = parent.sub_macros(text)
62
- out.sub(/<index>/, "<index to='#{target}'>")
63
- end
64
- end
65
-
66
19
  class PseudocodeBlockMacro < Asciidoctor::Extensions::BlockProcessor
67
20
  use_dsl
68
21
  named :pseudocode
@@ -97,138 +50,6 @@ module Metanorma
97
50
  end
98
51
  end
99
52
 
100
- class HTML5RubyMacro < Asciidoctor::Extensions::InlineMacroProcessor
101
- use_dsl
102
- named :ruby
103
- parse_content_as :text
104
- option :pos_attrs, %w(rpbegin rt rpend)
105
-
106
- # for example, html5ruby:楽聖少女[がくせいしょうじょ]
107
- def process(_parent, target, attributes)
108
- rpbegin = "("
109
- rpend = ")"
110
- if (attributes.size == 1) && attributes.key?("text")
111
- rt = attributes["text"]
112
- elsif (attributes.size == 2) && attributes.key?(1) &&
113
- attributes.key?("rpbegin")
114
- rt = attributes[1] || ""
115
- else
116
- rpbegin = attributes["rpbegin"]
117
- rt = attributes["rt"]
118
- rpend = attributes["rpend"]
119
- end
120
-
121
- "<ruby>#{target}<rp>#{rpbegin}</rp><rt>#{rt}</rt>"\
122
- "<rp>#{rpend}</rp></ruby>"
123
- end
124
- end
125
-
126
- class AutonumberInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
127
- use_dsl
128
- named :autonumber
129
- parse_content_as :text
130
-
131
- def process(parent, target, attrs)
132
- out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
133
- %{<autonumber type='#{target}'>#{out}</autonumber>}
134
- end
135
- end
136
-
137
- class VariantInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
138
- use_dsl
139
- named :lang
140
- parse_content_as :text
141
-
142
- def process(parent, target, attrs)
143
- /^(?<lang>[^-]*)(?:-(?<script>.*))?$/ =~ target
144
- out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
145
- if script
146
- %{<variant lang='#{lang}' script='#{script}'>#{out}</variant>}
147
- else
148
- %{<variant lang='#{lang}'>#{out}</variant>}
149
- end
150
- end
151
- end
152
-
153
- class AddMacro < Asciidoctor::Extensions::InlineMacroProcessor
154
- use_dsl
155
- named :add
156
- parse_content_as :text
157
- using_format :short
158
-
159
- def process(parent, _target, attrs)
160
- out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
161
- %{<add>#{out}</add>}
162
- end
163
- end
164
-
165
- class DelMacro < Asciidoctor::Extensions::InlineMacroProcessor
166
- use_dsl
167
- named :del
168
- parse_content_as :text
169
- using_format :short
170
-
171
- def process(parent, _target, attrs)
172
- out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
173
- %{<del>#{out}</del>}
174
- end
175
- end
176
-
177
- class ToCInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
178
- use_dsl
179
- named :toc
180
- parse_content_as :text
181
- using_format :short
182
-
183
- def process(parent, _target, attrs)
184
- out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
185
- content = CSV.parse_line(out).map do |x|
186
- x.sub!(/^(["'])(.+)\1/, "\\2")
187
- m = /^(.*?)(:\d+)?$/.match(x)
188
- %{<toc-xpath depth='#{m[2]&.sub(/:/, '') || 1}'>#{m[1]}</toc-xpath>}
189
- end.join
190
- "<toc>#{content}</toc>"
191
- end
192
- end
193
-
194
- # inject ZWNJ to prevent Asciidoctor from attempting regex substitutions
195
- class PassInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
196
- use_dsl
197
- named :"pass-format"
198
-
199
- def process(parent, target, attrs)
200
- format = target || "metanorma"
201
- out = Asciidoctor::Inline.new(parent, :quoted, attrs[1]).convert
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>}
217
- end
218
- end
219
-
220
- class StdLinkInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
221
- use_dsl
222
- named :"std-link"
223
- parse_content_as :text
224
- using_format :short
225
-
226
- def process(parent, _target, attrs)
227
- create_anchor(parent, "hidden%#{attrs['text']}",
228
- type: :xref, target: "_#{UUIDTools::UUID.random_create}")
229
- end
230
- end
231
-
232
53
  class NamedEscapePreprocessor < Asciidoctor::Extensions::Preprocessor
233
54
  def process(_document, reader)
234
55
  c = HTMLEntities.new
@@ -0,0 +1,194 @@
1
+ module Metanorma
2
+ module Standoc
3
+ class InheritInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
4
+ use_dsl
5
+ named :inherit
6
+ parse_content_as :text
7
+ using_format :short
8
+
9
+ def process(parent, _target, attrs)
10
+ out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
11
+ %{<inherit>#{out}</inherit>}
12
+ end
13
+ end
14
+
15
+ class IndexXrefInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
16
+ use_dsl
17
+ named :index
18
+
19
+ def preprocess_attrs(attrs)
20
+ return unless attrs.size > 1 && attrs.size < 5
21
+
22
+ ret = { primary: attrs[1], target: attrs[attrs.size] }
23
+ ret[:secondary] = attrs[2] if attrs.size > 2
24
+ ret[:tertiary] = attrs[3] if attrs.size > 3
25
+ ret
26
+ end
27
+
28
+ def process(_parent, target, attr)
29
+ args = preprocess_attrs(attr) or return
30
+ ret = "<index-xref also='#{target == 'also'}'>"\
31
+ "<primary>#{args[:primary]}</primary>"
32
+ ret += "<secondary>#{args[:secondary]}</secondary>" if args[:secondary]
33
+ ret += "<tertiary>#{args[:tertiary]}</tertiary>" if args[:tertiary]
34
+ ret + "<target>#{args[:target]}</target></index-xref>"
35
+ end
36
+ end
37
+
38
+ class IndexRangeInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
39
+ use_dsl
40
+ named :"index-range"
41
+ parse_content_as :text
42
+
43
+ def process(parent, target, attr)
44
+ text = attr["text"]
45
+ text = "((#{text}))" unless /^\(\(.+\)\)$/.match?(text)
46
+ out = parent.sub_macros(text)
47
+ out.sub(/<index>/, "<index to='#{target}'>")
48
+ end
49
+ end
50
+
51
+ class HTML5RubyMacro < Asciidoctor::Extensions::InlineMacroProcessor
52
+ use_dsl
53
+ named :ruby
54
+ parse_content_as :text
55
+ option :pos_attrs, %w(rpbegin rt rpend)
56
+
57
+ # for example, html5ruby:楽聖少女[がくせいしょうじょ]
58
+ def process(_parent, target, attributes)
59
+ rpbegin = "("
60
+ rpend = ")"
61
+ if (attributes.size == 1) && attributes.key?("text")
62
+ rt = attributes["text"]
63
+ elsif (attributes.size == 2) && attributes.key?(1) &&
64
+ attributes.key?("rpbegin")
65
+ rt = attributes[1] || ""
66
+ else
67
+ rpbegin = attributes["rpbegin"]
68
+ rt = attributes["rt"]
69
+ rpend = attributes["rpend"]
70
+ end
71
+
72
+ "<ruby>#{target}<rp>#{rpbegin}</rp><rt>#{rt}</rt>"\
73
+ "<rp>#{rpend}</rp></ruby>"
74
+ end
75
+ end
76
+
77
+ class AutonumberInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
78
+ use_dsl
79
+ named :autonumber
80
+ parse_content_as :text
81
+
82
+ def process(parent, target, attrs)
83
+ out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
84
+ %{<autonumber type='#{target}'>#{out}</autonumber>}
85
+ end
86
+ end
87
+
88
+ class VariantInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
89
+ use_dsl
90
+ named :lang
91
+ parse_content_as :text
92
+
93
+ def process(parent, target, attrs)
94
+ /^(?<lang>[^-]*)(?:-(?<script>.*))?$/ =~ target
95
+ out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
96
+ if script
97
+ %{<variant lang='#{lang}' script='#{script}'>#{out}</variant>}
98
+ else
99
+ %{<variant lang='#{lang}'>#{out}</variant>}
100
+ end
101
+ end
102
+ end
103
+
104
+ class AddMacro < Asciidoctor::Extensions::InlineMacroProcessor
105
+ use_dsl
106
+ named :add
107
+ parse_content_as :text
108
+ using_format :short
109
+
110
+ def process(parent, _target, attrs)
111
+ out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
112
+ %{<add>#{out}</add>}
113
+ end
114
+ end
115
+
116
+ class DelMacro < Asciidoctor::Extensions::InlineMacroProcessor
117
+ use_dsl
118
+ named :del
119
+ parse_content_as :text
120
+ using_format :short
121
+
122
+ def process(parent, _target, attrs)
123
+ out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
124
+ %{<del>#{out}</del>}
125
+ end
126
+ end
127
+
128
+ class ToCInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
129
+ use_dsl
130
+ named :toc
131
+ parse_content_as :text
132
+ using_format :short
133
+
134
+ def process(parent, _target, attrs)
135
+ out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
136
+ content = CSV.parse_line(out).map do |x|
137
+ x.sub!(/^(["'])(.+)\1/, "\\2")
138
+ m = /^(.*?)(:\d+)?$/.match(x)
139
+ %{<toc-xpath depth='#{m[2]&.sub(/:/, '') || 1}'>#{m[1]}</toc-xpath>}
140
+ end.join
141
+ "<toc>#{content}</toc>"
142
+ end
143
+ end
144
+
145
+ # inject ZWNJ to prevent Asciidoctor from attempting regex substitutions
146
+ class PassInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
147
+ use_dsl
148
+ named :"pass-format"
149
+
150
+ def process(parent, target, attrs)
151
+ format = target || "metanorma"
152
+ out = Asciidoctor::Inline.new(parent, :quoted, attrs[1]).convert
153
+ .gsub(/((?![<>&])[[:punct:]])/, "\\1&#x200c;")
154
+ %{<passthrough-inline formats="#{format}">#{out}</passthrough-inline>}
155
+ end
156
+ end
157
+
158
+ class IdentifierInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
159
+ use_dsl
160
+ named :identifier
161
+ parse_content_as :raw
162
+ using_format :short
163
+
164
+ def process(parent, _target, attrs)
165
+ out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
166
+ .gsub(/((?![<>&])[[:punct:]])/, "\\1&#x200c;")
167
+ %{<identifier>#{out}</identifier>}
168
+ end
169
+ end
170
+
171
+ class StdLinkInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
172
+ use_dsl
173
+ named :"std-link"
174
+ parse_content_as :text
175
+ using_format :short
176
+
177
+ def process(parent, _target, attrs)
178
+ create_anchor(parent, "hidden%#{attrs['text']}",
179
+ type: :xref, target: "_#{UUIDTools::UUID.random_create}")
180
+ end
181
+ end
182
+
183
+ class SpanInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
184
+ use_dsl
185
+ named :s
186
+ parse_content_as :text
187
+
188
+ def process(parent, target, attrs)
189
+ out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
190
+ %{<span class="#{target}">#{out}</span>}
191
+ end
192
+ end
193
+ end
194
+ end
@@ -84,7 +84,7 @@ module Metanorma
84
84
  if ref[:code].nil? || ref[:no_year] || @bibdb.nil?
85
85
  res << [ref, idx, nil]
86
86
  else
87
- @bibdb.fetch_async(HTMLEntities.new.decode(ref[:code]),
87
+ @bibdb.fetch_async(@c.decode(ref[:code]),
88
88
  ref[:year], ref) do |doc|
89
89
  res << [ref, idx, doc]
90
90
  end
@@ -131,7 +131,7 @@ module Metanorma
131
131
  global = !@no_isobib_cache && !node.attr("local-cache-only")
132
132
  local = node.attr("local-cache") || node.attr("local-cache-only")
133
133
  local = nil if @no_isobib_cache
134
- @bibdb = Relaton::DbCache.init_bib_caches(
134
+ @bibdb = Relaton::Db.init_bib_caches(
135
135
  local_cache: local,
136
136
  flush_caches: node.attr("flush-caches"),
137
137
  global_cache: global,
@@ -53,7 +53,7 @@ module Metanorma
53
53
 
54
54
  def docnumber(bib, code)
55
55
  bib.docnumber do |d|
56
- d << HTMLEntities.new.decode(code).sub(/^[^\d]*/, "")
56
+ d << @c.decode(code).sub(/^[^\d]*/, "")
57
57
  end
58
58
  end
59
59
 
@@ -7,7 +7,7 @@ module Metanorma
7
7
  module Standoc
8
8
  module Blocks
9
9
  def reqt_subpart(name)
10
- %w(specification measurement-target verification import label title
10
+ %w(specification measurement-target verification import identifier title
11
11
  description component subject inherit classification).include? name
12
12
  end
13
13
 
@@ -30,7 +30,7 @@ module Metanorma
30
30
 
31
31
  def req_classif_parse(classif)
32
32
  ret = []
33
- HTMLEntities.new.decode(classif).split(/;\s*/).each do |c|
33
+ @c.decode(classif).split(/;\s*/).each do |c|
34
34
  c1 = c.split(/:\s*/)
35
35
  next unless c1.size == 2
36
36
 
@@ -63,16 +63,16 @@ module Metanorma
63
63
 
64
64
  def requirement_elems(node, out)
65
65
  node.title and out.title { |t| t << node.title }
66
- a = node.attr("label") and out.label do |l|
66
+ a = node.attr("identifier") and out.identifier do |l|
67
67
  l << out.text(a)
68
68
  end
69
69
  a = node.attr("subject") and csv_split(a)&.each do |subj|
70
70
  out.subject { |s| s << out.text(subj) }
71
71
  end
72
- a = HTMLEntities.new.decode(node.attr("inherit")) and
72
+ a = @c.decode(node.attr("inherit")) and
73
73
  csv_split(a)&.each do |i|
74
74
  out.inherit do |inh|
75
- inh << HTMLEntities.new.encode(i, :hexadecimal)
75
+ inh << @c.encode(i, :hexadecimal)
76
76
  end
77
77
  end
78
78
  classif = node.attr("classification") and
@@ -108,7 +108,7 @@
108
108
  </element>
109
109
  </define>
110
110
  <define name="label">
111
- <element name="label">
111
+ <element name="identifier">
112
112
  <oneOrMore>
113
113
  <ref name="TextElement"/>
114
114
  </oneOrMore>
@@ -19,6 +19,6 @@ module Metanorma
19
19
  end
20
20
 
21
21
  module Standoc
22
- VERSION = "2.1.5".freeze
22
+ VERSION = "2.2.0".freeze
23
23
  end
24
24
  end
@@ -23,12 +23,11 @@ Gem::Specification.new do |spec|
23
23
  spec.bindir = "bin"
24
24
  spec.require_paths = ["lib"]
25
25
  spec.files = `git ls-files`.split("\n")
26
- spec.test_files = `git ls-files -- {spec}/*`.split("\n")
27
26
  spec.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
28
27
 
29
28
  spec.add_dependency "asciidoctor", "~> 2.0.0"
30
29
  spec.add_dependency "iev", "~> 0.3.0"
31
- spec.add_dependency "isodoc", "~> 2.1.0"
30
+ spec.add_dependency "isodoc", "~> 2.2.0"
32
31
  spec.add_dependency "metanorma-plugin-datastruct", "~> 0.2.0"
33
32
  spec.add_dependency "metanorma-plugin-lutaml"
34
33
  spec.add_dependency "ruby-jing"
@@ -55,5 +54,5 @@ Gem::Specification.new do |spec|
55
54
  spec.add_development_dependency "timecop", "~> 0.9"
56
55
  spec.add_development_dependency "vcr", "~> 6.1.0"
57
56
  spec.add_development_dependency "webmock"
58
- #spec.metadata["rubygems_mfa_required"] = "true"
57
+ # spec.metadata["rubygems_mfa_required"] = "true"
59
58
  end
@@ -840,7 +840,7 @@ RSpec.describe Metanorma::Standoc do
840
840
 
841
841
  INPUT
842
842
  output = <<~OUTPUT
843
- #{BLANK_HDR}
843
+ #{BLANK_HDR}
844
844
  <sections>
845
845
  <clause id='_' inline-header='false' obligation='normative'>
846
846
  <title>Section</title>
@@ -888,4 +888,87 @@ RSpec.describe Metanorma::Standoc do
888
888
  expect(xmlpp(strip_guid(Asciidoctor.convert(input, *OPTIONS))))
889
889
  .to be_equivalent_to xmlpp(output)
890
890
  end
891
+
892
+ it "processes microformatting of formatted references" do
893
+ input = <<~INPUT
894
+ #{ASCIIDOC_BLANK_HDR}
895
+
896
+ [bibliography]
897
+ === Normative References
898
+
899
+ * [[[A, B]]], s:surname[Wozniak], s:initials[S.] & s:givenname[Steve] s:surname[Jobs]. s:pubyear[1996]. s:title[_Work_]. In s:surname.editor[Gates], s:initials.editor[W. H], Collected Essays. s:docid.ISO[ISO 1234]. s:pubplace[Geneva]: s:publisher[International Standardization Organization]. s:uri.citation[http://www.example.com]. s:type[inbook]
900
+ INPUT
901
+ output = <<~OUTPUT
902
+ #{BLANK_HDR}
903
+ <sections> </sections>
904
+ <bibliography>
905
+ <references id='_' normative='true' obligation='informative'>
906
+ <title>Normative references</title>
907
+ <p id='_'>
908
+ The following documents are referred to in the text in such a way that
909
+ some or all of their content constitutes requirements of this document.
910
+ For dated references, only the edition cited applies. For undated
911
+ references, the latest edition of the referenced document (including any
912
+ amendments) applies.
913
+ </p>
914
+ <bibitem id='A' type="inbook">
915
+ <formattedref format='application/x-isodoc+xml'>
916
+ Wozniak, S. &amp; Steve Jobs. 1996.
917
+ <em>Work</em>
918
+ . In Gates, W. H, Collected Essays. ISO 1234. Geneva: International
919
+ Standardization Organization.
920
+ <link target='http://www.example.com'/>
921
+ .
922
+ </formattedref>
923
+ <title>
924
+ <em>Work</em>
925
+ </title>
926
+ <uri type='citation'>
927
+ <link target='http://www.example.com'/>
928
+ </uri>
929
+ <docidentifier>B</docidentifier>
930
+ <docidentifier type='ISO'>ISO 1234</docidentifier>
931
+ <date type='published'>1996</date>
932
+ <contributor>
933
+ <role type='author'/>
934
+ <person>
935
+ <name>
936
+ <initial>S.</initial>
937
+ <surname>Wozniak</surname>
938
+ </name>
939
+ </person>
940
+ </contributor>
941
+ <contributor>
942
+ <role type='author'/>
943
+ <person>
944
+ <name>
945
+ <forename>Steve</forename>
946
+ <surname>Jobs</surname>
947
+ </name>
948
+ </person>
949
+ </contributor>
950
+ <contributor>
951
+ <role type='editor'/>
952
+ <person>
953
+ <name>
954
+ <initial>W. H</initial>
955
+ <surname>Gates</surname>
956
+ </name>
957
+ </person>
958
+ </contributor>
959
+ <contributor>
960
+ <role type='publisher'/>
961
+ <organization>
962
+ <name>International Standardization Organization</name>
963
+ </organization>
964
+ </contributor>
965
+ <place/>
966
+ </bibitem>
967
+ </references>
968
+ </bibliography>
969
+ </standard-document>
970
+ OUTPUT
971
+ expect(xmlpp(strip_guid(Asciidoctor.convert(input, *OPTIONS))))
972
+ .to be_equivalent_to xmlpp(output)
973
+ end
891
974
  end