isodoc 1.0.15 → 1.0.16

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6a664c3da9b6df6b4e533371a17c3a407423cafaeb043eacc92a14ff0282113b
4
- data.tar.gz: a01075ddc20896c5347367c296379a2ade09177804f37631b386ea92046fd740
3
+ metadata.gz: 9b8b0f152601a2bbeb84c54de21063c1c8a3153b80a8d7c9e7e72af587afadf2
4
+ data.tar.gz: 8e3f19d7bc9d426db9bd2bd49ebd4005bc24ba03ce9add831341780cf2f24b7d
5
5
  SHA512:
6
- metadata.gz: 901a72db1d909f98dc6e2813ddb5d6ad7eec9feb870f0545d473fd5fc58e9c3e0d065f99c82dac964d06398af988c68b5c0743b19e51bf339ca085bcb7574125
7
- data.tar.gz: fb8143ee5d1f5fb2a49c40f1218eeaa0e36a6c9fb9ba0c1abda1ca10154f0816aa0ac76072a2bd58e539c255d6dc85ca28888385a7407992a6502a988a511d03
6
+ metadata.gz: fac36a308df3caa41ed65253c0248f74d6bd21cd1341f7996ef30195ac8cadbd2679ac6806c82dbabe9b2f355c39e42c2687d0569c35de8a29e3f16d8f077755
7
+ data.tar.gz: ad99d78fcce5692491b593e3d415f1520120e32a2440d350504040a779dc2bd9b636a316d6e27851c72fb5ec314dab4ad4c41abf06e87b773102ee950a681c3a
@@ -133,10 +133,6 @@ module IsoDoc
133
133
  "lib", "isodoc")
134
134
  SassC.load_paths << File.dirname(filename)
135
135
  engine = SassC::Engine.new(fontheader + stylesheet, syntax: :scss)
136
- #outname = File.basename(filename, ".*") + ".css"
137
- #File.open(outname, "w:UTF-8") { |f| f.write(engine.render) }
138
- #@files_to_delete << outname
139
- #outname
140
136
  Tempfile.open([File.basename(filename, ".*"), "css"],
141
137
  :encoding => "utf-8") do |f|
142
138
  f.write(engine.render)
@@ -1,5 +1,13 @@
1
1
  module IsoDoc::Function
2
2
  module Cleanup
3
+ def textcleanup(docxml)
4
+ docxml.
5
+ gsub(/\[TERMREF\]\s*/, l10n("[#{@source_lbl}: ")).
6
+ gsub(/\s*\[MODIFICATION\]\s*\[\/TERMREF\]/, l10n(", #{@modified_lbl} [/TERMREF]")).
7
+ gsub(/\s*\[\/TERMREF\]\s*/, l10n("]")).
8
+ gsub(/\s*\[MODIFICATION\]/, l10n(", #{@modified_lbl} &mdash; "))
9
+ end
10
+
3
11
  def cleanup(docxml)
4
12
  comment_cleanup(docxml)
5
13
  footnote_cleanup(docxml)
@@ -8,6 +8,10 @@ module IsoDoc::Function
8
8
  out.br
9
9
  end
10
10
 
11
+ def pagebreak_parse(_node, out)
12
+ out.br
13
+ end
14
+
11
15
  def hr_parse(node, out)
12
16
  out.hr
13
17
  end
@@ -25,7 +25,7 @@ module IsoDoc::Function
25
25
  if node["inline-header"] == "true"
26
26
  inline_header_title(out, node, c1)
27
27
  else
28
- div.send "h#{anchor(node['id'], :level) || '1'}" do |h|
28
+ div.send "h#{anchor(node['id'], :level, false) || '1'}" do |h|
29
29
  lbl = anchor(node['id'], :label, false)
30
30
  h << "#{lbl}#{clausedelim}" if lbl && !@suppressheadingnumbers
31
31
  clausedelimspace(out) if lbl && !@suppressheadingnumbers
@@ -43,7 +43,6 @@ module IsoDoc::Function
43
43
  def define_head(head, filename, _dir)
44
44
  if @standardstylesheet
45
45
  head.style do |style|
46
- #stylesheet = File.read(@standardstylesheet, encoding: "utf-8").
47
46
  @standardstylesheet.open
48
47
  stylesheet = @standardstylesheet.read.
49
48
  gsub("FILENAME", File.basename(filename))
@@ -150,7 +149,7 @@ module IsoDoc::Function
150
149
  when "br" then br_parse(node, out)
151
150
  when "hr" then hr_parse(node, out)
152
151
  when "bookmark" then bookmark_parse(node, out)
153
- when "pagebreak" then page_break(out)
152
+ when "pagebreak" then pagebreak_parse(node, out)
154
153
  when "callout" then callout_parse(node, out)
155
154
  when "stem" then stem_parse(node, out)
156
155
  when "clause" then clause_parse(node, out)
@@ -140,11 +140,6 @@ module IsoDoc::Function
140
140
 
141
141
  def populate_template(docxml, _format)
142
142
  meta = @meta.get.merge(@labels || {})
143
- docxml = docxml.
144
- gsub(/\[TERMREF\]\s*/, l10n("[#{@source_lbl}: ")).
145
- gsub(/\s*\[MODIFICATION\]\s*\[\/TERMREF\]/, l10n(", #{@modified_lbl} [/TERMREF]")).
146
- gsub(/\s*\[\/TERMREF\]\s*/, l10n("]")).
147
- gsub(/\s*\[MODIFICATION\]/, l10n(", #{@modified_lbl} &mdash; "))
148
143
  template = liquid(docxml)
149
144
  template.render(meta.map { |k, v| [k.to_s, empty2nil(v)] }.to_h).
150
145
  gsub('&lt;', '&#x3c;').gsub('&gt;', '&#x3e;').gsub('&amp;', '&#x26;')
@@ -152,12 +147,6 @@ module IsoDoc::Function
152
147
 
153
148
  def save_dataimage(uri, relative_dir = true)
154
149
  %r{^data:image/(?<imgtype>[^;]+);base64,(?<imgdata>.+)$} =~ uri
