isodoc 1.5.3 → 1.6.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rake.yml +1 -1
  3. data/.rubocop.yml +6 -4
  4. data/Gemfile +2 -2
  5. data/bin/rspec +1 -2
  6. data/isodoc.gemspec +11 -11
  7. data/lib/isodoc-yaml/i18n-ar.yaml +152 -0
  8. data/lib/isodoc-yaml/i18n-de.yaml +149 -0
  9. data/lib/isodoc-yaml/i18n-es.yaml +151 -0
  10. data/lib/isodoc-yaml/i18n-ru.yaml +154 -0
  11. data/lib/isodoc/base_style/all.css +7 -0
  12. data/lib/isodoc/base_style/metanorma_word.css +7 -0
  13. data/lib/isodoc/base_style/metanorma_word.scss +8 -0
  14. data/lib/isodoc/base_style/reset.css +7 -0
  15. data/lib/isodoc/base_style/reset.scss +9 -0
  16. data/lib/isodoc/base_style/scripts.html +187 -0
  17. data/lib/isodoc/class_utils.rb +6 -5
  18. data/lib/isodoc/common.rb +2 -0
  19. data/lib/isodoc/convert.rb +30 -17
  20. data/lib/isodoc/css.rb +42 -28
  21. data/lib/isodoc/function/blocks.rb +25 -4
  22. data/lib/isodoc/function/blocks_example_note.rb +2 -2
  23. data/lib/isodoc/function/cleanup.rb +1 -2
  24. data/lib/isodoc/function/form.rb +51 -0
  25. data/lib/isodoc/function/inline.rb +32 -10
  26. data/lib/isodoc/function/references.rb +55 -42
  27. data/lib/isodoc/function/table.rb +1 -0
  28. data/lib/isodoc/function/to_word_html.rb +29 -27
  29. data/lib/isodoc/function/utils.rb +41 -38
  30. data/lib/isodoc/gem_tasks.rb +30 -31
  31. data/lib/isodoc/html_convert.rb +6 -4
  32. data/lib/isodoc/html_function/form.rb +62 -0
  33. data/lib/isodoc/html_function/postprocess.rb +35 -76
  34. data/lib/isodoc/html_function/postprocess_footnotes.rb +59 -0
  35. data/lib/isodoc/i18n.rb +33 -31
  36. data/lib/isodoc/pdf_convert.rb +1 -3
  37. data/lib/isodoc/presentation_function/block.rb +26 -11
  38. data/lib/isodoc/presentation_function/inline.rb +60 -111
  39. data/lib/isodoc/presentation_function/math.rb +84 -0
  40. data/lib/isodoc/presentation_xml_convert.rb +2 -1
  41. data/lib/isodoc/version.rb +1 -1
  42. data/lib/isodoc/word_function/body.rb +28 -24
  43. data/lib/isodoc/word_function/footnotes.rb +22 -15
  44. data/lib/isodoc/word_function/inline.rb +6 -0
  45. data/lib/isodoc/word_function/postprocess.rb +16 -6
  46. data/lib/isodoc/xref.rb +10 -11
  47. data/lib/isodoc/xref/xref_counter.rb +31 -15
  48. data/lib/isodoc/xref/xref_gen.rb +28 -22
  49. data/lib/isodoc/xref/xref_sect_gen.rb +22 -20
  50. data/lib/isodoc/xslfo_convert.rb +36 -25
  51. data/spec/assets/html_override.css +1 -0
  52. data/spec/assets/word_override.css +1 -0
  53. data/spec/isodoc/blocks_spec.rb +2599 -2503
  54. data/spec/isodoc/cleanup_spec.rb +1107 -1109
  55. data/spec/isodoc/footnotes_spec.rb +1 -16
  56. data/spec/isodoc/form_spec.rb +156 -0
  57. data/spec/isodoc/i18n_spec.rb +984 -972
  58. data/spec/isodoc/inline_spec.rb +984 -920
  59. data/spec/isodoc/lists_spec.rb +316 -315
  60. data/spec/isodoc/postproc_spec.rb +1692 -1538
  61. data/spec/isodoc/presentation_xml_spec.rb +345 -338
  62. data/spec/isodoc/ref_spec.rb +718 -723
  63. data/spec/isodoc/section_spec.rb +910 -902
  64. data/spec/isodoc/table_spec.rb +566 -556
  65. data/spec/isodoc/terms_spec.rb +252 -256
  66. data/spec/isodoc/xref_spec.rb +3040 -2985
  67. data/spec/isodoc/xslfo_convert_spec.rb +39 -0
  68. data/spec/spec_helper.rb +30 -29
  69. metadata +80 -69
  70. data/.rubocop.ribose.yml +0 -65
  71. data/.rubocop.tb.yml +0 -650
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'sassc'
4
- require 'isodoc/sassc_importer'
5
- require 'rake/clean'
3
+ require "sassc"
4
+ require "isodoc/sassc_importer"
5
+ require "rake/clean"
6
6
 
