isodoc 1.6.1 → 1.6.6

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 (69) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rake.yml +2 -12
  3. data/.hound.yml +3 -1
  4. data/.rubocop.yml +4 -8
  5. data/Rakefile +2 -2
  6. data/isodoc.gemspec +4 -3
  7. data/lib/isodoc-yaml/i18n-ar.yaml +152 -0
  8. data/lib/isodoc-yaml/i18n-de.yaml +149 -0
  9. data/lib/isodoc-yaml/i18n-en.yaml +1 -0
  10. data/lib/isodoc-yaml/i18n-es.yaml +151 -0
  11. data/lib/isodoc-yaml/i18n-fr.yaml +1 -0
  12. data/lib/isodoc-yaml/i18n-ru.yaml +154 -0
  13. data/lib/isodoc-yaml/i18n-zh-Hans.yaml +1 -0
  14. data/lib/isodoc.rb +0 -2
  15. data/lib/isodoc/common.rb +2 -0
  16. data/lib/isodoc/convert.rb +8 -2
  17. data/lib/isodoc/function/blocks.rb +15 -4
  18. data/lib/isodoc/function/cleanup.rb +52 -43
  19. data/lib/isodoc/function/form.rb +51 -0
  20. data/lib/isodoc/function/inline.rb +8 -7
  21. data/lib/isodoc/function/references.rb +71 -77
  22. data/lib/isodoc/function/section.rb +28 -16
  23. data/lib/isodoc/function/table.rb +22 -22
  24. data/lib/isodoc/function/terms.rb +6 -7
  25. data/lib/isodoc/function/to_word_html.rb +19 -25
  26. data/lib/isodoc/function/utils.rb +181 -163
  27. data/lib/isodoc/gem_tasks.rb +8 -9
  28. data/lib/isodoc/headlesshtml_convert.rb +8 -7
  29. data/lib/isodoc/html_convert.rb +6 -0
  30. data/lib/isodoc/html_function/comments.rb +14 -12
  31. data/lib/isodoc/html_function/footnotes.rb +14 -7
  32. data/lib/isodoc/html_function/form.rb +62 -0
  33. data/lib/isodoc/html_function/html.rb +30 -26
  34. data/lib/isodoc/html_function/postprocess.rb +191 -182
  35. data/lib/isodoc/html_function/sectionsplit.rb +230 -0
  36. data/lib/isodoc/i18n.rb +13 -11
  37. data/lib/isodoc/metadata.rb +22 -20
  38. data/lib/isodoc/metadata_contributor.rb +31 -28
  39. data/lib/isodoc/pdf_convert.rb +11 -13
  40. data/lib/isodoc/presentation_function/bibdata.rb +54 -30
  41. data/lib/isodoc/presentation_function/inline.rb +70 -120
  42. data/lib/isodoc/presentation_function/math.rb +84 -0
  43. data/lib/isodoc/presentation_function/section.rb +55 -19
  44. data/lib/isodoc/presentation_xml_convert.rb +3 -0
  45. data/lib/isodoc/sassc_importer.rb +1 -1
  46. data/lib/isodoc/version.rb +1 -1
  47. data/lib/isodoc/word_function/body.rb +28 -24
  48. data/lib/isodoc/word_function/postprocess.rb +50 -36
  49. data/lib/isodoc/xref.rb +2 -0
  50. data/lib/isodoc/xref/xref_counter.rb +1 -2
  51. data/lib/isodoc/xref/xref_gen.rb +21 -14
  52. data/lib/isodoc/xref/xref_gen_seq.rb +60 -35
  53. data/lib/isodoc/xref/xref_sect_gen.rb +15 -15
  54. data/spec/assets/scripts_override.html +3 -0
  55. data/spec/isodoc/blocks_spec.rb +624 -997
  56. data/spec/isodoc/cleanup_spec.rb +40 -42
  57. data/spec/isodoc/form_spec.rb +156 -0
  58. data/spec/isodoc/i18n_spec.rb +694 -821
  59. data/spec/isodoc/inline_spec.rb +1105 -921
  60. data/spec/isodoc/metadata_spec.rb +384 -379
  61. data/spec/isodoc/postproc_spec.rb +461 -333
  62. data/spec/isodoc/presentation_xml_spec.rb +355 -278
  63. data/spec/isodoc/ref_spec.rb +5 -5
  64. data/spec/isodoc/section_spec.rb +216 -199
  65. data/spec/isodoc/sectionsplit_spec.rb +190 -0
  66. data/spec/isodoc/table_spec.rb +41 -42
  67. data/spec/isodoc/terms_spec.rb +84 -84
  68. data/spec/isodoc/xref_spec.rb +974 -932
  69. metadata +32 -7
@@ -12,12 +12,10 @@ module IsoDoc
12
12
 
13
13
  def install
14
14
  rule ".css" => [proc { |tn| tn.sub(/\.css$/, ".scss") }] do |current_task|
15
- begin
16
- puts(current_task)
17
- compile_scss_task(current_task)
18
- rescue StandardError => e
19
- notify_borken_compilation(e, current_task)
20
- end
15
+ puts(current_task)
16
+ compile_scss_task(current_task)
17
+ rescue StandardError => e
18
+ notify_borken_compilation(e, current_task)
21
19
  end
22
20
 
23
21
  scss_files = Rake::FileList["lib/**/*.scss"]
