isodoc 1.6.3 → 1.6.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rake.yml +2 -12
  3. data/.hound.yml +3 -1
  4. data/.rubocop.yml +4 -6
  5. data/isodoc.gemspec +3 -2
  6. data/lib/isodoc-yaml/i18n-en.yaml +1 -0
  7. data/lib/isodoc-yaml/i18n-fr.yaml +1 -0
  8. data/lib/isodoc-yaml/i18n-zh-Hans.yaml +1 -0
  9. data/lib/isodoc.rb +0 -2
  10. data/lib/isodoc/convert.rb +7 -1
  11. data/lib/isodoc/function/blocks.rb +5 -4
  12. data/lib/isodoc/function/cleanup.rb +52 -43
  13. data/lib/isodoc/function/inline.rb +7 -7
  14. data/lib/isodoc/function/references.rb +33 -52
  15. data/lib/isodoc/function/section.rb +28 -16
  16. data/lib/isodoc/function/table.rb +21 -22
  17. data/lib/isodoc/function/terms.rb +6 -7
  18. data/lib/isodoc/function/to_word_html.rb +6 -3
  19. data/lib/isodoc/function/utils.rb +181 -163
  20. data/lib/isodoc/gem_tasks.rb +8 -9
  21. data/lib/isodoc/headlesshtml_convert.rb +8 -7
  22. data/lib/isodoc/html_convert.rb +5 -1
  23. data/lib/isodoc/html_function/comments.rb +14 -12
  24. data/lib/isodoc/html_function/footnotes.rb +14 -7
  25. data/lib/isodoc/html_function/html.rb +30 -26
  26. data/lib/isodoc/html_function/postprocess.rb +191 -182
  27. data/lib/isodoc/html_function/sectionsplit.rb +230 -0
  28. data/lib/isodoc/metadata.rb +22 -20
  29. data/lib/isodoc/metadata_contributor.rb +31 -28
  30. data/lib/isodoc/pdf_convert.rb +11 -13
  31. data/lib/isodoc/presentation_function/bibdata.rb +50 -22
  32. data/lib/isodoc/presentation_function/inline.rb +20 -15
  33. data/lib/isodoc/presentation_function/section.rb +38 -1
  34. data/lib/isodoc/presentation_xml_convert.rb +2 -0
  35. data/lib/isodoc/version.rb +1 -1
  36. data/lib/isodoc/word_function/postprocess.rb +50 -36
  37. data/lib/isodoc/xref.rb +2 -0
  38. data/lib/isodoc/xref/xref_gen_seq.rb +60 -35
  39. data/lib/isodoc/xref/xref_sect_gen.rb +4 -4
  40. data/spec/assets/scripts_override.html +3 -0
  41. data/spec/isodoc/blocks_spec.rb +373 -685
  42. data/spec/isodoc/cleanup_spec.rb +40 -42
  43. data/spec/isodoc/i18n_spec.rb +694 -821
  44. data/spec/isodoc/inline_spec.rb +482 -328
  45. data/spec/isodoc/metadata_spec.rb +384 -379
  46. data/spec/isodoc/postproc_spec.rb +163 -55
  47. data/spec/isodoc/presentation_xml_spec.rb +355 -278
  48. data/spec/isodoc/ref_spec.rb +5 -5
  49. data/spec/isodoc/section_spec.rb +216 -199
  50. data/spec/isodoc/sectionsplit_spec.rb +190 -0
  51. data/spec/isodoc/table_spec.rb +41 -42
  52. data/spec/isodoc/terms_spec.rb +84 -84
  53. data/spec/isodoc/xref_spec.rb +974 -932
  54. metadata +22 -5
@@ -1,11 +1,10 @@
1
- require_relative "html_function/comments.rb"
2
- require_relative "html_function/footnotes.rb"
3
- require_relative "html_function/html.rb"
1
+ require_relative "html_function/comments"
2
+ require_relative "html_function/footnotes"
3
+ require_relative "html_function/html"
4
4
  require "metanorma"
