isodoc 2.3.2 → 2.3.4

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.
data/.rubocop.yml ADDED
@@ -0,0 +1,10 @@
1
+ # Auto-generated by Cimas: Do not edit it manually!
2
+ # See https://github.com/metanorma/cimas
3
+ inherit_from:
4
+ - https://raw.githubusercontent.com/riboseinc/oss-guides/master/ci/rubocop.yml
5
+
6
+ # local repo-specific modifications
7
+ # ...
8
+
9
+ AllCops:
10
+ TargetRubyVersion: 2.5
data/isodoc.gemspec CHANGED
@@ -25,23 +25,23 @@ Gem::Specification.new do |spec|
25
25
  spec.bindir = "bin"
26
26
  spec.require_paths = ["lib"]
27
27
  spec.files = `git ls-files -z`.split("\x0").reject do |f|
28
- f.match(%r{^(test|spec|features|.github)/}) \
29
- || f.match(%r{\.[a-zA-Z0-9_-]+\.yml|Rakefile|bin/rspec})
28
+ f.match(%r{^(test|spec|features|bin|.github)/}) \
29
+ || f.match(%r{Rakefile|bin/rspec})
30
30
  end
31
31
  spec.test_files = `git ls-files -- {spec}/*`.split("\n")
32
- spec.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
32
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.7.0")
33
33
 
34
34
  spec.add_dependency "asciimath"
35
- spec.add_dependency "html2doc", "~> 1.4.1"
35
+ spec.add_dependency "html2doc", "~> 1.4.3"
36
36
  spec.add_dependency "htmlentities", "~> 4.3.4"
37
37
  # spec.add_dependency "isodoc-i18n", "~> 1.1.0" # already in relaton-render and mn-requirements
38
38
  spec.add_dependency "liquid", "~> 4"
39
39
  # spec.add_dependency "metanorma", ">= 1.2.0"
40
40
  spec.add_dependency "emf2svg"
41
41
  spec.add_dependency "mathml2asciimath"
42
- spec.add_dependency "metanorma-utils", "~> 1.4.3"
42
+ spec.add_dependency "metanorma-utils", "~> 1.4.5"
43
43
  spec.add_dependency "mn2pdf"
44
- spec.add_dependency "mn-requirements", "~> 0.1.7"
44
+ spec.add_dependency "mn-requirements", "~> 0.2.0"
45
45
  spec.add_dependency "relaton-cli"
46
46
  spec.add_dependency "relaton-render", "~> 0.5.2"
47
47
  spec.add_dependency "roman-numerals"
@@ -35,7 +35,7 @@
35
35
  @include blockTitle();
36
36
  }
37
37
 
38
- > img {
38
+ > img, > svg {
39
39
  margin-left: auto;
40
40
  margin-right: auto;
41
41
  display: block;
@@ -47,6 +47,7 @@ module IsoDoc
47
47
  # tocrecommendations: add ToC for rcommendations
48
48
  # fonts: fontist fonts to install
49
49
  # fontlicenseagreement: fontist font license agreement
50
+ # modspecidentifierbase: base prefix for any Modspec identifiers
50
51
  def initialize(options) # rubocop:disable Lint/MissingSuper
51
52
  @options = options_preprocess(options)
52
53
  init_stylesheets(@options)
@@ -78,6 +79,7 @@ module IsoDoc
78
79
  @suppressasciimathdup = options[:suppressasciimathdup] == "true"
79
80
  @bare = options[:bare]
80
81
  @aligncrosselements = options[:aligncrosselements]
82
+ @modspecidentifierbase = options[:modspecidentifierbase]
81
83
  end
82
84
 
83
85
  def init_i18n(options)
@@ -216,7 +218,7 @@ module IsoDoc
216
218
  i18n_init(@lang, @script, @locale)
217
219
  @reqt_models = requirements_processor
218
220
  .new({ default: "default", lang: @lang, script: @script, locale: @locale,
219
- labels: @i18n.get })
221
+ labels: @i18n.get, modspecidentifierbase: @modspecidentifierbase })
220
222
  end
