isodoc 1.0.27 → 1.1.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 (70) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/macos.yml +4 -8
  3. data/.github/workflows/ubuntu.yml +18 -16
  4. data/.github/workflows/windows.yml +4 -8
  5. data/Rakefile +3 -1
  6. data/isodoc.gemspec +2 -2
  7. data/lib/isodoc.rb +2 -0
  8. data/lib/isodoc/base_style/metanorma_word.scss +0 -1
  9. data/lib/isodoc/base_style/reset.scss +3 -3
  10. data/lib/isodoc/common.rb +0 -4
  11. data/lib/isodoc/convert.rb +121 -58
  12. data/lib/isodoc/function/blocks.rb +42 -53
  13. data/lib/isodoc/function/blocks_example_note.rb +108 -0
  14. data/lib/isodoc/function/cleanup.rb +8 -4
  15. data/lib/isodoc/function/i18n.rb +1 -0
  16. data/lib/isodoc/function/inline.rb +70 -90
  17. data/lib/isodoc/function/inline_simple.rb +72 -0
  18. data/lib/isodoc/function/lists.rb +12 -6
  19. data/lib/isodoc/function/references.rb +33 -38
  20. data/lib/isodoc/function/reqt.rb +14 -5
  21. data/lib/isodoc/function/section.rb +8 -11
  22. data/lib/isodoc/function/table.rb +4 -4
  23. data/lib/isodoc/function/terms.rb +3 -3
  24. data/lib/isodoc/function/to_word_html.rb +21 -13
  25. data/lib/isodoc/function/utils.rb +57 -50
  26. data/lib/isodoc/gem_tasks.rb +104 -0
  27. data/lib/isodoc/headlesshtml_convert.rb +7 -6
  28. data/lib/isodoc/html_convert.rb +2 -1
  29. data/lib/isodoc/html_function/footnotes.rb +1 -1
  30. data/lib/isodoc/html_function/html.rb +13 -1
  31. data/lib/isodoc/html_function/postprocess.rb +4 -4
  32. data/lib/isodoc/metadata.rb +74 -62
  33. data/lib/isodoc/pdf_convert.rb +8 -6
  34. data/lib/isodoc/presentation_xml_convert.rb +29 -0
  35. data/lib/isodoc/sassc_importer.rb +11 -0
  36. data/lib/isodoc/version.rb +1 -1
  37. data/lib/isodoc/word_convert.rb +2 -1
  38. data/lib/isodoc/word_function/body.rb +14 -48
  39. data/lib/isodoc/word_function/footnotes.rb +1 -1
  40. data/lib/isodoc/word_function/inline.rb +75 -0
  41. data/lib/isodoc/word_function/postprocess.rb +1 -0
  42. data/lib/isodoc/word_function/table.rb +3 -3
  43. data/lib/isodoc/xref.rb +59 -0
  44. data/lib/isodoc/{function → xref}/xref_anchor.rb +10 -21
  45. data/lib/isodoc/xref/xref_counter.rb +74 -0
  46. data/lib/isodoc/{function → xref}/xref_gen.rb +9 -22
  47. data/lib/isodoc/{function → xref}/xref_gen_seq.rb +41 -32
  48. data/lib/isodoc/{function → xref}/xref_sect_gen.rb +33 -23
  49. data/lib/isodoc/xslfo_convert.rb +16 -4
  50. data/spec/assets/{html.css → html.scss} +0 -0
  51. data/spec/assets/i18n.yaml +4 -1
  52. data/spec/assets/odf.emf +0 -0
  53. data/spec/assets/odf.svg +4 -0
  54. data/spec/assets/odf1.svg +4 -0
  55. data/spec/isodoc/blocks_spec.rb +219 -47
  56. data/spec/isodoc/cleanup_spec.rb +135 -6
  57. data/spec/isodoc/footnotes_spec.rb +22 -7
  58. data/spec/isodoc/inline_spec.rb +262 -2
  59. data/spec/isodoc/lists_spec.rb +8 -8
  60. data/spec/isodoc/metadata_spec.rb +110 -3
  61. data/spec/isodoc/postproc_spec.rb +1321 -1351
  62. data/spec/isodoc/presentation_xml_spec.rb +20 -0
  63. data/spec/isodoc/ref_spec.rb +119 -50
  64. data/spec/isodoc/section_spec.rb +84 -18
  65. data/spec/isodoc/table_spec.rb +6 -6
  66. data/spec/isodoc/terms_spec.rb +7 -7
  67. data/spec/isodoc/xref_spec.rb +165 -45
  68. metadata +36 -27
  69. data/lib/isodoc/function/blocks_example.rb +0 -53
  70. data/lib/isodoc/function/xref_counter.rb +0 -50