5
5
 
6
6
  module IsoDoc
7
7
  class PdfConvert < ::IsoDoc::Convert
8
-
9
8
  include HtmlFunction::Comments
10
9
  include HtmlFunction::Footnotes
11
10
  include HtmlFunction::Html
@@ -13,6 +12,8 @@ module IsoDoc
13
12
  def initialize(options)
14
13
  @standardstylesheet = nil
15
14
  super
15
+ @format = :pdf
16
+ @suffix = "pdf"
16
17
  @scripts = @scripts_pdf if @scripts_pdf
17
18
  @maxwidth = 500
18
19
  @maxheight = 800
@@ -22,22 +23,19 @@ module IsoDoc
22
23
  "_pdfimages"
23
24
  end
24
25
 
25
- def initialize(options)
26
- @format = :pdf
27
- @suffix = "pdf"
28
- super
29
- end
30
-
31
26
  def convert(input_filename, file = nil, debug = false, output_filename = nil)
32
27
  file = File.read(input_filename, encoding: "utf-8") if file.nil?
33
28
  @openmathdelim, @closemathdelim = extract_delims(file)
34
29
  docxml, filename, dir = convert_init(file, input_filename, debug)
35
30
  result = convert1(docxml, filename, dir)
36
31
  return result if debug
37
- postprocess(result, filename + ".tmp.html", dir)
32
+
33
+ postprocess(result, "#{filename}.tmp.html", dir)
38
34
  FileUtils.rm_rf dir
39
- ::Metanorma::Output::Pdf.new.convert("#{filename}.tmp.html",
40
- output_filename || "#{filename}.#{@suffix}")
35
+ ::Metanorma::Output::Pdf.new.convert(
36
+ "#{filename}.tmp.html",
37
+ output_filename || "#{filename}.#{@suffix}",
38
+ )
41
39
  FileUtils.rm_rf ["#{filename}.tmp.html", tmpimagedir]
42
40
  end
43
41
 
@@ -1,13 +1,40 @@
1
1
  module IsoDoc
2
2
  class PresentationXMLConvert < ::IsoDoc::Convert
3
3
  def bibdata(docxml)
4
+ docid_prefixes(docxml)
4
5
  a = bibdata_current(docxml) or return
6
+ address_precompose(a)
5
7
  bibdata_i18n(a)
6
8
  a.next =
7
9
  "<localized-strings>#{i8n_name(trim_hash(@i18n.get), '').join('')}"\
8
10
  "</localized-strings>"
9
11
  end
10
12
 
13
+ def docid_prefixes(docxml)
14
+ docxml.xpath(ns("//references/bibitem/docidentifier")).each do |i|
15
+ i.children = @xrefs.klass.docid_prefix(i["type"], i.text)
16
+ end
17
+ end
18
+
19
+ def address_precompose(bib)
20
+ bib.xpath(ns("//bibdata//address")).each do |b|
21
+ next if b.at(ns("./formattedAddress"))
22
+
23
+ x = address_precompose1(b)
24
+ b.children = "<formattedAddress>#{x}</formattedAddress>"
25
+ end
26
+ end
27
+
28
+ def address_precompose1(addr)
29
+ ret = []
30
+ addr.xpath(ns("./street")).each { |s| ret << s.children.to_xml }
31
+ a = addr.at(ns("./city")) and ret << a.children.to_xml
32
+ addr.xpath(ns("./state")).each { |s| ret << s.children.to_xml }
33
+ a = addr.at(ns("./country")) and ret << a.children.to_xml
34
+ a = addr.at(ns("./postcode")) and ret[-1] += " #{a.children.to_xml}"
35
+ ret.join("<br/>")
36
+ end
37
+
11
38
  def bibdata_current(docxml)
12
39
  a = docxml.at(ns("//bibdata")) or return
13
40
  a.xpath(ns("./language")).each do |l|
