metanorma-standoc 2.1.5 → 2.2.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 (54) hide show
  1. checksums.yaml +4 -4
  2. data/lib/metanorma/standoc/base.rb +13 -0
  3. data/lib/metanorma/standoc/blocks.rb +26 -17
  4. data/lib/metanorma/standoc/cleanup.rb +1 -1
  5. data/lib/metanorma/standoc/cleanup_biblio.rb +210 -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 +3 -103
  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/front_contributor.rb +0 -10
  16. data/lib/metanorma/standoc/inline.rb +8 -4
  17. data/lib/metanorma/standoc/isodoc.rng +6 -1
  18. data/lib/metanorma/standoc/macros.rb +1 -180
  19. data/lib/metanorma/standoc/macros_inline.rb +194 -0
  20. data/lib/metanorma/standoc/ref_sect.rb +2 -2
  21. data/lib/metanorma/standoc/ref_utility.rb +1 -1
  22. data/lib/metanorma/standoc/reqt.rb +19 -75
  23. data/lib/metanorma/standoc/reqt.rng +1 -1
  24. data/lib/metanorma/standoc/section.rb +35 -3
  25. data/lib/metanorma/standoc/utils.rb +9 -43
  26. data/lib/metanorma/standoc/validate.rb +1 -69
  27. data/lib/metanorma/standoc/validate_table.rb +91 -0
  28. data/lib/metanorma/standoc/version.rb +1 -1
  29. data/metanorma-standoc.gemspec +4 -5
  30. data/spec/metanorma/{refs_dl_spec.rb → biblio_spec.rb} +90 -7
  31. data/spec/metanorma/blocks_spec.rb +31 -267
  32. data/spec/metanorma/cleanup_blocks_spec.rb +0 -171
  33. data/spec/metanorma/inline_spec.rb +4 -0
  34. data/spec/metanorma/macros_concept_spec.rb +1033 -0
  35. data/spec/metanorma/macros_spec.rb +2 -1030
  36. data/spec/metanorma/refs_spec.rb +0 -2
  37. data/spec/metanorma/reqt_spec.rb +130 -0
  38. data/spec/metanorma/section_spec.rb +5 -0
  39. data/spec/metanorma/validate_spec.rb +46 -6
  40. data/spec/vcr_cassettes/bsi16341.yml +80 -52
  41. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec.yml +94 -94
  42. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec1.yml +12 -12
  43. data/spec/vcr_cassettes/hide_refs.yml +70 -70
  44. data/spec/vcr_cassettes/isobib_get_123.yml +11 -11
  45. data/spec/vcr_cassettes/isobib_get_123_1.yml +23 -23
  46. data/spec/vcr_cassettes/isobib_get_123_1_fr.yml +35 -35
  47. data/spec/vcr_cassettes/isobib_get_123_2.yml +22 -22
  48. data/spec/vcr_cassettes/isobib_get_123_2001.yml +13 -13
  49. data/spec/vcr_cassettes/isobib_get_124.yml +11 -11
  50. data/spec/vcr_cassettes/rfcbib_get_rfc8341.yml +34 -64
  51. data/spec/vcr_cassettes/separates_iev_citations_by_top_level_clause.yml +45 -45
  52. data/spec/vcr_cassettes/std-link.yml +12 -12
  53. metadata +15 -11
  54. data/lib/metanorma/standoc/cleanup_ref_dl.rb +0 -113
@@ -10,19 +10,26 @@ module Metanorma
10
10
  @norm_ref = false
11
11
 
12
12
  def sectiontype1(node)
13
+ return "abstract" if node.attr("style") == "abstract"
14
+
13
15
  node&.attr("heading")&.downcase ||
14
- node.title.gsub(%r{<index>.*?</index>}m, "").gsub(/<[^>]+>/, "")
16
+ node.title
17
+ .gsub(%r{<index>.*?</index>}m, "")
18
+ .gsub(%r{<fn[^>]*>.*?</fn>}m, "")
19
+ .gsub(/<[^>]+>/, "")
15
20
  .strip.downcase
