metanorma-standoc 1.8.6 → 1.9.2

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 (62) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.rubocop.yml +5 -3
  4. data/Gemfile.devel +0 -0
  5. data/lib/asciidoctor/standoc/base.rb +41 -36
  6. data/lib/asciidoctor/standoc/biblio.rng +4 -6
  7. data/lib/asciidoctor/standoc/blocks.rb +44 -14
  8. data/lib/asciidoctor/standoc/blocks_notes.rb +41 -24
  9. data/lib/asciidoctor/standoc/cleanup.rb +33 -78
  10. data/lib/asciidoctor/standoc/cleanup_block.rb +77 -62
  11. data/lib/asciidoctor/standoc/cleanup_boilerplate.rb +51 -29
  12. data/lib/asciidoctor/standoc/cleanup_footnotes.rb +1 -0
  13. data/lib/asciidoctor/standoc/cleanup_image.rb +71 -0
  14. data/lib/asciidoctor/standoc/cleanup_maths.rb +37 -28
  15. data/lib/asciidoctor/standoc/cleanup_ref.rb +24 -15
  16. data/lib/asciidoctor/standoc/cleanup_ref_dl.rb +1 -1
  17. data/lib/asciidoctor/standoc/cleanup_reqt.rb +47 -0
  18. data/lib/asciidoctor/standoc/cleanup_section.rb +21 -15
  19. data/lib/asciidoctor/standoc/converter.rb +10 -3
  20. data/lib/asciidoctor/standoc/datamodel/plantuml_renderer.rb +67 -66
  21. data/lib/asciidoctor/standoc/front.rb +35 -18
  22. data/lib/asciidoctor/standoc/front_contributor.rb +5 -5
  23. data/lib/asciidoctor/standoc/inline.rb +1 -1
  24. data/lib/asciidoctor/standoc/isodoc.rng +304 -1
  25. data/lib/asciidoctor/standoc/lists.rb +4 -2
  26. data/lib/asciidoctor/standoc/macros.rb +50 -23
  27. data/lib/asciidoctor/standoc/macros_form.rb +63 -0
  28. data/lib/asciidoctor/standoc/ref.rb +87 -112
  29. data/lib/asciidoctor/standoc/ref_date_id.rb +62 -0
  30. data/lib/asciidoctor/standoc/ref_sect.rb +22 -19
  31. data/lib/asciidoctor/standoc/section.rb +3 -1
  32. data/lib/asciidoctor/standoc/terms.rb +27 -16
  33. data/lib/asciidoctor/standoc/utils.rb +35 -9
  34. data/lib/asciidoctor/standoc/validate.rb +30 -28
  35. data/lib/metanorma-standoc.rb +0 -1
  36. data/lib/metanorma/standoc/version.rb +5 -5
  37. data/metanorma-standoc.gemspec +11 -11
  38. data/spec/asciidoctor/base_spec.rb +78 -8
  39. data/spec/asciidoctor/blocks_spec.rb +832 -727
  40. data/spec/asciidoctor/cleanup_sections_spec.rb +52 -15
  41. data/spec/asciidoctor/cleanup_spec.rb +1860 -1874
  42. data/spec/asciidoctor/inline_spec.rb +272 -273
  43. data/spec/asciidoctor/isobib_cache_spec.rb +406 -358
  44. data/spec/asciidoctor/macros_spec.rb +539 -437
  45. data/spec/asciidoctor/macros_yaml2text_spec.rb +1 -1
  46. data/spec/asciidoctor/refs_spec.rb +135 -7
  47. data/spec/asciidoctor/section_spec.rb +743 -690
  48. data/spec/assets/html-override.css +1 -0
  49. data/spec/assets/word-override.css +1 -0
  50. data/spec/spec_helper.rb +11 -9
  51. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec.yml +60 -60
  52. data/spec/vcr_cassettes/isobib_get_123.yml +14 -14
  53. data/spec/vcr_cassettes/isobib_get_123_1.yml +30 -30
  54. data/spec/vcr_cassettes/isobib_get_123_1_fr.yml +42 -42
  55. data/spec/vcr_cassettes/isobib_get_123_2001.yml +15 -15
  56. data/spec/vcr_cassettes/isobib_get_124.yml +15 -15
  57. data/spec/vcr_cassettes/rfcbib_get_rfc8341.yml +14 -14
  58. data/spec/vcr_cassettes/separates_iev_citations_by_top_level_clause.yml +53 -49
  59. metadata +72 -68
  60. data/.rubocop.ribose.yml +0 -66
  61. data/.rubocop.tb.yml +0 -650
  62. data/spec/asciidoctor/macros_lutaml_spec.rb +0 -80
