isodoc 1.2.6 → 1.4.0

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 (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>