isodoc 1.7.6.1 → 1.8.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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/isodoc.gemspec +2 -2
  3. data/lib/isodoc/class_utils.rb +24 -1
  4. data/lib/isodoc/convert.rb +9 -0
  5. data/lib/isodoc/function/cleanup.rb +4 -0
  6. data/lib/isodoc/function/inline.rb +3 -5
  7. data/lib/isodoc/html_function/html.rb +1 -0
  8. data/lib/isodoc/html_function/postprocess.rb +4 -6
  9. data/lib/isodoc/metadata_date.rb +13 -11
  10. data/lib/isodoc/presentation_function/bibdata.rb +2 -2
  11. data/lib/isodoc/presentation_function/block.rb +0 -36
  12. data/lib/isodoc/presentation_function/inline.rb +14 -11
  13. data/lib/isodoc/presentation_function/terms.rb +223 -0
  14. data/lib/isodoc/presentation_xml_convert.rb +11 -4
  15. data/lib/isodoc/version.rb +1 -1
  16. data/lib/isodoc/word_function/body.rb +24 -14
  17. data/lib/isodoc/word_function/comments.rb +0 -4
  18. data/lib/isodoc/word_function/postprocess.rb +184 -176
  19. data/lib/isodoc/xref/xref_gen.rb +18 -22
  20. data/lib/isodoc/xref/xref_gen_seq.rb +10 -16
  21. data/lib/isodoc/xref/xref_sect_gen.rb +134 -129
  22. data/lib/isodoc/xslfo_convert.rb +11 -7
  23. data/lib/isodoc-yaml/i18n-ar.yaml +25 -0
  24. data/lib/isodoc-yaml/i18n-de.yaml +23 -0
  25. data/lib/isodoc-yaml/i18n-en.yaml +23 -0
  26. data/lib/isodoc-yaml/i18n-es.yaml +23 -0
  27. data/lib/isodoc-yaml/i18n-fr.yaml +23 -0
  28. data/lib/isodoc-yaml/i18n-ru.yaml +24 -1
  29. data/lib/isodoc-yaml/i18n-zh-Hans.yaml +24 -0
  30. data/lib/metanorma/output/xslfo.rb +4 -11
  31. data/spec/assets/i18n.yaml +3 -1
  32. data/spec/isodoc/blocks_spec.rb +14 -8
  33. data/spec/isodoc/i18n_spec.rb +23 -18
  34. data/spec/isodoc/inline_spec.rb +193 -9
  35. data/spec/isodoc/lists_spec.rb +344 -222
  36. data/spec/isodoc/section_spec.rb +23 -22
  37. data/spec/isodoc/table_spec.rb +71 -73
  38. data/spec/isodoc/terms_spec.rb +498 -124
  39. data/spec/isodoc/xref_numbering_spec.rb +347 -0
  40. data/spec/isodoc/xref_spec.rb +274 -353
  41. data/spec/isodoc/xslfo_convert_spec.rb +34 -9
  42. metadata +12 -11
  43. data/lib/isodoc/presentation_function/concept.rb +0 -68
@@ -54,11 +54,11 @@ module IsoDoc
54
54
  end
55
55
 
56
56
  def para_class(_node)
57
- classtype = nil
58
- classtype = "Note" if @note
59
- classtype = "MsoCommentText" if in_comment
60
- classtype = "Sourcecode" if @annotation
61
- classtype
57
+ return "Sourcecode" if @annotation
58
+ return "MsoCommentText" if @in_comment
59
+ return "Note" if @note
60
+
61
+ nil
62
62
  end
63
63
 
64
64
  def para_parse(node, out)
@@ -86,21 +86,31 @@ module IsoDoc
86
86
  end
87
87
 
88
88
  def dl_parse(node, out)
89
+ return super unless node.ancestors("table, dl").empty?
90
+
91
+ dl_parse_table(node, out)
92
+ end
93
+
94
+ def dl_parse_table(node, out)
89
95
  out.table **{ class: "dl" } do |v|
90
96
  node.elements.select { |n| dt_dd? n }.each_slice(2) do |dt, dd|