7
7
  module IsoDoc
8
8
  module GemTasks
@@ -11,7 +11,7 @@ module IsoDoc
11
11
  module_function
12
12
 
13
13
  def install
14
- rule '.css' => [proc { |tn| tn.sub(/\.css$/, '.scss') }] do |current_task|
14
+ rule ".css" => [proc { |tn| tn.sub(/\.css$/, ".scss") }] do |current_task|
15
15
  begin
16
16
  puts(current_task)
17
17
  compile_scss_task(current_task)
@@ -20,23 +20,23 @@ module IsoDoc
20
20
  end
21
21
  end
22
22
 
23
- scss_files = Rake::FileList['lib/**/*.scss']
24
- source_files = scss_files.ext('.css')
23
+ scss_files = Rake::FileList["lib/**/*.scss"]
24
+ source_files = scss_files.ext(".css")
25
25
 
26
26
  task :comment_out_liquid do
27
27
  process_css_files(scss_files) do |file_name|
28
- comment_out_liquid(File.read(file_name, encoding: 'UTF-8'))
28
+ comment_out_liquid(File.read(file_name, encoding: "UTF-8"))
29
29
  end
30
30
  end
31
31
 
32
32
  task build_scss: [:comment_out_liquid].push(*source_files) do
33
33
  process_css_files(scss_files) do |file_name|
34
- uncomment_out_liquid(File.read(file_name, encoding: 'UTF-8'))
34
+ uncomment_out_liquid(File.read(file_name, encoding: "UTF-8"))
35
35
  end
36
- git_cache_compiled_files && puts('Built scss!')
36
+ git_cache_compiled_files && puts("Built scss!")
37
37
  end
38
38
 
39
- Rake::Task['build'].enhance [:build_scss] do
39
+ Rake::Task["build"].enhance [:build_scss] do
40
40
  git_rm_compiled_files
41
41
  Rake::Task[:clean].invoke
42
42
  end
@@ -44,7 +44,7 @@ module IsoDoc
44
44
 
45
45
  def notify_borken_compilation(error, current_task)
46
46
  puts("Cannot compile #{current_task} because of #{error.message}")
47
- puts('continue anyway[y|n]?')
47
+ puts("continue anyway[y|n]?")
48
48
  answer = STDIN.gets.strip
49
49
  if %w[y yes].include?(answer.strip.downcase)
50
50
  puts("Cannot compile #{current_task} because of #{error.message}")
@@ -68,7 +68,7 @@ module IsoDoc
68
68
  def process_css_files(scss_files)
69
69
  scss_files.each do |file_name|
70
70
  result = yield(file_name)
71
- File.open(file_name, 'w', encoding: 'UTF-8') do |file|
71
+ File.open(file_name, "w", encoding: "UTF-8") do |file|
72
72
  file.puts(result)
73
73
  end
74
74
  end
@@ -81,42 +81,41 @@ module IsoDoc
81
81
  else
82
82
  line
83
83
  end
84
- end
85
- .join("\n")
84
+ end.join("\n")
86
85
  end
87
86
 
88
87
  def uncomment_out_liquid(text)
89
88
  text
90
- .gsub('/* LIQUID_COMMENT', '')
91
- .gsub('LIQUID_COMMENT */', '')
92
- .gsub('"{{', '{{').gsub('}}"', '}}')
89
+ .gsub("/* LIQUID_COMMENT", "")
90
+ .gsub("LIQUID_COMMENT */", "")
91
+ .gsub('"{{', '{{').gsub('}}"', "}}")
93
92
  end
94
93
 
95
94
  def fonts_placeholder
96
95
  <<~TEXT