@@ -35,27 +62,28 @@ module IsoDoc
35
62
  x.next.children = hash[x.text]
36
63
  end
37
64
 
38
- def i18n_tag(k, v)
39
- "<localized-string key='#{k}' language='#{@lang}'>#{v}</localized-string>"
65
+ def i18n_tag(key, value)
66
+ "<localized-string key='#{key}' language='#{@lang}'>#{value}"\
67
+ "</localized-string>"
40
68
  end
41
69
 
42
- def i18n_safe(k)
43
- k.to_s.gsub(/\s|\./, "_")
70
+ def i18n_safe(key)
71
+ key.to_s.gsub(/\s|\./, "_")
44
72
  end
45
73
 
46
- def i8n_name(h, pref)
47
- if h.is_a? Hash then i8n_name1(h, pref)
48
- elsif h.is_a? Array
49
- h.reject { |a| blank?(a) }.each_with_object([])
74
+ def i8n_name(hash, pref)
75
+ if hash.is_a? Hash then i8n_name1(hash, pref)
76
+ elsif hash.is_a? Array
77
+ hash.reject { |a| blank?(a) }.each_with_object([])
50
78
  .with_index do |(v1, g), i|
51
79
  i8n_name(v1, "#{i18n_safe(k)}.#{i}").each { |x| g << x }
52
80
  end
53
- else [i18n_tag(pref, h)]
81
+ else [i18n_tag(pref, hash)]
54
82
  end
55
83
  end
56
84
 
57
- def i8n_name1(h, pref)
58
- h.reject { |k, v| blank?(v) }.each_with_object([]) do |(k, v), g|
85
+ def i8n_name1(hash, pref)
86
+ hash.reject { |_k, v| blank?(v) }.each_with_object([]) do |(k, v), g|
59
87
  if v.is_a? Hash then i8n_name(v, i18n_safe(k)).each { |x| g << x }
60
88
  elsif v.is_a? Array
61
89
  v.reject { |a| blank?(a) }.each_with_index do |v1, i|
@@ -68,28 +96,28 @@ module IsoDoc
68
96
  end
69
97
 
70
98
  # https://stackoverflow.com/a/31822406
71
- def blank?(v)
72
- v.nil? || v.respond_to?(:empty?) && v.empty?
99
+ def blank?(elem)
100
+ elem.nil? || elem.respond_to?(:empty?) && elem.empty?
73
101
  end
74
102
 
75
- def trim_hash(h)
103
+ def trim_hash(hash)
76
104
  loop do
77
- h_new = trim_hash1(h)
78
- break h if h==h_new
105
+ h_new = trim_hash1(hash)
106
+ break hash if hash == h_new
79
107
 
80
- h = h_new
108
+ hash = h_new
81
109
  end
82
110
  end
83
111
 
84
- def trim_hash1(h)
85
- return h unless h.is_a? Hash
112
+ def trim_hash1(hash)
113
+ return hash unless hash.is_a? Hash
86
114
 
87
- h.each_with_object({}) do |(k, v), g|
115
+ hash.each_with_object({}) do |(k, v), g|
88
116
  next if blank?(v)
89
117
 
90
- g[k] = if v.is_a? Hash then trim_hash1(h[k])
118
+ g[k] = if v.is_a? Hash then trim_hash1(hash[k])
91
119
  elsif v.is_a? Array
92
- h[k].map { |a| trim_hash1(a) }.reject { |a| blank?(a) }
120
+ hash[k].map { |a| trim_hash1(a) }.reject { |a| blank?(a) }
93
121
  else
94
122
  v
95
123
  end
@@ -9,8 +9,8 @@ module IsoDoc
9
9
  return @xrefs.anchor(node["bibitemid"], :xref) || "???"
10
10
  elsif node["target"] && node["droploc"]
11
11
  return @xrefs.anchor(node["target"], :value) ||