91
- v.tr do |tr|
92
- tr.td **{ valign: "top", align: "left" } do |term|
93
- dt_parse(dt, term)
94
- end
95
- tr.td **{ valign: "top" } do |listitem|
96
- dd.children.each { |n| parse(n, listitem) }
97
- end
98
- end
97
+ dl_parse_table1(v, dt, dd)
99
98
  end
100
99
  dl_parse_notes(node, v)
101
100
  end
102
101
  end
103
102
 
103
+ def dl_parse_table1(table, dterm, ddefn)
104
+ table.tr do |tr|
105
+ tr.td **{ valign: "top", align: "left" } do |term|
106
+ dt_parse(dterm, term)
107
+ end
108
+ tr.td **{ valign: "top" } do |listitem|
109
+ ddefn.children.each { |n| parse(n, listitem) }
110
+ end
111
+ end
112
+ end
113
+
104
114
  def dl_parse_notes(node, out)
105
115
  return if node.elements.reject { |n| dt_dd? n }.empty?
106
116
 
@@ -120,8 +130,8 @@ module IsoDoc
120
130
  dl
121
131
  end
122
132
 
133
+ # get rid of footnote link, it is in diagram
123
134
  def figure_aside_process(fig, aside, key)
124
- # get rid of footnote link, it is in diagram
125
135
  fig&.at("./a[@class='TableFootnoteRef']")&.remove
126
136
  fnref = fig.at(".//span[@class='TableFootnoteRef']/..")
127
137
  tr = key.add_child("<tr></tr>").first
@@ -1,10 +1,6 @@
1
1
  module IsoDoc
2
2
  module WordFunction
3
3
  module Comments
4
- def in_comment
5
- @in_comment
6
- end
7
-
8
4
  def comments(div)
9
5
  return if @comments.empty?
10
6
 
@@ -1,229 +1,237 @@
1
1
  require "fileutils"
2
2
  require_relative "./postprocess_cover"
3
3
 
4
- module IsoDoc::WordFunction
5
- module Postprocess
6
- # add namespaces for Word fragments
7
- WORD_NOKOHEAD = <<~HERE.freeze
8
- <!DOCTYPE html SYSTEM "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
9
- <html xmlns="http://www.w3.org/1999/xhtml"
10
- xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office"
11
- xmlns:w="urn:schemas-microsoft-com:office:word"
12
- xmlns:m="http://schemas.microsoft.com/office/2004/12/omml">
13
- <head> <title></title> <meta charset="UTF-8" /> </head>
14
- <body> </body> </html>
15
- HERE
16
-
17
- def to_word_xhtml_fragment(xml)
18
- doc = ::Nokogiri::XML.parse(WORD_NOKOHEAD)
19
- ::Nokogiri::XML::DocumentFragment.new(doc, xml, doc.root)
20
- end
4
+ module IsoDoc
5
+ module WordFunction
6
+ module Postprocess
7
+ # add namespaces for Word fragments
8
+ WORD_NOKOHEAD = <<~HERE.freeze
9
+ <!DOCTYPE html SYSTEM "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
10
+ <html xmlns="http://www.w3.org/1999/xhtml"
11
+ xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office"
12
+ xmlns:w="urn:schemas-microsoft-com:office:word"
13
+ xmlns:m="http://schemas.microsoft.com/office/2004/12/omml">
14
+ <head> <title></title> <meta charset="UTF-8" /> </head>
15
+ <body> </body> </html>
16
+ HERE
17
+
18
+ def to_word_xhtml_fragment(xml)
19
+ doc = ::Nokogiri::XML.parse(WORD_NOKOHEAD)
20
+ ::Nokogiri::XML::DocumentFragment.new(doc, xml, doc.root)
21
+ end
21
22
 
22
- def table_note_cleanup(docxml)
23
- super
24
- # preempt html2doc putting MsoNormal there
25
- docxml.xpath("//p[not(self::*[@class])][ancestor::*[@class = 'Note']]")
26
- .each do |p|
27
- p["class"] = "Note"
23
+ def table_note_cleanup(docxml)
24
+ super
25
+ # preempt html2doc putting MsoNormal there
26
+ docxml.xpath("//p[not(self::*[@class])][ancestor::*[@class = 'Note']]")
27
+ .each do |p|
28
+ p["class"] = "Note"
29
+ end
28
30
  end
29
- end
30
31
 