@@ -88,7 +86,7 @@ module IsoDoc
88
86
  text
89
87
  .gsub("/* LIQUID_COMMENT", "")
90
88
  .gsub("LIQUID_COMMENT */", "")
91
- .gsub('"{{', '{{').gsub('}}"', "}}")
89
+ .gsub('"{{', "{{").gsub('}}"', "}}")
92
90
  end
93
91
 
94
92
  def fonts_placeholder
@@ -107,7 +105,8 @@ module IsoDoc
107
105
  require "sassc"
108
106
 
109
107
  isodoc_path = if Gem.loaded_specs["isodoc"]
110
- File.join(Gem.loaded_specs["isodoc"].full_gem_path, "lib", "isodoc")
108
+ File.join(Gem.loaded_specs["isodoc"].full_gem_path,
109
+ "lib", "isodoc")
111
110
  else
112
111
  File.join("lib", "isodoc")
113
112
  end
@@ -119,7 +118,7 @@ module IsoDoc
119
118
  SassC::Engine.new(fonts_placeholder + sheet_content,
120
119
  syntax: :scss,
121
120
  importer: SasscImporter)
122
- .render
121
+ .render
123
122
  end
124
123
 
125
124
  def compile_scss_task(current_task)
@@ -1,11 +1,10 @@
1
- require_relative "html_function/comments.rb"
2
- require_relative "html_function/footnotes.rb"
3
- require_relative "html_function/html.rb"
1
+ require_relative "html_function/comments"
2
+ require_relative "html_function/footnotes"
3
+ require_relative "html_function/html"
4
4
  require "fileutils"
5
5
 
6
6
  module IsoDoc
7
7
  class HeadlessHtmlConvert < ::IsoDoc::Convert
8
-
9
8
  include HtmlFunction::Comments
10
9
  include HtmlFunction::Footnotes
11
10
  include HtmlFunction::Html
@@ -26,16 +25,18 @@ module IsoDoc
26
25
  docxml, filename, dir = convert_init(file, input_filename, debug)
27
26
  result = convert1(docxml, filename, dir)
28
27
  return result if debug
29
- postprocess(result, filename + ".tmp.html", dir)
28
+
29
+ postprocess(result, "#{filename}.tmp.html", dir)
30
30
  FileUtils.rm_rf dir
31
- strip_head(filename + ".tmp.html", output_filename || "#{filename}.#{@suffix}")
31
+ strip_head("#{filename}.tmp.html",
32
+ output_filename || "#{filename}.#{@suffix}")
32
33
  FileUtils.rm_rf ["#{filename}.tmp.html", tmpimagedir]
33
34
  end
34
35
 
35
36
  def strip_head(input, output)
36
37
  file = File.read(input, encoding: "utf-8")
37
38
  doc = Nokogiri::XML(file)
38
- doc.xpath("//head").each { |x| x.remove }
39
+ doc.xpath("//head").each(&:remove)
39
40
  doc.xpath("//html").each { |x| x.name = "div" }
40
41
  body = doc.at("//body")
41
42
  body.replace(body.children)
@@ -2,12 +2,15 @@ require_relative "html_function/comments"
2
2
  require_relative "html_function/footnotes"
3
3
  require_relative "html_function/html"
4
4
  require_relative "html_function/postprocess"
5
+ require_relative "html_function/sectionsplit"
6
+ require_relative "html_function/form"
5
7
 
6
8
  module IsoDoc
7
9
  class HtmlConvert < ::IsoDoc::Convert
8
10
 
9
11
  include HtmlFunction::Comments
10
12
  include HtmlFunction::Footnotes
13
+ include HtmlFunction::Form
11
14
  include HtmlFunction::Html
12
15
 
13
16
  def tmpimagedir_suffix
@@ -21,6 +24,9 @@ module IsoDoc
21
24
  end
22
25
 
23
26
  def convert(filename, file = nil, debug = false, output_filename = nil)
27
+ @sectionsplit and
28
+ return sectionsplit_convert(filename, file, debug, output_filename)
29
+
24
30
  ret = super
25
31
  Dir.exists?(tmpimagedir) and Dir["#{tmpimagedir}/*"].empty? and
26
32
  FileUtils.rm_r tmpimagedir
@@ -24,16 +24,16 @@ module IsoDoc::HtmlFunction
24
24
  =end
25
25
  end
26
26
 