@@ -1,48 +1,12 @@
1
- require_relative "blocks_example"
1
+ require_relative "blocks_example_note"
2
2
 
3
3
  module IsoDoc::Function
4
4
  module Blocks
5
5
  @annotation = false
6
6
 
7
- def note_label(node)
8
- n = get_anchors[node["id"]]
9
- return @note_lbl if n.nil? || n[:label].nil? || n[:label].empty?
10
- l10n("#{@note_lbl} #{n[:label]}")
11
- end
12
-
13
- def note_p_parse(node, div)
14
- div.p do |p|
15
- p.span **{ class: "note_label" } do |s|
16
- s << note_label(node)
17
- end
18
- insert_tab(p, 1)
19
- node.first_element_child.children.each { |n| parse(n, p) }
20
- end
21
- node.element_children[1..-1].each { |n| parse(n, div) }
22
- end
23
-
24
- def note_parse1(node, div)
25
- div.p do |p|
26
- p.span **{ class: "note_label" } do |s|
27
- s << note_label(node)
28
- end
29
- insert_tab(p, 1)
30
- end
31
- node.children.each { |n| parse(n, div) }
32
- end
33
-
34
- def note_parse(node, out)
35
- @note = true
36
- out.div **{ id: node["id"], class: "Note" } do |div|
37
- node.first_element_child.name == "p" ?
38
- note_p_parse(node, div) : note_parse1(node, div)
39
- end
40
- @note = false
41
- end
42
-
43
7
  def figure_name_parse(node, div, name)
44
8
  return if name.nil? && node.at(ns("./figure"))
45
- lbl = anchor(node['id'], :label, false)
9
+ lbl = @xrefs.anchor(node['id'], :label, false)
46
10
  lbl = nil if labelled_ancestor(node) && node.ancestors("figure").empty?
47
11
  return if lbl.nil? && name.nil?
48
12
  div.p **{ class: "FigureTitle", style: "text-align:center;" } do |p|
@@ -58,11 +22,15 @@ module IsoDoc::Function
58
22
  end
59
23
  end
60
24
 
25
+ def figure_attrs(node)
26
+ attr_code(id: node["id"], class: "figure", style: keep_style(node))
27
+ end
28
+
61
29
  def figure_parse(node, out)
62
30
  return pseudocode_parse(node, out) if node["class"] == "pseudocode" ||
63
31
  node["type"] == "pseudocode"
64
32
  @in_figure = true
65
- out.div **attr_code(id: node["id"], class: "figure") do |div|
33
+ out.div **figure_attrs(node) do |div|
66
34
  node.children.each do |n|
67
35
  figure_key(out) if n.name == "dl"
68
36
  parse(n, div) unless n.name == "name"
@@ -72,10 +40,14 @@ module IsoDoc::Function
72
40
  @in_figure = false
73
41
  end
74
42
 
43
+ def pseudocode_attrs(node)
44
+ attr_code(id: node["id"], class: "pseudocode", style: keep_style(node))
45
+ end
46
+
75
47
  def pseudocode_parse(node, out)
76
48
  @in_figure = true
77
49
  name = node.at(ns("./name"))
78
- out.div **attr_code(id: node["id"], class: "pseudocode") do |div|
50
+ out.div **pseudocode_attrs(node) do |div|
79
51
  node.children.each { |n| parse(n, div) unless n.name == "name" }
80
52
  sourcecode_name_parse(node, div, name)
81
53
  end
@@ -83,7 +55,7 @@ module IsoDoc::Function
83
55
  end