31
- def postprocess(result, filename, dir)
32
- filename = filename.sub(/\.doc$/, "")
33
- header = generate_header(filename, dir)
34
- result = from_xhtml(cleanup(to_xhtml(textcleanup(result))))
35
- toWord(result, filename, dir, header)
36
- @files_to_delete.each { |f| FileUtils.rm_f f }
37
- end
32
+ def postprocess(result, filename, dir)
33
+ filename = filename.sub(/\.doc$/, "")
34
+ header = generate_header(filename, dir)
35
+ result = from_xhtml(cleanup(to_xhtml(textcleanup(result))))
36
+ toWord(result, filename, dir, header)
37
+ @files_to_delete.each { |f| FileUtils.rm_f f }
38
+ end
38
39
 
39
- def toWord(result, filename, dir, header)
40
- result = from_xhtml(word_cleanup(to_xhtml(result)))
41
- @wordstylesheet = wordstylesheet_update
42
- Html2Doc.process(
43
- result,
44
- filename: filename,
45
- stylesheet: @wordstylesheet&.path,
46
- header_file: header&.path, dir: dir,
47
- asciimathdelims: [@openmathdelim, @closemathdelim],
48
- liststyles: { ul: @ulstyle, ol: @olstyle }
49
- )
50
- header&.unlink
51
- @wordstylesheet.unlink if @wordstylesheet.is_a?(Tempfile)
52
- end
40
+ def toWord(result, filename, dir, header)
41
+ result = from_xhtml(word_cleanup(to_xhtml(result)))
42
+ @wordstylesheet = wordstylesheet_update
43
+ Html2Doc.process(
44
+ result,
45
+ filename: filename,
46
+ imagedir: @localdir,
47
+ stylesheet: @wordstylesheet&.path,
48
+ header_file: header&.path, dir: dir,
49
+ asciimathdelims: [@openmathdelim, @closemathdelim],
50
+ liststyles: { ul: @ulstyle, ol: @olstyle }
51
+ )
52
+ header&.unlink
53
+ @wordstylesheet.unlink if @wordstylesheet.is_a?(Tempfile)
54
+ end
53
55
 
54
- def wordstylesheet_update
55
- return if @wordstylesheet.nil?
56
+ def wordstylesheet_update
57
+ return if @wordstylesheet.nil?
56
58
 
57
- f = File.open(@wordstylesheet.path, "a")
58
- @landscapestyle.empty? or f.write(@landscapestyle)
59
- if @wordstylesheet_override && @wordstylesheet
60
- f.write(@wordstylesheet_override.read)
61
- @wordstylesheet_override.close
62
- elsif @wordstylesheet_override && !@wordstylesheet
63
- @wordstylesheet = @wordstylesheet_override
59
+ f = File.open(@wordstylesheet.path, "a")
60
+ @landscapestyle.empty? or f.write(@landscapestyle)
61
+ if @wordstylesheet_override && @wordstylesheet
62
+ f.write(@wordstylesheet_override.read)
63
+ @wordstylesheet_override.close
64
+ elsif @wordstylesheet_override && !@wordstylesheet
65
+ @wordstylesheet = @wordstylesheet_override
66
+ end
67
+ f.close
68
+ @wordstylesheet
64
69
  end
65
- f.close
66
- @wordstylesheet
67
- end
68
70
 
69
- def word_admonition_images(docxml)
70
- docxml.xpath("//div[@class = 'Admonition']//img").each do |i|
71
- i["width"], i["height"] =
72
- Html2Doc.image_resize(i, image_localfile(i), @maxheight, 300)
71
+ def word_admonition_images(docxml)
72
+ docxml.xpath("//div[@class = 'Admonition']//img").each do |i|
73
+ i["width"], i["height"] =
74
+ Html2Doc.image_resize(i, image_localfile(i), @maxheight, 300)
75
+ end
73
76
  end
74
- end
75
77
 
