isodoc 1.7.5 → 1.7.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,129 +1,139 @@
1
1
  require "fileutils"
2
2
  require "base64"
3
3
 
4
- module IsoDoc::HtmlFunction
5
- module Html
6
- def convert1(docxml, filename, dir)
7
- noko do |xml|
8
- xml.html **{ lang: @lang.to_s } do |html|
9
- info docxml, nil
10
- populate_css
11
- html.head { |head| define_head head, filename, dir }
12
- make_body(html, docxml)
13
- end
14
- end.join("\n")
15
- end
4
+ module IsoDoc
5
+ module HtmlFunction
6
+ module Html
7
+ def convert1(docxml, filename, dir)
8
+ noko do |xml|
9
+ xml.html **{ lang: @lang.to_s } do |html|
10
+ info docxml, nil
11
+ populate_css
12
+ html.head { |head| define_head head, filename, dir }
13
+ make_body(html, docxml)
14
+ end
15
+ end.join("\n")
16
+ end
16
17
 
17
- def make_body1(body, _docxml)
18
- return if @bare
18
+ def make_body1(body, _docxml)
19
+ return if @bare
19
20
 
20
- body.div **{ class: "title-section" } do |div1|
21
- div1.p { |p| p << "&nbsp;" } # placeholder
21
+ body.div **{ class: "title-section" } do |div1|
22
+ div1.p { |p| p << "&nbsp;" } # placeholder
23
+ end
24
+ section_break(body)
22
25
  end
23
- section_break(body)
24
- end
25
26
 
26
- def make_body2(body, _docxml)
27
- return if @bare
27
+ def make_body2(body, _docxml)
28
+ return if @bare
28
29
 
29
- body.div **{ class: "prefatory-section" } do |div2|
30
- div2.p { |p| p << "&nbsp;" } # placeholder
30
+ body.div **{ class: "prefatory-section" } do |div2|
31
+ div2.p { |p| p << "&nbsp;" } # placeholder
32
+ end
33
+ section_break(body)
31
34
  end
32
- section_break(body)
33
- end
34
35
 
35
- def make_body3(body, docxml)
36
- body.div **{ class: "main-section" } do |div3|
37
- boilerplate docxml, div3
38
- preface_block docxml, div3
39
- abstract docxml, div3
40
- foreword docxml, div3
41
- introduction docxml, div3
42
- preface docxml, div3
43
- acknowledgements docxml, div3
44
- middle docxml, div3
45
- footnotes div3
46
- comments div3
36
+ def make_body3(body, docxml)
37
+ body.div **{ class: "main-section" } do |div3|
38
+ boilerplate docxml, div3
39
+ preface_block docxml, div3
40
+ abstract docxml, div3
41
+ foreword docxml, div3
42
+ introduction docxml, div3
43
+ preface docxml, div3
44
+ acknowledgements docxml, div3
45
+ middle docxml, div3
46
+ footnotes div3
47
+ comments div3
48
+ end
47
49
  end
48
- end
49
50
 
50
- def googlefonts
51
- <<~HEAD.freeze
52
- <link href="https://fonts.googleapis.com/css?family=Overpass:300,300i,600,900" rel="stylesheet">
53
- <link href="https://fonts.googleapis.com/css?family=Lato:400,400i,700,900" rel="stylesheet">
54
- HEAD
55
- end
51
+ def googlefonts
52
+ <<~HEAD.freeze
53
+ <link href="https://fonts.googleapis.com/css?family=Overpass:300,300i,600,900" rel="stylesheet">
54
+ <link href="https://fonts.googleapis.com/css?family=Lato:400,400i,700,900" rel="stylesheet">
55
+ HEAD
56
+ end
56
57
 