84
56
 
85
57
  def sourcecode_name_parse(node, div, name)
86
- lbl = anchor(node['id'], :label, false)
58
+ lbl = @xrefs.anchor(node['id'], :label, false)
87
59
  lbl = nil if labelled_ancestor(node)
88
60
  return if lbl.nil? && name.nil?
89
61
  div.p **{ class: "SourceTitle", style: "text-align:center;" } do |p|
@@ -101,9 +73,13 @@ module IsoDoc::Function
101
73
  end
102
74
  end
103
75
 
76
+ def sourcecode_attrs(node)
77
+ attr_code(id: node["id"], class: "Sourcecode", style: keep_style(node))
78
+ end
79
+
104
80
  def sourcecode_parse(node, out)
105
81
  name = node.at(ns("./name"))
106
- out.p **attr_code(id: node["id"], class: "Sourcecode") do |div|
82
+ out.p **sourcecode_attrs(node) do |div|
107
83
  @sourcecode = true
108
84
  node.children.each { |n| parse(n, div) unless n.name == "name" }
109
85
  @sourcecode = false
@@ -138,10 +114,15 @@ module IsoDoc::Function
138
114
  name
139
115
  end
140
116
 
117
+ def admonition_attrs(node)
118
+ attr_code(id: node["id"], class: admonition_class(node),
119
+ style: keep_style(node))
120
+ end
121
+
141
122
  def admonition_parse(node, out)
142
123
  type = node["type"]
143
124
  name = admonition_name(node, type)
144
- out.div **{ class: admonition_class(node) } do |t|
125
+ out.div **admonition_attrs(node) do |t|
145
126
  admonition_name_parse(node, t, name) if name
146
127
  node.children.each { |n| parse(n, t) unless n.name == "name" }
147
128
  end
@@ -157,10 +138,10 @@ module IsoDoc::Function
157
138
  end
158
139
 
159
140
  def formula_parse1(node, out)
160
- out.div **attr_code(id: node["id"], class: "formula") do |div|
141
+ out.div **attr_code(class: "formula") do |div|
161
142
  div.p do |p|
162
143
  parse(node.at(ns("./stem")), div)
163
- lbl = anchor(node['id'], :label, false)
144
+ lbl = @xrefs.anchor(node['id'], :label, false)
164
145
  unless lbl.nil?
165
146
  insert_tab(div, 1)
166
147
  div << "(#{lbl})"
@@ -169,12 +150,18 @@ module IsoDoc::Function
169
150
  end
170
151
  end
171
152
 
153
+ def formula_attrs(node)
154
+ attr_code(id: node["id"], style: keep_style(node))
155
+ end
156
+
172
157
  def formula_parse(node, out)
173
- formula_parse1(node, out)
174
- formula_where(node.at(ns("./dl")), out)
175
- node.children.each do |n|
176
- next if %w(stem dl).include? n.name
177
- parse(n, out)
158
+ out.div **formula_attrs(node) do |div|
159
+ formula_parse1(node, div)
160
+ formula_where(node.at(ns("./dl")), div)
161
+ node.children.each do |n|
162
+ next if %w(stem dl).include? n.name
163
+ parse(n, div)
164
+ end
178
165
  end
179
166
  end
180
167
 
@@ -187,8 +174,9 @@ module IsoDoc::Function
187
174
 
188
175
  def para_attrs(node)
189
176
  attrs = { class: para_class(node), id: node["id"] }
190
- node["align"].nil? or
191
- attrs[:style] = "text-align:#{node['align']};"
177
+ s = node["align"].nil? ? "" : "text-align:#{node['align']};"
178
+ s = "#{s}#{keep_style(node)}"
179
+ attrs[:style] = s unless s.empty?
192
180
  attrs
193
181
  end
194
182
 
@@ -224,7 +212,8 @@ module IsoDoc::Function
224
212
  end
225
213
 
226
214
  def passthrough_parse(node, out)
227
- return if node["format"] and !(node["format"].split(/,/).include? @format.to_s)
215
+ return if node["format"] and
216
+ !(node["format"].split(/,/).include? @format.to_s)
228
217
  out.passthrough node.text