76
- def word_cleanup(docxml)
77
- word_annex_cleanup(docxml)
78
- word_preface(docxml)
79
- word_nested_tables(docxml)
80
- word_colgroup(docxml)
81
- word_table_align(docxml)
82
- word_table_separator(docxml)
83
- word_admonition_images(docxml)
84
- word_list_continuations(docxml)
85
- word_example_cleanup(docxml)
86
- word_pseudocode_cleanup(docxml)
87
- word_image_caption(docxml)
88
- word_section_breaks(docxml)
89
- authority_cleanup(docxml)
90
- word_footnote_format(docxml)
91
- docxml
92
- end
78
+ def word_cleanup(docxml)
79
+ word_annex_cleanup(docxml)
80
+ word_preface(docxml)
81
+ word_nested_tables(docxml)
82
+ word_colgroup(docxml)
83
+ word_table_align(docxml)
84
+ word_table_separator(docxml)
85
+ word_admonition_images(docxml)
86
+ word_list_continuations(docxml)
87
+ word_example_cleanup(docxml)
88
+ word_pseudocode_cleanup(docxml)
89
+ word_image_caption(docxml)
90
+ word_section_breaks(docxml)
91
+ authority_cleanup(docxml)
92
+ word_footnote_format(docxml)
93
+ docxml
94
+ end
93
95
 
94
- def word_colgroup(docxml)
95
- cells2d = {}
96
- docxml.xpath("//table[colgroup]").each do |t|
97
- w = colgroup_widths(t)
98
- t.xpath(".//tr").each_with_index { |_tr, r| cells2d[r] = {} }
99
- t.xpath(".//tr").each_with_index do |tr, r|
100
- tr.xpath("./td | ./th").each_with_index do |td, _i|
101
- x = 0
102
- rs = td&.attr("rowspan")&.to_i || 1
103
- cs = td&.attr("colspan")&.to_i || 1
104
- while cells2d[r][x]
105
- x += 1
106
- end
107
- (r..(r + rs - 1)).each do |y2|
108
- (x..(x + cs - 1)).each do |x2|
109
- cells2d[y2][x2] = 1
96
+ def word_colgroup(docxml)
97
+ cells2d = {}
98
+ docxml.xpath("//table[colgroup]").each do |t|
99
+ w = colgroup_widths(t)
100
+ t.xpath(".//tr").each_with_index { |_tr, r| cells2d[r] = {} }
101
+ t.xpath(".//tr").each_with_index do |tr, r|
102
+ tr.xpath("./td | ./th").each_with_index do |td, _i|
103
+ x = 0
104
+ rs = td&.attr("rowspan")&.to_i || 1
105
+ cs = td&.attr("colspan")&.to_i || 1
106
+ while cells2d[r][x]
107
+ x += 1
110
108
  end
109
+ (r..(r + rs - 1)).each do |y2|
110
+ (x..(x + cs - 1)).each do |x2|
111
+ cells2d[y2][x2] = 1
112
+ end
113
+ end
114
+ width = (x..(x + cs - 1)).each_with_object({ width: 0 }) do |z, m|
115
+ m[:width] += w[z]
116
+ end
117
+ td["width"] = "#{width[:width]}%"
118
+ x += cs
111
119
  end
112
- width = (x..(x + cs - 1)).each_with_object({ width: 0 }) do |z, m|
113
- m[:width] += w[z]
114
- end
115
- td["width"] = "#{width[:width]}%"
116
- x += cs
117
120
  end
118
121
  end
119
122
  end
120
- end
121
123
 
122
- # assume percentages
123
- def colgroup_widths(table)
124
- table.xpath("./colgroup/col").each_with_object([]) do |c, m|
125
- m << c["width"].sub(/%$/, "").to_f
124
+ # assume percentages
125
+ def colgroup_widths(table)
126
+ table.xpath("./colgroup/col").each_with_object([]) do |c, m|
127
+ m << c["width"].sub(/%$/, "").to_f
128
+ end
126
129
  end
127
- end
128
130
 
129
- def word_nested_tables(docxml)
130
- docxml.xpath("//table").each do |t|
131
- t.xpath(".//table").reverse.each do |tt|
132
- t.next = tt.remove
131
+ def word_nested_tables(docxml)
132
+ docxml.xpath("//table").each do |t|
133
+ t.xpath(".//table").reverse.each do |tt|
134
+ t.next = tt.remove
135
+ end
133
136
  end
134
137
  end
135
- end
136
138
 
137
- def style_update(node, css)
138
- return unless node
139
+ def style_update(node, css)
140
+ return unless node
139
141
 