97
- $bodyfont: '{{bodyfont}}';
98
- $headerfont: '{{headerfont}}';
99
- $monospacefont: '{{monospacefont}}';
100
- $normalfontsize: '{{normalfontsize}}';
101
- $smallerfontsize: '{{smallerfontsize}}';
102
- $footnotefontsize: '{{footnotefontsize}}';
103
- $monospacefontsize: '{{monospacefontsize}}';
96
+ $bodyfont: "{{bodyfont}}";
97
+ $headerfont: "{{headerfont}}";
98
+ $monospacefont: "{{monospacefont}}";
99
+ $normalfontsize: "{{normalfontsize}}";
100
+ $smallerfontsize: "{{smallerfontsize}}";
101
+ $footnotefontsize: "{{footnotefontsize}}";
102
+ $monospacefontsize: "{{monospacefontsize}}";
104
103
  TEXT
105
104
  end
106
105
 
107
106
  def compile_scss(filename)
108
- require 'sassc'
107
+ require "sassc"
109
108
 
110
- isodoc_path = if Gem.loaded_specs['isodoc']
111
- File.join(Gem.loaded_specs['isodoc'].full_gem_path, 'lib', 'isodoc')
109
+ isodoc_path = if Gem.loaded_specs["isodoc"]
110
+ File.join(Gem.loaded_specs["isodoc"].full_gem_path, "lib", "isodoc")
112
111
  else
113
- File.join('lib', 'isodoc')
112
+ File.join("lib", "isodoc")
114
113
  end
115
114
  [isodoc_path,
116
115
  File.dirname(filename)].each do |name|
117
116
  SassC.load_paths << name
118
117
  end
119
- sheet_content = File.read(filename, encoding: 'UTF-8')
118
+ sheet_content = File.read(filename, encoding: "UTF-8")
120
119
  SassC::Engine.new(fonts_placeholder + sheet_content,
121
120
  syntax: :scss,
122
121
  importer: SasscImporter)
@@ -125,10 +124,10 @@ module IsoDoc
125
124
 
126
125
  def compile_scss_task(current_task)
127
126
  filename = current_task.source
128
- basename = File.basename(filename, '.*')
127
+ basename = File.basename(filename, ".*")
129
128
  compiled_path = File.join(File.dirname(filename), "#{basename}.css")
130
129
  content = uncomment_out_liquid(compile_scss(filename))
131
- File.open(compiled_path, 'w:UTF-8') do |f|
130
+ File.open(compiled_path, "w:UTF-8") do |f|
132
131
  f.write(content)
133
132
  end
134
133
  CLEAN << compiled_path
@@ -1,13 +1,15 @@
1
- require_relative "html_function/comments.rb"
2
- require_relative "html_function/footnotes.rb"
3
- require_relative "html_function/html.rb"
4
- require_relative "html_function/postprocess.rb"
1
+ require_relative "html_function/comments"
2
+ require_relative "html_function/footnotes"
3
+ require_relative "html_function/html"
4
+ require_relative "html_function/form"
5
+ require_relative "html_function/postprocess"
5
6
 
6
7
  module IsoDoc
7
8
  class HtmlConvert < ::IsoDoc::Convert
8
9
 
9
10
  include HtmlFunction::Comments
10
11
  include HtmlFunction::Footnotes
12
+ include HtmlFunction::Form
11
13
  include HtmlFunction::Html
12
14
 
13
15
  def tmpimagedir_suffix
