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 +4 -4
- data/isodoc.gemspec +3 -3
- data/lib/isodoc/base_style/blocks.scss +1 -1
- data/lib/isodoc/function/utils.rb +30 -41
- data/lib/isodoc/html_function/postprocess.rb +7 -157
- data/lib/isodoc/html_function/postprocess_cover.rb +167 -0
- data/lib/isodoc/presentation_function/image.rb +6 -1
- data/lib/isodoc/presentation_function/inline.rb +3 -3
- data/lib/isodoc/presentation_function/xrefs.rb +18 -5
- data/lib/isodoc/version.rb +1 -1
- data/lib/isodoc/word_function/inline.rb +2 -0
- data/lib/isodoc/xref/xref_sect_gen.rb +42 -29
- data/lib/isodoc-yaml/i18n-en.yaml +1 -1
- metadata +9 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 73982c33aa666aee412b32318f01d964e21a7d2dfbb6d3afca3b19c7c0268549
|
4
|
+
data.tar.gz: 90fb6621afc2fedcc1c0db06d83a8bc53d96f0d62eb382cdb4d94f773a25c477
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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.
|
42
|
+
spec.add_dependency "metanorma-utils", "~> 1.4.5"
|
43
43
|
spec.add_dependency "mn2pdf"
|
44
|
-
spec.add_dependency "mn-requirements", "~> 0.
|
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"
|
@@ -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
|
-
|
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
|
-
|
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
|
-
|
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
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
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
|
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
|
-
|
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 =
|
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]
|
70
|
+
ret = prefix_container(container, ret, locs.first[:node],
|
71
|
+
locs.first[:node]["target"])
|
59
72
|
ret
|
60
73
|
end
|
61
74
|
|
data/lib/isodoc/version.rb
CHANGED
@@ -51,8 +51,13 @@ module IsoDoc
|
|
51
51
|
bookmark_anchor_names(doc)
|
52
52
|
end
|
53
53
|
|
54
|
-
def
|
55
|
-
clause.at(ns("./title"))&.text
|
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
|
-
|
66
|
-
|
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
|
-
"#{
|
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
|
-
|
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)))
|
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
|
-
|
110
|
+
clause.nil? and return num
|
100
111
|
|
101
112
|
num.increment(clause)
|
102
|
-
|
103
|
-
|
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
|
-
|
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
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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)
|
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.
|
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-
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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
|