12
- @xrefs.anchor(node["target"], :label) ||
13
- @xrefs.anchor(node["target"], :xref) || "???"
12
+ @xrefs.anchor(node["target"], :label) ||
13
+ @xrefs.anchor(node["target"], :xref) || "???"
14
14
  elsif node["target"] && !/.#./.match(node["target"])
15
15
  linkend = anchor_linkend1(node)
16
16
  end
@@ -33,6 +33,10 @@ module IsoDoc
33
33
  return linkend&.downcase if node["case"] == "lowercase"
34
34
  return linkend if linkend[0, 1].match?(/\p{Upper}/)
35
35
 
36
+ capitalise_xref1(node, linkend)
37
+ end
38
+
39
+ def capitalise_xref1(node, linkend)
36
40
  prec = nearest_block_parent(node).xpath("./descendant-or-self::text()") &
37
41
  node.xpath("./preceding::text()")
38
42
  if prec.empty? || /(?!<[^.].)\.\s+$/.match(prec.map(&:text).join)
@@ -43,8 +47,8 @@ module IsoDoc
43
47
 
44
48
  def nearest_block_parent(node)
45
49
  until %w(p title td th name formula li dt dd sourcecode pre)
46
- .include?(node.name)
47
- node = node.parent
50
+ .include?(node.name)
51
+ node = node.parent
48
52
  end
49
53
  node
50
54
  end
@@ -90,7 +94,7 @@ module IsoDoc
90
94
  ret
91
95
  end
92
96
 
93
- def eref_localities0(ref, _i, target, delim, node)
97
+ def eref_localities0(ref, _idx, target, delim, node)
94
98
  if ref["type"] == "whole" then l10n("#{delim} #{@i18n.wholeoftext}")
95
99
  else
