isodoc 2.3.2 → 2.3.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e09ef612cbed34d00104fae8b5aa9d6d4f17898cfbf4cae3255fdbb6218f402b
4
- data.tar.gz: b91758dc84682c50def94dd0904de92deb862fc1ffcd5c2af81f635fabece882
3
+ metadata.gz: 73982c33aa666aee412b32318f01d964e21a7d2dfbb6d3afca3b19c7c0268549
4
+ data.tar.gz: 90fb6621afc2fedcc1c0db06d83a8bc53d96f0d62eb382cdb4d94f773a25c477
5
5
  SHA512:
6
- metadata.gz: c61751e1d304d84e32d26626b03849d26c479f6422636665352415eba04be416cc431786e05a45a88329c73e67096f10f3a27465c94c0bac73fa96caad98d3b7
7
- data.tar.gz: 9c6f2492605198aad0d0548de81d69fb7cac42efcaab0d4ee9bf4c1afd0a9eef5bdf1d8317cf3df3d785d42d0e8cec69f0a480acb0c505f8bf6d1e03222eb993
6
+ metadata.gz: 0bb5d3dff4fd0f0ca32f424d3600685d974658a3fa69fa5593c91e59b3b9eb9dbc1f1bb62c28ae43277debf62ced423a4c3bff485411f14ef6777f74c126d999
7
+ data.tar.gz: 6b9e739460d40e0d74129563cbcdce6573348d7838380723dca798411f7e4a0f2882c50bd5a275cd7b3e58ec27cb87014a512dc41b2545707301bfbc007b8894
data/isodoc.gemspec CHANGED
@@ -32,16 +32,16 @@ Gem::Specification.new do |spec|
32
32
  spec.required_ruby_version = Gem::Requirement.new(">= 2.5.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;
@@ -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"]
@@ -212,9 +212,9 @@ module IsoDoc
212
212
  end
213
213
 
214
214
  def variant1(node)
215
- if (!node["lang"] || node["lang"] == @lang) &&
216
- (!node["script"] || node["script"] == @script)
217
- elsif found_matching_variant_sibling(node)
215
+ if !((!node["lang"] || node["lang"] == @lang) &&
216
+ (!node["script"] || node["script"] == @script)) &&
217
+ found_matching_variant_sibling(node)
218
218
  node["remove"] = "true"
219
219
  end
220
220
  end
@@ -1,7 +1,8 @@
1
1
  module IsoDoc
2
2
  class PresentationXMLConvert < ::IsoDoc::Convert
3
- def prefix_container(container, linkend, _target)
4
- l10n("#{@xrefs.anchor(container, :xref)}, #{linkend}")
3
+ def prefix_container(container, linkend, node, _target)
4
+ # l10n("#{@xrefs.anchor(container, :xref)}, #{linkend}")
5
+ l10n("#{anchor_xref(node, container)}, #{linkend}")
5
6
  end
6
7
 
7
8
  def anchor_value(id)
@@ -24,13 +25,24 @@ module IsoDoc
24
25
  end
25
26
 
26
27
  def anchor_linkend1(node)
27
- linkend = @xrefs.anchor(node["target"], :xref)
28
+ linkend = anchor_xref(node, node["target"])
28
29
  container = @xrefs.anchor(node["target"], :container, false)
29
30
  prefix_container?(container, node) and
30
- linkend = prefix_container(container, linkend, node["target"])
31
+ linkend = prefix_container(container, linkend, node, node["target"])
31
32
  capitalise_xref(node, linkend, anchor_value(node["target"]))
32
33
  end
33
34
 
35
+ def anchor_xref(node, target)
36
+ x = @xrefs.anchor(target, :xref)
37
+ t = @xrefs.anchor(target, :title)
38
+ if node["style"] == "basic" && t then t
39
+ elsif node["style"] == "full" && t
40
+ l10n("#{x}, #{t}")
41
+ else
42
+ x
43
+ end
44
+ end
45
+
34
46
  def prefix_container?(container, node)
35
47
  type = @xrefs.anchor(node["target"], :type)
36
48
  container &&
@@ -55,7 +67,8 @@ module IsoDoc
55
67
  container = @xrefs.anchor(locs.first[:node]["target"], :container,
56
68
  false)
57
69
  prefix_container?(container, locs.first[:node]) and
58
- ret = prefix_container(container, ret, locs.first[:node]["target"])
70
+ ret = prefix_container(container, ret, locs.first[:node],
71
+ locs.first[:node]["target"])
59
72
  ret
60
73
  end
61
74
 
@@ -1,3 +1,3 @@
1
1
  module IsoDoc
2
- VERSION = "2.3.2".freeze
2
+ VERSION = "2.3.3".freeze
3
3
  end
@@ -38,6 +38,8 @@ module IsoDoc
38
38
  def image_parse(node, out, caption)
39
39
  if emf = node.at(ns("./emf"))
40
40
  node["src"] = emf["src"]
41
+ node["height"] ||= emf["height"]
42
+ node["width"] ||= emf["width"]
41
43
  node["mimetype"] = "image/x-emf"
42
44
  node.children.remove
43
45
  end
@@ -51,8 +51,13 @@ module IsoDoc
51
51
  bookmark_anchor_names(doc)
52
52
  end
53
53
 
54
- def preface_clause_name(clause)
55
- clause.at(ns("./title"))&.text || clause.name.capitalize
54
+ def clause_title(clause, use_elem_name: false)
55
+ ret = clause.at(ns("./title"))&.text
56
+ if use_elem_name && !ret
57
+ clause.name.capitalize
58
+ else
59
+ ret
60
+ end
56
61
  end
57
62
 
58
63
  SUBCLAUSES =
@@ -62,25 +67,30 @@ module IsoDoc
62
67
  def preface_names(clause)
63
68
  return if clause.nil?
64
69
 
65
- @anchors[clause["id"]] =
66
- { label: nil, level: 1, xref: preface_clause_name(clause),
67
- type: "clause", elem: @labels["clause"] }
70
+ preface_name_anchors(clause, 1,
71
+ clause_title(clause, use_elem_name: true))
68
72
  clause.xpath(ns(SUBCLAUSES)).each_with_index do |c, i|
69
73
  preface_names1(c, c.at(ns("./title"))&.text,
70
- "#{preface_clause_name(clause)}, #{i + 1}", 2)
74
+ "#{clause_title(clause)}, #{i + 1}", 2)
71
75
  end