21
+ .sub(/\.$/, "")
16
22
  end
17
23
 
18
24
  def sectiontype(node, level = true)
19
25
  ret = sectiontype1(node)
20
- ret1 = sectiontype_streamline(ret)
26
+ ret1 = preface_main_filter(sectiontype_streamline(ret), node)
21
27
  return ret1 if ret1 == "symbols and abbreviated terms"
22
28
  return nil unless !level || node.level == 1
23
29
  return nil if @seen_headers.include? ret
24
30
 
25
- @seen_headers << ret
31
+ @seen_headers << ret unless ret1.nil?
32
+ @seen_headers_canonical << ret1 unless ret1.nil?
26
33
  ret1
27
34
  end
28
35
 
@@ -45,6 +52,31 @@ module Metanorma
45
52
  end
46
53
  end
47
54
 
55
+ PREFACE_CLAUSE_NAMES = %w(abstract foreword introduction
56
+ acknowledgements).freeze
57
+
58
+ MAIN_CLAUSE_NAMES =
59
+ ["normative references", "terms and definitions", "scope",
60
+ "symbols and abbreviated terms", "clause", "bibliography"].freeze
61
+
62
+ def start_main_section(ret, node)
63
+ @preface = false if MAIN_CLAUSE_NAMES.include?(ret) &&
64
+ node.role != "preface" && node.attr("style") != "preface"
65
+ @preface = false if (PREFACE_CLAUSE_NAMES)
66
+ .intersection(@seen_headers_canonical + [ret]).empty?
67
+ end
68
+
69
+ def preface_main_filter(ret, node)
70
+ start_main_section(ret, node)
71
+ if @preface
72
+ self.class::MAIN_CLAUSE_NAMES.include?(ret) and return nil
73
+ else
74
+ self.class::PREFACE_CLAUSE_NAMES.include?(ret) and return nil
75
+ end
76
+
77
+ ret
78
+ end
79
+
48
80
  def section_attributes(node)
