isodoc 1.6.3 → 1.6.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) 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 -6
  5. data/isodoc.gemspec +3 -2
  6. data/lib/isodoc-yaml/i18n-en.yaml +1 -0
  7. data/lib/isodoc-yaml/i18n-fr.yaml +1 -0
  8. data/lib/isodoc-yaml/i18n-zh-Hans.yaml +1 -0
  9. data/lib/isodoc.rb +0 -2
  10. data/lib/isodoc/convert.rb +7 -1
  11. data/lib/isodoc/function/blocks.rb +5 -4
  12. data/lib/isodoc/function/cleanup.rb +52 -43
  13. data/lib/isodoc/function/inline.rb +7 -7
  14. data/lib/isodoc/function/references.rb +33 -52
  15. data/lib/isodoc/function/section.rb +28 -16
  16. data/lib/isodoc/function/table.rb +21 -22
  17. data/lib/isodoc/function/terms.rb +6 -7
  18. data/lib/isodoc/function/to_word_html.rb +6 -3
  19. data/lib/isodoc/function/utils.rb +181 -163
  20. data/lib/isodoc/gem_tasks.rb +8 -9
  21. data/lib/isodoc/headlesshtml_convert.rb +8 -7
  22. data/lib/isodoc/html_convert.rb +5 -1
  23. data/lib/isodoc/html_function/comments.rb +14 -12
  24. data/lib/isodoc/html_function/footnotes.rb +14 -7
  25. data/lib/isodoc/html_function/html.rb +30 -26
  26. data/lib/isodoc/html_function/postprocess.rb +191 -182
  27. data/lib/isodoc/html_function/sectionsplit.rb +230 -0
  28. data/lib/isodoc/metadata.rb +22 -20
  29. data/lib/isodoc/metadata_contributor.rb +31 -28
  30. data/lib/isodoc/pdf_convert.rb +11 -13
  31. data/lib/isodoc/presentation_function/bibdata.rb +50 -22
  32. data/lib/isodoc/presentation_function/inline.rb +20 -15
  33. data/lib/isodoc/presentation_function/section.rb +38 -1
  34. data/lib/isodoc/presentation_xml_convert.rb +2 -0
  35. data/lib/isodoc/version.rb +1 -1
  36. data/lib/isodoc/word_function/postprocess.rb +50 -36
  37. data/lib/isodoc/xref.rb +2 -0
  38. data/lib/isodoc/xref/xref_gen_seq.rb +60 -35
  39. data/lib/isodoc/xref/xref_sect_gen.rb +4 -4
  40. data/spec/assets/scripts_override.html +3 -0
  41. data/spec/isodoc/blocks_spec.rb +373 -685
  42. data/spec/isodoc/cleanup_spec.rb +40 -42
  43. data/spec/isodoc/i18n_spec.rb +694 -821
  44. data/spec/isodoc/inline_spec.rb +482 -328
  45. data/spec/isodoc/metadata_spec.rb +384 -379
  46. data/spec/isodoc/postproc_spec.rb +163 -55
  47. data/spec/isodoc/presentation_xml_spec.rb +355 -278
  48. data/spec/isodoc/ref_spec.rb +5 -5
  49. data/spec/isodoc/section_spec.rb +216 -199
  50. data/spec/isodoc/sectionsplit_spec.rb +190 -0
  51. data/spec/isodoc/table_spec.rb +41 -42
  52. data/spec/isodoc/terms_spec.rb +84 -84
  53. data/spec/isodoc/xref_spec.rb +974 -932
  54. metadata +22 -5
@@ -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)
@@ -1,8 +1,9 @@
1
1
  require_relative "html_function/comments"
2
2
  require_relative "html_function/footnotes"
3
3
  require_relative "html_function/html"
4
- require_relative "html_function/form"
5
4
  require_relative "html_function/postprocess"
5
+ require_relative "html_function/sectionsplit"
6
+ require_relative "html_function/form"
6
7
 
7
8
  module IsoDoc
8
9
  class HtmlConvert < ::IsoDoc::Convert
@@ -23,6 +24,9 @@ module IsoDoc
23
24
  end
24
25
 
25
26
  def convert(filename, file = nil, debug = false, output_filename = nil)
27
+ @sectionsplit and
28
+ return sectionsplit_convert(filename, file, debug, output_filename)
29
+
26
30
  ret = super
27
31
  Dir.exists?(tmpimagedir) and Dir["#{tmpimagedir}/*"].empty? and
28
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
@@ -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