72
76
  end
73
77
 
74
78
  def preface_names1(clause, title, parent_title, level)
75
79
  label = title || parent_title
76
- @anchors[clause["id"]] = { label: nil, level: level, xref: label,
77
- type: "clause", elem: @labels["clause"] }
80
+ preface_name_anchors(clause, level, title || parent_title)
78
81
  clause.xpath(ns(SUBCLAUSES)).each_with_index do |c, i|
79
82
  preface_names1(c, c.at(ns("./title"))&.text, "#{label} #{i + 1}",
80
83
  level + 1)
81
84
  end
82
85
  end
83
86
 
87
+ def preface_name_anchors(clause, level, title)
88
+ @anchors[clause["id"]] =
89
+ { label: nil, level: level,
90
+ xref: title, title: nil,
91
+ type: "clause", elem: @labels["clause"] }
92
+ end
93
+
84
94
  def middle_section_asset_names(doc)
85
95
  middle_sections = "//clause[@type = 'scope'] | "\
86
96
  "#{@klass.norm_ref_xpath} | "\
@@ -90,35 +100,38 @@ module IsoDoc
90
100
  end
91
101
 
92
102
  def clause_names(docxml, num)
93
- docxml.xpath(ns(@klass.middle_clause(docxml))).each_with_index do |c, _i|
103
+ docxml.xpath(ns(@klass.middle_clause(docxml)))
104
+ .each_with_index do |c, _i|
94
105
  section_names(c, num, 1)
95
106
  end
96
107
  end
97
108
 
98
109
  def section_names(clause, num, lvl)
99
- return num if clause.nil?
110
+ clause.nil? and return num
100
111
 
101
112
  num.increment(clause)
102
- @anchors[clause["id"]] =
103
- { label: num.print, xref: l10n("#{@labels['clause']} #{num.print}"),
104
- level: lvl, type: "clause", elem: @labels["clause"] }
105
- i = Counter.new
106
- clause.xpath(ns(SUBCLAUSES)).each do |c|
113
+ section_name_anchors(clause, num.print, lvl)
114
+ clause.xpath(ns(SUBCLAUSES)).each_with_object(Counter.new) do |c, i|
107
115
  section_names1(c, "#{num.print}.#{i.increment(c).print}", lvl + 1)
108
116
  end
109
117
  num
110
118
  end
111
119
 
112
120
  def section_names1(clause, num, level)
113
- @anchors[clause["id"]] =
114
- { label: num, level: level, xref: l10n("#{@labels['clause']} #{num}"),
115
- type: "clause", elem: @labels["clause"] }
121
+ section_name_anchors(clause, num, level)
116
122
  i = Counter.new
117
123
  clause.xpath(ns(SUBCLAUSES)).each do |c|