96
100
  eref_localities1(target, ref["type"], ref.at(ns("./referenceFrom")),
@@ -99,24 +103,24 @@ module IsoDoc
99
103
  end
100
104
 
101
105
  # TODO: move to localization file
102
- def eref_localities1_zh(_target, type, from, to, node, delim)
106
+ def eref_localities1_zh(_target, type, from, upto, node, delim)
103
107
  ret = "#{delim} 第#{from.text}" if from
104
- ret += "&ndash;#{to.text}" if to
108
+ ret += "&ndash;#{upto.text}" if upto
105
109
  loc = (@i18n.locality[type] || type.sub(/^locality:/, "").capitalize)
106
110
  ret += " #{loc}" unless node["droploc"] == "true"
107
111
  ret
108
112
  end
109
113
 
110
114
  # TODO: move to localization file
111
- def eref_localities1(target, type, from, to, delim, node, lang = "en")
115
+ def eref_localities1(target, type, from, upto, delim, node, lang = "en")
112
116
  return "" if type == "anchor"
113
117
 
114
118
  lang == "zh" and
115
- return l10n(eref_localities1_zh(target, type, from, to, node, delim))
119
+ return l10n(eref_localities1_zh(target, type, from, upto, node, delim))
116
120
  ret = delim
117
121
  ret += eref_locality_populate(type, node)
118
122
  ret += " #{from.text}" if from
119
- ret += "&ndash;#{to.text}" if to
123
+ ret += "&ndash;#{upto.text}" if upto
120
124
  l10n(ret)
121
125
  end
122
126
 
@@ -161,11 +165,12 @@ module IsoDoc
161
165
  content = node.first_element_child.children.reject do |c|
162
166
  %w{locality localityStack}.include? c.name
163
167
  end.select { |c| !c.text? || /\S/.match(c) }
164
- if node.replace content.empty?
165
- @i18n.term_defined_in.sub(/%/, node.first_element_child.to_xml)
166
- else
167
- "<em>#{node.children.to_xml}</em>"
168
- end
168
+ n = if content.empty?
169
+ @i18n.term_defined_in.sub(/%/, node.first_element_child.to_xml)
170
+ else
171
+ "<em>#{node.children.to_xml}</em>"
172
+ end
173
+ node.replace(n)
169
174
  end
170
175
 
171
176
  def variant(docxml)
@@ -44,10 +44,47 @@ module IsoDoc
44
44
  prefix_name(elem, "", "#{lbl}#{clausedelim}", "name")
45
45
  end
46
46
 
47
- def references(docxml); end
47
+ def references(docxml)
48
+ end
49
+
50
+ def docid_prefixes(docxml)
51
+ docxml.xpath(ns("//references/bibitem/docidentifier")).each do |i|
52
+ i.children = @xrefs.klass.docid_prefix(i["type"], i.text)
53
+ end
54
+ end
48
55
 
49
56
  def index(docxml)
50
57
  docxml.xpath(ns("//index | //index-xref | //indexsect")).each(&:remove)
51
58
  end
59
+
60
+ def display_order_at(docxml, xpath, idx)
61
+ return idx unless c = docxml.at(ns(xpath))
62
+
63
+ idx += 1
64
+ c["displayorder"] = idx
65
+ idx
66
+ end
67
+
68
+ def display_order_xpath(docxml, xpath, idx)
69
+ docxml.xpath(ns(xpath)).each do |c|
70
+ idx += 1
71
+ c["displayorder"] = idx
72
+ end
73
+ idx
74
+ end
75
+
76
+ def display_order(docxml)
77
+ i = 0
78
+ i = display_order_xpath(docxml, "//preface/*", i)
79
+ i = display_order_at(docxml, "//clause[@type = 'scope']", i)
80
+ i = display_order_at(docxml, @xrefs.klass.norm_ref_xpath, i)
81
+ i = display_order_at(docxml, "//sections/terms | "\
82
+ "//sections/clause[descendant::terms]", i)
83
+ i = display_order_at(docxml, "//sections/definitions", i)
84
+ i = display_order_xpath(docxml, @xrefs.klass.middle_clause(docxml), i)
85
+ i = display_order_xpath(docxml, "//annex", i)
86
+ i = display_order_xpath(docxml, @xrefs.klass.bibliography_xpath, i)
87
+ display_order_xpath(docxml, "//indexsect", i)
88
+ end
52
89
  end
53
90
  end
@@ -22,12 +22,14 @@ module IsoDoc
22
22
 
23
23
  def conversions(docxml)
24
24
  bibdata docxml
25
+ @xrefs.parse docxml
25
26
  section docxml
26
27
  block docxml
27
28
  inline docxml
28
29
  end
29
30
 
30
31
  def section(docxml)
32
+ display_order docxml
31
33
  clause docxml
32
34
  annex docxml
33
35
  term docxml
@@ -1,3 +1,3 @@
1
1
  module IsoDoc
2
- VERSION = "1.6.3".freeze
2
+ VERSION = "1.6.7.1".freeze
3
3
  end
@@ -1,17 +1,17 @@
1
1
  require "fileutils"
2
- require_relative "./postprocess_cover.rb"
2
+ require_relative "./postprocess_cover"
3
3
 
4
4
  module IsoDoc::WordFunction
5
5
  module Postprocess
6
6
  # add namespaces for Word fragments
7
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>
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
15
  HERE
16
16
 
17
17
  def to_word_xhtml_fragment(xml)
@@ -22,7 +22,8 @@ xmlns:m="http://schemas.microsoft.com/office/2004/12/omml">
22
22
  def table_note_cleanup(docxml)
23
23
  super
24
24
  # preempt html2doc putting MsoNormal there
25
- docxml.xpath("//p[not(self::*[@class])][ancestor::*[@class = 'Note']]").each do |p|
25
+ docxml.xpath("//p[not(self::*[@class])][ancestor::*[@class = 'Note']]")
26
+ .each do |p|
26
27
  p["class"] = "Note"
27
28
  end
28
29
  end
@@ -38,16 +39,21 @@ xmlns:m="http://schemas.microsoft.com/office/2004/12/omml">
38
39
  def toWord(result, filename, dir, header)
39
40
  result = from_xhtml(word_cleanup(to_xhtml(result)))
40
41
  @wordstylesheet = wordstylesheet_update
41
- Html2Doc.process(result, filename: filename, stylesheet: @wordstylesheet&.path,
42
- header_file: header&.path, dir: dir,
43
- asciimathdelims: [@openmathdelim, @closemathdelim],
44
- liststyles: { ul: @ulstyle, ol: @olstyle })
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
+ )
45
50
  header&.unlink
