isodoc 1.2.6 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rake.yml +69 -0
  3. data/README.adoc +1 -3
  4. data/isodoc.gemspec +2 -1
  5. data/lib/isodoc-yaml/i18n-en.yaml +56 -0
  6. data/lib/isodoc-yaml/i18n-fr.yaml +64 -7
  7. data/lib/isodoc-yaml/i18n-zh-Hans.yaml +1 -0
  8. data/lib/isodoc/base_style/all.css +4 -0
  9. data/lib/isodoc/base_style/blocks.scss +2 -2
  10. data/lib/isodoc/base_style/reset.css +4 -0
  11. data/lib/isodoc/base_style/reset.scss +5 -0
  12. data/lib/isodoc/base_style/typography.scss +1 -1
  13. data/lib/isodoc/convert.rb +13 -98
  14. data/lib/isodoc/css.rb +95 -0
  15. data/lib/isodoc/function/inline.rb +0 -33
  16. data/lib/isodoc/function/inline_simple.rb +4 -1
  17. data/lib/isodoc/function/lists.rb +2 -1
  18. data/lib/isodoc/function/references.rb +8 -13
  19. data/lib/isodoc/function/section.rb +1 -1
  20. data/lib/isodoc/function/table.rb +10 -0
  21. data/lib/isodoc/function/to_word_html.rb +2 -2
  22. data/lib/isodoc/gem_tasks.rb +4 -0
  23. data/lib/isodoc/html_function/html.rb +1 -0
  24. data/lib/isodoc/html_function/mathvariant_to_plain.rb +82 -0
  25. data/lib/isodoc/html_function/postprocess.rb +41 -20
  26. data/lib/isodoc/i18n.rb +15 -2
  27. data/lib/isodoc/metadata.rb +28 -109
  28. data/lib/isodoc/metadata_contributor.rb +91 -0
  29. data/lib/isodoc/metadata_date.rb +6 -0
  30. data/lib/isodoc/presentation_function/bibdata.rb +79 -7
  31. data/lib/isodoc/presentation_function/block.rb +14 -9
  32. data/lib/isodoc/presentation_function/inline.rb +126 -22
  33. data/lib/isodoc/presentation_function/section.rb +9 -0
  34. data/lib/isodoc/presentation_xml_convert.rb +5 -0
  35. data/lib/isodoc/version.rb +1 -1
  36. data/lib/isodoc/word_convert.rb +0 -20
  37. data/lib/isodoc/word_function/body.rb +12 -0
  38. data/lib/isodoc/word_function/postprocess.rb +38 -80
  39. data/lib/isodoc/word_function/postprocess_cover.rb +55 -0
  40. data/lib/isodoc/word_function/table.rb +10 -0
  41. data/lib/isodoc/xref.rb +1 -0
  42. data/lib/isodoc/xref/xref_counter.rb +20 -9
  43. data/lib/isodoc/xref/xref_gen.rb +20 -2
  44. data/lib/isodoc/xref/xref_sect_gen.rb +1 -1
  45. data/spec/assets/html.scss +14 -0
  46. data/spec/assets/i18n.yaml +17 -9
  47. data/spec/isodoc/blocks_spec.rb +89 -241
  48. data/spec/isodoc/cleanup_spec.rb +0 -1
  49. data/spec/isodoc/footnotes_spec.rb +4 -5
  50. data/spec/isodoc/i18n_spec.rb +73 -38
  51. data/spec/isodoc/inline_spec.rb +177 -199
  52. data/spec/isodoc/lists_spec.rb +1 -1
  53. data/spec/isodoc/metadata_spec.rb +50 -7
  54. data/spec/isodoc/postproc_spec.rb +472 -11
  55. data/spec/isodoc/presentation_xml_spec.rb +584 -1
  56. data/spec/isodoc/ref_spec.rb +327 -12
  57. data/spec/isodoc/table_spec.rb +28 -0
  58. data/spec/isodoc/xref_spec.rb +162 -17
  59. data/spec/spec_helper.rb +2 -0
  60. metadata +22 -7
  61. data/.github/workflows/macos.yml +0 -42
  62. data/.github/workflows/ubuntu.yml +0 -62
  63. data/.github/workflows/windows.yml +0 -44