221
223
 
222
224
  def convert(input_filename, file = nil, debug = false,
@@ -71,7 +71,7 @@ module IsoDoc
71
71
  def bibitem_ref_code(bib)
72
72
  id = bib.at(ns("./docidentifier[@type = 'metanorma']"))
73
73
  id1 = pref_ref_code(bib)
74
- id2 = bib.at(ns("./docidentifier[@type = 'DOI' or @type = 'ISSN' or "\
74
+ id2 = bib.at(ns("./docidentifier[@type = 'DOI' or @type = 'ISSN' or " \
75
75
  "@type = 'ISBN']"))
76
76
  id3 = bib.at(ns("./docidentifier[@type = 'metanorma-ordinal']"))
77
77
  return [id, id1, id2, id3] if id || id1 || id2 || id3
@@ -179,7 +179,7 @@ module IsoDoc
179
179
  end
180
180
 
181
181
  def norm_ref_xpath
182
- "//bibliography/references[@normative = 'true'] | "\
182
+ "//bibliography/references[@normative = 'true'] | " \
183
183
  "//bibliography/clause[.//references[@normative = 'true']]"
184
184
  end
185
185
 
@@ -198,8 +198,8 @@ module IsoDoc
198
198
  end
199
199
 
200
200
  def bibliography_xpath
201
- "//bibliography/clause[.//references]"\
202
- "[not(.//references[@normative = 'true'])] | "\
201
+ "//bibliography/clause[.//references]" \
202
+ "[not(.//references[@normative = 'true'])] | " \
203
203
  "//bibliography/references[@normative = 'false']"
204
204
  end
205
205
 
@@ -82,7 +82,7 @@ module IsoDoc
82
82
  f = isoxml.at(ns("//sections/definitions")) or return num
83
83
  out.div **attr_code(id: f["id"], class: "Symbols") do |div|
84
84
  num = num + 1
85
- clause_name(num, f&.at(ns("./title")) || @i18n.symbols, div, nil)
85
+ clause_name(num, f.at(ns("./title")), div, nil)
86
86
  f.elements.each do |e|
87
87
  parse(e, div) unless e.name == "title"
88
88
  end
@@ -32,7 +32,8 @@ module IsoDoc
32
32
  def init_dir(filename, debug)
33
33
  dir = "#{filename}#{@tmpfilesdir_suffix}"
34
34
  unless debug
35
- Dir.mkdir(dir, 0o777) unless File.exist?(dir)
35
+ FileUtils.mkdir_p(dir)
36
+ FileUtils.chmod 0o777, dir
36
37
  FileUtils.rm_rf "#{dir}/*"
37
38
  end
38
39
  dir
@@ -205,10 +206,10 @@ module IsoDoc
205
206
  when "recommendation" then recommendation_parse(node, out)
206
207
  when "permission" then permission_parse(node, out)
207
208
  when "div" then div_parse(node, out)
208
- #when "subject", "classification"
209
+ # when "subject", "classification"
209
210
  # requirement_skip_parse(node, out)
210
- #when "inherit", "description", "specification", "measurement-target",
211
- #"verification", "import", "component"
211
+ # when "inherit", "description", "specification", "measurement-target",
212
+ # "verification", "import", "component"
212
213
  # requirement_component_parse(node, out)
213
214
  when "index" then index_parse(node, out)
214
215
  when "index-xref" then index_xref_parse(node, out)
@@ -1,3 +1,5 @@
1
+ require "metanorma-utils"
2
+
1
3
  module IsoDoc
2
4
  module Function
3
5
  module Utils
@@ -18,24 +20,8 @@ module IsoDoc
18
20
  [1..count].each { out << tab }
19
21
  end
20
22
 
21
- # add namespaces for Word fragments
22
- NOKOHEAD = <<~HERE.freeze
23
- <!DOCTYPE html SYSTEM
24
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
25
- <html xmlns="http://www.w3.org/1999/xhtml">
26
- <head> <title></title> <meta charset="UTF-8" /> </head>
27
- <body> </body> </html>
28
- HERE
29
-
30
- # block for processing XML document fragments as XHTML,
31
- # to allow for HTMLentities
32
23
  def noko(&block)
33
- doc = ::Nokogiri::XML.parse(NOKOHEAD)
34
- fragment = doc.fragment("")
35
- ::Nokogiri::XML::Builder.with fragment, &block
36
- fragment.to_xml(encoding: "US-ASCII").lines.map do |l|
37
- l.gsub(/\s*\n/, "")
38
- end
24
+ Metanorma::Utils::noko_html(&block)
39
25
  end
40
26
 
41
27
  def attr_code(attributes)
@@ -44,7 +30,7 @@ module IsoDoc
44
30
  end
45
31
  end
46
32
 
47
- DOCTYPE_HDR = "<!DOCTYPE html SYSTEM "\
33
+ DOCTYPE_HDR = "<!DOCTYPE html SYSTEM " \
48
34
  '"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'.freeze
49
35
 
50
36
  def to_xhtml(xml)
@@ -55,19 +41,13 @@ module IsoDoc
55
41
  File.open("#{@filename}.#{@format}.err", "w:UTF-8") do |f|
56
42
  f.write xml
57
43
  end
58
- abort "Malformed Output XML for #{@format}: #{e} "\
44
+ abort "Malformed Output XML for #{@format}: #{e} " \
59
45
  "(see #{@filename}.#{@format}.err)"
60
46
  end
61
47
  end
62
48
 
63
49
  def numeric_escapes(xml)
64
- c = HTMLEntities.new
65
- xml.split(/(&[^ \r\n\t#;]+;)/).map do |t|
66
- if /^(&[^ \t\r\n#;]+;)/.match?(t)
67
- c.encode(c.decode(t), :hexadecimal)
68
- else t
69
- end
70
- end.join
50
+ Metanorma::Utils::numeric_escapes(xml)
71
51
  end
72
52
 
73
53
  def to_xhtml_prep(xml)
@@ -77,8 +57,7 @@ module IsoDoc
77
57
  end
78
58
 
79
59
  def to_xhtml_fragment(xml)
80
- doc = ::Nokogiri::XML.parse(NOKOHEAD)
81
- doc.fragment(xml)
60
+ Metanorma::Utils::to_xhtml_fragment(xml)
82
61
  end
83
62
 
84
63
  def from_xhtml(xml)
@@ -87,11 +66,11 @@ module IsoDoc
87
66
  end
88
67
 
89
68
  CLAUSE_ANCESTOR =
90
- ".//ancestor::*[local-name() = 'annex' or "\
91
- "local-name() = 'definitions' or "\
92
- "local-name() = 'acknowledgements' or local-name() = 'term' or "\
93
- "local-name() = 'appendix' or local-name() = 'foreword' or "\
94
- "local-name() = 'introduction' or local-name() = 'terms' or "\
69
+ ".//ancestor::*[local-name() = 'annex' or " \
70
+ "local-name() = 'definitions' or " \
71
+ "local-name() = 'acknowledgements' or local-name() = 'term' or " \
72
+ "local-name() = 'appendix' or local-name() = 'foreword' or " \
73
+ "local-name() = 'introduction' or local-name() = 'terms' or " \
95
74
  "local-name() = 'clause' or local-name() = 'references']/@id".freeze
96
75
 
97
76
  def get_clause_id(node)
@@ -99,12 +78,12 @@ module IsoDoc
99
78
  end
100
79
 
101
80
  NOTE_CONTAINER_ANCESTOR =
102
- ".//ancestor::*[local-name() = 'annex' or "\
103
- "local-name() = 'foreword' or local-name() = 'appendix' or "\
104
- "local-name() = 'introduction' or local-name() = 'terms' or "\
105
- "local-name() = 'acknowledgements' or local-name() = 'term' or "\
106
- "local-name() = 'clause' or local-name() = 'references' or "\
107
- "local-name() = 'figure' or local-name() = 'formula' or "\
81
+ ".//ancestor::*[local-name() = 'annex' or " \
82
+ "local-name() = 'foreword' or local-name() = 'appendix' or " \
83
+ "local-name() = 'introduction' or local-name() = 'terms' or " \
84
+ "local-name() = 'acknowledgements' or local-name() = 'term' or " \
85
+ "local-name() = 'clause' or local-name() = 'references' or " \
86
+ "local-name() = 'figure' or local-name() = 'formula' or " \
108
87
  "local-name() = 'table' or local-name() = 'example']/@id".freeze
109
88
 
110
89
  # no recursion on references
@@ -121,7 +100,7 @@ module IsoDoc
121
100
 
122
101
  if array.length == 1 then array[0]
123
102
  else
124
- @i18n.l10n("#{array[0..-2].join(', ')} "\
103
+ @i18n.l10n("#{array[0..-2].join(', ')} " \
125
104
  "#{@i18n.and} #{array.last}",
126
105
  @lang, @script)
127
106
  end
@@ -197,7 +176,17 @@ module IsoDoc
197
176
  end
198
177
  end
199
178
 
179
+ def save_svg(img)
180
+ Tempfile.open(["image", ".svg"]) do |f|
181
+ f.write(img.to_xml)
182
+ @tempfile_cache << f # persist to the end
183
+ f.path
184
+ end
185
+ end
186
+
200
187
  def image_localfile(img)
188
+ img.name == "svg" && !img["src"] and
189
+ return save_svg(img)
201
190
  case img["src"]
202
191
  when /^data:/ then save_dataimage(img["src"], false)
203
192
  when %r{^([A-Z]:)?/} then img["src"]
@@ -206,7 +195,7 @@ module IsoDoc
206
195
  end
207
196
 
208
197
  def labelled_ancestor(node)
209
- !node.ancestors("example, requirement, recommendation, permission, "\
198
+ !node.ancestors("example, requirement, recommendation, permission, " \
210
199
  "note, table, figure, sourcecode").empty?
211
200
  end
212
201
 
@@ -1,5 +1,6 @@
1
1
  require "isodoc/html_function/mathvariant_to_plain"
2
2
  require_relative "postprocess_footnotes"
3
+ require_relative "postprocess_cover"
3
4
  require "metanorma-utils"
4
5
 
5
6
  module IsoDoc
@@ -11,16 +12,9 @@ module IsoDoc
11
12
  @files_to_delete.each { |f| FileUtils.rm_rf f }
12
13
  end
13
14
 
14
- def script_cdata(result)
15
- result.gsub(%r{<script([^>]*)>\s*<!\[CDATA\[}m, "<script\\1>")
16
- .gsub(%r{\]\]>\s*</script>}, "</script>")
17
- .gsub(%r{<!\[CDATA\[\s*<script([^>]*)>}m, "<script\\1>")
18
- .gsub(%r{</script>\s*\]\]>}, "</script>")
19
- end
20
-
21
15
  def toHTML(result, filename)
22
16
  result = from_xhtml(html_cleanup(to_xhtml(result)))
23
- result = from_xhtml(move_images(to_xhtml(result)))
17
+ result = from_xhtml(move_images(resize_images(to_xhtml(result))))
24
18
  result = html5(script_cdata(inject_script(result)))
25
19
  File.open(filename, "w:UTF-8") { |f| f.write(result) }
26
20
  end
@@ -56,132 +50,20 @@ module IsoDoc
56
50
  IsoDoc::HtmlFunction::MathvariantToPlain.new(docxml).convert
57
51
  end
58
52
 
59
- def htmlstylesheet(file)
60
- return if file.nil?
61
-
62
- file.open if file.is_a?(Tempfile)
63
- stylesheet = file.read
64
- xml = Nokogiri::XML("<style/>")
65
- xml.children.first << Nokogiri::XML::Comment
66
- .new(xml, "\n#{stylesheet}\n")
67
- file.close
68
- file.unlink if file.is_a?(Tempfile)
69
- xml.root.to_s
70
- end
71
-
72
- def htmlstyle(docxml)
73
- return docxml unless @htmlstylesheet
74
-
75
- head = docxml.at("//*[local-name() = 'head']")
76
- head << htmlstylesheet(@htmlstylesheet)
77
- s = htmlstylesheet(@htmlstylesheet_override) and head << s
78
- @bare and
79
- head << "<style>body {margin-left: 2em; margin-right: 2em;}</style>"
80
- docxml
81
- end
82
-
83
- def html_preface(docxml)
84
- html_cover(docxml) if @htmlcoverpage && !@bare
85
- html_intro(docxml) if @htmlintropage && !@bare
86
- docxml.at("//body") << mathjax(@openmathdelim, @closemathdelim)
87
- docxml.at("//body") << sourcecode_highlighter
88
- html_main(docxml)
89
- authority_cleanup(docxml)
90
- docxml
91
- end
92
-
93
- def authority_cleanup1(docxml, klass)
94
- dest = docxml.at("//div[@id = 'boilerplate-#{klass}-destination']")
95
- auth = docxml.at("//div[@id = 'boilerplate-#{klass}' or "\
96
- "@class = 'boilerplate-#{klass}']")
97
- auth&.xpath(".//h1[not(text())] | .//h2[not(text())]")&.each(&:remove)
98
- auth&.xpath(".//h1 | .//h2")&.each { |h| h["class"] = "IntroTitle" }
99
- dest and auth and dest.replace(auth.remove)
100
- end
101
-
102
- def authority_cleanup(docxml)
103
- %w(copyright license legal feedback).each do |t|
104
- authority_cleanup1(docxml, t)
105
- end
106
- coverpage_note_cleanup(docxml)
107
- end
108
-
109
- def coverpage_note_cleanup(docxml)
110
- if dest = docxml.at("//div[@id = 'coverpage-note-destination']")
111
- auth = docxml.xpath("//*[@coverpage]")
112
- if auth.empty? then dest.remove
113
- else
114
- auth.each do |x|
115
- dest << x.remove
116
- end
117
- end
118
- end
119
- docxml.xpath("//*[@coverpage]").each { |x| x.delete("coverpage") }
120
- end
121
-
122
- def html_cover(docxml)
123
- doc = to_xhtml_fragment(File.read(@htmlcoverpage, encoding: "UTF-8"))
124
- d = docxml.at('//div[@class="title-section"]')
125
- d.children.first.add_previous_sibling(
126
- populate_template(doc.to_xml(encoding: "US-ASCII"), :html),
127
- )
128
- end
129
-
130
- def html_intro(docxml)
131
- doc = to_xhtml_fragment(File.read(@htmlintropage, encoding: "UTF-8"))
132
- d = docxml.at('//div[@class="prefatory-section"]')
133
- d.children.first.add_previous_sibling(
134
- populate_template(doc.to_xml(encoding: "US-ASCII"), :html),
135
- )
136
- end
137
-
138
- def html_toc_entry(level, header)
139
- content = header.at("./following-sibling::p"\
140
- "[@class = 'variant-title-toc']") || header
141
- %(<li class="#{level}"><a href="##{header['id']}">\
142
- #{header_strip(content)}</a></li>)
143
- end
144
-
145
- def toclevel_classes
146
- (1..@htmlToClevels).reduce([]) { |m, i| m << "h#{i}" }
147
- end
148
-
149
- def toclevel
150
- ret = toclevel_classes.map do |l|
151
- "#{l}:not(:empty):not(.TermNum):not(.noTOC)"
152
- end
153
- <<~HEAD.freeze
154
- function toclevel() { return "#{ret.join(',')}";}
155
- HEAD
156
- end
157
-
158
- # needs to be same output as toclevel
159
- def html_toc(docxml)
160
- idx = docxml.at("//div[@id = 'toc']") or return docxml
161
- toc = "<ul>"
162
- path = toclevel_classes.map do |l|
163
- "//main//#{l}#{toc_exclude_class}"
164
- end
165
- docxml.xpath(path.join(" | ")).each_with_index do |h, tocidx|
166
- h["id"] ||= "toc#{tocidx}"
167
- toc += html_toc_entry(h.name, h)
53
+ def resize_images(docxml)
54
+ docxml.xpath("//*[local-name() = 'img' or local-name() = 'svg']")
55
+ .each do |i|
56
+ i["width"], i["height"] = Html2Doc.new({})
57
+ .image_resize(i, image_localfile(i), @maxheight, @maxwidth)
168
58
  end
169
- idx.children = "#{toc}</ul>"
170
59
  docxml
171
60
  end
172
61
 
173
- def toc_exclude_class
174
- "[not(@class = 'TermNum')][not(@class = 'noTOC')]"\
175
- "[string-length(normalize-space(.))>0]"
176
- end
177
-
178
62
  # presupposes that the image source is local
179
63
  def move_images(docxml)
180
64
  FileUtils.rm_rf tmpimagedir
181
65
  FileUtils.mkdir tmpimagedir
182
66
  docxml.xpath("//*[local-name() = 'img']").each do |i|
183
- i["width"], i["height"] = Html2Doc.new({})
184
- .image_resize(i, image_localfile(i), @maxheight, @maxwidth)
185
67
  next if /^data:/.match? i["src"]
186
68
 
187
69
  @datauriimage ? datauri(i) : move_image1(i)
@@ -212,38 +94,6 @@ module IsoDoc
212
94
  img["src"] = File.join(rel_tmpimagedir, fname)
213
95
  end
214
96
 
215
- def inject_script(doc)
216
- return doc unless @scripts
217
-
218
- scripts = File.read(@scripts, encoding: "UTF-8")
219
- scripts_override = ""
220
- @scripts_override and
221
- scripts_override = File.read(@scripts_override, encoding: "UTF-8")
222
- a = doc.split(%r{</body>})
223
- "#{a[0]}#{scripts}#{scripts_override}</body>#{a[1]}"
224
- end
225
-
226
- def sourcecode_highlighter
227
- '<script src="https://cdn.rawgit.com/google/code-prettify/master/'\
228
- 'loader/run_prettify.js"></script>'
229
- end
230
-
231
- MATHJAX_ADDR =
232
- "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js".freeze
233
- MATHJAX = <<~"MATHJAX".freeze
234
- <script type="text/x-mathjax-config">
235
- MathJax.Hub.Config({
236
- "HTML-CSS": { preferredFont: "STIX" },
237
- asciimath2jax: { delimiters: [['OPEN', 'CLOSE']] }
238
- });
239
- </script>
240
- <script src="#{MATHJAX_ADDR}?config=MML_HTMLorMML-full" async="async"></script>
241
- MATHJAX
242
-
243
- def mathjax(open, close)
244
- MATHJAX.gsub("OPEN", open).gsub("CLOSE", close)
245
- end
246
-
247
97
  def term_header(docxml)
248
98
  %w(h1 h2 h3 h4 h5 h6 h7 h8).each do |h|
249
99
  docxml.xpath("//p[@class = 'TermNum'][../#{h}]").each do |p|
@@ -0,0 +1,167 @@
1
+ require "isodoc/html_function/mathvariant_to_plain"
2
+ require_relative "postprocess_footnotes"
3
+ require "metanorma-utils"
4
+
5
+ module IsoDoc
6
+ module HtmlFunction
7
+ module Html
8
+ def script_cdata(result)
9
+ result.gsub(%r{<script([^>]*)>\s*<!\[CDATA\[}m, "<script\\1>")
10
+ .gsub(%r{\]\]>\s*</script>}, "</script>")
11
+ .gsub(%r{<!\[CDATA\[\s*<script([^>]*)>}m, "<script\\1>")
12
+ .gsub(%r{</script>\s*\]\]>}, "</script>")
13
+ end
14
+
15
+ def htmlstylesheet(file)
16
+ return if file.nil?
17
+
18
+ file.open if file.is_a?(Tempfile)
19
+ stylesheet = file.read
20
+ xml = Nokogiri::XML("<style/>")
21
+ xml.children.first << Nokogiri::XML::Comment
22
+ .new(xml, "\n#{stylesheet}\n")
23
+ file.close
24
+ file.unlink if file.is_a?(Tempfile)
25
+ xml.root.to_s
26
+ end
27
+
28
+ def htmlstyle(docxml)
29
+ return docxml unless @htmlstylesheet
30
+
31
+ head = docxml.at("//*[local-name() = 'head']")
32
+ head << htmlstylesheet(@htmlstylesheet)
33
+ s = htmlstylesheet(@htmlstylesheet_override) and head << s
34
+ @bare and
35
+ head << "<style>body {margin-left: 2em; margin-right: 2em;}</style>"
36
+ docxml
37
+ end
38
+
39
+ def html_preface(docxml)
40
+ html_cover(docxml) if @htmlcoverpage && !@bare
41
+ html_intro(docxml) if @htmlintropage && !@bare
42
+ docxml.at("//body") << mathjax(@openmathdelim, @closemathdelim)
43
+ docxml.at("//body") << sourcecode_highlighter
44
+ html_main(docxml)
45
+ authority_cleanup(docxml)
46
+ docxml
47
+ end
48
+
49
+ def authority_cleanup1(docxml, klass)
50
+ dest = docxml.at("//div[@id = 'boilerplate-#{klass}-destination']")
51
+ auth = docxml.at("//div[@id = 'boilerplate-#{klass}' or "\
52
+ "@class = 'boilerplate-#{klass}']")
53
+ auth&.xpath(".//h1[not(text())] | .//h2[not(text())]")&.each(&:remove)
54
+ auth&.xpath(".//h1 | .//h2")&.each { |h| h["class"] = "IntroTitle" }
55
+ dest and auth and dest.replace(auth.remove)
56
+ end
57
+
58
+ def authority_cleanup(docxml)
59
+ %w(copyright license legal feedback).each do |t|
60
+ authority_cleanup1(docxml, t)
61
+ end
62
+ coverpage_note_cleanup(docxml)
63
+ end
64
+
65
+ def coverpage_note_cleanup(docxml)
66
+ if dest = docxml.at("//div[@id = 'coverpage-note-destination']")
67
+ auth = docxml.xpath("//*[@coverpage]")
68
+ if auth.empty? then dest.remove
69
+ else
70
+ auth.each do |x|
71
+ dest << x.remove
72
+ end
73
+ end
74
+ end
75
+ docxml.xpath("//*[@coverpage]").each { |x| x.delete("coverpage") }
76
+ end
77
+
78
+ def html_cover(docxml)
79
+ doc = to_xhtml_fragment(File.read(@htmlcoverpage, encoding: "UTF-8"))
80
+ d = docxml.at('//div[@class="title-section"]')
81
+ d.children.first.add_previous_sibling(
82
+ populate_template(doc.to_xml(encoding: "US-ASCII"), :html),
83
+ )
84
+ end
85
+
86
+ def html_intro(docxml)
87
+ doc = to_xhtml_fragment(File.read(@htmlintropage, encoding: "UTF-8"))
88
+ d = docxml.at('//div[@class="prefatory-section"]')
89
+ d.children.first.add_previous_sibling(
90
+ populate_template(doc.to_xml(encoding: "US-ASCII"), :html),
91
+ )
92
+ end
93
+
94
+ def html_toc_entry(level, header)
95
+ content = header.at("./following-sibling::p"\
96
+ "[@class = 'variant-title-toc']") || header
97
+ %(<li class="#{level}"><a href="##{header['id']}">\
98
+ #{header_strip(content)}</a></li>)
99
+ end
100
+
101
+ def toclevel_classes
102
+ (1..@htmlToClevels).reduce([]) { |m, i| m << "h#{i}" }
103
+ end
104
+
105
+ def toclevel
106
+ ret = toclevel_classes.map do |l|
107
+ "#{l}:not(:empty):not(.TermNum):not(.noTOC)"
108
+ end
109
+ <<~HEAD.freeze
110
+ function toclevel() { return "#{ret.join(',')}";}
111
+ HEAD
112
+ end
113
+
114
+ # needs to be same output as toclevel
115
+ def html_toc(docxml)
116
+ idx = docxml.at("//div[@id = 'toc']") or return docxml
117
+ toc = "<ul>"
118
+ path = toclevel_classes.map do |l|
119
+ "//main//#{l}#{toc_exclude_class}"
120
+ end
121
+ docxml.xpath(path.join(" | ")).each_with_index do |h, tocidx|
122
+ h["id"] ||= "toc#{tocidx}"
123
+ toc += html_toc_entry(h.name, h)
124
+ end
125
+ idx.children = "#{toc}</ul>"
126
+ docxml
127
+ end
128
+
129
+ def toc_exclude_class
130
+ "[not(@class = 'TermNum')][not(@class = 'noTOC')]"\
131
+ "[string-length(normalize-space(.))>0]"
132
+ end
133
+
134
+ def inject_script(doc)
135
+ return doc unless @scripts
136
+
137
+ scripts = File.read(@scripts, encoding: "UTF-8")
138
+ scripts_override = ""
139
+ @scripts_override and
140
+ scripts_override = File.read(@scripts_override, encoding: "UTF-8")
141
+ a = doc.split(%r{</body>})
142
+ "#{a[0]}#{scripts}#{scripts_override}</body>#{a[1]}"
143
+ end
144
+
145
+ def sourcecode_highlighter
146
+ '<script src="https://cdn.rawgit.com/google/code-prettify/master/'\
147
+ 'loader/run_prettify.js"></script>'
148
+ end
149
+
150
+ MATHJAX_ADDR =
151
+ "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js".freeze
152
+ MATHJAX = <<~"MATHJAX".freeze
153
+ <script type="text/x-mathjax-config">
154
+ MathJax.Hub.Config({
155
+ "HTML-CSS": { preferredFont: "STIX" },
156
+ asciimath2jax: { delimiters: [['OPEN', 'CLOSE']] }
157
+ });
158
+ </script>
159
+ <script src="#{MATHJAX_ADDR}?config=MML_HTMLorMML-full" async="async"></script>
160
+ MATHJAX
161
+
162
+ def mathjax(open, close)
163
+ MATHJAX.gsub("OPEN", open).gsub("CLOSE", close)
164
+ end
165
+ end
166
+ end
167
+ end
@@ -108,6 +108,11 @@ module IsoDoc
108
108
 
109
109
  def svg_to_emf(node)
110
110
  uri = svg_to_emf_uri(node)
111
+ if node.elements&.first&.name == "svg" &&
112
+ (!node["height"] || node["height"] == "auto")
113
+ node["height"] = node.elements.first["height"]
114
+ node["width"] = node.elements.first["width"]
115
+ end
111
116
  ret = imgfile_suffix(uri, "emf")
112
117
  File.exist?(ret) and return ret
113
118
  inkscape_convert(uri, ret, '--export-type="emf"')
@@ -143,7 +148,7 @@ module IsoDoc
143
148
  end
144
149
 
145
150
  def svg_to_emf_uri_convert(node)
146
- if node&.elements&.first&.name == "svg"
151
+ if node.elements&.first&.name == "svg"
147
152
  a = Base64.strict_encode64(node.children.to_xml)
148
153
  "data:image/svg+xml;base64,#{a}"
149
154
  else node["src"]