46
- @wordstylesheet&.unlink if @wordstylesheet&.is_a?(Tempfile)
51
+ @wordstylesheet.unlink if @wordstylesheet.is_a?(Tempfile)
47
52
  end
48
53
 
49
- def wordstylesheet_update()
54
+ def wordstylesheet_update
50
55
  return if @wordstylesheet.nil?
56
+
51
57
  f = File.open(@wordstylesheet.path, "a")
52
58
  @landscapestyle.empty? or f.write(@landscapestyle)
53
59
  if @wordstylesheet_override && @wordstylesheet
@@ -62,7 +68,8 @@ xmlns:m="http://schemas.microsoft.com/office/2004/12/omml">
62
68
 
63
69
  def word_admonition_images(docxml)
64
70
  docxml.xpath("//div[@class = 'Admonition']//img").each do |i|
65
- i["width"], i["height"] = Html2Doc.image_resize(i, image_localfile(i), @maxheight, 300)
71
+ i["width"], i["height"] =
72
+ Html2Doc.image_resize(i, image_localfile(i), @maxheight, 300)
66
73
  end
67
74
  end
68
75
 
@@ -88,21 +95,23 @@ xmlns:m="http://schemas.microsoft.com/office/2004/12/omml">
88
95
  cells2d = {}
89
96
  docxml.xpath("//table[colgroup]").each do |t|
90
97
  w = colgroup_widths(t)
91
- t.xpath(".//tr").each_with_index { |tr, r| cells2d[r] = {} }
98
+ t.xpath(".//tr").each_with_index { |_tr, r| cells2d[r] = {} }
92
99
  t.xpath(".//tr").each_with_index do |tr, r|
93
- tr.xpath("./td | ./th").each_with_index do |td, i|
100
+ tr.xpath("./td | ./th").each_with_index do |td, _i|
94
101
  x = 0
95
102
  rs = td&.attr("rowspan")&.to_i || 1
96
103
  cs = td&.attr("colspan")&.to_i || 1
97
- while cells2d[r][x] do
98
- x += 1
104
+ while cells2d[r][x]
105
+ x += 1
99
106
  end
100
- for y2 in r..(r + rs - 1)
101
- for x2 in x..(x + cs - 1)
107
+ (r..(r + rs - 1)).each do |y2|
108
+ (x..(x + cs - 1)).each do |x2|
102
109
  cells2d[y2][x2] = 1
103
110
  end
104
111
  end
105
- width = (x..(x+cs-1)).each_with_object({width: 0}) { |z, m| m[:width] += w[z] }
112
+ width = (x..(x + cs - 1)).each_with_object({ width: 0 }) do |z, m|
113
+ m[:width] += w[z]
114
+ end
106
115
  td["width"] = "#{width[:width]}%"
107
116
  x += cs
108
117
  end
@@ -111,8 +120,8 @@ xmlns:m="http://schemas.microsoft.com/office/2004/12/omml">
111
120
  end
112
121
 
113
122
  # assume percentages
114
- def colgroup_widths(t)
115
- t.xpath("./colgroup/col").each_with_object([]) do |c, m|
123
+ def colgroup_widths(table)
124
+ table.xpath("./colgroup/col").each_with_object([]) do |c, m|
116
125
  m << c["width"].sub(/%$/, "").to_f
117
126
  end
118
127
  end
@@ -127,12 +136,13 @@ xmlns:m="http://schemas.microsoft.com/office/2004/12/omml">
127
136
 
128
137
  def style_update(node, css)
129
138
  return unless node