229
218
  end
230
219
  end
@@ -0,0 +1,108 @@
1
+ module IsoDoc::Function
2
+ module Blocks
3
+ def example_label(node, div, name)
4
+ n = @xrefs.get[node["id"]]
5
+ div.p **{ class: "example-title" } do |p|
6
+ lbl = (n.nil? || n[:label].nil? || n[:label].empty?) ? @example_lbl :
7
+ l10n("#{@example_lbl} #{n[:label]}")
8
+ p << lbl
9
+ name and !lbl.nil? and p << "&nbsp;&mdash; "
10
+ name and name.children.each { |n| parse(n, div) }
11
+ end
12
+ end
13
+
14
+ EXAMPLE_TBL_ATTR =
15
+ { class: "example_label", style: "width:82.8pt;padding:0 0 0 0;\
16
+ margin-left:0pt;vertical-align:top;" }.freeze
17
+
18
+ def example_div_attr(node)
19
+ attr_code(id: node["id"], class: "example", style: keep_style(node))
20
+ end
21
+
22
+ # used if we are boxing examples
23
+ def example_div_parse(node, out)
24
+ out.div **example_div_attr(node) do |div|
25
+ example_label(node, div, node.at(ns("./name")))
26
+ node.children.each do |n|
27
+ parse(n, div) unless n.name == "name"
28
+ end
29
+ end
30
+ end
31
+
32
+ def example_table_attr(node)
33
+ attr_code(id: node["id"], class: "example",
34
+ style: "border-collapse:collapse;border-spacing:0;"\
35
+ "#{keep_style(node)}" )
36
+ end
37
+
38
+ EXAMPLE_TD_ATTR =
39
+ { style: "vertical-align:top;padding:0;", class: "example" }.freeze
40
+
41
+ def example_table_parse(node, out)
42
+ out.table **example_table_attr(node) do |t|
43
+ t.tr do |tr|
44
+ tr.td **EXAMPLE_TBL_ATTR do |td|
45
+ example_label(node, td, node.at(ns("./name")))
46
+ end
47
+ tr.td **EXAMPLE_TD_ATTR do |td|
48
+ node.children.each { |n| parse(n, td) unless n.name == "name" }
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ def example_parse(node, out)
55
+ example_div_parse(node, out)
56
+ end
57
+
58
+ def note_label(node)
59
+ n = @xrefs.get[node["id"]]
60
+ return @note_lbl if n.nil? || n[:label].nil? || n[:label].empty?
61
+ l10n("#{@note_lbl} #{n[:label]}")
62
+ end
63
+
64
+ def note_p_parse(node, div)
65
+ div.p do |p|
66
+ p.span **{ class: "note_label" } do |s|
67
+ s << note_label(node)
68
+ end
69
+ insert_tab(p, 1)
70
+ node.first_element_child.children.each { |n| parse(n, p) }
71
+ end
72
+ node.element_children[1..-1].each { |n| parse(n, div) }
73
+ end
74
+
75
+ def note_parse1(node, div)
76
+ div.p do |p|
77
+ p.span **{ class: "note_label" } do |s|
78
+ s << note_label(node)
79
+ end
80
+ insert_tab(p, 1)
81
+ end
82
+ node.children.each { |n| parse(n, div) }
83
+ end
84
+
85
+ def keep_style(node)
86
+ ret = ""
87
+ node["keep-with-next"] == "true" and
88
+ ret += "page-break-after: avoid;"
89
+ node["keep-lines-together"] == "true" and
90
+ ret += "page-break-inside: avoid;"
91
+ return nil if ret.empty?
92
+ ret
93
+ end
94
+
95
+ def note_attrs(node)
96
+ attr_code(id: node["id"], class: "Note", style: keep_style(node))
97
+ end
98
+
99
+ def note_parse(node, out)
100
+ @note = true
101
+ out.div **note_attrs(node) do |div|
102
+ node.first_element_child.name == "p" ?
103
+ note_p_parse(node, div) : note_parse1(node, div)
104
+ end
105
+ @note = false
106
+ end
107
+ end
108
+ end
@@ -1,16 +1,20 @@
1
1
  module IsoDoc::Function
2
2
  module Cleanup
3
3
  def textcleanup(docxml)
4
- docxml = passthrough_cleanup(docxml)
4
+ docxml = termref_cleanup(passthrough_cleanup(docxml))
5
+ end
6
+
7
+ def termref_cleanup(docxml)
5
8
  docxml.
9
+ gsub(%r{\s*\[/TERMREF\]\s*</p>\s*<p>\s*\[TERMREF\]}, "; ").
6
10
  gsub(/\[TERMREF\]\s*/, l10n("[#{@source_lbl}: ")).
7
11
  gsub(/\s*\[MODIFICATION\]\s*\[\/TERMREF\]/, l10n(", #{@modified_lbl} [/TERMREF]")).
8
- gsub(/\s*\[\/TERMREF\]\s*/, l10n("]")).
12
+ gsub(%r{\s*\[\/TERMREF\]\s*}, l10n("]")).
9
13
  gsub(/\s*\[MODIFICATION\]/, l10n(", #{@modified_lbl} &mdash; "))
10
14
  end
11
15
 
12
16
  def passthrough_cleanup(docxml)
13
- docxml = docxml.split(%r{(<passthrough>|</passthrough>)}).each_slice(4).map do |a|
17
+ docxml.split(%r{(<passthrough>|</passthrough>)}).each_slice(4).map do |a|
14
18
  a.size > 2 and a[2] = HTMLEntities.new.decode(a[2])
15
19
  [a[0], a[2]]
16
20
  end.join
@@ -126,7 +130,7 @@ module IsoDoc::Function
126
130
  end
127
131
 
128
132
  def footnote_cleanup(docxml)
129
- docxml.xpath('//a[@epub:type = "footnote"]/sup').each_with_index do |x, i|
133
+ docxml.xpath('//a[@class = "FootnoteRef"]/sup').each_with_index do |x, i|
130
134
  x.content = (i + 1).to_s
131
135
  end
132
136
  docxml
@@ -87,6 +87,7 @@ module IsoDoc::Function
87
87
 
88
88
  # TODO: move to localization file
89
89
  def eref_localities1(target, type, from, to, delim, lang = "en")
90
+ return "" if type == "anchor"
90
91
  return l10n(eref_localities1_zh(target, type, from, to, delim)) if lang == "zh"
91
92
  ret = delim
92
93
  loc = @locality[type] || type.sub(/^locality:/, "").capitalize
@@ -1,28 +1,7 @@
1
+ require_relative "inline_simple"
2
+
1
3
  module IsoDoc::Function
2
4
  module Inline
3
- def section_break(body)
4
- body.br
5
- end
6
-
7
- def page_break(out)
8
- out.br
9
- end
10
-
11
- def pagebreak_parse(_node, out)
12
- out.br
13
- end
14
-
15
- def hr_parse(node, out)
16
- out.hr
17
- end
18
-
19
- def br_parse(node, out)
20
- out.br
21
- end
22
-
23
- def index_parse(node, out)
24
- end
25
-
26
5
  def link_parse(node, out)
27
6
  out.a **attr_code(href: node["target"], title: node["alt"]) do |l|
28
7
  if node.text.empty?
@@ -38,29 +17,51 @@ module IsoDoc::Function
38
17
  end
39
18
 
40
19
  def prefix_container(container, linkend, _target)
41
- l10n(anchor(container, :xref) + ", " + linkend)
20
+ l10n(@xrefs.anchor(container, :xref) + ", " + linkend)
42
21
  end
43
22
 
44
23
  def anchor_linkend(node, linkend)
45
24
  if node["citeas"].nil? && node["bibitemid"]
46
- return anchor(node["bibitemid"] ,:xref) || "???"
25
+ return @xrefs.anchor(node["bibitemid"] ,:xref) || "???"
47
26
  elsif node["target"] && !/.#./.match(node["target"])
48
- linkend = anchor(node["target"], :xref)
49
- container = anchor(node["target"], :container, false)
27
+ linkend = @xrefs.anchor(node["target"], :xref)
28
+ container = @xrefs.anchor(node["target"], :container, false)
50
29
  (container && get_note_container_id(node) != container &&
51
- @anchors[node["target"]]) &&
30
+ @xrefs.get[node["target"]]) &&
52
31
  linkend = prefix_container(container, linkend, node["target"])