155
- #uuid = UUIDTools::UUID.random_create.to_s
156
- #fname = "#{uuid}.#{imgtype}"
157
- #new_file = File.join(tmpimagedir, fname)
158
- #@files_to_delete << new_file
159
- #File.open(new_file, "wb") { |f| f.write(Base64.strict_decode64(imgdata)) }
160
- #File.join(relative_dir ? rel_tmpimagedir : tmpimagedir, fname)
161
150
  imgtype = "png" unless /^[a-z0-9]+$/.match imgtype
162
151
  Tempfile.open(["image", ".#{imgtype}"]) do |f|
163
152
  f.binmode
@@ -36,12 +36,14 @@ module IsoDoc::Function
36
36
  ret
37
37
  end
38
38
 
39
+ SUBCLAUSES = "./clause | ./references | ./term | ./terms | ./definitions".freeze
40
+
39
41
  # in StanDoc, prefaces have no numbering; they are referenced only by title
40
42
  def preface_names(clause)
41
43
  return if clause.nil?
42
44
  @anchors[clause["id"]] =
43
45
  { label: nil, level: 1, xref: preface_clause_name(clause), type: "clause" }
44
- clause.xpath(ns("./clause | ./terms | ./term | ./definitions | ./references")).each_with_index do |c, i|
46
+ clause.xpath(ns(SUBCLAUSES)).each_with_index do |c, i|
45
47
  preface_names1(c, c.at(ns("./title"))&.text, "#{preface_clause_name(clause)}, #{i+1}", 2)
46
48
  end
47
49
  end
@@ -50,7 +52,7 @@ module IsoDoc::Function
50
52
  label = title || parent_title
51
53
  @anchors[clause["id"]] =
52
54
  { label: nil, level: level, xref: label, type: "clause" }
53
- clause.xpath(ns("./clause | ./terms | ./term | ./definitions | ./references")).
55
+ clause.xpath(ns(SUBCLAUSES)).
54
56
  each_with_index do |c, i|
55
57
  preface_names1(c, c.at(ns("./title"))&.text, "#{label} #{i+1}", level + 1)
56
58
  end
@@ -77,7 +79,7 @@ module IsoDoc::Function
77
79
  num = num + 1
78
80
  @anchors[clause["id"]] =
79
81
  { label: num.to_s, xref: l10n("#{@clause_lbl} #{num}"), level: lvl, type: "clause" }
80
- clause.xpath(ns("./clause | ./term | ./terms | ./definitions | ./references")).
82
+ clause.xpath(ns(SUBCLAUSES)).
81
83
  each_with_index do |c, i|
82
84
  section_names1(c, "#{num}.#{i + 1}", lvl + 1)
83
85
  end
@@ -87,7 +89,7 @@ module IsoDoc::Function
87
89
  def section_names1(clause, num, level)
88
90
  @anchors[clause["id"]] =
89
91
  { label: num, level: level, xref: l10n("#{@clause_lbl} #{num}"), type: "clause" }
90
- clause.xpath(ns("./clause | ./terms | ./term | ./definitions | ./references")).
92
+ clause.xpath(ns(SUBCLAUSES)).
91
93
  each_with_index do |c, i|
92
94
  section_names1(c, "#{num}.#{i + 1}", level + 1)
93
95
  end
@@ -102,7 +104,7 @@ module IsoDoc::Function
102
104
  def annex_names(clause, num)
103
105
  @anchors[clause["id"]] = { label: annex_name_lbl(clause, num), type: "clause",
104
106
  xref: "#{@annex_lbl} #{num}", level: 1 }
105
- clause.xpath(ns("./clause | ./references | ./term | ./terms | ./definitions")).each_with_index do |c, i|
107
+ clause.xpath(ns(SUBCLAUSES)).each_with_index do |c, i|
106
108
  annex_names1(c, "#{num}.#{i + 1}", 2)
107
109
  end
108
110
  hierarchical_asset_names(clause, num)
@@ -111,7 +113,7 @@ module IsoDoc::Function
111
113
  def annex_names1(clause, num, level)
112
114
  @anchors[clause["id"]] = { label: num, xref: "#{@annex_lbl} #{num}",
113
115
  level: level, type: "clause" }
114
- clause.xpath(ns("./clause | ./references | ./term | ./terms | ./definitions")).each_with_index do |c, i|
116
+ clause.xpath(ns(SUBCLAUSES)).each_with_index do |c, i|
115
117
  annex_names1(c, "#{num}.#{i + 1}", level + 1)
116
118
  end
117
119
  end
@@ -38,7 +38,7 @@ module IsoDoc::HtmlFunction
38
38
 
39
39
  def html_head()
40
40
  <<~HEAD.freeze
41
- <title>{{ doctitle }}</title>
41
+ <title>#{@meta&.get&.dig(:doctitle)}</title>
42
42
  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
43
43
 
44
44
  <!--TOC script import-->
@@ -1,7 +1,7 @@
1
1
  module IsoDoc::HtmlFunction
2
2
  module Html
3
3
  def postprocess(result, filename, dir)
4
- result = from_xhtml(cleanup(to_xhtml(result)))
4
+ result = from_xhtml(cleanup(to_xhtml(textcleanup(result))))
5
5
  toHTML(result, filename)
6
6
  @files_to_delete.each { |f| FileUtils.rm_rf f }
7
7
  end
@@ -15,7 +15,7 @@ module IsoDoc::HtmlFunction
15
15
 
16
16
  def toHTML(result, filename)
17
17
  result = (from_xhtml(html_cleanup(to_xhtml(result))))
18
- result = populate_template(result, :html)
18
+ #result = populate_template(result, :html)
19
19
  result = from_xhtml(move_images(to_xhtml(result)))
20
20
  result = html5(script_cdata(inject_script(result)))
21
21
  File.open("#{filename}.html", "w:UTF-8") { |f| f.write(result) }
@@ -62,6 +62,7 @@ module IsoDoc::HtmlFunction
62
62
  def authority_cleanup1(docxml, klass)
63
63
  dest = docxml.at("//div[@id = 'boilerplate-#{klass}-destination']")
64
64
  auth = docxml.at("//div[@id = 'boilerplate-#{klass}' or @class = 'boilerplate-#{klass}']")