130
- node["style"] = node["style"] ? node["style"].sub(/;?$/, ";#{css}") : css
139
+
140
+ node["style"] = node["style"] ? node["style"].sub(/;?$/, ";#{css}") : css
131
141
  end
132
142
 
133
143
  def word_image_caption(docxml)
134
- docxml.xpath("//p[@class = 'FigureTitle' or @class = 'SourceTitle']").
135
- each do |t|
144
+ docxml.xpath("//p[@class = 'FigureTitle' or @class = 'SourceTitle']")
145
+ .each do |t|
136
146
  if t&.previous_element&.name == "img"
137
147
  img = t.previous_element
138
148
  t.previous_element.swap("<p class=\'figure\'>#{img.to_xml}</p>")
@@ -150,7 +160,8 @@ xmlns:m="http://schemas.microsoft.com/office/2004/12/omml">
150
160
  xpath.each do |list|
151
161
  (list.xpath(".//li") - list.xpath(".//ol//li | .//ul//li")).each do |l|
152
162
  l.xpath("./p | ./div | ./table").each_with_index do |p, i|
153
- next if i == 0
163
+ next if i.zero?
164
+
154
165
  p.wrap(%{<div class="ListContLevel#{lvl}"/>})
155
166
  end
156
167
  list_add(l.xpath(".//ul") - l.xpath(".//ul//ul | .//ol//ul"), lvl + 1)
@@ -162,20 +173,21 @@ xmlns:m="http://schemas.microsoft.com/office/2004/12/omml">
162
173
  def word_table_align(docxml)
163
174
  docxml.xpath("//td[@align]/p | //th[@align]/p").each do |p|
164
175
  next if p["align"]
165
- style_update(p, "text-align: #{p.parent["align"]}")
176
+
177
+ style_update(p, "text-align: #{p.parent['align']}")
166
178
  end
167
179
  end
168
180
 
169
181
  def word_table_separator(docxml)
170
182
  docxml.xpath("//p[@class = 'TableTitle']").each do |t|
171
183
  next unless t.children.empty?
184
+
172
185
  t["style"] = t["style"].sub(/;?$/, ";font-size:0pt;")
173
186
  t.children = "&nbsp;"
174
187
  end
175
188
  end
176
189
 
177
- def word_annex_cleanup(docxml)
178
- end
190
+ def word_annex_cleanup(docxml); end
179
191
 
180
192
  def word_example_cleanup(docxml)
181
193
  docxml.xpath("//div[@class = 'example']//p[not(@class)]").each do |p|
@@ -194,19 +206,21 @@ xmlns:m="http://schemas.microsoft.com/office/2004/12/omml">
194
206
  docxml.xpath("//div[p/br]").each do |d|
195
207
  /^WordSection\d+_\d+$/.match(d["class"]) or next
196
208
  d.elements[0].name == "p" && !d.elements[0].elements.empty? or next
197
- d.elements[0].elements[0].name == "br" && d.elements[0].elements[0]["style"] ==
198
- "mso-special-character:line-break;page-break-before:always" 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
199
212
  d.elements[0].remove
200
213
  end
201
214
  end
202
215
 
203
216
  def word_footnote_format(docxml)
204
- # the content is in a[@epub:type = 'footnote']//sup, but in Word,
217
+ # the content is in a[@epub:type = 'footnote']//sup, but in Word,
205
218
  # we need to inject content around the autonumbered footnote reference
206
219
  docxml.xpath("//a[@epub:type = 'footnote']").each do |x|
207
220
  footnote_reference_format(x)
208
221
  end
209
- docxml.xpath("//a[@class = 'TableFootnoteRef'] | //span[@class = 'TableFootnoteRef']").each do |x|
222
+ docxml.xpath("//a[@class = 'TableFootnoteRef'] | "\
223
+ "//span[@class = 'TableFootnoteRef']").each do |x|
210
224
  table_footnote_reference_format(x)
211
225
  end
212
226
  docxml