isodoc 1.7.5 → 1.7.6

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