140
- node["style"] = node["style"] ? node["style"].sub(/;?$/, ";#{css}") : css
141
- end
142
+ node["style"] =
143
+ node["style"] ? node["style"].sub(/;?$/, ";#{css}") : css
144
+ end
142
145
 
143
- def word_image_caption(docxml)
144
- docxml.xpath("//p[@class = 'FigureTitle' or @class = 'SourceTitle']")
145
- .each do |t|
146
- if t&.previous_element&.name == "img"
147
- img = t.previous_element
148
- t.previous_element.swap("<p class=\'figure\'>#{img.to_xml}</p>")
146
+ def word_image_caption(docxml)
147
+ docxml.xpath("//p[@class = 'FigureTitle' or @class = 'SourceTitle']")
148
+ .each do |t|
149
+ if t&.previous_element&.name == "img"
150
+ img = t.previous_element
151
+ t.previous_element.swap("<p class=\'figure\'>#{img.to_xml}</p>")
152
+ end
153
+ style_update(t&.previous_element, "page-break-after:avoid;")
149
154
  end
150
- style_update(t&.previous_element, "page-break-after:avoid;")
151
155
  end
152
- end
153
156
 
154
- def word_list_continuations(docxml)
155
- list_add(docxml.xpath("//ul[not(ancestor::ul) and not(ancestor::ol)]"), 1)
156
- list_add(docxml.xpath("//ol[not(ancestor::ul) and not(ancestor::ol)]"), 1)
157
- end
157
+ def word_list_continuations(docxml)
158
+ list_add(docxml.xpath("//ul[not(ancestor::ul) and not(ancestor::ol)]"),
159
+ 1)
160
+ list_add(docxml.xpath("//ol[not(ancestor::ul) and not(ancestor::ol)]"),
161
+ 1)
162
+ end
158
163
 
159
- def list_add(xpath, lvl)
160
- xpath.each do |list|
161
- (list.xpath(".//li") - list.xpath(".//ol//li | .//ul//li")).each do |l|
162
- l.xpath("./p | ./div | ./table").each_with_index do |p, i|
163
- next if i.zero?
164
+ def list_add(xpath, lvl)
165
+ xpath.each do |list|
166
+ (list.xpath(".//li") - list.xpath(".//ol//li | .//ul//li")).each do |l|
167
+ l.xpath("./p | ./div | ./table").each_with_index do |p, i|
168
+ next if i.zero?
164
169
 
165
- p.wrap(%{<div class="ListContLevel#{lvl}"/>})
170
+ p.wrap(%{<div class="ListContLevel#{lvl}"/>})
171
+ end
172
+ list_add(l.xpath(".//ul") - l.xpath(".//ul//ul | .//ol//ul"),
173
+ lvl + 1)
174
+ list_add(l.xpath(".//ol") - l.xpath(".//ul//ol | .//ol//ol"),
175
+ lvl + 1)
166
176
  end
167
- list_add(l.xpath(".//ul") - l.xpath(".//ul//ul | .//ol//ul"), lvl + 1)
168
- list_add(l.xpath(".//ol") - l.xpath(".//ul//ol | .//ol//ol"), lvl + 1)
169
177
  end
170
178
  end
171
- end
172
179
 
173
- def word_table_align(docxml)
174
- docxml.xpath("//td[@align]/p | //th[@align]/p").each do |p|
175
- next if p["align"]
180
+ def word_table_align(docxml)
181
+ docxml.xpath("//td[@align]/p | //th[@align]/p").each do |p|
182
+ next if p["align"]
176
183
 
177
- style_update(p, "text-align: #{p.parent['align']}")
184
+ style_update(p, "text-align: #{p.parent['align']}")
185
+ end
178
186
  end
179
- end
180
187
 
181
- def word_table_separator(docxml)
182
- docxml.xpath("//p[@class = 'TableTitle']").each do |t|
183
- next unless t.children.empty?
188
+ def word_table_separator(docxml)
189
+ docxml.xpath("//p[@class = 'TableTitle']").each do |t|
190
+ next unless t.children.empty?
184
191
 
185
- t["style"] = t["style"].sub(/;?$/, ";font-size:0pt;")
186
- t.children = "&nbsp;"
192
+ t["style"] = t["style"].sub(/;?$/, ";font-size:0pt;")
193
+ t.children = "&nbsp;"
194
+ end
187
195
  end