@@ -2,27 +2,29 @@ require "nokogiri"
2
2
  require "pathname"
3
3
  require "open-uri"
4
4
  require "html2doc"
5
- require_relative "./cleanup_block.rb"
6
- require_relative "./cleanup_footnotes.rb"
7
- require_relative "./cleanup_ref.rb"
8
- require_relative "./cleanup_ref_dl.rb"
9
- require_relative "./cleanup_boilerplate.rb"
10
- require_relative "./cleanup_section.rb"
11
- require_relative "./cleanup_terms.rb"
12
- require_relative "./cleanup_inline.rb"
13
- require_relative "./cleanup_amend.rb"
14
- require_relative "./cleanup_maths.rb"
5
+ require_relative "./cleanup_block"
6
+ require_relative "./cleanup_footnotes"
7
+ require_relative "./cleanup_ref"
8
+ require_relative "./cleanup_ref_dl"
9
+ require_relative "./cleanup_boilerplate"
10
+ require_relative "./cleanup_section"
11
+ require_relative "./cleanup_terms"
12
+ require_relative "./cleanup_inline"
13
+ require_relative "./cleanup_amend"
14
+ require_relative "./cleanup_maths"
15
+ require_relative "./cleanup_image"
16
+ require_relative "./cleanup_reqt"
15
17
  require "relaton_iev"
16
18
 
17
19
  module Asciidoctor
18
20
  module Standoc
19
21
  module Cleanup
20
22
  def textcleanup(result)
21
- text = result.flatten.map { |l| l.sub(/\s*$/, "") } * "\n"
23
+ text = result.flatten.map { |l| l.sub(/\s*$/, "") } * "\n"
22
24
  !@keepasciimath and text = asciimath2mathml(text)
23
25
  text = text.gsub(/\s+<fn /, "<fn ")
24
26
  text.gsub(%r{<passthrough\s+formats="metanorma">([^<]*)
25
- </passthrough>}mx) { |m| HTMLEntities.new.decode($1) }
27
+ </passthrough>}mx) { HTMLEntities.new.decode($1) }
26
28
  end
27
29
 
28
30
  def cleanup(xmldoc)
@@ -31,6 +33,7 @@ module Asciidoctor
31
33
  obligations_cleanup(xmldoc)
32
34
  table_cleanup(xmldoc)
33
35
  formula_cleanup(xmldoc)
36
+ form_cleanup(xmldoc)
34
37
  sourcecode_cleanup(xmldoc)
35
38
  figure_cleanup(xmldoc)
36
39
  element_name_cleanup(xmldoc)
@@ -73,22 +76,24 @@ module Asciidoctor
73
76
  xmldoc.xpath("//date").each { |d| Metanorma::Utils::endash_date(d) }
74
77
  xmldoc.traverse do |n|
75
78
  next unless n.text?
79
+
76
80
  if @smartquotes
