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