27
- def comment_link_attrs(fn, node)
28
- { style: "MsoCommentReference", target: fn,
27
+ def comment_link_attrs(fnote, node)
28
+ { style: "MsoCommentReference", target: fnote,
29
29
  class: "commentLink", from: node["from"],
30
30
  to: node["to"] }
31
31
  end
32
32
 
33
33
  # add in from and to links to move the comment into place
34
- def make_comment_link(out, fn, node)
35
- out.span(**comment_link_attrs(fn, node)) do |s1|
36
- s1.a **{ style: "mso-comment-reference:SMC_#{fn};"\
34
+ def make_comment_link(out, fnote, node)
35
+ out.span(**comment_link_attrs(fnote, node)) do |s1|
36
+ s1.a **{ style: "mso-comment-reference:SMC_#{fnote};"\
37
37
  "mso-comment-date:#{node['date'].gsub(/[-:Z]/, '')}" }
38
38
  end
39
39
  end
@@ -44,9 +44,9 @@ module IsoDoc::HtmlFunction
44
44
  end
45
45
  end
46
46
 
47
- def make_comment_text(node, fn)
47
+ def make_comment_text(node, fnote)
48
48
  noko do |xml|
49
- xml.div **{ style: "mso-element:comment", id: fn } do |div|
49
+ xml.div **{ style: "mso-element:comment", id: fnote } do |div|
50
50
  div.span **{ style: %{mso-comment-author:"#{node['reviewer']}"} }
51
51
  make_comment_target(div)
52
52
  node.children.each { |n| parse(n, div) }
@@ -84,6 +84,7 @@ module IsoDoc::HtmlFunction
84
84
  def comment_attributes(docxml, x)
85
85
  fromlink = docxml.at("//*[@id='#{x['from']}']")
86
86
  return(nil) if fromlink.nil?
87
+
87
88
  tolink = docxml.at("//*[@id='#{x['to']}']") || fromlink
88
89
  target = docxml.at("//*[@id='#{x['target']}']")
89
90
  { from: fromlink, to: tolink, target: target }
@@ -98,13 +99,13 @@ module IsoDoc::HtmlFunction
98
99
  from["style"] != "mso-special-character:comment"
99
100
  end
100
101
 
101
- def insert_comment_cont(from, to, target)
102
- # includes_to = from.at(".//*[@id='#{to}']")
103
- while !from.nil? && from["id"] != to
102
+ def insert_comment_cont(from, upto, target)
103
+ # includes_to = from.at(".//*[@id='#{upto}']")
104
+ while !from.nil? && from["id"] != upto
104
105
  following = from.xpath("./following::*")
105
- (from = following.shift) && incl_to = from.at(".//*[@id='#{to}']")
106
+ (from = following.shift) && incl_to = from.at(".//*[@id='#{upto}']")
106
107
  while !incl_to.nil? && !from.nil? && skip_comment_wrap(from)
107
- (from = following.shift) && incl_to = from.at(".//*[@id='#{to}']")
108
+ (from = following.shift) && incl_to = from.at(".//*[@id='#{upto}']")
108
109
  end
109
110
  wrap_comment_cont(from, target) if !from.nil?
110
111
  end
@@ -122,6 +123,7 @@ module IsoDoc::HtmlFunction
122
123
  comments = []
123
124
  docxml.xpath("//div[@style='mso-element:comment']").each do |c|
124
125
  next unless c["id"] && !link_order[c["id"]].nil?
126
+
125
127
  comments << { text: c.remove.to_s, id: c["id"] }
126
128
  end
127
129
  comments.sort! { |a, b| link_order[a[:id]] <=> link_order[b[:id]] }
@@ -3,6 +3,7 @@ module IsoDoc::HtmlFunction
3
3
 
4
4
  def footnotes(div)
5
5
  return if @footnotes.empty?
6
+
6
7
  @footnotes.each { |fn| div.parent << fn }
7
8
  end
8
9
 
@@ -44,15 +45,19 @@ module IsoDoc::HtmlFunction
44
45
  def get_table_ancestor_id(node)
45
46
  table = node.ancestors("table") || node.ancestors("figure")
46
47
  return UUIDTools::UUID.random_create.to_s if table.empty?
48
+
47
49
  table.last["id"]
48
50
  end
49
51
 
52
+ # @seen_footnote:
53
+ # do not output footnote text if we have already seen it for this table
54
+
50
55
  def table_footnote_parse(node, out)
51
56
  fn = node["reference"] || UUIDTools::UUID.random_create.to_s
52
57
  tid = get_table_ancestor_id(node)
53
58
  make_table_footnote_link(out, tid + fn, fn)
54
- # do not output footnote text if we have already seen it for this table
55
59
  return if @seen_footnote.include?(tid + fn)
60
+
56
61
  @in_footnote = true
57
62
  out.aside **{ class: "footnote" } do |a|
58
63
  a << make_table_footnote_text(node, tid + fn, fn)
@@ -62,8 +67,9 @@ module IsoDoc::HtmlFunction
62
67
  end
63
68
 
64
69
  def footnote_parse(node, out)
65
- return table_footnote_parse(node, out) if (@in_table || @in_figure) &&
66
- !node.ancestors.map {|m| m.name }.include?("name")
70
+ return table_footnote_parse(node, out) if (@in_table || @in_figure) &&
71
+ !node.ancestors.map(&:name).include?("name")
72
+
67
73
  fn = node["reference"] || UUIDTools::UUID.random_create.to_s
68
74
  attrs = { class: "FootnoteRef", href: "#fn:#{fn}" }
69
75
  out.a **attrs do |a|
@@ -72,12 +78,13 @@ module IsoDoc::HtmlFunction
72
78
  make_footnote(node, fn)
73
79
  end
74
80
 
75
- def make_footnote(node, fn)
76
- return if @seen_footnote.include?(fn)
81
+ def make_footnote(node, fnote)
82
+ return if @seen_footnote.include?(fnote)
83
+
77
84
  @in_footnote = true
78
- @footnotes << make_generic_footnote_text(node, fn)
85
+ @footnotes << make_generic_footnote_text(node, fnote)
79
86
  @in_footnote = false
80
- @seen_footnote << fn
87
+ @seen_footnote << fnote
81
88
  end
82
89
  end
83
90
  end
@@ -0,0 +1,62 @@
1
+ module IsoDoc::HtmlFunction
2
+ module Form
3
+ def form_parse(node, out)
4
+ out.form **attr_code(id: node["id"], name: node["name"],
5
+ action: node["action"]) do |div|
6
+ node.children.each do |n|
7
+ parse(n, div)
8
+ end
9
+ end
10
+ end
11
+
12
+ def input_parse(node, out)
13
+ out.input nil, **attr_code(
14
+ id: node["id"], name: node["name"], type: node["type"],
15
+ value: node["value"], disabled: node["disabled"],
16
+ readonly: node["readonly"], checked: node["checked"],
17
+ maxlength: node["maxlength"], minlength: node["minlength"]
18
+ )
19
+ end
20
+
21
+ def select_parse(node, out)
22
+ selected = node.at(ns("./option[@value = '#{node['value']}']"))
23
+ selected and selected["selected"] = true
24
+ out.select **attr_code(
25
+ id: node["id"], name: node["name"], size: node["size"],
26
+ disabled: node["disabled"], multiple: node["multiple"]
27
+ ) do |div|
28
+ node.children.each do |n|
29
+ parse(n, div)
30
+ end
31
+ end
32
+ end
33
+
34
+ def label_parse(node, out)
35
+ out.label **attr_code(for: node["for"]) do |div|
36
+ node.children.each do |n|
37
+ parse(n, div)
38
+ end
39
+ end
40
+ end
41
+
42
+ def option_parse(node, out)
43
+ out.option **attr_code(
44
+ disabled: node["disabled"], selected: node["selected"],
45
+ value: node["value"]
46
+ ) do |o|
47
+ node.children.each do |n|
48
+ parse(n, o)
49
+ end
50
+ end
51
+ end
52
+
53
+ def textarea_parse(node, out)
54
+ out.textarea **attr_code(
55
+ id: node["id"], name: node["name"], rows: node["rows"],
56
+ cols: node["cols"]
57
+ ) do |div|
58
+ node["value"] and div << node["value"]
59
+ end
60
+ end
61
+ end
62
+ end
@@ -5,9 +5,9 @@ module IsoDoc::HtmlFunction
5
5
  module Html
6
6
  def convert1(docxml, filename, dir)
7
7
  noko do |xml|
8
- xml.html **{ lang: "#{@lang}" } do |html|
8
+ xml.html **{ lang: @lang.to_s } do |html|
9
9
  info docxml, nil
10
- populate_css()
10
+ populate_css
11
11
  html.head { |head| define_head head, filename, dir }
12
12
  make_body(html, docxml)
13
13
  end
@@ -15,13 +15,17 @@ module IsoDoc::HtmlFunction
15
15
  end
16
16
 
17
17
  def make_body1(body, _docxml)
18
+ return if @bare
19
+
18
20
  body.div **{ class: "title-section" } do |div1|
19
21
  div1.p { |p| p << "&nbsp;" } # placeholder
20
22
  end
21
23
  section_break(body)
22
24
  end
23
25
 
24
- def make_body2(body, docxml)
26
+ def make_body2(body, _docxml)
27
+ return if @bare
28
+
25
29
  body.div **{ class: "prefatory-section" } do |div2|
26
30
  div2.p { |p| p << "&nbsp;" } # placeholder
27
31
  end
@@ -43,46 +47,47 @@ module IsoDoc::HtmlFunction
43
47
  end
44
48
  end
45
49
 
46
- def googlefonts()
50
+ def googlefonts
47
51
  <<~HEAD.freeze
48
- <link href="https://fonts.googleapis.com/css?family=Overpass:300,300i,600,900" rel="stylesheet">
49
- <link href="https://fonts.googleapis.com/css?family=Lato:400,400i,700,900" rel="stylesheet">
52
+ <link href="https://fonts.googleapis.com/css?family=Overpass:300,300i,600,900" rel="stylesheet">
53
+ <link href="https://fonts.googleapis.com/css?family=Lato:400,400i,700,900" rel="stylesheet">
50
54
  HEAD
51
55
  end
52
56
 
53
- def html_head()
57
+ def html_head
54
58
  <<~HEAD.freeze
55
- <title>#{@meta&.get&.dig(:doctitle)}</title>
56
- <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
57
-
58
- <!--TOC script import-->
59
- <script type="text/javascript" src="https://cdn.rawgit.com/jgallen23/toc/0.3.2/dist/toc.min.js"></script>
60
- <script type="text/javascript">#{toclevel}</script>
61
-
62
- <!--Google fonts-->
63
- <link rel="preconnect" href="https://fonts.gstatic.com">
64
- #{googlefonts}
65
- <!--Font awesome import for the link icon-->
66
- <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.8/css/solid.css" integrity="sha384-v2Tw72dyUXeU3y4aM2Y0tBJQkGfplr39mxZqlTBDUZAb9BGoC40+rdFCG0m10lXk" crossorigin="anonymous">
67
- <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.8/css/fontawesome.css" integrity="sha384-q3jl8XQu1OpdLgGFvNRnPdj5VIlCvgsDQTQB6owSOHWlAurxul7f+JpUOVdAiJ5P" crossorigin="anonymous">
68
- <style class="anchorjs"></style>
59
+ <title>#{@meta&.get&.dig(:doctitle)}</title>
60
+ <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
61
+
62
+ <!--TOC script import-->
63
+ <script type="text/javascript" src="https://cdn.rawgit.com/jgallen23/toc/0.3.2/dist/toc.min.js"></script>
64
+ <script type="text/javascript">#{toclevel}</script>
65
+
66
+ <!--Google fonts-->
67
+ <link rel="preconnect" href="https://fonts.gstatic.com">#{' '}
68
+ #{googlefonts}
69
+ <!--Font awesome import for the link icon-->
70
+ <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.8/css/solid.css" integrity="sha384-v2Tw72dyUXeU3y4aM2Y0tBJQkGfplr39mxZqlTBDUZAb9BGoC40+rdFCG0m10lXk" crossorigin="anonymous">
71
+ <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.8/css/fontawesome.css" integrity="sha384-q3jl8XQu1OpdLgGFvNRnPdj5VIlCvgsDQTQB6owSOHWlAurxul7f+JpUOVdAiJ5P" crossorigin="anonymous">
72
+ <style class="anchorjs"></style>
69
73
  HEAD
70
74
  end
71
75
 
72
- def html_button()
76
+ def html_button
73
77
  '<button onclick="topFunction()" id="myBtn" '\
74
78
  'title="Go to top">Top</button>'.freeze
75
79
  end
76
80
 
77
81
  def html_main(docxml)
78
- docxml.at("//head").add_child(html_head())
82
+ docxml.at("//head").add_child(html_head)
79
83
  d = docxml.at('//div[@class="main-section"]')
80
84
  d.name = "main"
81
- d.children.empty? or d.children.first.previous = html_button()
85
+ d.children.empty? or d.children.first.previous = html_button
82
86
  end
83
87
 
84
88
  def sourcecodelang(lang)
85
89
  return unless lang
90
+
86
91
  case lang.downcase
87
92
  when "javascript" then "lang-js"
88
93
  when "c" then "lang-c"
@@ -117,7 +122,6 @@ module IsoDoc::HtmlFunction
117
122
  end
118
123
  end
119
124
 
120
- def table_long_strings_cleanup(docxml)
121
- end
125
+ def table_long_strings_cleanup(docxml); end
122
126
  end
123
127
  end
@@ -1,224 +1,233 @@
1
1
  require "isodoc/html_function/mathvariant_to_plain"
2
2
  require_relative "postprocess_footnotes"
3
3
 
4
- module IsoDoc::HtmlFunction
5
- module Html
6
- def postprocess(result, filename, _dir)
7
- result = from_xhtml(cleanup(to_xhtml(textcleanup(result))))
8
- toHTML(result, filename)
9
- @files_to_delete.each { |f| FileUtils.rm_rf f }
10
- end
4
+ module IsoDoc
5
+ module HtmlFunction
6
+ module Html
7
+ def postprocess(result, filename, _dir)
8
+ result = from_xhtml(cleanup(to_xhtml(textcleanup(result))))
9
+ toHTML(result, filename)
10
+ @files_to_delete.each { |f| FileUtils.rm_rf f }
11
+ end
11
12
 
12
- def script_cdata(result)
13
- result.gsub(%r{<script([^>]*)>\s*<!\[CDATA\[}m, "<script\\1>")
14
- .gsub(%r{\]\]>\s*</script>}, "</script>")
15
- .gsub(%r{<!\[CDATA\[\s*<script([^>]*)>}m, "<script\\1>")
16
- .gsub(%r{</script>\s*\]\]>}, "</script>")
17
- end
13
+ def script_cdata(result)
14
+ result.gsub(%r{<script([^>]*)>\s*<!\[CDATA\[}m, "<script\\1>")
15
+ .gsub(%r{\]\]>\s*</script>}, "</script>")
16
+ .gsub(%r{<!\[CDATA\[\s*<script([^>]*)>}m, "<script\\1>")
17
+ .gsub(%r{</script>\s*\]\]>}, "</script>")
18
+ end
18
19
 
19
- def toHTML(result, filename)
20
- result = from_xhtml(html_cleanup(to_xhtml(result)))
21
- # result = populate_template(result, :html)
22
- result = from_xhtml(move_images(to_xhtml(result)))
23
- result = html5(script_cdata(inject_script(result)))
24
- File.open(filename, "w:UTF-8") { |f| f.write(result) }
25
- end
20
+ def toHTML(result, filename)
21
+ result = from_xhtml(html_cleanup(to_xhtml(result)))
22
+ # result = populate_template(result, :html)
23
+ result = from_xhtml(move_images(to_xhtml(result)))
24
+ result = html5(script_cdata(inject_script(result)))
25
+ File.open(filename, "w:UTF-8") { |f| f.write(result) }
26
+ end
26
27
 
27
- def html5(doc)
28
- doc.sub(%r{<!DOCTYPE html [^>]+>}, "<!DOCTYPE html>")
29
- .sub(%r{<\?xml[^>]+>}, "")
30
- end
28
+ def html5(doc)
29
+ doc.sub(%r{<!DOCTYPE html [^>]+>}, "<!DOCTYPE html>")
30
+ .sub(%r{<\?xml[^>]+>}, "")
31
+ end
31
32
 
32
- def html_cleanup(x)
33
- mathml(
34
- footnote_format(
35
- footnote_backlinks(
36
- html_toc(
37
- term_header(html_footnote_filter(html_preface(htmlstyle(x))))
38
- )
39
- )
40
- )
41
- )
42
- end
33
+ def html_cleanup(html)
34
+ html = term_header(html_footnote_filter(html_preface(htmlstyle(html))))
35
+ html = footnote_format(footnote_backlinks(html_toc(html)))
36
+ mathml(html_list_clean(html))
37
+ end
43
38
 
44
- def mathml(docxml)
45
- IsoDoc::HtmlFunction::MathvariantToPlain.new(docxml).convert
46
- end
39
+ def html_list_clean(html)
40
+ html.xpath("//ol/div | //ul/div").each do |div|
41
+ li = div&.xpath("./preceding-sibling::li")&.last ||
42
+ div.at("./following-sibling::li")
43
+ div.parent = li
44
+ end
45
+ html
46
+ end
47
47
 
48
- def htmlstylesheet(file)
49
- return if file.nil?
48
+ def mathml(docxml)
49
+ IsoDoc::HtmlFunction::MathvariantToPlain.new(docxml).convert
50
+ end
50
51
 
51
- file.open if file.is_a?(Tempfile)
52
- stylesheet = file.read
53
- xml = Nokogiri::XML("<style/>")
54
- xml.children.first << Nokogiri::XML::Comment.new(xml, "\n#{stylesheet}\n")
55
- file.close
56
- file.unlink if file.is_a?(Tempfile)
57
- xml.root.to_s
58
- end
52
+ def htmlstylesheet(file)
53
+ return if file.nil?
54
+
55
+ file.open if file.is_a?(Tempfile)
56
+ stylesheet = file.read
57
+ xml = Nokogiri::XML("<style/>")
58
+ xml.children.first << Nokogiri::XML::Comment
59
+ .new(xml, "\n#{stylesheet}\n")
60
+ file.close
61
+ file.unlink if file.is_a?(Tempfile)
62
+ xml.root.to_s
63
+ end
59
64
 
60
- def htmlstyle(docxml)
61
- return docxml unless @htmlstylesheet
65
+ def htmlstyle(docxml)
66
+ return docxml unless @htmlstylesheet
62
67
 
63
- title = docxml.at("//*[local-name() = 'head']/*[local-name() = 'title']")
64
- head = docxml.at("//*[local-name() = 'head']")
65
- head << htmlstylesheet(@htmlstylesheet)
66
- s = htmlstylesheet(@htmlstylesheet_override) and head << s
67
- docxml
68
- end
68
+ head = docxml.at("//*[local-name() = 'head']")
69
+ head << htmlstylesheet(@htmlstylesheet)
70
+ s = htmlstylesheet(@htmlstylesheet_override) and head << s
71
+ docxml
72
+ end
69
73
 
70
- def html_preface(docxml)
71
- html_cover(docxml) if @htmlcoverpage
72
- html_intro(docxml) if @htmlintropage
73
- docxml.at("//body") << mathjax(@openmathdelim, @closemathdelim)
74
- docxml.at("//body") << sourcecode_highlighter
75
- html_main(docxml)
76
- authority_cleanup(docxml)
77
- docxml
78
- end
74
+ def html_preface(docxml)
75
+ html_cover(docxml) if @htmlcoverpage && !@bare
76
+ html_intro(docxml) if @htmlintropage && !@bare
77
+ docxml.at("//body") << mathjax(@openmathdelim, @closemathdelim)
78
+ docxml.at("//body") << sourcecode_highlighter
79
+ html_main(docxml)
80
+ authority_cleanup(docxml)
81
+ docxml
82
+ end
79
83
 
80
- def authority_cleanup1(docxml, klass)
81
- dest = docxml.at("//div[@id = 'boilerplate-#{klass}-destination']")
82
- auth = docxml.at("//div[@id = 'boilerplate-#{klass}' or @class = 'boilerplate-#{klass}']")
83
- auth&.xpath(".//h1[not(text())] | .//h2[not(text())]")&.each(&:remove)
84
- auth&.xpath(".//h1 | .//h2")&.each { |h| h["class"] = "IntroTitle" }
85
- dest and auth and dest.replace(auth.remove)
86
- end
84
+ def authority_cleanup1(docxml, klass)
85
+ dest = docxml.at("//div[@id = 'boilerplate-#{klass}-destination']")
86
+ auth = docxml.at("//div[@id = 'boilerplate-#{klass}' or "\
87
+ "@class = 'boilerplate-#{klass}']")
88
+ auth&.xpath(".//h1[not(text())] | .//h2[not(text())]")&.each(&:remove)
89
+ auth&.xpath(".//h1 | .//h2")&.each { |h| h["class"] = "IntroTitle" }
90
+ dest and auth and dest.replace(auth.remove)
91
+ end
87
92
 
88
- def authority_cleanup(docxml)
89
- %w(copyright license legal feedback).each do |t|
90
- authority_cleanup1(docxml, t)
93
+ def authority_cleanup(docxml)
94
+ %w(copyright license legal feedback).each do |t|
95
+ authority_cleanup1(docxml, t)
96
+ end
91
97
  end
92
- end
93
98
 
94
- def html_cover(docxml)
95
- doc = to_xhtml_fragment(File.read(@htmlcoverpage, encoding: "UTF-8"))
96
- d = docxml.at('//div[@class="title-section"]')
97
- # d.children.first.add_previous_sibling doc.to_xml(encoding: "US-ASCII")
98
- d.children.first.add_previous_sibling(
99
- populate_template(doc.to_xml(encoding: "US-ASCII"), :html)
100
- )
101
- end
99
+ def html_cover(docxml)
100
+ doc = to_xhtml_fragment(File.read(@htmlcoverpage, encoding: "UTF-8"))
101
+ d = docxml.at('//div[@class="title-section"]')
102
+ # d.children.first.add_previous_sibling doc.to_xml(encoding: "US-ASCII")
103
+ d.children.first.add_previous_sibling(
104
+ populate_template(doc.to_xml(encoding: "US-ASCII"), :html),
105
+ )
106
+ end
102
107
 
103
- def html_intro(docxml)
104
- doc = to_xhtml_fragment(File.read(@htmlintropage, encoding: "UTF-8"))
105
- d = docxml.at('//div[@class="prefatory-section"]')
106
- # d.children.first.add_previous_sibling doc.to_xml(encoding: "US-ASCII")
107
- d.children.first.add_previous_sibling(
108
- populate_template(doc.to_xml(encoding: "US-ASCII"), :html)
109
- )
110
- end
108
+ def html_intro(docxml)
109
+ doc = to_xhtml_fragment(File.read(@htmlintropage, encoding: "UTF-8"))
110
+ d = docxml.at('//div[@class="prefatory-section"]')
111
+ # d.children.first.add_previous_sibling doc.to_xml(encoding: "US-ASCII")
112
+ d.children.first.add_previous_sibling(
113
+ populate_template(doc.to_xml(encoding: "US-ASCII"), :html),
114
+ )
115
+ end
111
116
 
112
- def html_toc_entry(level, header)
113
- %(<li class="#{level}"><a href="##{header['id']}">\
117
+ def html_toc_entry(level, header)
118
+ %(<li class="#{level}"><a href="##{header['id']}">\
114
119
  #{header_strip(header)}</a></li>)
115
- end
116
-
117
- def toclevel_classes
118
- (1..@htmlToClevels).reduce([]) { |m, i| m << "h#{i}" }
119
- end
120
+ end
120
121
 
121
- def toclevel
122
- ret = toclevel_classes.map do |l|
123
- "#{l}:not(:empty):not(.TermNum):not(.noTOC)"
122
+ def toclevel_classes
123
+ (1..@htmlToClevels).reduce([]) { |m, i| m << "h#{i}" }
124
124
  end
125
- <<~HEAD.freeze
126
- function toclevel() { return "#{ret.join(',')}";}
127
- HEAD
128
- end
129
125
 
130
- # needs to be same output as toclevel
131
- def html_toc(docxml)
132
- (idx = docxml.at("//div[@id = 'toc']")) or (return docxml)
133
- toc = "<ul>"
134
- path = toclevel_classes.map do |l|
135
- "//main//#{l}[not(@class = 'TermNum')][not(@class = 'noTOC')][text()]"
126
+ def toclevel
127
+ ret = toclevel_classes.map do |l|
128
+ "#{l}:not(:empty):not(.TermNum):not(.noTOC)"
129
+ end
130
+ <<~HEAD.freeze
131
+ function toclevel() { return "#{ret.join(',')}";}
132
+ HEAD
136
133
  end
137
- docxml.xpath(path.join(" | ")).each_with_index do |h, tocidx|
138
- h["id"] ||= "toc#{tocidx}"
139
- toc += html_toc_entry(h.name, h)
134
+
135
+ # needs to be same output as toclevel
136
+ def html_toc(docxml)
137
+ idx = docxml.at("//div[@id = 'toc']") or return docxml
138
+ toc = "<ul>"
139
+ path = toclevel_classes.map do |l|
140
+ "//main//#{l}[not(@class = 'TermNum')][not(@class = 'noTOC')][text()]"
141
+ end
142
+ docxml.xpath(path.join(" | ")).each_with_index do |h, tocidx|
143
+ h["id"] ||= "toc#{tocidx}"
144
+ toc += html_toc_entry(h.name, h)
145
+ end
146
+ idx.children = "#{toc}</ul>"
147
+ docxml
140
148
  end
141
- idx.children = "#{toc}</ul>"
142
- docxml
143
- end
144
149
 
145
- # presupposes that the image source is local
146
- def move_images(docxml)
147
- FileUtils.rm_rf tmpimagedir
148
- FileUtils.mkdir tmpimagedir
149
- docxml.xpath("//*[local-name() = 'img']").each do |i|
150
- i["width"], i["height"] = Html2Doc.image_resize(i, image_localfile(i),
151
- @maxheight, @maxwidth)
152
- next if /^data:/.match i["src"]
150
+ # presupposes that the image source is local
151
+ def move_images(docxml)
152
+ FileUtils.rm_rf tmpimagedir
153
+ FileUtils.mkdir tmpimagedir
154
+ docxml.xpath("//*[local-name() = 'img']").each do |i|
155
+ i["width"], i["height"] = Html2Doc.image_resize(i, image_localfile(i),
156
+ @maxheight, @maxwidth)
157
+ next if /^data:/.match? i["src"]
153
158
 
154
- @datauriimage ? datauri(i) : move_image1(i)
159
+ @datauriimage ? datauri(i) : move_image1(i)
160
+ end
161
+ docxml
155
162
  end
156
- docxml
157
- end
158
163
 
159
- def datauri(img)
160
- type = img["src"].split(".")[-1]
161
- supertype = type == "xml" ? "application" : "image"
162
- bin = IO.binread(image_localfile(img))
163
- data = Base64.strict_encode64(bin)
164
- img["src"] = "data:#{supertype}/#{type};base64,#{data}"
165
- end
164
+ def datauri(img)
165
+ type = img["src"].split(".")[-1]
166
+ supertype = type == "xml" ? "application" : "image"
167
+ bin = IO.binread(image_localfile(img))
168
+ data = Base64.strict_encode64(bin)
169
+ img["src"] = "data:#{supertype}/#{type};base64,#{data}"
170
+ end
166
171
 
167
- def image_suffix(img)
168
- type = img["mimetype"]&.sub(%r{^[^/*]+/}, "")
169
- matched = /\.(?<suffix>[^. \r\n\t]+)$/.match img["src"]
170
- type and !type.empty? and return type
172
+ def image_suffix(img)
173
+ type = img["mimetype"]&.sub(%r{^[^/*]+/}, "")
174
+ matched = /\.(?<suffix>[^. \r\n\t]+)$/.match img["src"]
175
+ type and !type.empty? and return type
171
176
 
172
- !matched.nil? and matched[:suffix] and return matched[:suffix]
173
- "png"
174
- end
177
+ !matched.nil? and matched[:suffix] and return matched[:suffix]
178
+ "png"
179
+ end
175
180
 
176
- def move_image1(img)
177
- suffix = image_suffix(img)
178
- uuid = UUIDTools::UUID.random_create.to_s
179
- fname = "#{uuid}.#{suffix}"
180
- new_full_filename = File.join(tmpimagedir, fname)
181
- local_filename = image_localfile(img)
182
- FileUtils.cp local_filename, new_full_filename
183
- img["src"] = File.join(rel_tmpimagedir, fname)
184
- end
181
+ def move_image1(img)
182
+ suffix = image_suffix(img)
183
+ uuid = UUIDTools::UUID.random_create.to_s
184
+ fname = "#{uuid}.#{suffix}"
185
+ new_full_filename = File.join(tmpimagedir, fname)
186
+ local_filename = image_localfile(img)
187
+ FileUtils.cp local_filename, new_full_filename
188
+ img["src"] = File.join(rel_tmpimagedir, fname)
189
+ end
185
190
 
186
- def inject_script(doc)
187
- return doc unless @scripts
191
+ def inject_script(doc)
192
+ return doc unless @scripts
188
193
 
189
- scripts = File.read(@scripts, encoding: "UTF-8")
190
- a = doc.split(%r{</body>})
191
- a[0] + scripts + "</body>" + a[1]
192
- end
194
+ scripts = File.read(@scripts, encoding: "UTF-8")
195
+ scripts_override = ""
196
+ @scripts_override and
197
+ scripts_override = File.read(@scripts_override, encoding: "UTF-8")
198
+ a = doc.split(%r{</body>})
199
+ "#{a[0]}#{scripts}#{scripts_override}</body>#{a[1]}"
200
+ end
193
201
 
194
- def sourcecode_highlighter
195
- '<script src="https://cdn.rawgit.com/google/code-prettify/master/'\
196
- 'loader/run_prettify.js"></script>'
197
- end
202
+ def sourcecode_highlighter
203
+ '<script src="https://cdn.rawgit.com/google/code-prettify/master/'\
204
+ 'loader/run_prettify.js"></script>'
205
+ end
198
206
 
199
- MATHJAX_ADDR =
200
- "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js".freeze
201
- MATHJAX = <<~"MATHJAX".freeze
202
- <script type="text/x-mathjax-config">
203
- MathJax.Hub.Config({
204
- "HTML-CSS": { preferredFont: "STIX" },
205
- asciimath2jax: { delimiters: [['OPEN', 'CLOSE']] }
206
- });
207
- </script>
208
- <script src="#{MATHJAX_ADDR}?config=MML_HTMLorMML-full" async="async"></script>
209
- MATHJAX
210
-
211
- def mathjax(open, close)
212
- MATHJAX.gsub("OPEN", open).gsub("CLOSE", close)
213
- end
207
+ MATHJAX_ADDR =
208
+ "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js".freeze
209
+ MATHJAX = <<~"MATHJAX".freeze
210
+ <script type="text/x-mathjax-config">
211
+ MathJax.Hub.Config({
212
+ "HTML-CSS": { preferredFont: "STIX" },
213
+ asciimath2jax: { delimiters: [['OPEN', 'CLOSE']] }
214
+ });
215
+ </script>
216
+ <script src="#{MATHJAX_ADDR}?config=MML_HTMLorMML-full" async="async"></script>
217
+ MATHJAX
218
+
219
+ def mathjax(open, close)
220
+ MATHJAX.gsub("OPEN", open).gsub("CLOSE", close)
221
+ end
214
222
 
215
- def term_header(docxml)
216
- %w(h1 h2 h3 h4 h5 h6 h7 h8).each do |h|
217
- docxml.xpath("//p[@class = 'TermNum'][../#{h}]").each do |p|
218
- p.name = "h#{h[1].to_i + 1}"
223
+ def term_header(docxml)
224
+ %w(h1 h2 h3 h4 h5 h6 h7 h8).each do |h|
225
+ docxml.xpath("//p[@class = 'TermNum'][../#{h}]").each do |p|
226
+ p.name = "h#{h[1].to_i + 1}"
227
+ end
219
228
  end
229
+ docxml
220
230
  end
221
- docxml
222
231
  end
223
232
  end
224
233
  end