77
81
  /[-'"(<>]|\.\.|\dx/.match(n) or next
78
- n.ancestors("pre, tt, sourcecode, bibdata, on, stem, figure[@class = 'pseudocode']").empty? or next
82
+
83
+ n.ancestors("pre, tt, sourcecode, bibdata, on, "\
84
+ "stem, figure[@class = 'pseudocode']").empty? or next
79
85
  n.replace(Metanorma::Utils::smartformat(n.text))
80
86
  else
81
- n.replace(n.text.gsub(/(?<=\p{Alnum})\u2019(?=\p{Alpha})/, "'"))#.
82
- #gsub(/</, "&lt;").gsub(/>/, "&gt;"))
87
+ n.replace(n.text.gsub(/(?<=\p{Alnum})\u2019(?=\p{Alpha})/, "'")) # .
88
+ # gsub(/</, "&lt;").gsub(/>/, "&gt;"))
83
89
  end
84
90
  end
85
91
  end
86
92
 
87
- def docidentifier_cleanup(xmldoc)
88
- end
93
+ def docidentifier_cleanup(xmldoc); end
89
94
 
90
95
  TEXT_ELEMS =
91
- %w{status language script version author name callout phone email
96
+ %w{status language script version author name callout phone email
92
97
  street city state country postcode identifier referenceFrom surname
93
98
  referenceTo docidentifier docnumber prefix initial addition forename
94
99
  title draft secretariat title-main title-intro title-part}.freeze
@@ -110,57 +115,6 @@ module Asciidoctor
110
115
  xmldoc.traverse { |n| n.name = n.name.gsub(/_/, "-") }
111
116
  end
112
117
 
113
- def link_callouts_to_annotations(callouts, annotations)
114
- callouts.each_with_index do |c, i|
115
- c["target"] = "_" + UUIDTools::UUID.random_create
116
- annotations[i]["id"] = c["target"]
117
- end
118
- end
119
-
120
- def align_callouts_to_annotations(xmldoc)
121
- xmldoc.xpath("//sourcecode").each do |x|
122
- callouts = x.elements.select { |e| e.name == "callout" }
123
- annotations = x.elements.select { |e| e.name == "annotation" }
124
- callouts.size == annotations.size and
125
- link_callouts_to_annotations(callouts, annotations)
126
- end
127
- end
128
-
129
- def merge_annotations_into_sourcecode(xmldoc)
130
- xmldoc.xpath("//sourcecode").each do |x|
131
- while x&.next_element&.name == "annotation"
132
- x.next_element.parent = x
133
- end
134
- end
135
- end
136
-
137
- def callout_cleanup(xmldoc)
138
- merge_annotations_into_sourcecode(xmldoc)
139
- align_callouts_to_annotations(xmldoc)
140
- end
141
-
142
- def sourcecode_cleanup(xmldoc)
143
- xmldoc.xpath("//sourcecode").each do |x|
144
- x.traverse do |n|
145
- next unless n.text?
146
- next unless /#{Regexp.escape(@sourcecode_markup_start)}/.match(n.text)
147
- n.replace(sourcecode_markup(n))
148
- end
149
- end
150
- end
151
-
152
- def sourcecode_markup(n)
153
- acc = []
154
- n.text.split(/(#{Regexp.escape(@sourcecode_markup_start)}|#{Regexp.escape(@sourcecode_markup_end)})/).
155
- each_slice(4).map do |a|
156
- acc << Nokogiri::XML::Text.new(a[0], n.document).
157
- to_xml(encoding: "US-ASCII", save_with: Nokogiri::XML::Node::SaveOptions::NO_DECLARATION)
158
- next unless a.size == 4
159
- acc << Asciidoctor.convert(a[2], backend: (self&.backend&.to_sym || :standoc), doctype: :inline)
160
- end
161
- acc.join
162
- end
163
-
164
118
  # allows us to deal with doc relation localities,
165
119
  # temporarily stashed to "bpart"
166
120
  def bpart_cleanup(xmldoc)
@@ -170,23 +124,24 @@ module Asciidoctor
170
124
  end
171
125
  end
172
126
 
173
- def img_cleanup(xmldoc)
174
- return xmldoc unless @datauriimage
175
- xmldoc.xpath("//image").each { |i| i["src"] = Metanorma::Utils::datauri(i["src"], @localdir) }
176
- end
177
-
178
127
  def variant_cleanup(xmldoc)
179
128
  xmldoc.xpath("//*[variant]").each do |c|
180
- c&.next&.text? && c&.next&.next&.name == "variant" && c.next.text.gsub(/\s/, "").empty? and
129
+ c&.next&.text? && c&.next&.next&.name == "variant" &&
130
+ c.next.text.gsub(/\s/, "").empty? and
181
131
  c.next.remove
182
132
  end
183
133
  xmldoc.xpath("//*[variant]").each do |c|
184
- next unless c.children.any? { |n| n.name != "variant" && (!n.text? || !n.text.gsub(/\s/, "").empty?) }
134
+ next unless c.children.any? do |n|
135
+ n.name != "variant" && (!n.text? || !n.text.gsub(/\s/, "").empty?)
136
+ end
137
+
185
138
  c.xpath("./variant").each do |n|
186
- if n.at_xpath('preceding-sibling::node()[not(self::text()[not(normalize-space())])][1][self::variantwrap]')
139
+ if n.at_xpath("preceding-sibling::node()"\
140
+ "[not(self::text()[not(normalize-space())])][1]"\
141
+ "[self::variantwrap]")
187
142
  n.previous_element << n
188
143
  else
189
- n.replace('<variantwrap/>').first << n
144
+ n.replace("<variantwrap/>").first << n
190
145
  end
191
146
  end
192
147
  end
@@ -29,7 +29,7 @@ module Asciidoctor
29
29
  def dl2_table_cleanup(xmldoc)
30
30
  q = "//table/following-sibling::*[1][self::p]"
31
31
  xmldoc.xpath(q).each do |s|
32
- if s.text =~ /^\s*key[^a-z]*$/i && !s.next_element.nil? && s.next_element.name == "dl"
32
+ if s.text =~ /^\s*key[^a-z]*$/i && s&.next_element&.name == "dl"
33
33
  s.next_element["key"] = "true"
34
34
  s.previous_element << s.next_element.remove
35
35
  s.remove
@@ -37,14 +37,15 @@ module Asciidoctor
37
37
  end
38
38
  end
39
39
 
40
- def insert_thead(s)
41
- thead = s.at("./thead")
40
+ def insert_thead(table)
41
+ thead = table.at("./thead")
42
42
  return thead unless thead.nil?
43
- if tname = s.at("./name")
43
+
44
+ if tname = table.at("./name")
44
45
  thead = tname.add_next_sibling("<thead/>").first
45
46
  return thead
46
47
  end
47
- s.children.first.add_previous_sibling("<thead/>").first
48
+ table.children.first.add_previous_sibling("<thead/>").first
48
49
  end
49
50
 
50
51
  def header_rows_cleanup(xmldoc)
@@ -80,22 +81,22 @@ module Asciidoctor
80
81
  end
81
82
 
82
83
  # include where definition list inside stem block
83
- def formula_cleanup(x)
84
- formula_cleanup_where1(x)
85
- formula_cleanup_where2(x)
84
+ def formula_cleanup(formula)
85
+ formula_cleanup_where1(formula)
86
+ formula_cleanup_where2(formula)
86
87
  end
87
88
 
88
- def formula_cleanup_where1(x)
89
+ def formula_cleanup_where1(formula)
89
90
  q = "//formula/following-sibling::*[1][self::dl]"
90
- x.xpath(q).each do |s|
91
+ formula.xpath(q).each do |s|
91
92
  s["key"] == "true" and s.previous_element << s.remove
92
93
  end
93
94
  end
94
95
 
95
- def formula_cleanup_where2(x)
96
+ def formula_cleanup_where2(formula)
96
97
  q = "//formula/following-sibling::*[1][self::p]"
97
- x.xpath(q).each do |s|
98
- if s.text =~ /^\s*where[^a-z]*$/i && !s.next_element.nil? && s.next_element.name == "dl"
98
+ formula.xpath(q).each do |s|
99
+ if s.text =~ /^\s*where[^a-z]*$/i && s&.next_element&.name == "dl"
99
100
  s.next_element["key"] = "true"
100
101
  s.previous_element << s.next_element.remove
101
102
  s.remove
@@ -114,7 +115,7 @@ module Asciidoctor
114
115
  def figure_dl_cleanup2(xmldoc)
115
116
  q = "//figure/following-sibling::*[self::p]"
116
117
  xmldoc.xpath(q).each do |s|
117
- if s.text =~ /^\s*key[^a-z]*$/i && !s.next_element.nil? && s.next_element.name == "dl"
118
+ if s.text =~ /^\s*key[^a-z]*$/i && s&.next_element&.name == "dl"
118
119
  s.next_element["key"] = "true"
119
120
  s.previous_element << s.next_element.remove
120
121
  s.remove
@@ -125,7 +126,10 @@ module Asciidoctor
125
126
  # examples containing only figures become subfigures of figures
126
127
  def subfigure_cleanup(xmldoc)
127
128
  xmldoc.xpath("//example[figure]").each do |e|
128
- next unless e.elements.map { |m| m.name }.reject { |m| %w(name figure).include? m }.empty?
129
+ next unless e.elements.map(&:name).reject do |m|
130
+ %w(name figure).include? m
131
+ end.empty?
132
+
129
133
  e.name = "figure"
130
134
  end
131
135
  end
@@ -140,82 +144,93 @@ module Asciidoctor
140
144
  ELEMS_ALLOW_NOTES = %w[p formula ul ol dl figure].freeze
141
145
 
142
146
  # if a note is at the end of a section, it is left alone
143
- # if a note is followed by a non-note block, it is moved inside its preceding block if it is not delimited
147
+ # if a note is followed by a non-note block,
148
+ # it is moved inside its preceding block if it is not delimited
144
149
  # (so there was no way of making that block include the note)
145
150
  def note_cleanup(xmldoc)
146
151
  q = "//note[following-sibling::*[not(local-name() = 'note')]]"
147
152
  xmldoc.xpath(q).each do |n|
148
153
  next if n["keep-separate"] == "true"
149
154
  next unless n.ancestors("table").empty?
155
+
150
156
  prev = n.previous_element || next
151
157
  n.parent = prev if ELEMS_ALLOW_NOTES.include? prev.name
152
158
  end
153
- xmldoc.xpath("//note[@keep-separate]").each { |n| n.delete("keep-separate") }
154
- xmldoc.xpath("//termnote[@keep-separate]").each { |n| n.delete("keep-separate") }
159
+ xmldoc.xpath("//note[@keep-separate] | "\
160
+ "//termnote[@keep-separate]").each do |n|
161
+ n.delete("keep-separate")
162
+ end
155
163
  end
156
164
 
157
- def requirement_cleanup(x)
158
- requirement_descriptions(x)
159
- requirement_inherit(x)
165
+ def link_callouts_to_annotations(callouts, annotations)
166
+ callouts.each_with_index do |c, i|
167
+ c["target"] = "_#{UUIDTools::UUID.random_create}"
168
+ annotations[i]["id"] = c["target"]
169
+ end
160
170
  end
161
171
 
162
- def requirement_inherit(x)
163
- x.xpath("//requirement | //recommendation | //permission").each do |r|
164
- ins = r.at("./classification") ||
165
- r.at("./description | ./measurementtarget | ./specification | "\
166
- "./verification | ./import | ./description | ./requirement | "\
167
- "./recommendation | ./permission")
168
- r.xpath("./*//inherit").each { |i| ins.previous = i }
172
+ def align_callouts_to_annotations(xmldoc)
173
+ xmldoc.xpath("//sourcecode").each do |x|
174
+ callouts = x.elements.select { |e| e.name == "callout" }
175
+ annotations = x.elements.select { |e| e.name == "annotation" }
176
+ callouts.size == annotations.size and
177
+ link_callouts_to_annotations(callouts, annotations)
169
178
  end
170
179
  end
171
180
 
172
- def requirement_descriptions(x)
173
- x.xpath("//requirement | //recommendation | //permission").each do |r|
174
- r.children.each do |e|
175
- unless e.element? && (reqt_subpart(e.name) ||
176
- %w(requirement recommendation permission).include?(e.name))
177
- t = Nokogiri::XML::Element.new("description", x)
178
- e.before(t)
179
- t.children = e.remove
180
- end
181
+ def merge_annotations_into_sourcecode(xmldoc)
182
+ xmldoc.xpath("//sourcecode").each do |x|
183
+ while x&.next_element&.name == "annotation"
184
+ x.next_element.parent = x
181
185
  end
182
- requirement_cleanup1(r)
183
186
  end
184
187
  end
185
188
 
186
- def requirement_cleanup1(r)
187
- while d = r.at("./description[following-sibling::*[1][self::description]]")
188
- n = d.next.remove
189
- d << n.children
189
+ def callout_cleanup(xmldoc)
190
+ merge_annotations_into_sourcecode(xmldoc)
191
+ align_callouts_to_annotations(xmldoc)
192
+ end
193
+
194
+ def sourcecode_cleanup(xmldoc)
195
+ xmldoc.xpath("//sourcecode").each do |x|
196
+ x.traverse do |n|
197
+ next unless n.text?
198
+ next unless /#{Regexp.escape(@sourcecode_markup_start)}/
199
+ .match?(n.text)
200
+
201
+ n.replace(sourcecode_markup(n))
202
+ end
190
203
  end
191
- r.xpath("./description[normalize-space(.)='']").each { |d| d.replace("\n") }
192
204
  end
193
205
 
194
- def svgmap_cleanup(xmldoc)
195
- svgmap_populate(xmldoc)
196
- Metanorma::Utils::svgmap_rewrite(xmldoc, @localdir)
206
+ def safe_noko(text, doc)
207
+ Nokogiri::XML::Text.new(text, doc).to_xml(
208
+ encoding: "US-ASCII",
209
+ save_with: Nokogiri::XML::Node::SaveOptions::NO_DECLARATION
210
+ )
197
211
  end
198
212
 
199
- def svgmap_populate(xmldoc)
200
- xmldoc.xpath("//svgmap").each do |s|
201
- s1 = s.dup
202
- s.children.remove
203
- f = s1.at(".//figure") and s << f
204
- s1.xpath(".//li").each do |li|
205
- t = li&.at(".//eref | .//link | .//xref") or next
206
- href = t.xpath("./following-sibling::node()")
207
- next if href.empty?
208
- s << %[<target href="#{svgmap_target(href)}">#{t.to_xml}</target>]
209
- end
213
+ def sourcecode_markup(node)
214
+ acc = []
215
+ node.text.split(/(#{Regexp.escape(@sourcecode_markup_start)}|
216
+ #{Regexp.escape(@sourcecode_markup_end)})/x)
217
+ .each_slice(4).map do |a|
218
+ acc << safe_noko(a[0], node.document)
219
+ next unless a.size == 4
220
+
221
+ acc << Asciidoctor.convert(
222
+ a[2], doctype: :inline, backend: (self&.backend&.to_sym || :standoc)
223
+ )
210
224
  end
225
+ acc.join
211
226
  end
212
227
 
213
- def svgmap_target(nodeset)
214
- nodeset.each do |n|
215
- next unless n.name == "link"
216
- n.children = n["target"]
228
+ def form_cleanup(xmldoc)
229
+ xmldoc.xpath("//select").each do |s|
230
+ while s&.next_element&.name == "option"
231
+ s << s.next_element
232
+ end
217
233
  end
218
- nodeset.text.sub(/^[,; ]/, "").strip
219
234
  end
220
235
  end
221
236
  end
@@ -3,21 +3,26 @@ module Asciidoctor
3
3
  module Cleanup
4
4
  def external_terms_boilerplate(sources)
5
5
  @i18n.l10n(
6
- @i18n.external_terms_boilerplate.gsub(/%/, sources || "???"), @lang, @script)
6
+ @i18n.external_terms_boilerplate.gsub(/%/, sources || "???"),
7
+ @lang, @script
8
+ )
7
9
  end
8
10
 
9
11
  def internal_external_terms_boilerplate(sources)
10
12
  @i18n.l10n(
11
- @i18n.internal_external_terms_boilerplate.gsub(/%/, sources || "??"), @lang, @script)
13
+ @i18n.internal_external_terms_boilerplate.gsub(/%/, sources || "??"),
14
+ @lang, @script
15
+ )
12
16
  end
13
17
 
14
18
  def term_defs_boilerplate(div, source, term, preface, isodoc)
15
19
  a = @i18n.term_def_boilerplate and div.next = a
16
20
  source.each do |s|
17
21
  @anchors[s["bibitemid"]] or
18
- @log.add("Crossreferences", nil, "term source #{s['bibitemid']} not referenced")
22
+ @log.add("Crossreferences", nil,
23
+ "term source #{s['bibitemid']} not referenced")
19
24
  end
20
- a = (source.empty? && term.nil?) ? @i18n.no_terms_boilerplate :
25
+ a = source.empty? && term.nil? ? @i18n.no_terms_boilerplate :
21
26
  term_defs_boilerplate_cont(source, term, isodoc)
22
27
  a and div.next = a
23
28
  end
@@ -33,17 +38,23 @@ module Asciidoctor
33
38
  end
34
39
  end
35
40
 
36
- def norm_ref_preface(f)
37
- refs = f.elements.select do |e|
38
- ["reference", "bibitem"].include? e.name
41
+ def norm_ref_preface(ref)
42
+ if ref.at("./note[@type = 'boilerplate']")
43
+ unwrap_boilerplate_clauses(ref, ".")
44
+ else
45
+ refs = ref.elements.select do |e|
46
+ %w(references bibitem).include? e.name
47
+ end
48
+ pref = refs.empty? ? @i18n.norm_empty_pref : @i18n.norm_with_refs_pref
49
+ ref.at("./title").next = "<p>#{pref}</p>"
39
50
  end
40
- f.at("./title").next =
41
- "<p>#{(refs.empty? ? @i18n.norm_empty_pref : @i18n.norm_with_refs_pref)}</p>"
42
51
  end
43
52
 
44
- TERM_CLAUSE = "//sections/terms | //sections/clause[descendant::terms]".freeze
53
+ TERM_CLAUSE = "//sections/terms | "\
54
+ "//sections/clause[descendant::terms]".freeze
45
55
 
46
- NORM_REF = "//bibliography/references[@normative = 'true']".freeze
56
+ NORM_REF = "//bibliography/references[@normative = 'true'] | "\
57
+ "//bibliography/clause[.//references[@normative = 'true']]".freeze
47
58
 
48
59
  def boilerplate_isodoc(xmldoc)
49
60
  x = xmldoc.dup
@@ -55,44 +66,53 @@ module Asciidoctor
55
66
  end
56
67
 
57
68
  def termdef_boilerplate_cleanup(xmldoc)
58
- #termdef_remove_initial_paras(xmldoc)
69
+ # termdef_remove_initial_paras(xmldoc)
59
70
  end
60
71
 
61
72
  def termdef_remove_initial_paras(xmldoc)
62
73
  xmldoc.xpath("//terms/p | //terms/ul").each(&:remove)
63
74
  end
64
75
 
65
- def termdef_unwrap_boilerplate_clauses(xmldoc)
66
- xmldoc.xpath(self.class::TERM_CLAUSE).each do |f|
67
- f.xpath(".//clause[@type = 'boilerplate']").each do |c|
76
+ def unwrap_boilerplate_clauses(xmldoc, xpath)
77
+ xmldoc.xpath(xpath).each do |f|
78
+ f.xpath(".//clause[@type = 'boilerplate'] | "\
79
+ ".//note[@type = 'boilerplate']").each do |c|
68
80
  c&.at("./title")&.remove
69
81
  c.replace(c.children)
70
82
  end
71
83
  end
72
84
  end
73
85
 
74
- def boilerplate_cleanup(xmldoc)
75
- isodoc = boilerplate_isodoc(xmldoc)
76
- termdef_boilerplate_cleanup(xmldoc)
86
+ def termdef_boilerplate_insert(xmldoc, isodoc, once = false)
77
87
  xmldoc.xpath(self.class::TERM_CLAUSE).each do |f|
78
88
  next if f.at("./clause[@type = 'boilerplate']")
79
- term_defs_boilerplate(f.at("./title"), xmldoc.xpath(".//termdocsource"),
89
+
90
+ term_defs_boilerplate(f.at("./title"),
91
+ xmldoc.xpath(".//termdocsource"),
80
92
  f.at(".//term"), f.at(".//p"), isodoc)
93
+ break if once
81
94
  end
82
- termdef_unwrap_boilerplate_clauses(xmldoc)
95
+ end
96
+
97
+ def boilerplate_cleanup(xmldoc)
98
+ isodoc = boilerplate_isodoc(xmldoc)
99
+ termdef_boilerplate_cleanup(xmldoc)
100
+ termdef_boilerplate_insert(xmldoc, isodoc)
101
+ unwrap_boilerplate_clauses(xmldoc, self.class::TERM_CLAUSE)
83
102
  f = xmldoc.at(self.class::NORM_REF) and norm_ref_preface(f)
84
103
  initial_boilerplate(xmldoc, isodoc)
85
104
  end
86
105
 
87
- def initial_boilerplate(x, isodoc)
88
- return if x.at("//boilerplate")
89
- preface = x.at("//preface") || x.at("//sections") || x.at("//annex") ||
90
- x.at("//references") || return
91
- b = boilerplate(x, isodoc) or return
106
+ def initial_boilerplate(xml, isodoc)
107
+ return if xml.at("//boilerplate")
108
+
109
+ preface = xml.at("//preface") || xml.at("//sections") ||
110
+ xml.at("//annex") || xml.at("//references") || return
111
+ b = boilerplate(xml, isodoc) or return
92
112
  preface.previous = b
93
113
  end
94
114
 
95
- def boilerplate_file(xmldoc)
115
+ def boilerplate_file(_xmldoc)
96
116
  File.join(@libdir, "boilerplate.xml")
97
117
  end
98
118
 
@@ -100,7 +120,7 @@ module Asciidoctor
100
120
  file = boilerplate_file(xml)
101
121
  file = File.join(@localdir, @boilerplateauthority) if @boilerplateauthority
102
122
  !file.nil? and File.exists?(file) or return
103
- conv.populate_template((File.read(file, encoding: "UTF-8")), nil)
123
+ conv.populate_template(File.read(file, encoding: "UTF-8"), nil)
104
124
  end
105
125
 
106
126
  def bibdata_cleanup(xmldoc)
@@ -118,14 +138,16 @@ module Asciidoctor
118
138
  def bibdata_docidentifier_cleanup(xmldoc)
119
139
  ins = xmldoc.at("//bibdata/docidentifier")
120
140
  xmldoc.xpath("//bibdata/docidentifier").each_with_index do |b, i|
121
- next if i == 0
141
+ next if i.zero?
142
+
122
143
  ins.next = b.remove
123
144
  ins = ins.next
124
145
  end
125
146
  end
126
147
 
127
148
  def gather_indirect_erefs(xmldoc, prefix)
128
- xmldoc.xpath("//eref[@type = '#{prefix}']").each_with_object({}) do |e, m|
149
+ xmldoc.xpath("//eref[@type = '#{prefix}']")
150
+ .each_with_object({}) do |e, m|
129
151
  e.delete("type")
130
152
  m[e["bibitemid"]] = true
131
153
  end.keys