32
+ linkend = capitalise_xref(node, linkend)
53
33
  end
54
34
  linkend || "???"
55
35
  end
56
36
 
37
+ def capitalise_xref(node, linkend)
38
+ return linkend unless %w(Latn Cyrl Grek).include? @script
39
+ return linkend&.capitalize if node["case"] == "capital"
40
+ return linkend&.downcase if node["case"] == "lowercase"
41
+ return linkend if linkend[0,1].match(/\p{Upper}/)
42
+ prec = nearest_block_parent(node).xpath("./descendant-or-self::text()") &
43
+ node.xpath("./preceding::text()")
44
+ (prec.empty? || /(?!<[^.].)\.\s+$/.match(prec.map { |p| p.text }.join)) ?
45
+ linkend&.capitalize : linkend
46
+ end
47
+
48
+ def nearest_block_parent(node)
49
+ until %w(p title td th name formula
50
+ li dt dd sourcecode pre).include?(node.name)
51
+ node = node.parent
52
+ end
53
+ node
54
+ end
55
+
57
56
  def get_linkend(node)
58
- contents = node.children.select { |c| !%w{locality localityStack}.include? c.name }.
59
- select { |c| !c.text? || /\S/.match(c) }
57
+ contents = node.children.select do |c|
58
+ !%w{locality localityStack}.include? c.name
59
+ end.select { |c| !c.text? || /\S/.match(c) }
60
60
  !contents.empty? and