57
- def html_head
58
- <<~HEAD.freeze
59
- <title>#{@meta&.get&.dig(:doctitle)}</title>
60
- <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
61
-
62
- <!--TOC script import-->
63
- <script type="text/javascript" src="https://cdn.rawgit.com/jgallen23/toc/0.3.2/dist/toc.min.js"></script>
64
- <script type="text/javascript">#{toclevel}</script>
65
-
66
- <!--Google fonts-->
67
- <link rel="preconnect" href="https://fonts.gstatic.com">#{' '}
68
- #{googlefonts}
69
- <!--Font awesome import for the link icon-->
70
- <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.8/css/solid.css" integrity="sha384-v2Tw72dyUXeU3y4aM2Y0tBJQkGfplr39mxZqlTBDUZAb9BGoC40+rdFCG0m10lXk" crossorigin="anonymous">
71
- <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.8/css/fontawesome.css" integrity="sha384-q3jl8XQu1OpdLgGFvNRnPdj5VIlCvgsDQTQB6owSOHWlAurxul7f+JpUOVdAiJ5P" crossorigin="anonymous">
72
- <style class="anchorjs"></style>
73
- HEAD
74
- end
58
+ def html_head
59
+ <<~HEAD.freeze
60
+ <title>#{@meta&.get&.dig(:doctitle)}</title>
61
+ <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
62
+
63
+ <!--TOC script import-->
64
+ <script type="text/javascript" src="https://cdn.rawgit.com/jgallen23/toc/0.3.2/dist/toc.min.js"></script>
65
+ <script type="text/javascript">#{toclevel}</script>
66
+
67
+ <!--Google fonts-->
68
+ <link rel="preconnect" href="https://fonts.gstatic.com">#{' '}
69
+ #{googlefonts}
70
+ <!--Font awesome import for the link icon-->
71
+ <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.8/css/solid.css" integrity="sha384-v2Tw72dyUXeU3y4aM2Y0tBJQkGfplr39mxZqlTBDUZAb9BGoC40+rdFCG0m10lXk" crossorigin="anonymous">
72
+ <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.8/css/fontawesome.css" integrity="sha384-q3jl8XQu1OpdLgGFvNRnPdj5VIlCvgsDQTQB6owSOHWlAurxul7f+JpUOVdAiJ5P" crossorigin="anonymous">
73
+ <style class="anchorjs"></style>
74
+ HEAD
75
+ end
75
76
 
76
- def html_button
77
- return "" if @bare
77
+ def html_button
78
+ return "" if @bare
78
79
 
79
- '<button onclick="topFunction()" id="myBtn" '\
80
+ '<button onclick="topFunction()" id="myBtn" '\
80
81
  'title="Go to top">Top</button>'.freeze
81
- end
82
+ end
82
83
 
83
- def html_main(docxml)
84
- docxml.at("//head").add_child(html_head)
85
- d = docxml.at('//div[@class="main-section"]')
86
- d.name = "main"
87
- d.children.empty? or d.children.first.previous = html_button
88
- end
84
+ def html_main(docxml)
85
+ docxml.at("//head").add_child(html_head)
86
+ d = docxml.at('//div[@class="main-section"]')
87
+ d.name = "main"
88
+ d.children.empty? or d.children.first.previous = html_button
89
+ end
89
90
 
90
- def sourcecodelang(lang)
91
- return unless lang
92
-
93
- case lang.downcase
94
- when "javascript" then "lang-js"
95
- when "c" then "lang-c"
96
- when "c+" then "lang-cpp"
97
- when "console" then "lang-bsh"
98
- when "ruby" then "lang-rb"
99
- when "html" then "lang-html"
100
- when "java" then "lang-java"
101
- when "xml" then "lang-xml"
102
- when "perl" then "lang-perl"
103
- when "python" then "lang-py"
104
- when "xsl" then "lang-xsl"
105
- else
106
- ""
91
+ def sourcecodelang(lang)
92
+ return unless lang
93
+
94
+ case lang.downcase
95
+ when "javascript" then "lang-js"
96
+ when "c" then "lang-c"
97
+ when "c+" then "lang-cpp"
98
+ when "console" then "lang-bsh"
99
+ when "ruby" then "lang-rb"
100
+ when "html" then "lang-html"
101
+ when "java" then "lang-java"
102
+ when "xml" then "lang-xml"
103
+ when "perl" then "lang-perl"
104
+ when "python" then "lang-py"
105
+ when "xsl" then "lang-xsl"
106
+ else
107
+ ""
108
+ end
107
109
  end