188
- end
189
196
 
190
- def word_annex_cleanup(docxml); end
197
+ def word_annex_cleanup(docxml); end
191
198
 
192
- def word_example_cleanup(docxml)
193
- docxml.xpath("//div[@class = 'example']//p[not(@class)]").each do |p|
194
- p["class"] = "example"
199
+ def word_example_cleanup(docxml)
200
+ docxml.xpath("//div[@class = 'example']//p[not(@class)]").each do |p|
201
+ p["class"] = "example"
202
+ end
195
203
  end
196
- end
197
204
 
198
- def word_pseudocode_cleanup(docxml)
199
- docxml.xpath("//div[@class = 'pseudocode']//p[not(@class)]").each do |p|
200
- p["class"] = "pseudocode"
205
+ def word_pseudocode_cleanup(docxml)
206
+ docxml.xpath("//div[@class = 'pseudocode']//p[not(@class)]").each do |p|
207
+ p["class"] = "pseudocode"
208
+ end
201
209
  end
202
- end
203
210
 
204
- # applies for <div class="WordSectionN_M"><p><pagebreak/></p>...
205
- def word_remove_pb_before_annex(docxml)
206
- docxml.xpath("//div[p/br]").each do |d|
207
- /^WordSection\d+_\d+$/.match(d["class"]) or next
208
- d.elements[0].name == "p" && !d.elements[0].elements.empty? or next
209
- d.elements[0].elements[0].name == "br" &&
210
- d.elements[0].elements[0]["style"] ==
211
- "mso-special-character:line-break;page-break-before:always" or next
212
- d.elements[0].remove
211
+ # applies for <div class="WordSectionN_M"><p><pagebreak/></p>...
212
+ def word_remove_pb_before_annex(docxml)
213
+ docxml.xpath("//div[p/br]").each do |d|
214
+ /^WordSection\d+_\d+$/.match(d["class"]) or next
215
+ d.elements[0].name == "p" && !d.elements[0].elements.empty? or next
216
+ d.elements[0].elements[0].name == "br" &&
217
+ d.elements[0].elements[0]["style"] ==
218
+ "mso-special-character:line-break;page-break-before:always" or next
219
+ d.elements[0].remove
220
+ end
213
221
  end
214
- end
215
222
 
216
- def word_footnote_format(docxml)
217
- # the content is in a[@epub:type = 'footnote']//sup, but in Word,
218
- # we need to inject content around the autonumbered footnote reference
219
- docxml.xpath("//a[@epub:type = 'footnote']").each do |x|
220
- footnote_reference_format(x)
221
- end
222
- docxml.xpath("//a[@class = 'TableFootnoteRef'] | "\
223
- "//span[@class = 'TableFootnoteRef']").each do |x|
224
- table_footnote_reference_format(x)
223
+ def word_footnote_format(docxml)
224
+ # the content is in a[@epub:type = 'footnote']//sup, but in Word,
225
+ # we need to inject content around the autonumbered footnote reference
226
+ docxml.xpath("//a[@epub:type = 'footnote']").each do |x|
227
+ footnote_reference_format(x)
228
+ end
229
+ docxml.xpath("//a[@class = 'TableFootnoteRef'] | "\
230
+ "//span[@class = 'TableFootnoteRef']").each do |x|
231
+ table_footnote_reference_format(x)
232
+ end
233
+ docxml
225
234
  end
226
- docxml
227
235
  end
228
236
  end
229
237
  end
@@ -7,6 +7,10 @@ module IsoDoc
7
7
  recommendation permission figure table formula
8
8
  admonition sourcecode).freeze
9
9
 
10
+ def blank?(text)
11
+ text.nil? || text.empty?
12
+ end
13
+
10
14
  def amend_preprocess(xmldoc)
11
15
  xmldoc.xpath(ns("//amend[newcontent]")).each do |a|
12
16
  autonum = amend_autonums(a)
@@ -39,11 +43,9 @@ module IsoDoc
39
43
  end
40
44
 
41
45
  def termnote_anchor_names(docxml)
42
- docxml.xpath(ns("//term[descendant::termnote]")).each do |t|
46
+ docxml.xpath(ns("//term[termnote]")).each do |t|
43
47
  c = Counter.new