65
+ auth&.xpath(".//h1[not(text())] | .//h2[not(text())]")&.each { |h| h.remove }
65
66
  auth&.xpath(".//h1 | .//h2")&.each { |h| h["class"] = "IntroTitle" }
66
67
  dest and auth and dest.replace(auth.remove)
67
68
  end
@@ -75,26 +76,15 @@ module IsoDoc::HtmlFunction
75
76
  def html_cover(docxml)
76
77
  doc = to_xhtml_fragment(File.read(@htmlcoverpage, encoding: "UTF-8"))
77
78
  d = docxml.at('//div[@class="title-section"]')
78
- d.children.first.add_previous_sibling doc.to_xml(encoding: "US-ASCII")
79
+ #d.children.first.add_previous_sibling doc.to_xml(encoding: "US-ASCII")
80
+ d.children.first.add_previous_sibling populate_template(doc.to_xml(encoding: "US-ASCII"), :html)
79
81
  end
80
82
 
81
83
  def html_intro(docxml)
82
84
  doc = to_xhtml_fragment(File.read(@htmlintropage, encoding: "UTF-8"))
83
85
  d = docxml.at('//div[@class="prefatory-section"]')
84
- d.children.first.add_previous_sibling doc.to_xml(encoding: "US-ASCII")
85
- end
86
-
87
-
88
- def html_cover(docxml)
89
- doc = to_xhtml_fragment(File.read(@htmlcoverpage, encoding: "UTF-8"))
90
- d = docxml.at('//div[@class="title-section"]')
91
- d.children.first.add_previous_sibling doc.to_xml(encoding: "US-ASCII")
92
- end
93
-
94
- def html_intro(docxml)
95
- doc = to_xhtml_fragment(File.read(@htmlintropage, encoding: "UTF-8"))
96
- d = docxml.at('//div[@class="prefatory-section"]')
97
- d.children.first.add_previous_sibling doc.to_xml(encoding: "US-ASCII")
86
+ #d.children.first.add_previous_sibling doc.to_xml(encoding: "US-ASCII")
87
+ d.children.first.add_previous_sibling populate_template(doc.to_xml(encoding: "US-ASCII"), :html)
98
88
  end
99
89
 
100
90
  def html_toc_entry(level, header)
@@ -1,3 +1,3 @@
1
1
  module IsoDoc
2
- VERSION = "1.0.15".freeze
2
+ VERSION = "1.0.16".freeze
3
3
  end
@@ -1,3 +1,5 @@
1
+ require_relative "./table.rb"
2
+
1
3
  module IsoDoc::WordFunction
2
4
  module Body
3
5
  def define_head(head, filename, _dir)
@@ -56,39 +58,6 @@ module IsoDoc::WordFunction
56
58
  classtype
57
59
  end
58
60
 
59
- def remove_bottom_border(td)
60
- td["style"] =
61
- td["style"].gsub(/border-bottom:[^;]+;/, "border-bottom:0pt;").
62
- gsub(/mso-border-bottom-alt:[^;]+;/, "mso-border-bottom-alt:0pt;")
63
- end
64
-
65
- SW1 = "solid windowtext".freeze
66
-
67
- def new_fullcolspan_row(t, tfoot)
68
- # how many columns in the table?
69
- cols = 0
70
- t.at(".//tr").xpath("./td | ./th").each do |td|
71
- cols += (td["colspan"] ? td["colspan"].to_i : 1)
72
- end
73
- style = "border-top:0pt;mso-border-top-alt:0pt;"\
74
- "border-bottom:#{SW1} 1.5pt;mso-border-bottom-alt:#{SW1} 1.5pt;"
75
- tfoot.add_child("<tr><td colspan='#{cols}' style='#{style}'/></tr>")
76
- tfoot.xpath(".//td").last
77
- end
78
-
79
- def make_tr_attr(td, row, totalrows, _header)
80
- style = td.name == "th" ? "font-weight:bold;" : ""
81
- rowmax = td["rowspan"] ? row + td["rowspan"].to_i - 1 : row
82
- style += <<~STYLE
83
- border-top:#{row.zero? ? "#{SW1} 1.5pt;" : 'none;'}
84
- mso-border-top-alt:#{row.zero? ? "#{SW1} 1.5pt;" : 'none;'}
85
- border-bottom:#{SW1} #{rowmax == totalrows ? '1.5' : '1.0'}pt;
86
- mso-border-bottom-alt:#{SW1} #{rowmax == totalrows ? '1.5' : '1.0'}pt;
87
- STYLE
88
- { rowspan: td["rowspan"], colspan: td["colspan"],
89
- align: td["align"], style: style.gsub(/\n/, "") }
90
- end
91
-
92
61
  def section_break(body)
93
62
  body.p do |p|
94
63
  p.br **{ clear: "all", class: "section" }
@@ -103,6 +72,14 @@ module IsoDoc::WordFunction
103
72
  end
104
73
  end
105
74
 
75
+ def pagebreak_parse(node, out)
76
+ return page_break(out) if node["orientation"].nil?
77
+ out.p do |p|
78
+ p.br **{clear: "all", class: "section",
79
+ orientation: node["orientation"] }
80
+ end
81
+ end
82
+
106
83
  WORD_DT_ATTRS = {class: @note ? "Note" : nil, align: "left",
107
84
  style: "margin-left:0pt;text-align:left;"}.freeze
108
85
 
@@ -238,30 +215,5 @@ module IsoDoc::WordFunction
238
215
  "mso-table-overlap:never;border-collapse:collapse;"
239
216
  })
240
217
  end
241
-
242
- def make_table_attr(node)
243
- super.merge(attr_code({
244
- summary: node["summary"],
245
- style: "mso-table-lspace:15.0cm;margin-left:423.0pt;"\
246
- "mso-table-rspace:15.0cm;margin-right:423.0pt;"\
247
- "mso-table-anchor-horizontal:column;"\
248
- "mso-table-overlap:never;border-spacing:0;border-width:1px;"
249
- }))
250
- end
251
-
252
- def table_parse(node, out)
253
- @in_table = true
254
- table_title_parse(node, out)
255
- out.div **{ align: "center", class: "table_container" } do |div|
256
- div.table **make_table_attr(node) do |t|
257
- thead_parse(node, t)
258
- tbody_parse(node, t)
259
- tfoot_parse(node, t)
260
- (dl = node.at(ns("./dl"))) && parse(dl, out)
261
- node.xpath(ns("./note")).each { |n| parse(n, out) }
262
- end
263
- end
264
- @in_table = false
265
- end
266
218
  end