@@ -0,0 +1,62 @@
1
+ module IsoDoc::HtmlFunction
2
+ module Form
3
+ def form_parse(node, out)
4
+ out.form **attr_code(id: node["id"], name: node["name"],
5
+ action: node["action"]) do |div|
6
+ node.children.each do |n|
7
+ parse(n, div)
8
+ end
9
+ end
10
+ end
11
+
12
+ def input_parse(node, out)
13
+ out.input nil, **attr_code(
14
+ id: node["id"], name: node["name"], type: node["type"],
15
+ value: node["value"], disabled: node["disabled"],
16
+ readonly: node["readonly"], checked: node["checked"],
17
+ maxlength: node["maxlength"], minlength: node["minlength"]
18
+ )
19
+ end
20
+
21
+ def select_parse(node, out)
22
+ selected = node.at(ns("./option[@value = '#{node['value']}']"))
23
+ selected and selected["selected"] = true
24
+ out.select **attr_code(
25
+ id: node["id"], name: node["name"], size: node["size"],
26
+ disabled: node["disabled"], multiple: node["multiple"]
27
+ ) do |div|
28
+ node.children.each do |n|
29
+ parse(n, div)
30
+ end
31
+ end
32
+ end
33
+
34
+ def label_parse(node, out)
35
+ out.label **attr_code(for: node["for"]) do |div|
36
+ node.children.each do |n|
37
+ parse(n, div)
38
+ end
39
+ end
40
+ end
41
+
42
+ def option_parse(node, out)
43
+ out.option **attr_code(
44
+ disabled: node["disabled"], selected: node["selected"],
45
+ value: node["value"]
46
+ ) do |o|
47
+ node.children.each do |n|
48
+ parse(n, o)
49
+ end
50
+ end
51
+ end
52
+
53
+ def textarea_parse(node, out)
54
+ out.textarea **attr_code(
55
+ id: node["id"], name: node["name"], rows: node["rows"],
56
+ cols: node["cols"]
57
+ ) do |div|
58
+ node["value"] and div << node["value"]
59
+ end
60
+ end
61
+ end
62
+ end
@@ -1,4 +1,5 @@
1
1
  require "isodoc/html_function/mathvariant_to_plain"
2
+ require_relative "postprocess_footnotes"
2
3
 
3
4
  module IsoDoc::HtmlFunction
4
5
  module Html
@@ -44,20 +45,25 @@ module IsoDoc::HtmlFunction
44
45
  IsoDoc::HtmlFunction::MathvariantToPlain.new(docxml).convert
45
46
  end
46
47
 
47
- def htmlstylesheet
48
- @htmlstylesheet.open
49
- stylesheet = @htmlstylesheet.read
48
+ def htmlstylesheet(file)
49
+ return if file.nil?
50
+
51
+ file.open if file.is_a?(Tempfile)
52
+ stylesheet = file.read
50
53
  xml = Nokogiri::XML("<style/>")
51
54
  xml.children.first << Nokogiri::XML::Comment.new(xml, "\n#{stylesheet}\n")
52
- @htmlstylesheet.close!
55
+ file.close
56
+ file.unlink if file.is_a?(Tempfile)
53
57
  xml.root.to_s
54
58
  end
55
59
 
56
60
  def htmlstyle(docxml)
57
61
  return docxml unless @htmlstylesheet
62
+
58
63
  title = docxml.at("//*[local-name() = 'head']/*[local-name() = 'title']")
59
64
  head = docxml.at("//*[local-name() = 'head']")
60
- head << htmlstylesheet
65
+ head << htmlstylesheet(@htmlstylesheet)
66
+ s = htmlstylesheet(@htmlstylesheet_override) and head << s
61
67
  docxml
62
68
  end
63
69
 
@@ -74,7 +80,7 @@ module IsoDoc::HtmlFunction
74
80
  def authority_cleanup1(docxml, klass)
75
81
  dest = docxml.at("//div[@id = 'boilerplate-#{klass}-destination']")
76
82
  auth = docxml.at("//div[@id = 'boilerplate-#{klass}' or @class = 'boilerplate-#{klass}']")
77
- auth&.xpath(".//h1[not(text())] | .//h2[not(text())]")&.each { |h| h.remove }
83
+ auth&.xpath(".//h1[not(text())] | .//h2[not(text())]")&.each(&:remove)
78
84
  auth&.xpath(".//h1 | .//h2")&.each { |h| h["class"] = "IntroTitle" }
79
85
  dest and auth and dest.replace(auth.remove)
80
86
  end
@@ -89,14 +95,18 @@ module IsoDoc::HtmlFunction
89
95
  doc = to_xhtml_fragment(File.read(@htmlcoverpage, encoding: "UTF-8"))
90
96
  d = docxml.at('//div[@class="title-section"]')
91
97
  # d.children.first.add_previous_sibling doc.to_xml(encoding: "US-ASCII")
92
- d.children.first.add_previous_sibling populate_template(doc.to_xml(encoding: "US-ASCII"), :html)
98
+ d.children.first.add_previous_sibling(
99
+ populate_template(doc.to_xml(encoding: "US-ASCII"), :html)
100
+ )
93
101
  end
94
102
 
95
103
  def html_intro(docxml)
96
104
  doc = to_xhtml_fragment(File.read(@htmlintropage, encoding: "UTF-8"))