108
- end
109
110
 
110
- def sourcecode_parse(node, out)
111
- name = node.at(ns("./name"))
112
- class1 = "prettyprint #{sourcecodelang(node&.at(ns('./@lang'))&.value)}"
113
- out.pre **sourcecode_attrs(node).merge(class: class1) do |div|
114
- @sourcecode = true
115
- node.children.each { |n| parse(n, div) unless n.name == "name" }
116
- @sourcecode = false
111
+ def sourcecode_parse(node, out)
112
+ name = node.at(ns("./name"))
113
+ class1 = "prettyprint #{sourcecodelang(node&.at(ns('./@lang'))&.value)}"
114
+ out.pre **sourcecode_attrs(node).merge(class: class1) do |div|
115
+ @sourcecode = true
116
+ node.children.each { |n| parse(n, div) unless n.name == "name" }
117
+ @sourcecode = false
118
+ end
119
+ sourcecode_name_parse(node, out, name)
117
120
  end
118
- sourcecode_name_parse(node, out, name)
119
- end
120
121
 
121
- def underline_parse(node, out)
122
- out.span **{ style: "text-decoration: underline;" } do |e|
123
- node.children.each { |n| parse(n, e) }
122
+ def underline_parse(node, out)
123
+ out.span **{ style: "text-decoration: underline;" } do |e|
124
+ node.children.each { |n| parse(n, e) }
125
+ end
124
126
  end
125
- end
126
127
 
127
- def table_long_strings_cleanup(docxml); end
128
+ def table_long_strings_cleanup(docxml); end
129
+
130
+ def image_parse(node, out, caption)
131
+ if svg = node.at("./m:svg", "m" => "http://www.w3.org/2000/svg")
132
+ svg_parse(svg, out)
133
+ return
134
+ end
135
+ super
136
+ end
137
+ end
128
138
  end
129
139
  end
@@ -1,4 +1,4 @@
1
- require "base64"
1
+ require_relative "./image"
2
2
 
3
3
  module IsoDoc
4
4
  class PresentationXMLConvert < ::IsoDoc::Convert
@@ -8,38 +8,6 @@ module IsoDoc
8
8
  text.capitalize
9
9
  end
10
10
 
11
- def figure(docxml)
12
- docxml.xpath(ns("//image")).each { |f| svg_extract(f) }
13
- docxml.xpath(ns("//figure")).each { |f| figure1(f) }
14
- docxml.xpath(ns("//svgmap")).each do |s|
15
- if f = s.at(ns("./figure")) then s.replace(f)
16
- else s.remove
17
- end
18
- end
19
- end
20
-
21
- def svg_extract(elem)
22
- return unless %r{^data:image/svg\+xml;base64,}.match?(elem["src"])
23
-
24
- svg = Base64.strict_decode64(elem["src"]
25
- .sub(%r{^data:image/svg\+xml;base64,}, ""))
26
- x = Nokogiri::XML.fragment(svg.sub(/<\?xml[^>]*>/, "")) do |config|
27
- config.huge
28
- end
29
- elem.replace(x)
30
- end
31
-
32
- def figure1(elem)
33
- return sourcecode1(elem) if elem["class"] == "pseudocode" ||
34
- elem["type"] == "pseudocode"
35
- return if labelled_ancestor(elem) && elem.ancestors("figure").empty? ||
36
- elem.at(ns("./figure")) && !elem.at(ns("./name"))
37
-
38
- lbl = @xrefs.anchor(elem["id"], :label, false) or return
39
- prefix_name(elem, "&nbsp;&mdash; ",
40
- l10n("#{lower2cap @i18n.figure} #{lbl}"), "name")
41
- end
42
-
43
11
  def prefix_name(node, delim, number, elem)
44
12
  return if number.nil? || number.empty?
45
13
 
