isodoc 1.5.4 → 1.6.3

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 (74) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +6 -4
  3. data/Gemfile +2 -2
  4. data/Rakefile +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 +21 -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 -28
  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/bibdata.rb +13 -10
  38. data/lib/isodoc/presentation_function/block.rb +17 -8
  39. data/lib/isodoc/presentation_function/inline.rb +75 -118
  40. data/lib/isodoc/presentation_function/math.rb +84 -0
  41. data/lib/isodoc/presentation_function/section.rb +20 -22
  42. data/lib/isodoc/presentation_xml_convert.rb +2 -1
  43. data/lib/isodoc/sassc_importer.rb +1 -1
  44. data/lib/isodoc/version.rb +1 -1
  45. data/lib/isodoc/word_function/body.rb +28 -24
  46. data/lib/isodoc/word_function/footnotes.rb +22 -15
  47. data/lib/isodoc/word_function/postprocess.rb +16 -6
  48. data/lib/isodoc/xref.rb +10 -11
  49. data/lib/isodoc/xref/xref_counter.rb +32 -17
  50. data/lib/isodoc/xref/xref_gen.rb +45 -32
  51. data/lib/isodoc/xref/xref_sect_gen.rb +33 -31
  52. data/lib/isodoc/xslfo_convert.rb +36 -25
  53. data/spec/assets/html_override.css +1 -0
  54. data/spec/assets/word_override.css +1 -0
  55. data/spec/isodoc/blocks_spec.rb +2518 -2570
  56. data/spec/isodoc/cleanup_spec.rb +1107 -1109
  57. data/spec/isodoc/footnotes_spec.rb +1 -16
  58. data/spec/isodoc/form_spec.rb +156 -0
  59. data/spec/isodoc/i18n_spec.rb +984 -972
  60. data/spec/isodoc/inline_spec.rb +984 -920
  61. data/spec/isodoc/lists_spec.rb +316 -315
  62. data/spec/isodoc/postproc_spec.rb +1692 -1538
  63. data/spec/isodoc/presentation_xml_spec.rb +345 -342
  64. data/spec/isodoc/ref_spec.rb +718 -723
  65. data/spec/isodoc/section_spec.rb +910 -902
  66. data/spec/isodoc/table_spec.rb +566 -556
  67. data/spec/isodoc/terms_spec.rb +252 -256
  68. data/spec/isodoc/xref_spec.rb +3040 -2985
  69. data/spec/isodoc/xslfo_convert_spec.rb +39 -0
  70. data/spec/spec_helper.rb +30 -29
  71. metadata +80 -70
  72. data/.rubocop.ribose.yml +0 -65
  73. data/.rubocop.tb.yml +0 -650
  74. data/lib/twitter-cldr/patch.rb +0 -39
@@ -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