isodoc 2.3.2 → 2.3.3

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