49
81
  ret = { id: Metanorma::Utils::anchor_or_uuid(node),
50
82
  language: node.attributes["language"],
@@ -17,43 +17,20 @@ module Metanorma
17
17
  nil
18
18
  end
19
19
 
20
- NOKOHEAD = <<~HERE.freeze
21
- <!DOCTYPE html SYSTEM
22
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
23
- <html xmlns="http://www.w3.org/1999/xhtml">
24
- <head> <title></title> <meta charset="UTF-8" /> </head>
25
- <body> </body> </html>
26
- HERE
27
-
28
- # block for processing XML document fragments as XHTML,
29
- # to allow for HTMLentities
30
- # Unescape special chars used in Asciidoctor substitution processing
31
20
  def noko(&block)
32
- doc = ::Nokogiri::XML.parse(NOKOHEAD)
33
- fragment = doc.fragment("")
34
- ::Nokogiri::XML::Builder.with fragment, &block
35
- fragment.to_xml(encoding: "US-ASCII", indent: 0,
36
- save_with: Nokogiri::XML::Node::SaveOptions::AS_XML)
37
- .lines.map do |l|
38
- l.gsub(/>\n$/, ">").gsub(/\s*\n$/m, " ").gsub("&#150;", "\u0096")
39
- .gsub("&#151;", "\u0097").gsub("&#x96;", "\u0096")
40
- .gsub("&#x97;", "\u0097")
41
- end
21
+ Metanorma::Utils::noko(&block)
42
22
  end
43
23
 
44
24
  def attr_code(attributes)
45
- attributes.compact.transform_values do |v|
46
- v.is_a?(String) ? HTMLEntities.new.decode(v) : v
47
- end
25
+ Metanorma::Utils::attr_code(attributes)
26
+ end
27
+
28
+ def csv_split(text, delim = ";")
29
+ Metanorma::Utils::csv_split(text, delim)
48
30
  end
49
31
 
50
- # if the contents of node are blocks, output them to out;
51
- # else, wrap them in <p>
52
32
  def wrap_in_para(node, out)
53
- if node.blocks? then out << node.content
54
- else
55
- out.p { |p| p << node.content }
56
- end
33
+ Metanorma::Utils::wrap_in_para(node, out)
57
34
  end
58
35
 
59
36
  SUBCLAUSE_XPATH = "//clause[not(parent::sections)]"\
@@ -67,22 +44,11 @@ module Metanorma
67
44
  end
68
45
 
69
46
  def dl_to_attrs(elem, dlist, name)
70
- e = dlist.at("./dt[text()='#{name}']") or return
71
- val = e.at("./following::dd/p") || e.at("./following::dd") or return
72
- elem[name] = val.text
47
+ Metanorma::Utils::dl_to_attrs(elem, dlist, name)
73
48
  end
74
49
 
75
50
  def dl_to_elems(ins, elem, dlist, name)
76
- a = elem.at("./#{name}[last()]")
77
- ins = a if a
78
- dlist.xpath("./dt[text()='#{name}']").each do |e|
79
- v = e.at("./following::dd")
80
- e = v.elements and e.size == 1 && e.first.name == "p" and v = e.first
81
- v.name = name
82
- ins.next = v
83
- ins = ins.next
84
- end
85
- ins
51
+ Metanorma::Utils::dl_to_elems(ins, elem, dlist, name)
86
52
  end
87
53
 
88
54
  def term_expr(elem)
@@ -1,5 +1,6 @@
1
1
  require "metanorma/standoc/utils"
2
2
  require_relative "./validate_section"
3
+ require_relative "./validate_table"
3
4
  require "nokogiri"
4
5
  require "jing"
5
6
  require "iev"
@@ -53,75 +54,6 @@ module Metanorma
53
54
  @fatalerror.empty? or clean_abort(@fatalerror.join("\n"), doc.to_xml)
54
55
  end
55
56
 
56
- def table_validate(doc)
57
- doc.xpath("//table[colgroup]").each do |t|
58
- maxrowcols_validate(t, t.xpath("./colgroup/col").size)
59
- end
60
- doc.xpath("//table[.//*[@colspan] | .//*[@rowspan]]").each do |t|
61
- maxrowcols_validate(t, max_td_count(t))
62
- end
63
- end
64
-
65
- def max_td_count(table)
66
- max = 0
67
- table.xpath("./tr").each do |tr|
68
- n = tr.xpath("./td | ./th").size
69
- max < n and max = n
70
- end
71
- max
72
- end
73
-
74
- def maxrowcols_validate(table, maxcols)
75
- cells2d = table.xpath("./*/tr").each_with_object([]) { |_r, m| m << {} }
76
- table.xpath("./*/tr").each_with_index do |tr, r|
77
- curr = 0
78
- tr.xpath("./td | ./th").each do |td|
79
- curr = maxcols_validate1(td, r, curr, cells2d, maxcols)
80
- end
81
- end
82
- maxrows_validate(table, cells2d)
83
- end
84
-
85
- # code doesn't actually do anything, since Asciidoctor refuses to generate
86
- # table with inconsistent column count
87
- def maxcols_validate1(tcell, row, curr, cells2d, maxcols)
88
- rs = tcell&.attr("rowspan")&.to_i || 1
89
- cs = tcell&.attr("colspan")&.to_i || 1
90
- curr = table_tracker_update(cells2d, row, curr, rs, cs)
91
- maxcols_check(curr + cs - 1, maxcols, tcell)
92
- curr + cs
93
- end
94
-
95
- def table_tracker_update(cells2d, row, curr, rowspan, colspan)
96
- cells2d[row] ||= {}
97
- while cells2d[row][curr]
98
- curr += 1
99
- end
100
- (row..(row + rowspan - 1)).each do |y2|
101
- cells2d[y2] ||= {}
102
- (curr..(curr + colspan - 1)).each { |x2| cells2d[y2][x2] = 1 }
103
- end
104
- curr
105
- end
106
-
107
- def maxrows_validate(table, cells2d)
108
- if cells2d.any? { |x| x.size != cells2d.first.size }
109
- @log.add("Table", table,
110
- "Table rows in table are inconsistent: check rowspan")
111
- @fatalerror << "Table rows in table are inconsistent: check rowspan"
112
- end
113
- end
114
-
115
- # if maxcols or maxrows negative, do not check them
116
- def maxcols_check(col, maxcols, tcell)
117
- if maxcols.positive? && col > maxcols
118
- @log.add("Table", tcell, "Table exceeds maximum number of columns "\
119
- "defined (#{maxcols})")
120
- @fatalerror << "Table exceeds maximum number of columns defined "\
121
- "(#{maxcols})"
122
- end
123
- end
124
-
125
57
  def norm_ref_validate(doc)
126
58
  found = false
127
59
  doc.xpath("//references[@normative = 'true']/bibitem").each do |b|
@@ -0,0 +1,91 @@
1
+ module Metanorma
2
+ module Standoc
3
+ module Validate
4
+ def table_validate(doc)
5
+ doc.xpath("//table[colgroup]").each do |t|
6
+ maxrowcols_validate(t, t.xpath("./colgroup/col").size)
7
+ end
8
+ doc.xpath("//table[.//*[@colspan] | .//*[@rowspan]]").each do |t|
9
+ maxrowcols_validate(t, max_td_count(t), mode: "row_cols")
10
+ end
11
+ doc.xpath("//table[.//*[@rowspan]]").each do |t|
12
+ maxrowcols_validate(t, max_td_count(t), mode: "thead_row")
13
+ end
14
+ end
15
+
16
+ def max_td_count(table)
17
+ max = 0
18
+ table.xpath("./tr").each do |tr|
19
+ n = tr.xpath("./td | ./th").size
20
+ max < n and max = n
21
+ end
22
+ max
23
+ end
24
+
25
+ def maxrowcols_validate(table, maxcols, mode: "row_cols")
26
+ case mode
27
+ when "row_cols"
28
+ maxrowcols_validate0(table, maxcols, "*", mode)
29
+ when "thead_row"
30
+ %w{thead tbody tfoot}.each do |w|
31
+ maxrowcols_validate0(table, maxcols, w, mode)
32
+ end
33
+ end
34
+ end
35
+
36
+ def maxrowcols_validate0(table, maxcols, tablechild, mode)
37
+ cells2d = table.xpath("./#{tablechild}/tr")
38
+ .each_with_object([]) { |_r, m| m << {} }
39
+ table.xpath("./#{tablechild}/tr").each_with_index do |tr, r|
40
+ curr = 0
41
+ tr.xpath("./td | ./th").each do |td|
42
+ curr = maxcols_validate1(td, r, curr, cells2d, maxcols, mode)
43
+ end
44
+ end
45
+ maxrows_validate(table, cells2d, tablechild, mode)
46
+ end
47
+
48
+ # code doesn't actually do anything, since Asciidoctor refuses to generate
49
+ # table with inconsistent column count
50
+ def maxcols_validate1(tcell, row, curr, cells2d, maxcols, mode)
51
+ rs = tcell&.attr("rowspan")&.to_i || 1
52
+ cs = tcell&.attr("colspan")&.to_i || 1
53
+ curr = table_tracker_update(cells2d, row, curr, rs, cs)
54
+ maxcols_check(curr + cs - 1, maxcols, tcell) if mode == "row_cols"
55
+ curr + cs
56
+ end
57
+
58
+ def table_tracker_update(cells2d, row, curr, rowspan, colspan)
59
+ cells2d[row] ||= {}
60
+ while cells2d[row][curr]
61
+ curr += 1
62
+ end
63
+ (row..(row + rowspan - 1)).each do |y2|
64
+ cells2d[y2] ||= {}
65
+ (curr..(curr + colspan - 1)).each { |x2| cells2d[y2][x2] = 1 }
66
+ end
67
+ curr
68
+ end
69
+
70
+ def maxrows_validate(table, cells2d, tablechild, mode)
71
+ err = "are inconsistent"
72
+ mode == "thead_row" and err = "cannot go outside #{tablechild}"
73
+ err = "Table rows in table #{err}: check rowspan"
74
+ if cells2d.any? { |x| x.size != cells2d.first.size }
75
+ @log.add("Table", table, err)
76
+ @fatalerror << err
77
+ end
78
+ end
79
+
80
+ # if maxcols or maxrows negative, do not check them
81
+ def maxcols_check(col, maxcols, tcell)
82
+ if maxcols.positive? && col > maxcols
83
+ @log.add("Table", tcell, "Table exceeds maximum number of columns "\
84
+ "defined (#{maxcols})")
85
+ @fatalerror << "Table exceeds maximum number of columns defined "\
86
+ "(#{maxcols})"
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
@@ -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.1".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"
@@ -37,8 +36,8 @@ Gem::Specification.new do |spec|
37
36
  spec.add_dependency "concurrent-ruby"
38
37
  spec.add_dependency "latexmath"
39
38
  spec.add_dependency "mathml2asciimath"
40
- spec.add_dependency "metanorma-utils", "~> 1.2.8"
41
- spec.add_dependency "relaton-cli", "~> 1.12.0"
39
+ spec.add_dependency "mn-requirements", "~> 0.0.1"
40
+ spec.add_dependency "relaton-cli", "~> 1.13.0"
42
41
  spec.add_dependency "relaton-iev", "~> 1.1.0"
43
42
  spec.add_dependency "unicode2latex", "~> 0.0.1"
44
43
 
@@ -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
@@ -235,7 +235,7 @@ RSpec.describe Metanorma::Standoc do
235
235
  person::
236
236
  name:::
237
237
  language:::: en
238
- initial:::: A.
238
+ formatted_initials:::: A.
239
239
  surname:::: Bierman
240
240
  affiliation:::
241
241
  +
@@ -377,8 +377,8 @@ RSpec.describe Metanorma::Standoc do
377
377
  <role type="author"/>
378
378
  <person>
379
379
  <name>
380
- <initial language="en">A.</initial>
381
- <surname language="en">Bierman</surname>
380
+ <formatted-initials>A.</formatted-initials>
381
+ <surname>Bierman</surname>
382
382
  </name>
383
383
  <affiliation>
384
384
  <description language="en" script="Latn">Affiliation description</description>
@@ -590,7 +590,7 @@ RSpec.describe Metanorma::Standoc do
590
590
  contributor.role:: publisher
591
591
  contributor::
592
592
  contributor.person.name.language:: en
593
- contributor.person.name.initial:: A.
593
+ contributor.person.name.formatted_initials:: A.
594
594
  contributor.person.name.surname:: Bierman
595
595
  contributor.person.affiliation.organization.name:: IETF
596
596
  contributor.person.affiliation.organization.abbreviation:: IETF
@@ -706,8 +706,8 @@ RSpec.describe Metanorma::Standoc do
706
706
  <role type="author"/>
707
707
  <person>
708
708
  <name>
709
- <initial language="en">A.</initial>
710
- <surname language="en">Bierman</surname>
709
+ <formatted-initials>A.</formatted-initials>
710
+ <surname>Bierman</surname>
711
711
  </name>
712
712
  <affiliation>
713
713
  <description language="en" script="Latn">Affiliation description</description>
@@ -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]]], span:surname[Wozniak], span:initials[S.] & span:givenname[Steve] span:surname[Jobs]. span:pubyear[1996]. span:title[_Work_]. In span:surname.editor[Gates], span:initials.editor[W. H], Collected Essays. span:docid.ISO[ISO 1234]. span:pubplace[Geneva]: span:publisher[International Standardization Organization]. span:uri.citation[http://www.example.com]. span: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
+ <formatted-initials>S.</formatted-initials>
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
+ <formatted-initials>W. H</formatted-initials>
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