@@ -0,0 +1,95 @@
1
+ module IsoDoc
2
+ class Convert < ::IsoDoc::Common
3
+ # Check if already compiled version(.css) exists,
4
+ # if not, return original scss file. During release
5
+ # we compile scss into css files in order to not depend on scss
6
+ def precompiled_style_or_original(stylesheet_path)
7
+ # Already have compiled stylesheet, use it
8
+ return stylesheet_path if stylesheet_path.nil? ||
9
+ File.extname(stylesheet_path) == '.css'
10
+ basename = File.basename(stylesheet_path, '.*')
11
+ compiled_path = File.join(File.dirname(stylesheet_path),
12
+ "#{basename}.css")
13
+ return stylesheet_path unless File.file?(compiled_path)
14
+ compiled_path
15
+ end
16
+
17
+ # run this after @meta is populated
18
+ def populate_css
19
+ @htmlstylesheet = generate_css(@htmlstylesheet_name, true)
20
+ @wordstylesheet = generate_css(@wordstylesheet_name, false)
21
+ @standardstylesheet = generate_css(@standardstylesheet_name, false)
22
+ end
23
+
24
+ def default_fonts(_options)
25
+ {
26
+ bodyfont: 'Arial',
27
+ headerfont: 'Arial',
28
+ monospacefont: 'Courier',
29
+ }
30
+ end
31
+
32
+ # none for this parent gem, but will be populated in child gems
33
+ # which have access to stylesheets &c
34
+ def default_file_locations(_options)
35
+ {}
36
+ end
37
+
38
+ def fonts_options
39
+ {
40
+ 'bodyfont' => options[:bodyfont] || 'Arial',
41
+ 'headerfont' => options[:headerfont] || 'Arial',
42
+ 'monospacefont' => options[:monospacefont] || 'Courier',
43
+ "normalfontsize" => options[:normalfontsize],
44
+ "monospacefontsize" => options[:monospacefontsize],
45
+ "smallerfontsize" => options[:smallerfontsize],
46
+ "footnotefontsize" => options[:footnotefontsize]
47
+ }
48
+ end
49
+
50
+ def scss_fontheader(is_html_css)
51
+ b = options[:bodyfont] || 'Arial'
52
+ h = options[:headerfont] || 'Arial'
53
+ m = options[:monospacefont] || 'Courier'
54
+ ns = options[:normalfontsize] || (is_html_css ? "1.0em" : '12.0pt')
55
+ ms = options[:monospacefontsize] || (is_html_css ? "0.8em" : '11.0pt')
56
+ ss = options[:smallerfontsize] || (is_html_css ? "0.9em" : '10.0pt')
57
+ fs = options[:footnotefontsize] || (is_html_css ? "0.9em" : '9.0pt')
58
+ "$bodyfont: #{b};\n$headerfont: #{h};\n$monospacefont: #{m};\n"\
59
+ "$normalfontsize: #{ns};\n$monospacefontsize: #{ms};\n"\
60
+ "$smallerfontsize: #{ss};\n$footnotefontsize: #{fs};\n"
61
+ end
62
+
63
+ def convert_scss(filename, stylesheet, stripwordcss)
64
+ require 'sassc'
65
+ require 'isodoc/sassc_importer'
66
+
67
+ [File.join(Gem.loaded_specs['isodoc'].full_gem_path,
68
+ 'lib', 'isodoc'),
69
+ File.dirname(filename)].each do |name|
70
+ SassC.load_paths << name
71
+ end
72
+ SassC::Engine.new(scss_fontheader(stripwordcss) + stylesheet,
73
+ syntax: :scss, importer: SasscImporter)
74
+ .render
75
+ end
76
+
77
+ # stripwordcss if HTML stylesheet, !stripwordcss if DOC stylesheet
78
+ def generate_css(filename, stripwordcss)
79
+ return nil if filename.nil?
80
+
81
+ filename = precompiled_style_or_original(filename)
82
+ stylesheet = File.read(filename, encoding: 'UTF-8')
83
+ stylesheet = populate_template(stylesheet, :word)
84
+ stylesheet.gsub!(/(\s|\{)mso-[^:]+:[^;]+;/m, '\\1') if stripwordcss
85
+ if File.extname(filename) == '.scss'
86
+ stylesheet = convert_scss(filename, stylesheet, stripwordcss)
87
+ end
88
+ Tempfile.open([File.basename(filename, '.*'), 'css'],
89
+ encoding: 'utf-8') do |f|
90
+ f.write(stylesheet)
91
+ f
92
+ end
93
+ end
94
+ end
95
+ end
@@ -67,19 +67,6 @@ module IsoDoc::Function
67
67
  out << "Termbase #{node['base']}, term ID #{node['target']}"
68
68
  end
69
69
 
70
- def concept_parse(node, out)
71
- content = node.first_element_child.children.select do |c|
72
- !%w{locality localityStack}.include? c.name
73
- end.select { |c| !c.text? || /\S/.match(c) }
74
- if content.empty?
75
- out << "[Term defined in "
76
- parse(node.first_element_child, out)
77
- out << "]"
78
- else
79
- content.each { |n| parse(n, out) }
80
- end
81
- end
82
-
83
70
  def stem_parse(node, out)
84
71
  ooml = if node["type"] == "AsciiMath"
85
72
  "#{@openmathdelim}#{HTMLEntities.new.encode(node.text)}"\
@@ -131,25 +118,5 @@ module IsoDoc::Function
131
118
  p.b(**{ role: "strong" }) { |e| e << text }
132
119
  end
133
120
  end
134
-
135
- def variant_parse(node, out)
136
- if node["lang"] == @lang && node["script"] == @script
137
- node.children.each { |n| parse(n, out) }
138
- else
139
- return if found_matching_variant_sibling(node)
140
- return unless !node.at("./preceding-sibling::xmlns:variant")
141
- node.children.each { |n| parse(n, out) }
142
- end
143
- end
144
-
145
- def found_matching_variant_sibling(node)
146
- prev = node.xpath("./preceding-sibling::xmlns:variant")
147
- foll = node.xpath("./following-sibling::xmlns:variant")
148
- found = false
149
- (prev + foll).each do |n|
150
- found = true if n["lang"] == @lang && n["script"] == @script
151
- end
152
- found
153
- end
154
121
  end
155
122
  end
@@ -23,7 +23,10 @@ module IsoDoc::Function
23
23
  def index_parse(node, out)
24
24
  end
25
25
 
26
- def bookmark_parse(node, out)
26
+ def index_xref_parse(node, out)
27
+ end
28
+
29
+ def bookmark_parse(node, out)
27
30
  out.a **attr_code(id: node["id"])
28
31
  end
29
32
 
@@ -38,7 +38,8 @@ module IsoDoc::Function
38
38
  end
39
39
 
40
40
  def ol_attrs(node)
41
- { type: ol_depth(node), id: node["id"], style: keep_style(node) }
41
+ { type: node["type"] ? ol_style(node["type"].to_sym) : ol_depth(node),
42
+ id: node["id"], style: keep_style(node) }
42
43
  end
43
44
 
44
45
  def ol_parse(node, out)
@@ -80,7 +80,8 @@ module IsoDoc::Function
80
80
  end
81
81
 
82
82
  def docid_prefix(prefix, docid)
83
- docid = "#{prefix} #{docid}" if prefix && !omit_docid_prefix(prefix)
83
+ docid = "#{prefix} #{docid}" if prefix && !omit_docid_prefix(prefix) &&
84
+ !/^#{prefix}\b/.match(docid)
84
85
  docid_l10n(docid)
85
86
  end
86
87
 
@@ -90,7 +91,7 @@ module IsoDoc::Function
90
91
  end
91
92
 
92
93
  def date_note_process(b, ref)
93
- date_note = b.at(ns("./note[@type = 'ISO DATE']"))
94
+ date_note = b.at(ns("./note[@type = 'Unpublished-Status']"))
94
95
  return if date_note.nil?
95
96
  date_note.children.first.replace("<p>#{date_note.content}</p>")
96
97
  footnote_parse(date_note, ref)
@@ -111,7 +112,7 @@ module IsoDoc::Function
111
112
  # reference not to be rendered because it is deemed implicit
112
113
  # in the standards environment
113
114
  def implicit_reference(b)
114
- false
115
+ b["hidden"] == "true"
115
116
  end
116
117
 
117
118
  def prefix_bracketed_ref(ref, text)
@@ -160,7 +161,7 @@ module IsoDoc::Function
160
161
  end
161
162
 
162
163
  def norm_ref(isoxml, out, num)
163
- f = isoxml.at(ns(norm_ref_xpath)) or return num
164
+ f = isoxml.at(ns(norm_ref_xpath)) and f["hidden"] != "true" or return num
164
165
  out.div do |div|
165
166
  num = num + 1
166
167
  clause_name(num, f.at(ns("./title")), div, nil)
@@ -180,10 +181,9 @@ module IsoDoc::Function
180
181
  end
181
182
 
182
183
  def bibliography(isoxml, out)
183
- f = isoxml.at(ns(bibliography_xpath)) || return
184
+ f = isoxml.at(ns(bibliography_xpath)) and f["hidden"] != "true" or return
184
185
  page_break(out)
185
186
  out.div do |div|
186
- #div.h1 @bibliography_lbl, **{ class: "Section3" }
187
187
  div.h1 **{class: "Section3"} do |h1|
188
188
  f&.at(ns("./title"))&.children&.each { |c2| parse(c2, h1) }
189
189
  end
@@ -192,6 +192,7 @@ module IsoDoc::Function
192
192
  end
193
193
 
194
194
  def bibliography_parse(node, out)
195
+ node["hidden"] != true or return
195
196
  title = node&.at(ns("./title"))&.text || ""
196
197
  out.div do |div|
197
198
  clause_parse_title(node, div, node.at(ns("./title")), out,
@@ -202,15 +203,9 @@ module IsoDoc::Function
202
203
 
203
204
  def format_ref(ref, prefix, isopub, date, allparts)
204
205
  ref = docid_prefix(prefix, ref)
205
- return "[#{ref}]" if /^\d+$/.match(ref) && !prefix &&
206
+ return "[#{ref}]" if ref && /^\d+$/.match(ref) && !prefix &&
206
207
  !/^\[.*\]$/.match(ref)
207
208
  ref
208
209
  end
209
-
210
- # def ref_names(ref)
211
- # linkend = ref.text
212
- # linkend.gsub!(/[\[\]]/, "") unless /^\[\d+\]$/.match linkend
213
- # @anchors[ref["id"]] = { xref: linkend }
214
- # end
215
210
  end
216
211
  end
@@ -56,7 +56,7 @@ module IsoDoc::Function
56
56
  end
57
57
 
58
58
  def clause(isoxml, out)
59
- isoxml.xpath(ns(middle_clause)).each do |c|
59
+ isoxml.xpath(ns(middle_clause(isoxml))).each do |c|
60
60
  out.div **attr_code(clause_attrs(c)) do |s|
61
61
  clause_name(nil, c&.at(ns("./title")), s, nil)
62
62
  c.elements.reject { |c1| c1.name == "title" }.each do |c1|
@@ -58,11 +58,21 @@ module IsoDoc::Function
58
58
  end
59
59
  end
60
60
 
61
+ def colgroup(node, t)
62
+ colgroup = node.at(ns("./colgroup")) or return
63
+ t.colgroup do |cg|
64
+ colgroup.xpath(ns("./col")).each do |c|
65
+ cg.col **{ style: "width: #{c['width']};" }
66
+ end
67
+ end
68
+ end
69
+
61
70
  def table_parse(node, out)
62
71
  @in_table = true
63
72
  table_title_parse(node, out)
64
73
  out.table **table_attrs(node) do |t|
65
74
  tcaption(node, t)
75
+ colgroup(node, t)
66
76
  thead_parse(node, t)
67
77
  tbody_parse(node, t)
68
78
  tfoot_parse(node, t)
@@ -96,6 +96,7 @@ module IsoDoc::Function
96
96
  @meta.subtitle isoxml, out
97
97
  @meta.docstatus isoxml, out
98
98
  @meta.docid isoxml, out
99
+ @meta.otherid isoxml, out
99
100
  @meta.docnumeric isoxml, out
100
101
  @meta.doctype isoxml, out
101
102
  @meta.author isoxml, out
@@ -214,14 +215,13 @@ module IsoDoc::Function
214
215
  when "verification" then requirement_component_parse(node, out)
215
216
  when "import" then requirement_component_parse(node, out)
216
217
  when "index" then index_parse(node, out)
217
- when "concept" then concept_parse(node, out)
218
+ when "index-xref" then index_xref_parse(node, out)
218
219
  when "termref" then termrefelem_parse(node, out)
219
220
  when "copyright-statement" then copyright_parse(node, out)
220
221
  when "license-statement" then license_parse(node, out)
221
222
  when "legal-statement" then legal_parse(node, out)
222
223
  when "feedback-statement" then feedback_parse(node, out)
223
224
  when "passthrough" then passthrough_parse(node, out)
224
- when "variant" then variant_parse(node, out)
225
225
  when "amend" then amend_parse(node, out)
226
226
  when "tab" then clausedelimspace(out) # in Presentation XML only
227
227
  else
@@ -97,6 +97,10 @@ module IsoDoc
97
97
  $bodyfont: '{{bodyfont}}';
98
98
  $headerfont: '{{headerfont}}';
99
99
  $monospacefont: '{{monospacefont}}';
100
+ $normalfontsize: '{{normalfontsize}}';
101
+ $smallerfontsize: '{{smallerfontsize}}';
102
+ $footnotefontsize: '{{footnotefontsize}}';
103
+ $monospacefontsize: '{{monospacefontsize}}';
100
104
  TEXT
101
105
  end
102
106
 
@@ -60,6 +60,7 @@ module IsoDoc::HtmlFunction
60
60
  <script type="text/javascript">#{toclevel}</script>
61
61
 
62
62
  <!--Google fonts-->
63
+ <link rel="preconnect" href="https://fonts.gstatic.com">
63
64
  #{googlefonts}
64
65
  <!--Font awesome import for the link icon-->
65
66
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.8/css/solid.css" integrity="sha384-v2Tw72dyUXeU3y4aM2Y0tBJQkGfplr39mxZqlTBDUZAb9BGoC40+rdFCG0m10lXk" crossorigin="anonymous">
@@ -0,0 +1,82 @@
1
+ module IsoDoc
2
+ module HtmlFunction
3
+ # Class for recursively converting mathvariant text into plain text symbols
4
+ class MathvariantToPlain
5
+ MATHML = { "m" => "http://www.w3.org/1998/Math/MathML" }.freeze
6
+ MATHVARIANT_SPECIAL_CASE_MAPPINGS_1 = %w[bold italic sans-serif]
7
+ .permutation
8
+ .each_with_object(:sansbolditalic)
9
+ .map { |n, y| [n, y] }
10
+ .to_h
11
+ .freeze
12
+ MATHVARIANT_SPECIAL_CASE_MAPPINGS_2 = {
13
+ %w[bold fraktur] => :frakturbold,
14
+ %w[bold script] => :scriptbold,
15
+ %w[sans-serif bold] => :sansbold,
16
+ %w[sans-serif italic] => :sansitalic,
17
+ %w[sans-serif bold-italic] => :sansbolditalic,
18
+ %w[bold-sans-serif italic] => :sansbolditalic,
19
+ %w[sans-serif-italic bold] => :sansbolditalic,
20
+ }.freeze
21
+ MATHVARIANT_TO_PLANE_MAPPINGS = {
22
+ %w[double-struck] => :doublestruck,
23
+ %w[bold-fraktur] => :frakturbold,
24
+ %w[script] => :script,
25
+ %w[bold-script] => :scriptbold,
26
+ %w[fraktur] => :fraktur,
27
+ %w[sans-serif] => :sans,
28
+ %w[bold-sans-serif] => :sansbold,
29
+ %w[sans-serif-italic] => :sansitalic,
30
+ %w[sans-serif-bold-italic] => :sansbolditalic,
31
+ %w[monospace] => :monospace,
32
+ }.freeze
33
+
34
+ attr_reader :docxml
35
+
36
+ # @param [Nokogiri::Document] docxml
37
+ def initialize(docxml)
38
+ @docxml = docxml
39
+ end
40
+
41
+ def convert
42
+ docxml.xpath("//m:math", MATHML).each do |elem|
43
+ next if nothing_to_style(elem)
44
+ mathml1(elem)
45
+ end
46
+ docxml
47
+ end
48
+
49
+ private
50
+
51
+ def nothing_to_style(elem)
52
+ !elem.at("./*[@mathvariant][not(@mathvariant = 'normal')][not(@mathvariant = 'italic')]")
53
+ end
54
+
55
+ def mathml1(base_elem)
56
+ MATHVARIANT_SPECIAL_CASE_MAPPINGS_1
57
+ .merge(MATHVARIANT_SPECIAL_CASE_MAPPINGS_2)
58
+ .merge(MATHVARIANT_TO_PLANE_MAPPINGS)
59
+ .each_pair do |mathvariant_list, plain_font|
60
+ base_elem.xpath(mathvariant_xpath(mathvariant_list)).each do |elem|
61
+ toPlane(elem, plain_font)
62
+ end
63
+ end
64
+ end
65
+
66
+ def mathvariant_xpath(list)
67
+ list
68
+ .map { |variant| "//*[@mathvariant = '#{variant}']" }
69
+ .join
70
+ end
71
+
72
+ def toPlane(elem, font)
73
+ elem.traverse do |n|
74
+ next unless n.text?
75
+
76
+ n.replace(Plane1Converter.conv(HTMLEntities.new.decode(n.text), font))
77
+ end
78
+ elem
79
+ end
80
+ end
81
+ end
82
+ end
@@ -1,35 +1,47 @@
1
+ require "isodoc/html_function/mathvariant_to_plain"
2
+
1
3
  module IsoDoc::HtmlFunction
2
4
  module Html
3
- def postprocess(result, filename, dir)
5
+ def postprocess(result, filename, _dir)
4
6
  result = from_xhtml(cleanup(to_xhtml(textcleanup(result))))
5
7
  toHTML(result, filename)
6
8
  @files_to_delete.each { |f| FileUtils.rm_rf f }
7
9
  end
8
10
 
9
11
  def script_cdata(result)
10
- result.gsub(%r{<script([^>]*)>\s*<!\[CDATA\[}m, "<script\\1>").
11
- gsub(%r{\]\]>\s*</script>}, "</script>").
12
- gsub(%r{<!\[CDATA\[\s*<script([^>]*)>}m, "<script\\1>").
13
- gsub(%r{</script>\s*\]\]>}, "</script>")
12
+ result.gsub(%r{<script([^>]*)>\s*<!\[CDATA\[}m, "<script\\1>")
13
+ .gsub(%r{\]\]>\s*</script>}, "</script>")
14
+ .gsub(%r{<!\[CDATA\[\s*<script([^>]*)>}m, "<script\\1>")
15
+ .gsub(%r{</script>\s*\]\]>}, "</script>")
14
16
  end
15
17
 
16
18
  def toHTML(result, filename)
17
- result = (from_xhtml(html_cleanup(to_xhtml(result))))
18
- #result = populate_template(result, :html)
19
+ result = from_xhtml(html_cleanup(to_xhtml(result)))
20
+ # result = populate_template(result, :html)
19
21
  result = from_xhtml(move_images(to_xhtml(result)))
20
22
  result = html5(script_cdata(inject_script(result)))
21
23
  File.open(filename, "w:UTF-8") { |f| f.write(result) }
22
24
  end
23
25
 
24
26
  def html5(doc)
25
- doc.sub(%r{<!DOCTYPE html [^>]+>}, "<!DOCTYPE html>").
26
- sub(%r{<\?xml[^>]+>}, "")
27
+ doc.sub(%r{<!DOCTYPE html [^>]+>}, "<!DOCTYPE html>")
28
+ .sub(%r{<\?xml[^>]+>}, "")
27
29
  end
28
30
 
29
31
  def html_cleanup(x)
30
- footnote_format(footnote_backlinks(html_toc(
31
- term_header((html_footnote_filter(html_preface(htmlstyle(x))))))
32
- ))
32
+ mathml(
33
+ footnote_format(
34
+ footnote_backlinks(
35
+ html_toc(
36
+ term_header(html_footnote_filter(html_preface(htmlstyle(x))))
37
+ )
38
+ )
39
+ )
40
+ )
41
+ end
42
+
43
+ def mathml(docxml)
44
+ IsoDoc::HtmlFunction::MathvariantToPlain.new(docxml).convert
33
45
  end
34
46
 
35
47
  def htmlstylesheet
@@ -76,14 +88,14 @@ module IsoDoc::HtmlFunction
76
88
  def html_cover(docxml)
77
89
  doc = to_xhtml_fragment(File.read(@htmlcoverpage, encoding: "UTF-8"))
78
90
  d = docxml.at('//div[@class="title-section"]')
79
- #d.children.first.add_previous_sibling doc.to_xml(encoding: "US-ASCII")
91
+ # d.children.first.add_previous_sibling doc.to_xml(encoding: "US-ASCII")
80
92
  d.children.first.add_previous_sibling populate_template(doc.to_xml(encoding: "US-ASCII"), :html)
81
93
  end
82
94
 
83
95
  def html_intro(docxml)
84
96
  doc = to_xhtml_fragment(File.read(@htmlintropage, encoding: "UTF-8"))
85
97
  d = docxml.at('//div[@class="prefatory-section"]')
86
- #d.children.first.add_previous_sibling doc.to_xml(encoding: "US-ASCII")
98
+ # d.children.first.add_previous_sibling doc.to_xml(encoding: "US-ASCII")
87
99
  d.children.first.add_previous_sibling populate_template(doc.to_xml(encoding: "US-ASCII"), :html)
88
100
  end
89
101
 
@@ -93,19 +105,19 @@ module IsoDoc::HtmlFunction
93
105
  end
94
106
 
95
107
  def toclevel_classes
96
- (1..@htmlToClevels).inject([]) { |m, i| m << "h#{i}" }
108
+ (1..@htmlToClevels).reduce([]) { |m, i| m << "h#{i}" }
97
109
  end
98
110
 
99
111
  def toclevel
100
112
  ret = toclevel_classes.map { |l| "#{l}:not(:empty):not(.TermNum):not(.noTOC)" }
101
113
  <<~HEAD.freeze
102
- function toclevel() { return "#{ret.join(',')}";}
114
+ function toclevel() { return "#{ret.join(',')}";}
103
115
  HEAD
104
116
  end
105
117
 
106
118
  # needs to be same output as toclevel
107
119
  def html_toc(docxml)
108
- idx = docxml.at("//div[@id = 'toc']") or return docxml
120
+ (idx = docxml.at("//div[@id = 'toc']")) or (return docxml)
109
121
  toc = "<ul>"
110
122
  path = toclevel_classes.map do |l|
111
123
  "//main//#{l}[not(@class = 'TermNum')][not(@class = 'noTOC')][text()]"
@@ -186,14 +198,22 @@ module IsoDoc::HtmlFunction
186
198
  docxml
187
199
  end
188
200
 
201
+ def footnote_backlinks1(x, fn)
202
+ xdup = x.dup
203
+ xdup.remove["id"]
204
+ if fn.elements.empty?
205
+ fn.children.first.previous = xdup
206
+ else
207
+ fn.elements.first.children.first.previous = xdup
208
+ end
209
+ end
210
+
189
211
  def footnote_backlinks(docxml)
190
212
  seen = {}
191
213
  docxml.xpath('//a[@class = "FootnoteRef"]').each_with_index do |x, i|
192
214
  seen[x["href"]] and next or seen[x["href"]] = true
193
215
  fn = docxml.at(%<//*[@id = '#{x['href'].sub(/^#/, '')}']>) || next
194
- xdup = x.dup
195
- xdup.remove["id"]
196
- fn.elements.first.children.first.previous = xdup
216
+ footnote_backlinks1(x, fn)
197
217
  x["id"] ||= "fnref:#{i + 1}"
198
218
  fn.add_child "<a href='##{x['id']}'>&#x21A9;</a>"
199
219
  end
@@ -221,6 +241,7 @@ module IsoDoc::HtmlFunction
221
241
  MATHJAX = <<~"MATHJAX".freeze
222
242
  <script type="text/x-mathjax-config">
223
243
  MathJax.Hub.Config({
244
+ "HTML-CSS": { preferredFont: "STIX" },
224
245
  asciimath2jax: { delimiters: [['OPEN', 'CLOSE']] }
225
246
  });
226
247
  </script>