isodoc 0.7.1 → 0.8

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 (59) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +8 -6
  3. data/README.adoc +3 -3
  4. data/lib/{isodoc → isodoc-yaml}/i18n-en.yaml +0 -0
  5. data/lib/{isodoc → isodoc-yaml}/i18n-fr.yaml +0 -0
  6. data/lib/{isodoc → isodoc-yaml}/i18n-zh-Hans.yaml +0 -0
  7. data/lib/isodoc.rb +13 -6
  8. data/lib/isodoc/class_utils.rb +24 -0
  9. data/lib/isodoc/common.rb +34 -0
  10. data/lib/isodoc/convert.rb +3 -16
  11. data/lib/isodoc/function.rb +4 -0
  12. data/lib/isodoc/{blocks.rb → function/blocks.rb} +2 -2
  13. data/lib/isodoc/{cleanup.rb → function/cleanup.rb} +4 -9
  14. data/lib/isodoc/{i18n.rb → function/i18n.rb} +13 -10
  15. data/lib/isodoc/{inline.rb → function/inline.rb} +2 -4
  16. data/lib/isodoc/{lists.rb → function/lists.rb} +5 -4
  17. data/lib/isodoc/{references.rb → function/references.rb} +4 -3
  18. data/lib/isodoc/{section.rb → function/section.rb} +4 -3
  19. data/lib/isodoc/{table.rb → function/table.rb} +3 -2
  20. data/lib/isodoc/{terms.rb → function/terms.rb} +3 -2
  21. data/lib/isodoc/{iso2wordhtml.rb → function/to_word_html.rb} +2 -3
  22. data/lib/isodoc/{utils.rb → function/utils.rb} +6 -22
  23. data/lib/isodoc/{xref_gen.rb → function/xref_gen.rb} +4 -3
  24. data/lib/isodoc/{xref_sect_gen.rb → function/xref_sect_gen.rb} +4 -3
  25. data/lib/isodoc/html_convert.rb +12 -0
  26. data/lib/isodoc/html_function.rb +4 -0
  27. data/lib/isodoc/{htmlconvert → html_function}/comments.rb +2 -3
  28. data/lib/isodoc/{htmlconvert → html_function}/footnotes.rb +3 -4
  29. data/lib/isodoc/{htmlconvert → html_function}/html.rb +5 -5
  30. data/lib/isodoc/iso/html/html_iso_titlepage.html +2 -2
  31. data/lib/isodoc/iso/{convert.rb → html_convert.rb} +1 -1
  32. data/lib/isodoc/iso/{wordconvert.rb → word_convert.rb} +0 -0
  33. data/lib/isodoc/metadata.rb +27 -12
  34. data/lib/isodoc/version.rb +1 -1
  35. data/lib/isodoc/{wordconvert/convert.rb → word_convert.rb} +9 -11
  36. data/lib/isodoc/word_function.rb +4 -0
  37. data/lib/isodoc/word_function/body.rb +149 -0
  38. data/lib/isodoc/{wordconvert → word_function}/comments.rb +2 -2
  39. data/lib/isodoc/word_function/footnotes.rb +81 -0
  40. data/lib/isodoc/word_function/postprocess.rb +116 -0
  41. data/spec/isodoc/blocks_spec.rb +17 -17
  42. data/spec/isodoc/cleanup_spec.rb +8 -8
  43. data/spec/isodoc/footnotes_spec.rb +2 -2
  44. data/spec/isodoc/i18n_spec.rb +4 -4
  45. data/spec/isodoc/inline_spec.rb +7 -7
  46. data/spec/isodoc/iso_spec.rb +5 -5
  47. data/spec/isodoc/lists_spec.rb +4 -4
  48. data/spec/isodoc/metadata_spec.rb +2 -2
  49. data/spec/isodoc/postproc_spec.rb +9 -9
  50. data/spec/isodoc/ref_spec.rb +3 -3
  51. data/spec/isodoc/section_spec.rb +6 -6
  52. data/spec/isodoc/table_spec.rb +1 -1
  53. data/spec/isodoc/terms_spec.rb +1 -1
  54. data/spec/isodoc/xref_spec.rb +11 -11
  55. metadata +35 -30
  56. data/lib/isodoc/htmlconvert/convert.rb +0 -13
  57. data/lib/isodoc/wordconvert/footnotes.rb +0 -81
  58. data/lib/isodoc/wordconvert/postprocess.rb +0 -115
  59. data/lib/isodoc/wordconvert/wordconvertmodule.rb +0 -150