61
61
  return Nokogiri::XML::NodeSet.new(node.document, contents).to_xml
62
62
  link = anchor_linkend(node, docid_l10n(node["target"] || node["citeas"]))
63
- link + eref_localities(node.xpath(ns("./locality | ./localityStack")), link)
63
+ link + eref_localities(node.xpath(ns("./locality | ./localityStack")),
64
+ link)
64
65
  # so not <origin bibitemid="ISO7301" citeas="ISO 7301">
65
66
  # <locality type="section"><reference>3.1</reference></locality></origin>
66
67
  end
@@ -83,27 +84,44 @@ module IsoDoc::Function
83
84
  end
84
85
  else
85
86
  ret += eref_localities0(r, i, target, delim)
86
- end
87
+ end
87
88
  end
88
89
  ret
89
90
  end
90
91
 
91
92
  def eref_localities0(r, i, target, delim)
92
- if r["type"] == "whole" then l10n("#{delim} #{@whole_of_text}")
93
+ if r["type"] == "whole" then l10n("#{delim} #{@wholeoftext_lbl}")
93
94
  else
94
95
  eref_localities1(target, r["type"], r.at(ns("./referenceFrom")),
95
96
  r.at(ns("./referenceTo")), delim, @lang)
96
97
  end
97
98
  end
98
99
 