118
124
  section_names1(c, "#{num}.#{i.increment(c).print}", level + 1)
119
125
  end
120
126
  end
121
127
 
128
+ def section_name_anchors(clause, num, level)
129
+ @anchors[clause["id"]] =
130
+ { label: num, xref: l10n("#{@labels['clause']} #{num}"),
131
+ title: clause_title(clause), level: level, type: "clause",
132
+ elem: @labels["clause"] }
133
+ end
134
+
122
135
  def annex_name_lbl(clause, num)
123
136
  obl = l10n("(#{@labels['inform_annex']})")
124
137
  clause["obligation"] == "normative" and
@@ -127,21 +140,23 @@ module IsoDoc
127
140
  l10n("<strong>#{title} #{num}</strong><br/>#{obl}")
128
141
  end
129
142
 
130
- def annex_name_anchors(clause, num)
131
- { label: annex_name_lbl(clause, num),
132
- elem: @labels["annex"], type: "clause",
133
- subtype: "annex", value: num.to_s, level: 1,
134
- xref: "#{@labels['annex']} #{num}" }
143
+ def annex_name_anchors(clause, num, level)
144
+ label = level == 1 ? annex_name_lbl(clause, num) : num
145
+ @anchors[clause["id"]] =
146
+ { label: label,
147
+ elem: @labels["annex"], type: "clause",
148
+ subtype: "annex", value: num.to_s, level: level,
149
+ title: clause_title(clause),
150
+ xref: "#{@labels['annex']} #{num}" }
135
151
  end
136
152
 
137
153
  def annex_names(clause, num)
138
- @anchors[clause["id"]] = annex_name_anchors(clause, num)
154
+ annex_name_anchors(clause, num, 1)
139
155
  if @klass.single_term_clause?(clause)
140
156
  annex_names1(clause.at(ns("./references | ./terms | ./definitions")),
141
157
  num.to_s, 1)
142
158
  else
143
- i = Counter.new
144
- clause.xpath(ns(SUBCLAUSES)).each do |c|
159
+ clause.xpath(ns(SUBCLAUSES)).each_with_object(Counter.new) do |c, i|
145
160
  annex_names1(c, "#{num}.#{i.increment(c).print}", 2)
146
161
  end
147
162
  end
@@ -149,9 +164,7 @@ module IsoDoc
149
164
  end
150
165
 
151
166
  def annex_names1(clause, num, level)
152
- @anchors[clause["id"]] = { xref: "#{@labels['annex']} #{num}",
153
- elem: @labels["annex"], type: "clause",
154
- label: num, level: level, subtype: "annex" }
167
+ annex_name_anchors(clause, num, level)
155
168
  i = Counter.new
156
169
  clause.xpath(ns(SUBCLAUSES)).each do |c|
157
170
  annex_names1(c, "#{num}.#{i.increment(c).print}", level + 1)
@@ -61,7 +61,7 @@ table: Table
61
61
  requirement: Requirement
62
62
  recommendation: Recommendation
63
63
  permission: Permission
64
- # OGC
64
+ # Modspec
65
65
  recommendationtest: Recommendation test
66
66
  requirementtest: Requirement test
67
67
  permissiontest: Permission test
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: isodoc
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.2
4
+ version: 2.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-10-10 00:00:00.000000000 Z
11
+ date: 2022-10-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asciimath
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 1.4.1
33
+ version: 1.4.3
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 1.4.1
40
+ version: 1.4.3
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: htmlentities
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -100,14 +100,14 @@ dependencies:
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: 1.4.3
103
+ version: 1.4.5
104
104
  type: :runtime
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: 1.4.3
110
+ version: 1.4.5
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: mn2pdf
113
113
  requirement: !ruby/object:Gem::Requirement
@@ -128,14 +128,14 @@ dependencies:
128
128
  requirements:
129
129
  - - "~>"
130
130
  - !ruby/object:Gem::Version
131
- version: 0.1.7
131
+ version: 0.2.0
132
132
  type: :runtime
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
- version: 0.1.7
138
+ version: 0.2.0
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: relaton-cli
141
141
  requirement: !ruby/object:Gem::Requirement
@@ -446,6 +446,7 @@ files:
446
446
  - lib/isodoc/html_function/html.rb
447
447
  - lib/isodoc/html_function/mathvariant_to_plain.rb
448
448
  - lib/isodoc/html_function/postprocess.rb
449
+ - lib/isodoc/html_function/postprocess_cover.rb
449
450
  - lib/isodoc/html_function/postprocess_footnotes.rb
450
451
  - lib/isodoc/i18n.rb
451
452
  - lib/isodoc/init.rb