97
105
  d = docxml.at('//div[@class="prefatory-section"]')
98
106
  # d.children.first.add_previous_sibling doc.to_xml(encoding: "US-ASCII")
99
- d.children.first.add_previous_sibling populate_template(doc.to_xml(encoding: "US-ASCII"), :html)
107
+ d.children.first.add_previous_sibling(
108
+ populate_template(doc.to_xml(encoding: "US-ASCII"), :html)
109
+ )
100
110
  end
101
111
 
102
112
  def html_toc_entry(level, header)
@@ -109,7 +119,9 @@ module IsoDoc::HtmlFunction
109
119
  end
110
120
 
111
121
  def toclevel
112
- ret = toclevel_classes.map { |l| "#{l}:not(:empty):not(.TermNum):not(.noTOC)" }
122
+ ret = toclevel_classes.map do |l|
123
+ "#{l}:not(:empty):not(.TermNum):not(.noTOC)"
124
+ end
113
125
  <<~HEAD.freeze
114
126
  function toclevel() { return "#{ret.join(',')}";}
115
127
  HEAD
@@ -138,100 +150,47 @@ module IsoDoc::HtmlFunction
138
150
  i["width"], i["height"] = Html2Doc.image_resize(i, image_localfile(i),
139
151
  @maxheight, @maxwidth)
140
152
  next if /^data:/.match i["src"]
153
+
141
154
  @datauriimage ? datauri(i) : move_image1(i)
142
155
  end
143
156
  docxml
144
157
  end
145
158
 
146
- def datauri(i)
147
- type = i["src"].split(".")[-1]
159
+ def datauri(img)
160
+ type = img["src"].split(".")[-1]
148
161
  supertype = type == "xml" ? "application" : "image"
149
- bin = IO.binread(image_localfile(i))
162
+ bin = IO.binread(image_localfile(img))
150
163
  data = Base64.strict_encode64(bin)
151
- i["src"] = "data:#{supertype}/#{type};base64,#{data}"
164
+ img["src"] = "data:#{supertype}/#{type};base64,#{data}"
152
165
  end
153
166
 