100
+ def suffix_url(url)
101
+ return url if %r{^http[s]?://}.match(url)
102
+ url.sub(/#{File.extname(url)}$/, ".html")
103
+ end
104
+
105
+ def eref_target(node)
106
+ href = "#" + node["bibitemid"]
107
+ url = node.at(ns("//bibitem[@id = '#{node['bibitemid']}']/"\
108
+ "uri[@type = 'citation']"))
109
+ return href unless url
110
+ href = suffix_url(url.text)
111
+ anchor = node&.at(ns(".//locality[@type = 'anchor']"))&.text
112
+ anchor and href += "##{anchor}"
113
+ href
114
+ end
115
+
99
116
  def eref_parse(node, out)
100
117
  linkend = get_linkend(node)
118
+ href = eref_target(node)
101
119
  if node["type"] == "footnote"
102
120
  out.sup do |s|
103
- s.a(**{ "href": "#" + node["bibitemid"] }) { |l| l << linkend }
121
+ s.a(**{ "href": href }) { |l| l << linkend }
104
122
  end
105
123
  else
106
- out.a(**{ "href": "#" + node["bibitemid"] }) { |l| l << linkend }
124
+ out.a(**{ "href": href }) { |l| l << linkend }
107
125
  end
108
126
  end
109
127
 
@@ -120,8 +138,9 @@ module IsoDoc::Function
120
138
  end
121
139
 
122
140
  def concept_parse(node, out)
123
- content = node.first_element_child.children.select { |c| !%w{locality localityStack}.include? c.name }.
124
- select { |c| !c.text? || /\S/.match(c) }
141
+ content = node.first_element_child.children.select do |c|
142
+ !%w{locality localityStack}.include? c.name
143
+ end.select { |c| !c.text? || /\S/.match(c) }
125
144
  if content.empty?
126
145
  out << "[Term defined in "
127
146
  parse(node.first_element_child, out)
@@ -133,7 +152,8 @@ module IsoDoc::Function
133
152
 
134
153
  def stem_parse(node, out)
135
154
  ooml = if node["type"] == "AsciiMath"
136
- "#{@openmathdelim}#{HTMLEntities.new.encode(node.text)}#{@closemathdelim}"
155
+ "#{@openmathdelim}#{HTMLEntities.new.encode(node.text)}"\
156
+ "#{@closemathdelim}"
137
157
  elsif node["type"] == "MathML" then node.first_element_child.to_s
138
158
  else
139
159
  HTMLEntities.new.encode(node.text)
@@ -175,52 +195,6 @@ module IsoDoc::Function
175
195
  out << text
176
196
  end
177
197
 
178
- def bookmark_parse(node, out)
179
- out.a **attr_code(id: node["id"])
180
- end
181
-
182
- def keyword_parse(node, out)
183
- out.span **{ class: "keyword" } do |s|
184
- node.children.each { |n| parse(n, s) }
185
- end
186
- end
187
-
188
- def em_parse(node, out)
189
- out.i do |e|
190
- node.children.each { |n| parse(n, e) }
191
- end
192
- end
193
-
194
- def strong_parse(node, out)
195
- out.b do |e|
196
- node.children.each { |n| parse(n, e) }
197
- end
198
- end
199
-
200
- def sup_parse(node, out)
201
- out.sup do |e|
202
- node.children.each { |n| parse(n, e) }
203
- end
204
- end
205
-
206
- def sub_parse(node, out)
207
- out.sub do |e|
208
- node.children.each { |n| parse(n, e) }
209
- end
210
- end
211
-
212
- def tt_parse(node, out)
213
- out.tt do |e|
214
- node.children.each { |n| parse(n, e) }
215
- end
216
- end
217
-
218
- def strike_parse(node, out)
219
- out.s do |e|
220
- node.children.each { |n| parse(n, e) }
221
- end
222
- end
223
-
224
198
  def error_parse(node, out)
225
199
  text = node.to_xml.gsub(/</, "&lt;").gsub(/>/, "&gt;")
226
200
  out.para do |p|
@@ -232,14 +206,20 @@ module IsoDoc::Function
232
206
  if node["lang"] == @lang && node["script"] == @script
233
207
  node.children.each { |n| parse(n, out) }
234
208
  else
235
- prev = node.xpath("./preceding-sibling::xmlns:variant")
236
- foll = node.xpath("./following-sibling::xmlns:variant")
237
- found = false
238
- (prev + foll).each { |n| found = true if n["lang"] == @lang && n["script"] == @script }
239
- return if found
240
- return unless prev.empty?
209
+ return if found_matching_variant_sibling(node)
210
+ return unless !node.at("./preceding-sibling::xmlns:variant")
241
211
  node.children.each { |n| parse(n, out) }
242
212
  end
243
213
  end
214
+
215
+ def found_matching_variant_sibling(node)
216
+ prev = node.xpath("./preceding-sibling::xmlns:variant")
217
+ foll = node.xpath("./following-sibling::xmlns:variant")
218
+ found = false
219
+ (prev + foll).each do |n|
220
+ found = true if n["lang"] == @lang && n["script"] == @script
221
+ end
222
+ found
223
+ end
244
224
  end
245
225
  end