44
- t.xpath(ns(".//termnote")).each do |n|
45
- next if n["id"].nil? || n["id"].empty?
46
-
48
+ t.xpath(ns("./termnote")).reject { |n| blank?(n["id"]) }.each do |n|
47
49
  c.increment(n)
48
50
  @anchors[n["id"]] =
49
51
  { label: termnote_label(c.print), type: "termnote", value: c.print,
@@ -54,18 +56,18 @@ module IsoDoc
54
56
  end
55
57
 
56
58
  def termexample_anchor_names(docxml)
57
- docxml.xpath(ns("//term[descendant::termexample]")).each do |t|
58
- examples = t.xpath(ns(".//termexample"))
59
+ docxml.xpath(ns("//term[termexample]")).each do |t|
60
+ examples = t.xpath(ns("./termexample"))
59
61
  c = Counter.new
60
- examples.each do |n|
61
- next if n["id"].nil? || n["id"].empty?
62
-
62
+ examples.reject { |n| blank?(n["id"]) }.each do |n|
63
63
  c.increment(n)
64
64
  idx = increment_label(examples, n, c, false)
65
65
  @anchors[n["id"]] =
66
- { type: "termexample", label: idx, value: c.print,
67
- xref: l10n("#{anchor(t['id'], :xref)}, "\
68
- "#{@labels['example_xref']} #{c.print}") }
66
+ # { type: "termexample", label: idx, value: c.print,
67
+ # xref: l10n("#{anchor(t['id'], :xref)}, "\
68
+ # "#{@labels['example_xref']} #{c.print}") }
69
+ anchor_struct(idx, n,
70
+ @labels["example_xref"], "termexample", n["unnumbered"])
69
71
  end
70
72
  end
71
73
  end
@@ -127,9 +129,7 @@ module IsoDoc
127
129
  notes = s.xpath(ns(".//ol")) - s.xpath(ns(".//clause//ol")) -
128
130
  s.xpath(ns(".//appendix//ol")) - s.xpath(ns(".//ol//ol"))
129
131
  c = Counter.new
130
- notes.each do |n|
131
- next if n["id"].nil? || n["id"].empty?
132
-
132
+ notes.reject { |n| blank?(n["id"]) }.each do |n|
133
133
  @anchors[n["id"]] = anchor_struct(increment_label(notes, n, c), n,
134
134
  @labels["list"], "list", false)
135
135
  list_item_anchor_names(n, @anchors[n["id"]], 1, "", notes.size != 1)
@@ -158,9 +158,7 @@ module IsoDoc
158
158
  notes = s.xpath(ns(".//dl")) - s.xpath(ns(".//clause//dl")) -
159
159
  s.xpath(ns(".//appendix//dl")) - s.xpath(ns(".//dl//dl"))
160
160
  c = Counter.new
161
- notes.each do |n|
162
- next if n["id"].nil? || n["id"].empty?
163
-
161
+ notes.reject { |n| blank?(n["id"]) }.each do |n|
164
162
  @anchors[n["id"]] =
165
163
  anchor_struct(increment_label(notes, n, c), n,
166
164
  @labels["deflist"], "deflist", false)
@@ -183,10 +181,8 @@ module IsoDoc
183
181
  end
184
182
  end
185
183
 
186
- def bookmark_anchor_names(docxml)
187
- docxml.xpath(ns(".//bookmark")).each do |n|
188
- next if n["id"].nil? || n["id"].empty?
189
-
184
+ def bookmark_anchor_names(xml)
185
+ xml.xpath(ns(".//bookmark")).reject { |n| blank?(n["id"]) }.each do |n|
190
186
  parent = nil
191
187
  n.ancestors.each do |a|
192
188
  next unless a["id"] && parent = @anchors.dig(a["id"], :xref)
@@ -34,8 +34,7 @@ module IsoDoc::XrefGen
34
34
 
35
35
  def sequential_table_names(clause)
36
36
  c = Counter.new
37
- clause.xpath(ns(".//table")).each do |t|
38
- next if t["id"].nil? || t["id"].empty?
37
+ clause.xpath(ns(".//table")).reject { |n| blank?(n["id"]) }.each do |t|
39
38
 
40
39
  @anchors[t["id"]] = anchor_struct(
41
40
  c.increment(t).print, nil,
@@ -46,8 +45,7 @@ module IsoDoc::XrefGen
46
45
 
47
46
  def sequential_formula_names(clause)
48
47
  c = Counter.new
49
- clause.xpath(ns(".//formula")).each do |t|
50
- next if t["id"].nil? || t["id"].empty?
48
+ clause.xpath(ns(".//formula")).reject { |n| blank?(n["id"]) }.each do |t|
51
49
 
52
50
  @anchors[t["id"]] = anchor_struct(
53
51
  c.increment(t).print, t,
@@ -62,8 +60,8 @@ module IsoDoc::XrefGen
62
60
 
63
61
  def sequential_permission_names(clause, klass, label)
64
62
  c = Counter.new
65
- clause.xpath(ns(".//#{klass}#{FIRST_LVL_REQ}")).each do |t|
66
- next if t["id"].nil? || t["id"].empty?
63
+ clause.xpath(ns(".//#{klass}#{FIRST_LVL_REQ}"))
64
+ .reject { |n| blank?(n["id"]) }.each do |t|
67
65
 
68
66
  id = c.increment(t).print
69
67
  @anchors[t["id"]] = anchor_struct(id, t, label, klass, t["unnumbered"])
@@ -82,8 +80,7 @@ module IsoDoc::XrefGen
82
80
 
83
81
  def sequential_permission_names1(block, lbl, klass, label)
84
82
  c = Counter.new
85
- block.xpath(ns("./#{klass}")).each do |t|
86
- next if t["id"].nil? || t["id"].empty?
83
+ block.xpath(ns("./#{klass}")).reject { |n| blank?(n["id"]) }.each do |t|
87
84
 
88
85
  id = "#{lbl}#{hierfigsep}#{c.increment(t).print}"
89
86
  @anchors[t["id"]] = anchor_struct(id, t, label, klass, t["unnumbered"])
@@ -118,8 +115,7 @@ module IsoDoc::XrefGen
118
115
 
119
116
  def hierarchical_table_names(clause, num)
120
117
  c = Counter.new
121
- clause.xpath(ns(".//table")).each do |t|
122
- next if t["id"].nil? || t["id"].empty?
118
+ clause.xpath(ns(".//table")).reject { |n| blank?(n["id"]) }.each do |t|
123
119
 
124
120
  @anchors[t["id"]] =
125
121
  anchor_struct("#{num}#{hiersep}#{c.increment(t).print}",
@@ -141,8 +137,7 @@ module IsoDoc::XrefGen
141
137
 
142
138
  def hierarchical_formula_names(clause, num)
143
139
  c = Counter.new
144
- clause.xpath(ns(".//formula")).each do |t|
145
- next if t["id"].nil? || t["id"].empty?
140
+ clause.xpath(ns(".//formula")).reject { |n| blank?(n["id"]) }.each do |t|
146
141
 
147
142
  @anchors[t["id"]] = anchor_struct(
148
143
  "#{num}#{hiersep}#{c.increment(t).print}", nil,
@@ -154,8 +149,8 @@ module IsoDoc::XrefGen
154
149
 
155
150
  def hierarchical_permission_names(clause, num, klass, label)
156
151
  c = Counter.new
157
- clause.xpath(ns(".//#{klass}#{FIRST_LVL_REQ}")).each do |t|
158
- next if t["id"].nil? || t["id"].empty?
152
+ clause.xpath(ns(".//#{klass}#{FIRST_LVL_REQ}"))
153
+ .reject { |n| blank?(n["id"]) }.each do |t|
159
154
 
160
155
  id = "#{num}#{hiersep}#{c.increment(t).print}"
161
156
  @anchors[t["id"]] =
@@ -175,8 +170,7 @@ module IsoDoc::XrefGen
175
170
 
176
171
  def hierarchical_permission_names1(block, lbl, klass, label)
177
172
  c = Counter.new
178
- block.xpath(ns("./#{klass}")).each do |t|
179
- next if t["id"].nil? || t["id"].empty?
173
+ block.xpath(ns("./#{klass}")).reject { |n| blank?(n["id"]) }.each do |t|
180
174
 
181
175
  id = "#{lbl}#{hierfigsep}#{c.increment(t).print}"
182
176
  @anchors[t["id"]] =