154
- def image_suffix(i)
155
- type = i["mimetype"]&.sub(%r{^[^/*]+/}, "")
156
- matched = /\.(?<suffix>[^. \r\n\t]+)$/.match i["src"]
167
+ def image_suffix(img)
168
+ type = img["mimetype"]&.sub(%r{^[^/*]+/}, "")
169
+ matched = /\.(?<suffix>[^. \r\n\t]+)$/.match img["src"]
157
170
  type and !type.empty? and return type
171
+
158
172
  !matched.nil? and matched[:suffix] and return matched[:suffix]
159
173
  "png"
160
174
  end
161
175
 
162
- def move_image1(i)
163
- suffix = image_suffix(i)
176
+ def move_image1(img)
177
+ suffix = image_suffix(img)
164
178
  uuid = UUIDTools::UUID.random_create.to_s
165
179
  fname = "#{uuid}.#{suffix}"
166
180
  new_full_filename = File.join(tmpimagedir, fname)
167
- local_filename = image_localfile(i)
181
+ local_filename = image_localfile(img)
168
182
  FileUtils.cp local_filename, new_full_filename
169
- i["src"] = File.join(rel_tmpimagedir, fname)
183
+ img["src"] = File.join(rel_tmpimagedir, fname)
170
184
  end
171
185
 
172
186
  def inject_script(doc)
173
187
  return doc unless @scripts
188
+
174
189
  scripts = File.read(@scripts, encoding: "UTF-8")
175
190
  a = doc.split(%r{</body>})
176
191
  a[0] + scripts + "</body>" + a[1]
177
192
  end
178
193
 
179
- def update_footnote_filter(fn, x, i, seen)
180
- if seen[fn.text]
181
- x.at("./sup").content = seen[fn.text][:num].to_s
182
- fn.remove unless x["href"] == seen[fn.text][:href]
183
- x["href"] = seen[fn.text][:href]
184
- else
185
- seen[fn.text] = { num: i, href: x["href"] }
186
- x.at("./sup").content = i.to_s
187
- i += 1
188
- end
189
- [i, seen]
190
- end
191
-
192
- def html_footnote_filter(docxml)
193
- seen = {}
194
- i = 1
195
- docxml.xpath('//a[@class = "FootnoteRef"]').each do |x|
196
- fn = docxml.at(%<//*[@id = '#{x['href'].sub(/^#/, '')}']>) || next
197
- i, seen = update_footnote_filter(fn, x, i, seen)
198
- end
199
- docxml
200
- end
201
-
202
- def footnote_backlinks1(x, fn)
203
- xdup = x.dup
204
- xdup.remove["id"]
205
- if fn.elements.empty?
206
- fn.children.first.previous = xdup
207
- else
208
- fn.elements.first.children.first.previous = xdup
209
- end
210
- end
211
-
212
- def footnote_backlinks(docxml)
213
- seen = {}
214
- docxml.xpath('//a[@class = "FootnoteRef"]').each_with_index do |x, i|
215
- seen[x["href"]] and next or seen[x["href"]] = true
216
- fn = docxml.at(%<//*[@id = '#{x['href'].sub(/^#/, '')}']>) || next
217
- footnote_backlinks1(x, fn)
218
- x["id"] ||= "fnref:#{i + 1}"
219
- fn.add_child "<a href='##{x['id']}'>&#x21A9;</a>"
220
- end
221
- docxml
222
- end
223
-
224
- def footnote_format(docxml)
225
- docxml.xpath("//a[@class = 'FootnoteRef']/sup").each do |x|
226
- footnote_reference_format(x)
227
- end
228
- docxml.xpath("//a[@class = 'TableFootnoteRef'] | "\
229
- "//span[@class = 'TableFootnoteRef']").each do |x|
230
- table_footnote_reference_format(x)
231
- end
232
- docxml
233
- end
234
-
235
194
  def sourcecode_highlighter
236
195
  '<script src="https://cdn.rawgit.com/google/code-prettify/master/'\
237
196
  'loader/run_prettify.js"></script>'
@@ -0,0 +1,59 @@
1
+ module IsoDoc::HtmlFunction
2
+ module Html
3
+ def update_footnote_filter(fn, x, i, seen)
4
+ if seen[fn.text]
5
+ x.at("./sup").content = seen[fn.text][:num].to_s
6
+ fn.remove unless x["href"] == seen[fn.text][:href]
7
+ x["href"] = seen[fn.text][:href]
8
+ else
9
+ seen[fn.text] = { num: i, href: x["href"] }
10
+ x.at("./sup").content = i.to_s
11
+ i += 1
12
+ end
13
+ [i, seen]
14
+ end
15
+
16
+ def html_footnote_filter(docxml)
17
+ seen = {}
18
+ i = 1
19
+ docxml.xpath('//a[@class = "FootnoteRef"]').each do |x|
20
+ fn = docxml.at(%<//*[@id = '#{x['href'].sub(/^#/, '')}']>) || next
21
+ i, seen = update_footnote_filter(fn, x, i, seen)
22
+ end
23
+ docxml
24
+ end
25
+
26
+ def footnote_backlinks1(x, fn)
27
+ xdup = x.dup
28
+ xdup.remove["id"]
29
+ if fn.elements.empty?
30
+ fn.children.first.previous = xdup
31
+ else
32
+ fn.elements.first.children.first.previous = xdup
33
+ end
34
+ end
35
+
36
+ def footnote_backlinks(docxml)
37
+ seen = {}
38
+ docxml.xpath('//a[@class = "FootnoteRef"]').each_with_index do |x, i|
39
+ seen[x["href"]] and next or seen[x["href"]] = true
40
+ fn = docxml.at(%<//*[@id = '#{x['href'].sub(/^#/, '')}']>) || next
41
+ footnote_backlinks1(x, fn)
42
+ x["id"] ||= "fnref:#{i + 1}"
43
+ fn.add_child "<a href='##{x['id']}'>&#x21A9;</a>"
44
+ end
45
+ docxml
46
+ end
47
+
48
+ def footnote_format(docxml)
49
+ docxml.xpath("//a[@class = 'FootnoteRef']/sup").each do |x|
50
+ footnote_reference_format(x)
51
+ end
52
+ docxml.xpath("//a[@class = 'TableFootnoteRef'] | "\
53
+ "//span[@class = 'TableFootnoteRef']").each do |x|
54
+ table_footnote_reference_format(x)
55
+ end
56
+ docxml
57
+ end
58
+ end
59
+ end