@@ -1,7 +1,8 @@
1
1
  require "roman-numerals"
2
2
 
3
- module IsoDoc
4
- class Common
3
+ module IsoDoc::Function
4
+ module XrefGen
5
+
5
6
  @anchors = {}
6
7
 
7
8
  def get_anchors
@@ -103,7 +104,7 @@ module IsoDoc
103
104
  label = listlabel(depth, i + 1)
104
105
  label = "#{prev_label}.#{label}" unless prev_label.empty?
105
106
  label = "#{list_anchor[:xref]} #{label}" if refer_list
106
- li["id"] && @anchors[li["id"]] = { xref: "#{label})",
107
+ li["id"] && @anchors[li["id"]] = { xref: "#{label})",
107
108
  container: list_anchor[:container] }
108
109
  li.xpath(ns("./ol")).each do |ol|
109
110
  list_item_anchor_names(ol, list_anchor, depth + 1, label, false)
@@ -1,5 +1,6 @@
1
- module IsoDoc
2
- class Common
1
+ module IsoDoc::Function
2
+ module XrefSectGen
3
+
3
4
  def back_anchor_names(docxml)
4
5
  docxml.xpath(ns("//annex")).each_with_index do |c, i|
5
6
  annex_names(c, (65 + i).chr.to_s)
@@ -77,7 +78,7 @@ module IsoDoc
77
78
  end
78
79
 
79
80
  def annex_names(clause, num)
80
- @anchors[clause["id"]] = { label: annex_name_lbl(clause, num),
81
+ @anchors[clause["id"]] = { label: annex_name_lbl(clause, num),
81
82
  xref: "#{@annex_lbl} #{num}", level: 1 }
82
83
  clause.xpath(ns("./clause")).each_with_index do |c, i|
83
84
  annex_names1(c, "#{num}.#{i + 1}", 2)
@@ -0,0 +1,12 @@
1
+ require_relative "html_function/comments.rb"
2
+ require_relative "html_function/footnotes.rb"
3
+ require_relative "html_function/html.rb"
4
+
5
+ module IsoDoc
6
+ class HtmlConvert < ::IsoDoc::Convert
7
+
8
+ include HtmlFunction::Comments
9
+ include HtmlFunction::Footnotes
10
+ include HtmlFunction::Html
11
+ end
12
+ end
@@ -0,0 +1,4 @@
1
+ module IsoDoc
2
+ module HtmlFunction
3
+ end
4
+ end
@@ -1,7 +1,6 @@
1
- require "uuidtools"
1
+ module IsoDoc::HtmlFunction
2
+ module Comments
2
3
 
3
- module IsoDoc
4
- class Convert < Common
5
4
  def in_comment
6
5
  @in_comment
7
6
  end
@@ -1,7 +1,6 @@
1
- require "uuidtools"
1
+ module IsoDoc::HtmlFunction
2
+ module Footnotes
2
3
 
3
- module IsoDoc
4
- class Convert < Common
5
4
  def footnotes(div)
6
5
  return if @footnotes.empty?
7
6
  @footnotes.each { |fn| div.parent << fn }
@@ -69,7 +68,7 @@ module IsoDoc
69
68
  end
70
69
  make_footnote(node, fn)
71
70
  end
72
-
71
+
73
72
  def make_footnote(node, fn)
74
73
  return if @seen_footnote.include?(fn)
75
74
  @in_footnote = true
@@ -1,6 +1,6 @@
1
- module IsoDoc
2
- class Convert < Common
3
- def make_body1(body, _docxml)
1
+ module IsoDoc::HtmlFunction
2
+ module Html
3
+ def make_body1(body, _docxml)
4
4
  body.div **{ class: "title-section" } do |div1|
5
5
  div1.p { |p| p << "&nbsp;" } # placeholder
6
6
  end
@@ -78,7 +78,7 @@ module IsoDoc
78
78
  docxml
79
79
  end
80
80
 
81
- def html_head()
81
+ def html_head()
82
82
  <<~HEAD.freeze
83
83
  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
84
84
 
@@ -94,7 +94,7 @@ module IsoDoc
94
94
  HEAD
95
95
  end
96
96
 
97
- def html_button()
97
+ def html_button()
98
98
  '<button onclick="topFunction()" id="myBtn" '\
99
99
  'title="Go to top">Top</button>'.freeze
100
100
  end
@@ -6,9 +6,9 @@
6
6
  <p class="coverpage_techcommittee"><a
7
7
  name="CVP_Secretariat_Loca">Secretariat</a>: {{ secretariat }}</p>
8
8
 
9
- <div class="doctitle-en"><span class="subtitle">{{ doctitle }}</span></div>
9
+ <div class="doctitle-en"><span class="title">{{ doctitleintro }}</span> <span class="subtitle">{{ doctitlemain }}</span> <span class="part">{{ doctitlepart }}</span></div>
10
10
 
11
- <div class="doctitle-fr"><span class="subtitle">{{ docsubtitle }}</span></div>
11
+ <div class="doctitle-fr"><span class="title">{{ docsubtitleintro }}</span> <span class="subtitle">{{ docsubtitlemain }}</span> <span class="part">{{ docsubtitlepart }}</span></div>
12
12
 
13
13
  <div class="coverpage_docstage"><p>{{ stageabbr }} stage</p></div>
14
14
 
@@ -1,6 +1,6 @@
1
1
  module IsoDoc
2
2
  module Iso
3
- class Convert < IsoDoc::Convert
3
+ class HtmlConvert < IsoDoc::HtmlConvert
4
4
 
5
5
  def default_fonts(options)
6
6
  b = options[:bodyfont] ||
@@ -1,5 +1,3 @@
1
- require "htmlentities"
2
-
3
1
  module IsoDoc
4
2
  class Metadata
5
3
  DATETYPES = %w{published accessed created implemented obsoleted confirmed
@@ -10,11 +8,15 @@ module IsoDoc
10
8
  end
11
9
 
12
10
  def initialize(lang, script, labels)
13
- @metadata = { tc: "XXXX", sc: "XXXX", wg: "XXXX",
14
- editorialgroup: [],
15
- secretariat: "XXXX",
16
- obsoletes: nil,
17
- obsoletes_part: nil }
11
+ @metadata = {
12
+ tc: "XXXX",
13
+ sc: "XXXX",
14
+ wg: "XXXX",
15
+ editorialgroup: [],
16
+ secretariat: "XXXX",
17
+ obsoletes: nil,
18
+ obsoletes_part: nil
19
+ }
18
20
  DATETYPES.each { |w| @metadata["#{w}date".to_sym] = "XXX" }
19
21
  @lang = lang
20
22
  @script = script
@@ -90,7 +92,7 @@ module IsoDoc
90
92
  def iso?(org)
91
93
  name = org&.at(ns("./name"))&.text
92
94
  abbrev = org&.at(ns("./abbreviation"))&.text
93
- (abbrev == "ISO" ||
95
+ (abbrev == "ISO" ||
94
96
  name == "International Organization for Standardization" )
95
97
  end
96
98
 
@@ -163,7 +165,7 @@ module IsoDoc
163
165
  draftinfo += ", #{revdate}" if revdate
164
166
  draftinfo += ")"
165
167
  end
166
- Common::l10n(draftinfo, @lang, @script)
168
+ IsoDoc::Function::I18n::l10n(draftinfo, @lang, @script)
167
169
  end
168
170
 
169
171
  def version(isoxml, _out)
@@ -183,14 +185,20 @@ module IsoDoc
183
185
  end
184
186
  end
185
187
 
188
+ def part_title(part, partnum, subpartnum, lang)
189
+ return "" unless part
190
+ suffix = @c.encode(part.text, :hexadecimal)
191
+ partnum = "#{partnum}&ndash;#{subpartnum}" if partnum && subpartnum
192
+ suffix = "#{part_label(lang)}&nbsp;#{partnum}: " + suffix if partnum
193
+ suffix
194
+ end
195
+
186
196
  def compose_title(main, intro, part, partnum, subpartnum, lang)
187
197
  main = main.nil? ? "" : @c.encode(main.text, :hexadecimal)
188
198
  intro &&
189
199
  main = "#{@c.encode(intro.text, :hexadecimal)}&nbsp;&mdash; #{main}"
190
200
  if part
191
- suffix = @c.encode(part.text, :hexadecimal)
192
- partnum = "#{partnum}&ndash;#{subpartnum}" if partnum && subpartnum
193
- suffix = "#{part_label(lang)}&nbsp;#{partnum}: " + suffix if partnum
201
+ suffix = part_title(part, partnum, subpartnum, lang)
194
202
  main = "#{main}&nbsp;&mdash; #{suffix}"
195
203
  end
196
204
  main
@@ -202,8 +210,12 @@ module IsoDoc
202
210
  part = isoxml.at(ns("//title-part[@language='en']"))
203
211
  partnumber = isoxml.at(ns("//project-number/@part"))
204
212
  subpartnumber = isoxml.at(ns("//project-number/@subpart"))
213
+
214
+ set(:doctitlemain, @c.encode(main ? main.text : "", :hexadecimal))
205
215
  main = compose_title(main, intro, part, partnumber, subpartnumber, "en")
206
216
  set(:doctitle, main)
217
+ set(:doctitleintro, @c.encode(intro ? intro.text : "", :hexadecimal)) if intro
218
+ set(:doctitlepart, part_title(part, partnumber, subpartnumber, "en"))
207
219
  end
208
220
 
209
221
  def subtitle(isoxml, _out)
@@ -212,8 +224,11 @@ module IsoDoc
212
224
  part = isoxml.at(ns("//title-part[@language='fr']"))
213
225
  partnumber = isoxml.at(ns("//project-number/@part"))
214
226
  subpartnumber = isoxml.at(ns("//project-number/@subpart"))
227
+ set(:docsubtitlemain, @c.encode(main ? main.text : "", :hexadecimal))
215
228
  main = compose_title(main, intro, part, partnumber, subpartnumber, "fr")
216
229
  set(:docsubtitle, main)
230
+ set(:docsubtitleintro, @c.encode(intro ? intro.text : "", :hexadecimal)) if intro
231
+ set(:docsubtitlepart, part_title(part, partnumber, subpartnumber, "fr"))
217
232
  end
218
233
 
219
234
  def relations(isoxml, _out)
@@ -1,3 +1,3 @@
1
1
  module IsoDoc
2
- VERSION = "0.7.1".freeze
2
+ VERSION = "0.8".freeze
3
3
  end
@@ -1,11 +1,7 @@
1
- require "uuidtools"
2
- require "html2doc"
3
- require "liquid"
4
-
5
- require_relative "wordconvertmodule"
6
- require_relative "comments"
7
- require_relative "footnotes"
8
- require_relative "postprocess"
1
+ require_relative "word_function/comments.rb"
2
+ require_relative "word_function/footnotes.rb"
3
+ require_relative "word_function/body.rb"
4
+ require_relative "word_function/postprocess.rb"
9
5
 
10
6
  module IsoDoc
11
7
 
@@ -28,8 +24,10 @@ module IsoDoc
28
24
  end
29
25
  =end
30
26
 
31
- class WordConvert < Common
32
- #include WordConvertModule
27
+ class WordConvert < ::IsoDoc::Convert
28
+ include WordFunction::Comments
29
+ include WordFunction::Footnotes
30
+ include WordFunction::Body
31
+ include WordFunction::Postprocess
33
32
  end
34
33
  end
35
-
@@ -0,0 +1,4 @@
1
+ module IsoDoc
2
+ module WordFunction
3
+ end
4
+ end
@@ -0,0 +1,149 @@
1
+ module IsoDoc::WordFunction
2
+ module Body
3
+ def make_body1(body, _docxml)
4
+ body.div **{ class: "WordSection1" } do |div1|
5
+ div1.p { |p| p << "&nbsp;" } # placeholder
6
+ end
7
+ section_break(body)
8
+ end
9
+
10
+ def make_body2(body, docxml)
11
+ body.div **{ class: "WordSection2" } do |div2|
12
+ info docxml, div2
13
+ foreword docxml, div2
14
+ introduction docxml, div2
15
+ div2.p { |p| p << "&nbsp;" } # placeholder
16
+ end
17
+ section_break(body)
18
+ end
19
+
20
+ def make_body3(body, docxml)
21
+ body.div **{ class: "WordSection3" } do |div3|
22
+ middle docxml, div3
23
+ footnotes div3
24
+ comments div3
25
+ end
26
+ end
27
+
28
+ def insert_tab(out, n)
29
+ out.span **attr_code(style: "mso-tab-count:#{n}") do |span|
30
+ [1..n].each { span << "&#xA0; " }
31
+ end
32
+ end
33
+
34
+ def para_attrs(node)
35
+ classtype = nil
36
+ classtype = "Note" if @note
37
+ classtype = "MsoCommentText" if in_comment
38
+ classtype = "Sourcecode" if @annotation
39
+ attrs = { class: classtype, id: node["id"] }
40
+ unless node["align"].nil?
41
+ attrs[:align] = node["align"] unless node["align"] == "justify"
42
+ attrs[:style] = "text-align:#{node['align']}"
43
+ end
44
+ attrs
45
+ end
46
+
47
+ def remove_bottom_border(td)
48
+ td["style"] =
49
+ td["style"].gsub(/border-bottom:[^;]+;/, "border-bottom:0pt;").
50
+ gsub(/mso-border-bottom-alt:[^;]+;/, "mso-border-bottom-alt:0pt;")
51
+ end
52
+
53
+ SW1 = "solid windowtext".freeze
54
+
55
+ def new_fullcolspan_row(t, tfoot)
56
+ # how many columns in the table?
57
+ cols = 0
58
+ t.at(".//tr").xpath("./td | ./th").each do |td|
59
+ cols += (td["colspan"] ? td["colspan"].to_i : 1)
60
+ end
61
+ style = %{border-top:0pt;mso-border-top-alt:0pt;border-bottom:#{SW1} 1.5pt;mso-border-bottom-alt:#{SW1} 1.5pt;}
62
+ tfoot.add_child("<tr><td colspan='#{cols}' style='#{style}'/></tr>")
63
+ tfoot.xpath(".//td").last
64
+ end
65
+
66
+ def make_tr_attr(td, row, totalrows)
67
+ style = td.name == "th" ? "font-weight:bold;" : ""
68
+ rowmax = td["rowspan"] ? row + td["rowspan"].to_i - 1 : row
69
+ style += <<~STYLE
70
+ border-top:#{row.zero? ? "#{SW1} 1.5pt;" : 'none;'}
71
+ mso-border-top-alt:#{row.zero? ? "#{SW1} 1.5pt;" : 'none;'}
72
+ border-bottom:#{SW1} #{rowmax == totalrows ? '1.5' : '1.0'}pt;
73
+ mso-border-bottom-alt:#{SW1} #{rowmax == totalrows ? '1.5' : '1.0'}pt;
74
+ STYLE
75
+ { rowspan: td["rowspan"], colspan: td["colspan"],
76
+ align: td["align"], style: style.gsub(/\n/, "") }
77
+ end
78
+
79
+ def section_break(body)
80
+ body.br **{ clear: "all", class: "section" }
81
+ end
82
+
83
+ def page_break(out)
84
+ out.br **{ clear: "all",
85
+ style: "mso-special-character:line-break;page-break-before:always" }
86
+ end
87
+
88
+ WORD_DT_ATTRS = {class: @note ? "Note" : nil, align: "left",
89
+ style: "margin-left:0pt;text-align:left;"}.freeze
90
+
91
+ def dt_parse(dt, term)
92
+ term.p **attr_code(WORD_DT_ATTRS) do |p|
93
+ if dt.elements.empty?
94
+ p << dt.text
95
+ else
96
+ dt.children.each { |n| parse(n, p) }
97
+ end
98
+ end
99
+ end
100
+
101
+ def dl_parse(node, out)
102
+ out.table **{ class: "dl" } do |v|
103
+ node.elements.select { |n| dt_dd? n }.each_slice(2) do |dt, dd|
104
+ v.tr do |tr|
105
+ tr.td **{ valign: "top", align: "left" } do |term|
106
+ dt_parse(dt, term)
107
+ end
108
+ tr.td **{ valign: "top" } do |listitem|
109
+ dd.children.each { |n| parse(n, listitem) }
110
+ end
111
+ end
112
+ end
113
+ dl_parse_notes(node, v)
114
+ end
115
+ end
116
+
117
+ def dl_parse_notes(node, v)
118
+ return if node.elements.reject { |n| dt_dd? n }.empty?
119
+ v.tr do |tr|
120
+ tr.td **{ rowspan: 2 } do |td|
121
+ node.elements.reject { |n| dt_dd? n }.each { |n| parse(n, td) }
122
+ end
123
+ end
124
+ end
125
+
126
+ def figure_get_or_make_dl(t)
127
+ dl = t.at(".//table[@class = 'dl']")
128
+ if dl.nil?
129
+ t.add_child("<p><b>#{@key_lbl}</b></p><table class='dl'></table>")
130
+ dl = t.at(".//table[@class = 'dl']")
131
+ end
132
+ dl
133
+ end
134
+
135
+ def figure_aside_process(f, aside, key)
136
+ # get rid of footnote link, it is in diagram
137
+ f&.at("./a[@class='TableFootnoteRef']")&.remove
138
+ fnref = f.at(".//a[@class='TableFootnoteRef']")
139
+ tr = key.add_child("<tr></tr>").first
140
+ dt = tr.add_child("<td valign='top' align='left'></td>").first
141
+ dd = tr.add_child("<td valign='top'></td>").first
142
+ fnref.parent = dt
143
+ aside.xpath(".//p").each do |a|
144
+ a.delete("class")
145
+ a.parent = dd
146
+ end
147
+ end
148
+ end
149
+ end
@@ -1,5 +1,5 @@
1
- module IsoDoc
2
- class WordConvert < Common
1
+ module IsoDoc::WordFunction
2
+ module Comments
3
3
 
4
4
  def in_comment
5
5
  @in_comment
@@ -0,0 +1,81 @@
1
+ module IsoDoc::WordFunction
2
+ module Footnotes
3
+
4
+ def footnotes(div)
5
+ return if @footnotes.empty?
6
+ @footnotes.each { |fn| div.parent << fn }
7
+ end
8
+
9
+ def make_table_footnote_link(out, fnid, fnref)
10
+ attrs = { href: "##{fnid}", class: "TableFootnoteRef" }
11
+ out.a **attrs do |a|
12
+ a << fnref
13
+ end
14
+ end
15
+
16
+ def make_table_footnote_target(out, fnid, fnref)
17
+ attrs = { id: fnid, class: "TableFootnoteRef" }
18
+ out.a **attrs do |a|
19
+ a << fnref
20
+ insert_tab(a, 1)
21
+ end
22
+ end
23
+
24
+ def make_table_footnote_text(node, fnid, fnref)
25
+ attrs = { id: "ftn#{fnid}" }
26
+ noko do |xml|
27
+ xml.div **attr_code(attrs) do |div|
28
+ make_table_footnote_target(div, fnid, fnref)
29
+ node.children.each { |n| parse(n, div) }
30
+ end
31
+ end.join("\n")
32
+ end
33
+
34
+ def make_generic_footnote_text(node, fnid)
35
+ noko do |xml|
36
+ xml.aside **{ id: "ftn#{fnid}" } do |div|
37
+ node.children.each { |n| parse(n, div) }
38
+ end
39
+ end.join("\n")
40
+ end
41
+
42
+ def get_table_ancestor_id(node)
43
+ table = node.ancestors("table") || node.ancestors("figure")
44
+ return UUIDTools::UUID.random_create.to_s if table.empty?
45
+ table.last["id"]
46
+ end
47
+
48
+ def table_footnote_parse(node, out)
49
+ fn = node["reference"]
50
+ tid = get_table_ancestor_id(node)
51
+ make_table_footnote_link(out, tid + fn, fn)
52
+ # do not output footnote text if we have already seen it for this table
53
+ return if @seen_footnote.include?(tid + fn)
54
+ @in_footnote = true
55
+ out.aside { |a| a << make_table_footnote_text(node, tid + fn, fn) }
56
+ @in_footnote = false
57
+ @seen_footnote << (tid + fn)
58
+ end
59
+
60
+ def footnote_parse(node, out)
61
+ return table_footnote_parse(node, out) if @in_table || @in_figure
62
+ fn = node["reference"]
63
+ out.a **{ "epub:type": "footnote", href: "#ftn#{fn}" } do |a|
64
+ a.sup { |sup| sup << fn }
65
+ end
66
+ return if @seen_footnote.include?(fn)
67
+ @in_footnote = true
68
+ @footnotes << make_generic_footnote_text(node, fn)
69
+ @in_footnote = false
70
+ @seen_footnote << fn
71
+ end
72
+
73
+ def make_footnote(node, fn)
74
+ return if @seen_footnote.include?(fn)
75
+ @in_footnote = true
76
+ @footnotes << make_generic_footnote_text(node, fn)
77
+ @in_footnote = false
78
+ @seen_footnote << fn
79
+ end
80
+ end
81
+ end