267
219
  end
@@ -1,4 +1,5 @@
1
1
  require "fileutils"
2
+ require_relative "./postprocess_cover.rb"
2
3
 
3
4
  module IsoDoc::WordFunction
4
5
  module Postprocess
@@ -32,14 +33,19 @@ xmlns:m="http://schemas.microsoft.com/office/2004/12/omml">
32
33
 
33
34
  def postprocess(result, filename, dir)
34
35
  header = generate_header(filename, dir)
35
- result = from_xhtml(cleanup(to_xhtml(result)))
36
+ result = from_xhtml(cleanup(to_xhtml(textcleanup(result))))
36
37
  toWord(result, filename, dir, header)
37
38
  @files_to_delete.each { |f| FileUtils.rm_f f }
38
39
  end
39
40
 
40
41
  def toWord(result, filename, dir, header)
41
- result = populate_template(result, :word)
42
+ #result = populate_template(result, :word)
42
43
  result = from_xhtml(word_cleanup(to_xhtml(result)))
44
+ unless @landscapestyle.empty?
45
+ @wordstylesheet&.open
46
+ @wordstylesheet&.write(@landscapestyle)
47
+ @wordstylesheet&.close
48
+ end
43
49
  Html2Doc.process(result, filename: filename, stylesheet: @wordstylesheet&.path,
44
50
  header_file: header&.path, dir: dir,
45
51
  asciimathdelims: [@openmathdelim, @closemathdelim],
@@ -65,6 +71,7 @@ xmlns:m="http://schemas.microsoft.com/office/2004/12/omml">
65
71
  word_example_cleanup(docxml)
66
72
  word_pseudocode_cleanup(docxml)
67
73
  word_image_caption(docxml)
74
+ word_section_breaks(docxml)
68
75
  authority_cleanup(docxml)
69
76
  docxml
70
77
  end
@@ -72,6 +79,7 @@ xmlns:m="http://schemas.microsoft.com/office/2004/12/omml">
72
79
  def authority_cleanup1(docxml, klass)
73
80
  dest = docxml.at("//div[@id = 'boilerplate-#{klass}-destination']")
74
81
  auth = docxml.at("//div[@id = 'boilerplate-#{klass}' or @class = 'boilerplate-#{klass}']")
82
+ auth&.xpath(".//h1[not(text())] | .//h2[not(text())]")&.each { |h| h.remove }
75
83
  auth&.xpath(".//h1 | .//h2")&.each do |h|
76
84
  h.name = "p"
77
85
  h["class"] = "TitlePageSubhead"
@@ -162,32 +170,6 @@ xmlns:m="http://schemas.microsoft.com/office/2004/12/omml">
162
170
  end
163
171
  end
164
172
 
165
- def word_preface(docxml)
166
- word_cover(docxml) if @wordcoverpage
167
- word_intro(docxml, @wordToClevels) if @wordintropage
168
- end
169
-
170
- def word_cover(docxml)
171
- cover = File.read(@wordcoverpage, encoding: "UTF-8")
172
- cover = populate_template(cover, :word)
173
- coverxml = to_word_xhtml_fragment(cover)
174
- docxml.at('//div[@class="WordSection1"]').children.first.previous =
175
- coverxml.to_xml(encoding: "US-ASCII")
176
- end
177
-
178
- def insert_toc(intro, docxml, level)
179
- intro.sub(/WORDTOC/, make_WordToC(docxml, level))
180
- end
181
-
182
- def word_intro(docxml, level)
183
- intro = insert_toc(File.read(@wordintropage, encoding: "UTF-8"),
184
- docxml, level)
185
- intro = populate_template(intro, :word)
186
- introxml = to_word_xhtml_fragment(intro)
187
- docxml.at('//div[@class="WordSection2"]').children.first.previous =
188
- introxml.to_xml(encoding: "US-ASCII")
189
- end
190
-
191
173
  def generate_header(filename, _dir)
192
174
  return nil unless @header
193
175
  template = IsoDoc::Common.liquid(File.read(@header, encoding: "UTF-8"))
@@ -200,54 +182,31 @@ xmlns:m="http://schemas.microsoft.com/office/2004/12/omml">
200
182
  end
201
183
  end
202
184
 
203
- def word_toc_entry(toclevel, heading)
204
- bookmark = bookmarkid # Random.rand(1000000000)
205
- <<~TOC
206
- <p class="MsoToc#{toclevel}"><span class="MsoHyperlink"><span
207
- lang="EN-GB" style='mso-no-proof:yes'>
208
- <a href="#_Toc#{bookmark}">#{heading}<span lang="EN-GB"
209
- class="MsoTocTextSpan">
210
- <span style='mso-tab-count:1 dotted'>. </span>
211
- </span><span lang="EN-GB" class="MsoTocTextSpan">
212
- <span style='mso-element:field-begin'></span></span>
213
- <span lang="EN-GB"
214
- class="MsoTocTextSpan"> PAGEREF _Toc#{bookmark} \\h </span>
215
- <span lang="EN-GB" class="MsoTocTextSpan"><span
216
- style='mso-element:field-separator'></span></span><span
217
- lang="EN-GB" class="MsoTocTextSpan">1</span>
218
- <span lang="EN-GB"
219
- class="MsoTocTextSpan"></span><span
220
- lang="EN-GB" class="MsoTocTextSpan"><span
221
- style='mso-element:field-end'></span></span></a></span></span></p>
222
-
223
- TOC
224
- end
225
-
226
- def word_toc_preface(level)
227
- <<~TOC.freeze
228
- <span lang="EN-GB"><span
229
- style='mso-element:field-begin'></span><span
230
- style='mso-spacerun:yes'>&#xA0;</span>TOC
231
- \\o &quot;1-#{level}&quot; \\h \\z \\u <span
232
- style='mso-element:field-separator'></span></span>
233
- TOC
234
- end
235
-
236
- WORD_TOC_SUFFIX1 = <<~TOC.freeze
237
- <p class="MsoToc1"><span lang="EN-GB"><span
238
- style='mso-element:field-end'></span></span><span
239
- lang="EN-GB"><o:p>&nbsp;</o:p></span></p>
240
- TOC
241
-
242
- def make_WordToC(docxml, level)
243
- toc = ""
244
- #docxml.xpath("//h1 | //h2[not(ancestor::*[@class = 'Section3'])]").
245
- xpath = (1..level).each.map { |i| "//h#{i}" }.join (" | ")
246
- docxml.xpath(xpath).each do |h|
247
- toc += word_toc_entry(h.name[1].to_i, header_strip(h))
185
+ def word_section_breaks(docxml)
186
+ @landscapestyle = ""
187
+ word_section_breaks1(docxml, "WordSection2")
188
+ word_section_breaks1(docxml, "WordSection3")
189
+ end
190
+
191
+ def word_section_breaks1(docxml, sect)
192
+ docxml.xpath("//div[@class = '#{sect}']//br[@orientation]").reverse.
193
+ each_with_index do |br, i|
194
+ @landscapestyle += "\ndiv.#{sect}_#{i} {page:#{sect}"\
195
+ "#{br["orientation"] == "landscape" ? "L" : "P"};}\n"
196
+ br.delete("orientation")
197
+ split_at_section_break(docxml, sect, br, i)
198
+ end
199
+ end
200
+
201
+ def split_at_section_break(docxml, sect, br, i)
202
+ move = br.parent.xpath("following::node()") &
203
+ br.document.xpath("//div[@class = '#{sect}']//*")
204
+ ins = docxml.at("//div[@class = '#{sect}']").
205
+ after("<div class='#{sect}_#{i}'/>").next_element
206
+ move.each do |m|
207
+ next if m.at("./ancestor::div[@class = '#{sect}_#{i}']")
208
+ ins << m.remove
248
209
  end
249
- toc.sub(/(<p class="MsoToc1">)/,
250
- %{\\1#{word_toc_preface(level)}}) + WORD_TOC_SUFFIX1
251
210
  end
252
211
  end
253
212
  end
@@ -0,0 +1,79 @@
1
+ module IsoDoc::WordFunction
2
+ module Postprocess
3
+ def word_preface(docxml)
4
+ word_cover(docxml) if @wordcoverpage
5
+ word_intro(docxml, @wordToClevels) if @wordintropage
6
+ end
7
+
8
+ def word_cover(docxml)
9
+ cover = File.read(@wordcoverpage, encoding: "UTF-8")
10
+ cover = populate_template(cover, :word)
11
+ coverxml = to_word_xhtml_fragment(cover)
12
+ docxml.at('//div[@class="WordSection1"]').children.first.previous =
13
+ coverxml.to_xml(encoding: "US-ASCII")
14
+ end
15
+
16
+ def word_intro(docxml, level)
17
+ intro = insert_toc(File.read(@wordintropage, encoding: "UTF-8"),
18
+ docxml, level)
19
+ intro = populate_template(intro, :word)
20
+ introxml = to_word_xhtml_fragment(intro)
21
+ docxml.at('//div[@class="WordSection2"]').children.first.previous =
22
+ introxml.to_xml(encoding: "US-ASCII")
23
+ end
24
+
25
+ def insert_toc(intro, docxml, level)
26
+ intro.sub(/WORDTOC/, make_WordToC(docxml, level))
27
+ end
28
+
29
+ def word_toc_entry(toclevel, heading)
30
+ bookmark = bookmarkid # Random.rand(1000000000)
31
+ <<~TOC
32
+ <p class="MsoToc#{toclevel}"><span class="MsoHyperlink"><span
33
+ lang="EN-GB" style='mso-no-proof:yes'>
34
+ <a href="#_Toc#{bookmark}">#{heading}<span lang="EN-GB"
35
+ class="MsoTocTextSpan">
36
+ <span style='mso-tab-count:1 dotted'>. </span>
37
+ </span><span lang="EN-GB" class="MsoTocTextSpan">
38
+ <span style='mso-element:field-begin'></span></span>
39
+ <span lang="EN-GB"
40
+ class="MsoTocTextSpan"> PAGEREF _Toc#{bookmark} \\h </span>
41
+ <span lang="EN-GB" class="MsoTocTextSpan"><span
42
+ style='mso-element:field-separator'></span></span><span
43
+ lang="EN-GB" class="MsoTocTextSpan">1</span>
44
+ <span lang="EN-GB"
45
+ class="MsoTocTextSpan"></span><span
46
+ lang="EN-GB" class="MsoTocTextSpan"><span
47
+ style='mso-element:field-end'></span></span></a></span></span></p>
48
+
49
+ TOC
50
+ end
51
+
52
+ def word_toc_preface(level)
53
+ <<~TOC.freeze
54
+ <span lang="EN-GB"><span
55
+ style='mso-element:field-begin'></span><span
56
+ style='mso-spacerun:yes'>&#xA0;</span>TOC
57
+ \\o &quot;1-#{level}&quot; \\h \\z \\u <span
58
+ style='mso-element:field-separator'></span></span>
59
+ TOC
60
+ end
61
+
62
+ WORD_TOC_SUFFIX1 = <<~TOC.freeze
63
+ <p class="MsoToc1"><span lang="EN-GB"><span
64
+ style='mso-element:field-end'></span></span><span
65
+ lang="EN-GB"><o:p>&nbsp;</o:p></span></p>
66
+ TOC
67
+
68
+ def make_WordToC(docxml, level)
69
+ toc = ""
70
+ #docxml.xpath("//h1 | //h2[not(ancestor::*[@class = 'Section3'])]").
71
+ xpath = (1..level).each.map { |i| "//h#{i}" }.join (" | ")
72
+ docxml.xpath(xpath).each do |h|
73
+ toc += word_toc_entry(h.name[1].to_i, header_strip(h))
74
+ end
75
+ toc.sub(/(<p class="MsoToc1">)/,
76
+ %{\\1#{word_toc_preface(level)}}) + WORD_TOC_SUFFIX1
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,61 @@
1
+ module IsoDoc::WordFunction
2
+ module Body
3
+ def remove_bottom_border(td)
4
+ td["style"] =
5
+ td["style"].gsub(/border-bottom:[^;]+;/, "border-bottom:0pt;").
6
+ gsub(/mso-border-bottom-alt:[^;]+;/, "mso-border-bottom-alt:0pt;")
7
+ end
8
+
9
+ SW1 = "solid windowtext".freeze
10
+
11
+ def new_fullcolspan_row(t, tfoot)
12
+ # how many columns in the table?
13
+ cols = 0
14
+ t.at(".//tr").xpath("./td | ./th").each do |td|
15
+ cols += (td["colspan"] ? td["colspan"].to_i : 1)
16
+ end
17
+ style = "border-top:0pt;mso-border-top-alt:0pt;"\
18
+ "border-bottom:#{SW1} 1.5pt;mso-border-bottom-alt:#{SW1} 1.5pt;"
19
+ tfoot.add_child("<tr><td colspan='#{cols}' style='#{style}'/></tr>")
20
+ tfoot.xpath(".//td").last
21
+ end
22
+
23
+ def make_tr_attr(td, row, totalrows, _header)
24
+ style = td.name == "th" ? "font-weight:bold;" : ""
25
+ rowmax = td["rowspan"] ? row + td["rowspan"].to_i - 1 : row
26
+ style += <<~STYLE
27
+ border-top:#{row.zero? ? "#{SW1} 1.5pt;" : 'none;'}
28
+ mso-border-top-alt:#{row.zero? ? "#{SW1} 1.5pt;" : 'none;'}
29
+ border-bottom:#{SW1} #{rowmax == totalrows ? '1.5' : '1.0'}pt;
30
+ mso-border-bottom-alt:#{SW1} #{rowmax == totalrows ? '1.5' : '1.0'}pt;
31
+ STYLE
32
+ { rowspan: td["rowspan"], colspan: td["colspan"],
33
+ align: td["align"], style: style.gsub(/\n/, "") }
34
+ end
35
+
36
+ def make_table_attr(node)
37
+ super.merge(attr_code({
38
+ summary: node["summary"],
39
+ style: "mso-table-lspace:15.0cm;margin-left:423.0pt;"\
40
+ "mso-table-rspace:15.0cm;margin-right:423.0pt;"\
41
+ "mso-table-anchor-horizontal:column;"\
42
+ "mso-table-overlap:never;border-spacing:0;border-width:1px;"
43
+ }))
44
+ end
45
+
46
+ def table_parse(node, out)
47
+ @in_table = true
48
+ table_title_parse(node, out)
49
+ out.div **{ align: "center", class: "table_container" } do |div|
50
+ div.table **make_table_attr(node) do |t|
51
+ thead_parse(node, t)
52
+ tbody_parse(node, t)
53
+ tfoot_parse(node, t)
54
+ (dl = node.at(ns("./dl"))) && parse(dl, out)
55
+ node.xpath(ns("./note")).each { |n| parse(n, out) }
56
+ end
57
+ end
58
+ @in_table = false
59
+ end
60
+ end
61
+ end
@@ -762,4 +762,5 @@ INPUT
762
762
 
763
763
  OUTPUT
764
764
  end
765
+
765
766
  end
@@ -8,7 +8,7 @@ RSpec.describe IsoDoc do
8
8
  <p>
9
9
  <em>A</em> <strong>B</strong> <sup>C</sup> <sub>D</sub> <tt>E</tt>
10
10
  <strike>F</strike> <smallcap>G</smallcap> <keyword>I</keyword> <br/> <hr/>
11
- <bookmark id="H"/> <pagebreak/>
11
+ <bookmark id="H"/> <pagebreak/> <pagebreak orientation="landscape"/>
12
12
  </p>
13
13
  </foreword></preface>
14
14
  <sections>
@@ -21,7 +21,7 @@ RSpec.describe IsoDoc do
21
21
  <p>
22
22
  <i>A</i> <b>B</b> <sup>C</sup> <sub>D</sub> <tt>E</tt>
23
23
  <s>F</s> <span style="font-variant:small-caps;">G</span> <span class="keyword">I</span> <br/> <hr/>
24
- <a id="H"/> <br/>
24
+ <a id="H"/> <br/> <br/>
25
25
  </p>
26
26
  </div>
27
27
  <p class="zzSTDTitle1"/>
@@ -31,6 +31,49 @@ RSpec.describe IsoDoc do
31
31
  OUTPUT
32
32
  end
33
33
 
34
+ it "processes inline formatting (Word)" do
35
+ expect(xmlpp(IsoDoc::WordConvert.new({}).convert("test", <<~"INPUT", true))).to be_equivalent_to xmlpp(<<~"OUTPUT")
36
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
37
+ <preface/><sections><clause>
38
+ <p>
39
+ <em>A</em> <strong>B</strong> <sup>C</sup> <sub>D</sub> <tt>E</tt>
40
+ <strike>F</strike> <smallcap>G</smallcap> <keyword>I</keyword> <br/> <hr/>
41
+ <bookmark id="H"/> <pagebreak/> <pagebreak orientation="landscape"/>
42
+ </p>
43
+ </clause></sections>
44
+ </iso-standard>
45
+ INPUT
46
+ #{WORD_HDR}
47
+ <p class='zzSTDTitle1'/>
48
+ <div>
49
+ <h1/>
50
+ <p>
51
+ <i>A</i>
52
+ <b>B</b>
53
+ <sup>C</sup>
54
+ <sub>D</sub>
55
+ <tt>E</tt>
56
+ <s>F</s>
57
+ <span style='font-variant:small-caps;'>G</span>
58
+ <span class='keyword'>I</span>
59
+ <br/>
60
+ <hr/>
61
+ <a id='H'/>
62
+ <p>
63
+ <br clear='all' style='mso-special-character:line-break;page-break-before:always'/>
64
+ </p>
65
+ <p>
66
+ <br clear='all' class='section' orientation='landscape'/>
67
+ </p>
68
+ </p>
69
+ </div>
70
+ </div>
71
+ </body>
72
+ </html>
73
+
74
+ OUTPUT
75
+ end
76
+
34
77
  it "ignores index entries" do
35
78
  expect(xmlpp(IsoDoc::HtmlConvert.new({}).convert("test", <<~"INPUT", true))).to be_equivalent_to xmlpp(<<~"OUTPUT")
36
79
  <iso-standard xmlns="http://riboseinc.com/isoxml">
@@ -25,6 +25,44 @@ RSpec.describe IsoDoc do
25
25
  expect(html).to match(/delimiters: \[\['\(#\(', '\)#\)'\]\]/)
26
26
  end
27
27
 
28
+ it "ignores Liquid markup in the document body" do
29
+ FileUtils.rm_f "test.doc"
30
+ FileUtils.rm_f "test.html"
31
+ IsoDoc::HtmlConvert.new({wordstylesheet: "spec/assets/word.css"}).convert("test", <<~"INPUT", false)
32
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
33
+ <bibdata>
34
+ <title language="en">test</title>
35
+ </bibdata>
36
+ <preface><foreword>
37
+ <note>
38
+ <p id="_f06fd0d1-a203-4f3d-a515-0bdba0f8d83f">{% elif %}These results are based on a study carried out on three different types of kernel.</p>
39
+ </note>
40
+ </foreword></preface>
41
+ </iso-standard>
42
+ INPUT
43
+ expect(File.exist?("test.html")).to be true
44
+ html = File.read("test.html")
45
+ end
46
+
47
+ it "ignores Liquid markup in the document body (Word)" do
48
+ FileUtils.rm_f "test.doc"
49
+ FileUtils.rm_f "test.html"
50
+ IsoDoc::WordConvert.new({wordstylesheet: "spec/assets/word.css"}).convert("test", <<~"INPUT", false)
51
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
52
+ <bibdata>
53
+ <title language="en">test</title>
54
+ </bibdata>
55
+ <preface><foreword>
56
+ <note>
57
+ <p id="_f06fd0d1-a203-4f3d-a515-0bdba0f8d83f">{% elif %}These results are based on a study carried out on three different types of kernel.</p>
58
+ </note>
59
+ </foreword></preface>
60
+ </iso-standard>
61
+ INPUT
62
+ expect(File.exist?("test.doc")).to be true
63
+ html = File.read("test.doc")
64
+ end
65
+
28
66
  it "generates HTML output docs with null configuration" do
29
67
  FileUtils.rm_f "test.doc"
30
68
  FileUtils.rm_f "test.html"
@@ -1221,4 +1259,186 @@ OUTPUT
1221
1259
  OUTPUT
1222
1260
  end
1223
1261
 
1262
+ it "deals with landscape and portrait pagebreaks (Word)" do
1263
+ FileUtils.rm_f "test.doc"
1264
+ IsoDoc::WordConvert.new({wordstylesheet: "spec/assets/word.css", htmlstylesheet: "spec/assets/html.css", filename: "test"}).convert("test", <<~"INPUT", false)
1265
+ <standard-document xmlns="http://riboseinc.com/isoxml">
1266
+ <bibdata type="standard">
1267
+ <title language="en" format="text/plain">Document title</title>
1268
+ <version>
1269
+ <draft>1.2</draft>
1270
+ </version>
1271
+ <language>en</language>
1272
+ <script>Latn</script>
1273
+ <status><stage>published</stage></status>
1274
+ <ext>
1275
+ <doctype>article</doctype>
1276
+ </ext>
1277
+ </bibdata>
1278
+ <preface>
1279
+ <introduction><title>Preface 1</title>
1280
+ <p align="center">This is a <pagebreak orientation="landscape"/> paragraph</p>
1281
+ <table>
1282
+ <tbody>
1283
+ <tr><td>A</td><td>B</td></tr>
1284
+ </tbody>
1285
+ </table>
1286
+ <clause><title>Preface 1.1</title>
1287
+ <p>On my side</p>
1288
+ <pagebreak orientation="portrait"/>
1289
+ <p>Upright again</p>
1290
+ </clause>
1291
+ <clause><title>Preface 1.3</title>
1292
+ <p>And still upright</p>
1293
+ </clause>
1294
+ </introduction>
1295
+ </preface>
1296
+ <sections><clause><title>Foreword</title>
1297
+ <note>
1298
+ <p id="_">For further information on the Foreword, see <strong>ISO/IEC Directives, Part 2, 2016, Clause 12.</strong></p>
1299
+ <pagebreak orientation="landscape"/>
1300
+ <table id="_c09a7e60-b0c7-4418-9bfc-2ef0bc09a249">
1301
+ <thead>
1302
+ <tr>
1303
+ <th align="left">A</th>
1304
+ <th align="left">B</th>
1305
+ </tr>
1306
+ </thead>
1307
+ <tbody>
1308
+ <tr>
1309
+ <td align="left">C</td>
1310
+ <td align="left">D</td>
1311
+ </tr>
1312
+ </tbody>
1313
+ <note id="_8fff1596-290e-4314-b03c-7a8aab97eebe">
1314
+ <p id="_32c22439-387a-48cf-a006-5ab3b934ba73">B</p>
1315
+ </note></table>
1316
+ <pagebreak orientation="portrait"/>
1317
+ <p>And up</p>
1318
+ </note>
1319
+ </clause></sections>
1320
+ </standard-document>
1321
+ INPUT
1322
+ expect(File.exist?("test.doc")).to be true
1323
+ html = File.read("test.doc", encoding: "UTF-8")
1324
+ expect(html).to include "div.WordSection2_0 {page:WordSection2P;}"
1325
+ expect(html).to include "div.WordSection2_1 {page:WordSection2L;}"
1326
+ expect(html).to include "div.WordSection3_0 {page:WordSection3P;}"
1327
+ expect(html).to include "div.WordSection3_1 {page:WordSection3L;}"
1328
+
1329
+ expect(xmlpp(html.sub(/^.*<body /m, "<body ").sub(%r{</body>.*$}m, "</body>"))).to be_equivalent_to xmlpp(<<~"OUTPUT")
1330
+ <body lang='EN-US' xml:lang='EN-US' link='blue' vlink='#954F72'>
1331
+ <div class='WordSection1'>
1332
+ <p class='MsoNormal'>&#xA0;</p>
1333
+ </div>
1334
+ <p class='MsoNormal'>
1335
+ <br clear='all' class='section'/>
1336
+ </p>
1337
+ <div class='WordSection2'>
1338
+ <p class='MsoNormal'>
1339
+ <br clear='all' style='mso-special-character:line-break;page-break-before:always'/>
1340
+ </p>
1341
+ <div class='Section3' id=''>
1342
+ <h1 class='IntroTitle'>Introduction</h1>
1343
+ <p align='center' style='text-align:center' class='MsoNormal'>
1344
+ This is a
1345
+ <p class='MsoNormal'>
1346
+ <br clear='all' class='section'/>
1347
+ </p>
1348
+ paragraph
1349
+ </p>
1350
+ </div>
1351
+ </div>
1352
+ <div class='WordSection2_1'>
1353
+ <div align='center' class='table_container'>
1354
+ <table class='MsoISOTable' style='mso-table-lspace:15.0cm;margin-left:423.0pt;mso-table-rspace:15.0cm;margin-right:423.0pt;mso-table-anchor-horizontal:column;mso-table-overlap:never;border-spacing:0;border-width:1px;'>
1355
+ <tbody>
1356
+ <tr>
1357
+ <td style='border-top:solid windowtext 1.5pt;mso-border-top-alt:solid windowtext 1.5pt;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;'>A</td>
1358
+ <td style='border-top:solid windowtext 1.5pt;mso-border-top-alt:solid windowtext 1.5pt;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;'>B</td>
1359
+ </tr>
1360
+ </tbody>
1361
+ </table>
1362
+ </div>
1363
+ <div>
1364
+ <h1>Preface 1.1</h1>
1365
+ <p class='MsoNormal'>On my side</p>
1366
+ <p class='MsoNormal'>
1367
+ <br clear='all' class='section'/>
1368
+ </p>
1369
+ </div>
1370
+ </div>
1371
+ <div class='WordSection2_0'>
1372
+ <p class='MsoNormal'>Upright again</p>
1373
+ <div>
1374
+ <h1>Preface 1.3</h1>
1375
+ <p class='MsoNormal'>And still upright</p>
1376
+ </div>
1377
+ <p class='MsoNormal'>&#xA0;</p>
1378
+ </div>
1379
+ <p class='MsoNormal'>
1380
+ <br clear='all' class='section'/>
1381
+ </p>
1382
+ <div class='WordSection3'>
1383
+ <p class='zzSTDTitle1'>Document title</p>
1384
+ <div>
1385
+ <h1>Foreword</h1>
1386
+ <div id='' class='Note'>
1387
+ <p class='Note'>
1388
+ <span class='note_label'>NOTE 1</span>
1389
+ <span style='mso-tab-count:1'>&#xA0; </span>
1390
+ For further information on the Foreword, see
1391
+ <b>ISO/IEC Directives, Part 2, 2016, Clause 12.</b>
1392
+ </p>
1393
+ <p class='Note'>
1394
+ <br clear='all' class='section'/>
1395
+ </p>
1396
+ </div>
1397
+ </div>
1398
+ </div>
1399
+ <div class='WordSection3_1'>
1400
+ <p class='TableTitle' style='text-align:center;'>Table 1</p>
1401
+ <div align='center' class='table_container'>
1402
+ <table class='MsoISOTable' style='mso-table-lspace:15.0cm;margin-left:423.0pt;mso-table-rspace:15.0cm;margin-right:423.0pt;mso-table-anchor-horizontal:column;mso-table-overlap:never;border-spacing:0;border-width:1px;'>
1403
+ <a name='_c09a7e60-b0c7-4418-9bfc-2ef0bc09a249' id='_c09a7e60-b0c7-4418-9bfc-2ef0bc09a249'/>
1404
+ <thead>
1405
+ <tr>
1406
+ <th align='left' style='font-weight:bold;border-top:solid windowtext 1.5pt;mso-border-top-alt:solid windowtext 1.5pt;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;'>A</th>
1407
+ <th align='left' style='font-weight:bold;border-top:solid windowtext 1.5pt;mso-border-top-alt:solid windowtext 1.5pt;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;'>B</th>
1408
+ </tr>
1409
+ </thead>
1410
+ <tbody>
1411
+ <tr>
1412
+ <td align='left' style='border-top:solid windowtext 1.5pt;mso-border-top-alt:solid windowtext 1.5pt;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;'>C</td>
1413
+ <td align='left' style='border-top:solid windowtext 1.5pt;mso-border-top-alt:solid windowtext 1.5pt;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;'>D</td>
1414
+ </tr>
1415
+ </tbody>
1416
+ <tfoot>
1417
+ <tr>
1418
+ <td colspan='2' style='border-top:0pt;mso-border-top-alt:0pt;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;'>
1419
+ <div class='Note'>
1420
+ <a name='_8fff1596-290e-4314-b03c-7a8aab97eebe' id='_8fff1596-290e-4314-b03c-7a8aab97eebe'/>
1421
+ <p class='Note'>
1422
+ <span class='note_label'>NOTE</span>
1423
+ <span style='mso-tab-count:1'>&#xA0; </span>
1424
+ B
1425
+ </p>
1426
+ </div>
1427
+ </td>
1428
+ </tr>
1429
+ </tfoot>
1430
+ </table>
1431
+ </div>
1432
+ <p class='Note'>
1433
+ <br clear='all' class='section'/>
1434
+ </p>
1435
+ </div>
1436
+ <div class='WordSection3_0'>
1437
+ <p class='Note'>And up</p>
1438
+ </div>
1439
+ <div style='mso-element:footnote-list'/>
1440
+ </body>
1441
+ OUTPUT
1442
+ end
1443
+
1224
1444
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: isodoc
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.15
4
+ version: 1.0.16
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-01-30 00:00:00.000000000 Z
11
+ date: 2020-02-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asciimath
@@ -351,6 +351,8 @@ files:
351
351
  - lib/isodoc/word_function/comments.rb
352
352
  - lib/isodoc/word_function/footnotes.rb
353
353
  - lib/isodoc/word_function/postprocess.rb
354
+ - lib/isodoc/word_function/postprocess_cover.rb
355
+ - lib/isodoc/word_function/table.rb
354
356
  - spec/assets/header.html
355
357
  - spec/assets/html.css
356
358
  - spec/assets/htmlcover.html