@@ -0,0 +1,68 @@
1
+ module IsoDoc
2
+ class PresentationXMLConvert < ::IsoDoc::Convert
3
+ def concept(docxml)
4
+ docxml.xpath(ns("//concept")).each { |f| concept1(f) }
5
+ end
6
+
7
+ def concept1(node)
8
+ xref = node&.at(ns("./xref/@target"))&.text or
9
+ return concept_render(node, ital: node["ital"] || "true",
10
+ ref: node["ref"] || "true",
11
+ linkref: node["linkref"] || "true",
12
+ linkmention: node["linkmention"] || "false")
13
+ if node.at(ns("//definitions//dt[@id = '#{xref}']"))
14
+ concept_render(node, ital: node["ital"] || "false",
15
+ ref: node["ref"] || "false",
16
+ linkref: node["linkref"] || "true",
17
+ linkmention: node["linkmention"] || "false")
18
+ else concept_render(node, ital: node["ital"] || "true",
19
+ ref: node["ref"] || "true",
20
+ linkref: node["linkref"] || "true",
21
+ linkmention: node["linkmention"] || "false")
22
+ end
23
+ end
24
+
25
+ def concept_render(node, opts)
26
+ node&.at(ns("./refterm"))&.remove
27
+ r = node.at(ns("./renderterm"))
28
+ ref = node.at(ns("./xref | ./eref | ./termref"))
29
+ ref && opts[:ref] != "false" and r&.next = " "
30
+ opts[:ital] == "true" and r&.name = "em"
31
+ if opts[:linkmention] == "true" && !r.nil? && !ref.nil?
32
+ ref2 = ref.clone
33
+ r2 = r.clone
34
+ r.replace(ref2).children = r2
35
+ end
36
+ concept1_ref(node, ref, opts)
37
+ if opts[:ital] == "false"
38
+ r = node.at(ns(".//renderterm"))
39
+ r&.replace(r&.children)
40
+ end
41
+ node.replace(node.children)
42
+ end
43
+
44
+ def concept1_ref(_node, ref, opts)
45
+ ref.nil? and return
46
+ return ref.remove if opts[:ref] == "false"
47
+
48
+ r = concept1_ref_content(ref)
49
+ ref = r.at("./descendant-or-self::xmlns:xref | "\
50
+ "./descendant-or-self::xmlns:eref | "\
51
+ "./descendant-or-self::xmlns:termref")
52
+ %w(xref eref).include? ref&.name and get_linkend(ref)
53
+ if opts[:linkref] == "false" && %w(xref eref).include?(ref&.name)
54
+ ref.replace(ref.children)
55
+ end
56
+ end
57
+
58
+ def concept1_ref_content(ref)
59
+ if non_locality_elems(ref).select do |c|
60
+ !c.text? || /\S/.match(c)
61
+ end.empty?
62
+ ref.replace(@i18n.term_defined_in.sub(/%/,
63
+ ref.to_xml))
64
+ else ref.replace("[#{ref.to_xml}]")
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,112 @@
1
+ require "base64"
2
+ require "emf2svg"
3
+
4
+ module IsoDoc
5
+ class PresentationXMLConvert < ::IsoDoc::Convert
6
+ def figure(docxml)
7
+ docxml.xpath(ns("//image")).each { |f| svg_extract(f) }
8
+ docxml.xpath(ns("//figure")).each { |f| figure1(f) }
9
+ docxml.xpath(ns("//svgmap")).each do |s|
10
+ if f = s.at(ns("./figure")) then s.replace(f)
11
+ else s.remove
12
+ end
13
+ end
14
+ docxml.xpath(ns("//image")).each { |f| svg_emf_double(f) }
15
+ end
16
+
17
+ def svg_extract(elem)
18
+ return unless %r{^data:image/svg\+xml;}.match?(elem["src"])
19
+
20
+ svg = Base64.strict_decode64(elem["src"]
21
+ .sub(%r{^data:image/svg\+xml;(charset=[^;]+;)?base64,}, ""))
22
+ x = Nokogiri::XML.fragment(svg.sub(/<\?xml[^>]*>/, "")) do |config|
23
+ config.huge
24
+ end
25
+ elem["src"] = ""
26
+ elem.children = x
27
+ end
28
+
29
+ def figure1(elem)
30
+ return sourcecode1(elem) if elem["class"] == "pseudocode" ||
31
+ elem["type"] == "pseudocode"
32
+ return if labelled_ancestor(elem) && elem.ancestors("figure").empty? ||
33
+ elem.at(ns("./figure")) && !elem.at(ns("./name"))
34
+
35
+ lbl = @xrefs.anchor(elem["id"], :label, false) or return
36
+ prefix_name(elem, "&nbsp;&mdash; ",
37
+ l10n("#{lower2cap @i18n.figure} #{lbl}"), "name")
38
+ end
39
+
40
+ def svg_emf_double(img)
41
+ if emf?(img["mimetype"])
42
+ img = emf_encode(img)
43
+ img.children.first.previous = emf_to_svg(img)
44
+ elsif img["mimetype"] == "image/svg+xml"
45
+ src = svg_to_emf(img) and img << "<emf src='#{src}'/>"
46
+ end
47
+ end
48
+
49
+ def emf_encode(img)
50
+ img["mimetype"] = "image/svg+xml"
51
+ unless %r{^data:image}.match?(img["src"])
52
+ img["src"] = Metanorma::Utils::datauri(img["src"])
53
+ end
54
+ img.children = "<emf src='#{img['src']}'/>"
55
+ img["src"] = ""
56
+ img
57
+ end
58
+
59
+ def emf_to_svg(img)
60
+ emf = Metanorma::Utils::save_dataimage(img.at(ns("./emf/@src")).text)
61
+ Emf2svg.from_file(emf).sub(/<\?[^>]+>/, "")
62
+ end
63
+
64
+ def svg_to_emf(node)
65
+ uri = svg_to_emf_uri(node)
66
+ ret = svg_to_emf_filename(uri)
67
+ File.exists?(ret) and return ret
68
+ exe = inkscape_installed? or return nil
69
+ uri = Metanorma::Utils::external_path uri
70
+ exe = Metanorma::Utils::external_path exe
71
+ system(%(#{exe} --export-type="emf" #{uri})) and
72
+ return Metanorma::Utils::datauri(ret)
73
+
74
+ warn %(Fail on #{exe} --export-type="emf" #{uri})
75
+
76
+ nil
77
+ end
78
+
79
+ def svg_to_emf_uri(node)
80
+ uri = if node&.elements&.first&.name == "svg"
81
+ a = Base64.strict_encode64(node.children.to_xml)
82
+ "data:image/svg+xml;base64,#{a}"
83
+ else node["src"]
84
+ end
85
+ if %r{^data:}.match?(uri)
86
+ uri = save_dataimage(uri)
87
+ @tempfile_cache << uri
88
+ end
89
+ uri
90
+ end
91
+
92
+ def svg_to_emf_filename(uri)
93
+ "#{File.join(File.dirname(uri), File.basename(uri, '.*'))}.emf"
94
+ end
95
+
96
+ def emf_to_svgfilename(uri)
97
+ "#{File.join(File.dirname(uri), File.basename(uri, '.*'))}.svg"
98
+ end
99
+
100
+ def inkscape_installed?
101
+ cmd = "inkscape"
102
+ exts = ENV["PATHEXT"] ? ENV["PATHEXT"].split(";") : [""]
103
+ ENV["PATH"].split(File::PATH_SEPARATOR).each do |path|
104
+ exts.each do |ext|
105
+ exe = File.join(path, "#{cmd}#{ext}")
106
+ return exe if File.executable?(exe) && !File.directory?(exe)
107
+ end
108
+ end
109
+ nil
110
+ end
111
+ end
112
+ end
@@ -1,4 +1,5 @@
1
1
  require "metanorma-utils"
2
+ require_relative "./concept"
2
3
 
3
4
  module IsoDoc
4
5
  class PresentationXMLConvert < ::IsoDoc::Convert
@@ -69,7 +70,7 @@ module IsoDoc
69
70
  link += eref_localities(node.xpath(ns("./locality | ./localityStack")),
70
71
  link, node)
71
72
  non_locality_elems(node).each(&:remove)
72
- node.add_child(link)
73
+ node.add_child(cleanup_entities(link))
73
74
  end
74
75
  # so not <origin bibitemid="ISO7301" citeas="ISO 7301">
75
76
  # <locality type="section"><reference>3.1</reference></locality></origin>
@@ -90,8 +91,7 @@ module IsoDoc
90
91
  ret += eref_localities0(rr, j, target, delim, node)
91
92
  delim = ","
92
93
  end
93
- else
94
- ret += eref_localities0(ref, idx, target, delim, node)
94
+ else ret += eref_localities0(ref, idx, target, delim, node)
95
95
  end
96
96
  ret
97
97
  end
@@ -157,71 +157,6 @@ module IsoDoc
157
157
  get_linkend(node)
158
158
  end
159
159
 
160
- def concept(docxml)
161
- docxml.xpath(ns("//concept")).each { |f| concept1(f) }
162
- end
163
-
164
- def concept1(node)
165
- xref = node&.at(ns("./xref/@target"))&.text or
166
- return concept_render(node, ital: node["ital"] || "true",
167
- ref: node["ref"] || "true",
168
- linkref: node["linkref"] || "true",
169
- linkmention: node["linkmention"] || "false")
170
- if node.at(ns("//definitions//dt[@id = '#{xref}']"))
171
- concept_render(node, ital: node["ital"] || "false",
172
- ref: node["ref"] || "false",
173
- linkref: node["linkref"] || "true",
174
- linkmention: node["linkmention"] || "false")
175
- else concept_render(node, ital: node["ital"] || "true",
176
- ref: node["ref"] || "true",
177
- linkref: node["linkref"] || "true",
178
- linkmention: node["linkmention"] || "false")
179
- end
180
- end
181
-
182
- def concept_render(node, opts)
183
- node&.at(ns("./refterm"))&.remove
184
- r = node.at(ns("./renderterm"))
185
- ref = node.at(ns("./xref | ./eref | ./termref"))
186
- ref && opts[:ref] != "false" and r&.next = " "
187
- opts[:ital] == "true" and r&.name = "em"
188
- if opts[:linkmention] == "true" && !r.nil? && !ref.nil?
189
- ref2 = ref.clone
190
- r2 = r.clone
191
- r.replace(ref2).children = r2
192
- end
193
- concept1_ref(node, ref, opts)
194
- if opts[:ital] == "false"
195
- r = node.at(ns(".//renderterm"))
196
- r&.replace(r&.children)
197
- end
198
- node.replace(node.children)
199
- end
200
-
201
- def concept1_ref(_node, ref, opts)
202
- ref.nil? and return
203
- return ref.remove if opts[:ref] == "false"
204
-
205
- r = concept1_ref_content(ref)
206
- ref = r.at("./descendant-or-self::xmlns:xref | "\
207
- "./descendant-or-self::xmlns:eref | "\
208
- "./descendant-or-self::xmlns:termref")
209
- %w(xref eref).include? ref&.name and get_linkend(ref)
210
- if opts[:linkref] == "false" && %w(xref eref).include?(ref&.name)
211
- ref.replace(ref.children)
212
- end
213
- end
214
-
215
- def concept1_ref_content(ref)
216
- if non_locality_elems(ref).select do |c|
217
- !c.text? || /\S/.match(c)
218
- end.empty?
219
- ref.replace(@i18n.term_defined_in.sub(/%/,
220
- ref.to_xml))
221
- else ref.replace("[#{ref.to_xml}]")
222
- end
223
- end
224
-
225
160
  def variant(docxml)
226
161
  docxml.xpath(ns("//variant")).each { |f| variant1(f) }
227
162
  docxml.xpath(ns("//variant[@remove = 'true']")).each(&:remove)
@@ -1,3 +1,3 @@
1
1
  module IsoDoc
2
- VERSION = "1.7.5".freeze
2
+ VERSION = "1.7.6".freeze
3
3
  end