metanorma-utils 1.0.6 → 1.2.0
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/.github/workflows/rake.yml +5 -3
- data/.gitignore +1 -0
- data/.rubocop.yml +10 -2
- data/lib/metanorma-utils.rb +1 -0
- data/lib/utils/image.rb +143 -0
- data/lib/utils/log.rb +28 -25
- data/lib/utils/main.rb +51 -143
- data/lib/utils/version.rb +1 -1
- data/metanorma-utils.gemspec +3 -2
- data/spec/utils_spec.rb +275 -235
- metadata +27 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a355e89f8c66d323f0ca9954226b2255c1c4706ab9346db5004aa7984ceade6c
|
4
|
+
data.tar.gz: cc240e1eec9ea056d87b38bae0fea45ac16f1e6f2cef1a6cb2d04c2d20de50e9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 20d8d717e2113249d060bf15f15faf1150cf5e06d29368f9faf00b0a496aa7c3e711a80c83dbb6fd328cf39ac2e65359825a6632199fb6cdf13cb882934ac11f
|
7
|
+
data.tar.gz: be4fe517ccc3731678ebaa5fedf2b7ec0923e510c83193a5f73d26db3b9a290cbe3be3aaeda4dbfa90fd76fd8c1bf14099f283b6bd158b00c5138d488c2fdf14
|
data/.github/workflows/rake.yml
CHANGED
@@ -30,7 +30,9 @@ jobs:
|
|
30
30
|
os: 'macos-latest'
|
31
31
|
experimental: true
|
32
32
|
steps:
|
33
|
-
- uses: actions/checkout@
|
33
|
+
- uses: actions/checkout@v2
|
34
|
+
with:
|
35
|
+
submodules: true
|
34
36
|
|
35
37
|
- uses: ruby/setup-ruby@v1
|
36
38
|
with:
|
@@ -45,7 +47,7 @@ jobs:
|
|
45
47
|
steps:
|
46
48
|
- uses: peter-evans/repository-dispatch@v1
|
47
49
|
with:
|
48
|
-
token: ${{ secrets.GITHUB_TOKEN }}
|
50
|
+
token: ${{ secrets.METANORMA_CI_PAT_TOKEN || secrets.GITHUB_TOKEN }}
|
49
51
|
repository: ${{ github.repository }}
|
50
52
|
event-type: notify
|
51
|
-
client-payload: '{"ref": "${{ github.ref }}"}'
|
53
|
+
client-payload: '{"ref": "${{ github.ref }}", "sha": "${{ github.sha }}"}'
|
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
.rubocop-https--*
|
data/.rubocop.yml
CHANGED
@@ -1,6 +1,14 @@
|
|
1
1
|
# This project follows the Ribose OSS style guide.
|
2
2
|
# https://github.com/riboseinc/oss-guides
|
3
3
|
# All project-specific additions and overrides should be specified in this file.
|
4
|
-
|
5
4
|
inherit_from:
|
6
|
-
- https://raw.githubusercontent.com/riboseinc/oss-guides/master/ci/rubocop.yml
|
5
|
+
- https://raw.githubusercontent.com/riboseinc/oss-guides/master/ci/rubocop.yml
|
6
|
+
|
7
|
+
# local repo-specific modifications
|
8
|
+
|
9
|
+
AllCops:
|
10
|
+
DisplayCopNames: false
|
11
|
+
StyleGuideCopsOnly: false
|
12
|
+
TargetRubyVersion: 2.4
|
13
|
+
Rails:
|
14
|
+
Enabled: true
|
data/lib/metanorma-utils.rb
CHANGED
data/lib/utils/image.rb
ADDED
@@ -0,0 +1,143 @@
|
|
1
|
+
require "asciidoctor"
|
2
|
+
require "tempfile"
|
3
|
+
require "marcel"
|
4
|
+
require "mime/types"
|
5
|
+
require "base64"
|
6
|
+
|
7
|
+
module Metanorma
|
8
|
+
module Utils
|
9
|
+
class << self
|
10
|
+
class Namespace
|
11
|
+
def initialize(xmldoc)
|
12
|
+
@namespace = xmldoc.root.namespace
|
13
|
+
end
|
14
|
+
|
15
|
+
def ns(path)
|
16
|
+
return path if @namespace.nil?
|
17
|
+
|
18
|
+
path.gsub(%r{/([a-zA-z])}, "/xmlns:\\1")
|
19
|
+
.gsub(%r{::([a-zA-z])}, "::xmlns:\\1")
|
20
|
+
.gsub(%r{\[([a-zA-z][a-z0-9A-Z@/]* ?=)}, "[xmlns:\\1")
|
21
|
+
.gsub(%r{\[([a-zA-z][a-z0-9A-Z@/]*\])}, "[xmlns:\\1")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def save_dataimage(uri)
|
26
|
+
%r{^data:(image|application)/(?<imgtype>[^;]+);base64,(?<imgdata>.+)$} =~ uri
|
27
|
+
imgtype.sub!(/\+[a-z0-9]+$/, "") # svg+xml
|
28
|
+
imgtype = "png" unless /^[a-z0-9]+$/.match? imgtype
|
29
|
+
Tempfile.open(["image", ".#{imgtype}"]) do |f|
|
30
|
+
f.binmode
|
31
|
+
f.write(Base64.strict_decode64(imgdata))
|
32
|
+
f.path
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
SVG_NS = "http://www.w3.org/2000/svg".freeze
|
37
|
+
|
38
|
+
def svgmap_rewrite(xmldoc, localdirectory = "")
|
39
|
+
n = Namespace.new(xmldoc)
|
40
|
+
xmldoc.xpath(n.ns("//svgmap")).each do |s|
|
41
|
+
next unless svgmap_rewrite0(s, n, localdirectory)
|
42
|
+
next if s.at(n.ns("./target/eref"))
|
43
|
+
|
44
|
+
s.replace(s.at(n.ns("./figure")))
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def svgmap_rewrite0(svgmap, namespace, localdirectory)
|
49
|
+
if (i = svgmap.at(namespace.ns(".//image"))) && (src = i["src"])
|
50
|
+
path = svgmap_rewrite0_path(src, localdirectory)
|
51
|
+
File.file?(path) or return false
|
52
|
+
svg = Nokogiri::XML(File.read(path, encoding: "utf-8"))
|
53
|
+
i.replace(svgmap_rewrite1(svgmap, svg, namespace))
|
54
|
+
/^data:/.match(src) and i["src"] = datauri(path)
|
55
|
+
elsif i = svgmap.at(".//m:svg", "m" => SVG_NS)
|
56
|
+
i.replace(svgmap_rewrite1(svgmap, i, namespace))
|
57
|
+
else
|
58
|
+
return false
|
59
|
+
end
|
60
|
+
true
|
61
|
+
end
|
62
|
+
|
63
|
+
def svgmap_rewrite0_path(src, localdirectory)
|
64
|
+
if /^data:/.match?(src)
|
65
|
+
save_dataimage(src)
|
66
|
+
else
|
67
|
+
File.file?(src) ? src : localdirectory + src
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def svgmap_rewrite1(svgmap, svg, namespace)
|
72
|
+
targ = svgmap_rewrite1_targets(svgmap, namespace)
|
73
|
+
svg.xpath(".//m:a", "m" => SVG_NS).each do |a|
|
74
|
+
["xlink:href", "href"].each do |p|
|
75
|
+
a[p] and x = targ[File.expand_path(a[p])] and a[p] = x
|
76
|
+
end
|
77
|
+
end
|
78
|
+
svg.to_xml
|
79
|
+
end
|
80
|
+
|
81
|
+
def svgmap_rewrite1_targets(svgmap, namespace)
|
82
|
+
svgmap.xpath(namespace.ns("./target"))
|
83
|
+
.each_with_object({}) do |t, m|
|
84
|
+
x = t.at(namespace.ns("./xref")) and
|
85
|
+
m[File.expand_path(t["href"])] = "##{x['target']}"
|
86
|
+
x = t.at(namespace.ns("./link")) and
|
87
|
+
m[File.expand_path(t["href"])] = x["target"]
|
88
|
+
t.remove if t.at(namespace.ns("./xref | ./link"))
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# sources/plantuml/plantuml20200524-90467-1iqek5i.png
|
93
|
+
# already includes localdir
|
94
|
+
def datauri(uri, localdirectory = ".")
|
95
|
+
return uri if /^data:/.match?(uri)
|
96
|
+
|
97
|
+
path = datauri_path(uri, localdirectory)
|
98
|
+
return path unless File.exist?(path)
|
99
|
+
|
100
|
+
types = MIME::Types.type_for(path)
|
101
|
+
type = types ? types.first.to_s : 'text/plain; charset="utf-8"'
|
102
|
+
bin = File.open(path, "rb", &:read)
|
103
|
+
data = Base64.strict_encode64(bin)
|
104
|
+
"data:#{type};base64,#{data}"
|
105
|
+
end
|
106
|
+
|
107
|
+
def datauri_path(uri, localdirectory)
|
108
|
+
path = if %r{^([A-Z]:)?/}.match?(uri) then uri
|
109
|
+
else
|
110
|
+
File.exist?(uri) ? uri : File.join(localdirectory, uri)
|
111
|
+
end
|
112
|
+
unless File.exist?(path)
|
113
|
+
warn "image at #{path} not found"
|
114
|
+
return uri
|
115
|
+
end
|
116
|
+
path
|
117
|
+
end
|
118
|
+
|
119
|
+
def datauri2mime(uri)
|
120
|
+
%r{^data:image/(?<imgtype>[^;]+);base64,(?<imgdata>.+)$} =~ uri
|
121
|
+
type = nil
|
122
|
+
imgtype = "png" unless /^[a-z0-9]+$/.match? imgtype
|
123
|
+
::Tempfile.open(["imageuri", ".#{imgtype}"]) do |file|
|
124
|
+
type = datauri2mime1(file, imgdata)
|
125
|
+
end
|
126
|
+
[type]
|
127
|
+
end
|
128
|
+
|
129
|
+
def datauri2mime1(file, imgdata)
|
130
|
+
type = nil
|
131
|
+
begin
|
132
|
+
file.binmode
|
133
|
+
file.write(Base64.strict_decode64(imgdata))
|
134
|
+
file.rewind
|
135
|
+
type = Marcel::MimeType.for file
|
136
|
+
ensure
|
137
|
+
file.close!
|
138
|
+
end
|
139
|
+
type
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
data/lib/utils/log.rb
CHANGED
@@ -7,48 +7,51 @@ module Metanorma
|
|
7
7
|
|
8
8
|
def add(category, loc, msg)
|
9
9
|
return if @novalid
|
10
|
+
|
10
11
|
@log[category] = [] unless @log[category]
|
11
12
|
@log[category] << { location: current_location(loc), message: msg,
|
12
13
|
context: context(loc) }
|
13
14
|
loc = loc.nil? ? "" : "(#{current_location(loc)}): "
|
14
|
-
warn "#{category}: #{loc}#{msg}"
|
15
|
+
warn "#{category}: #{loc}#{msg}"
|
15
16
|
end
|
16
17
|
|
17
|
-
def current_location(
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
!
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
18
|
+
def current_location(node)
|
19
|
+
if node.nil? then ""
|
20
|
+
elsif node.is_a? String then node
|
21
|
+
elsif node.respond_to?(:lineno) && !node.lineno.nil? &&
|
22
|
+
!node.lineno.empty?
|
23
|
+
"Asciidoctor Line #{'%06d' % node.lineno}"
|
24
|
+
elsif node.respond_to?(:line) && !node.line.nil?
|
25
|
+
"XML Line #{'%06d' % node.line}"
|
26
|
+
elsif node.respond_to?(:id) && !node.id.nil? then "ID #{node.id}"
|
27
|
+
else
|
28
|
+
while !node.nil? &&
|
29
|
+
(!node.respond_to?(:level) || node.level.positive?) &&
|
30
|
+
(!node.respond_to?(:context) || node.context != :section)
|
31
|
+
node = node.parent
|
32
|
+
return "Section: #{node.title}" if node&.respond_to?(:context) &&
|
33
|
+
node&.context == :section
|
34
|
+
end
|
35
|
+
"??"
|
31
36
|
end
|
32
|
-
"??"
|
33
37
|
end
|
34
38
|
|
35
|
-
def context(
|
36
|
-
return nil if
|
37
|
-
|
38
|
-
|
39
|
+
def context(node)
|
40
|
+
return nil if node.is_a? String
|
41
|
+
|
42
|
+
node.respond_to?(:to_xml) and return node.to_xml
|
43
|
+
node.respond_to?(:to_s) and return node.to_s
|
39
44
|
nil
|
40
45
|
end
|
41
46
|
|
42
47
|
def write(file)
|
43
48
|
File.open(file, "w:UTF-8") do |f|
|
44
49
|
f.puts "#{file} errors"
|
45
|
-
@log.
|
50
|
+
@log.each_key do |key|
|
46
51
|
f.puts "\n\n== #{key}\n\n"
|
47
|
-
@log[key].
|
48
|
-
a[:location] <=> b[:location]
|
49
|
-
end.each do |n|
|
52
|
+
@log[key].sort_by { |a| a[:location] }.each do |n|
|
50
53
|
loc = n[:location] ? "(#{n[:location]}): " : ""
|
51
|
-
f.puts "#{loc}#{n[:message]}"
|
54
|
+
f.puts "#{loc}#{n[:message]}"
|
52
55
|
n[:context]&.split(/\n/)&.first(5)&.each { |l| f.puts "\t#{l}" }
|
53
56
|
end
|
54
57
|
end
|
data/lib/utils/main.rb
CHANGED
@@ -2,56 +2,61 @@ require "asciidoctor"
|
|
2
2
|
require "tempfile"
|
3
3
|
require "sterile"
|
4
4
|
require "uuidtools"
|
5
|
-
require "mimemagic"
|
6
|
-
require "mime/types"
|
7
|
-
require "base64"
|
8
5
|
|
9
6
|
module Metanorma
|
10
7
|
module Utils
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
"\u203f-\u2040".freeze
|
8
|
+
NAMECHAR = "\u0000-\u0022\u0024\u002c\u002f\u003a-\u0040\\u005b-\u005e"\
|
9
|
+
"\u0060\u007b-\u00b6\u00b8-\u00bf\u00d7\u00f7\u037e\u2000-\u200b"\
|
10
|
+
"\u200e-\u203e\u2041-\u206f\u2190-\u2bff\u2ff0-\u3000".freeze
|
11
|
+
NAMESTARTCHAR = "\\u002d\u002e\u0030-\u0039\u00b7\u0300-\u036f"\
|
12
|
+
"\u203f-\u2040".freeze
|
17
13
|
|
18
14
|
class << self
|
19
|
-
def to_ncname(
|
20
|
-
start =
|
21
|
-
ret1 = %r([#{NAMECHAR}#]).match(start)
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
15
|
+
def to_ncname(tag)
|
16
|
+
start = tag[0]
|
17
|
+
ret1 = if %r([#{NAMECHAR}#]).match?(start)
|
18
|
+
"_"
|
19
|
+
else
|
20
|
+
(%r([#{NAMESTARTCHAR}#]).match?(start) ? "_#{start}" : start)
|
21
|
+
end
|
22
|
+
ret2 = tag[1..-1] || ""
|
23
|
+
(ret1 || "") + ret2.gsub(%r([#{NAMECHAR}#]), "_")
|
26
24
|
end
|
27
25
|
|
28
26
|
def anchor_or_uuid(node = nil)
|
29
27
|
uuid = UUIDTools::UUID.random_create
|
30
|
-
node.nil? || node.id.nil? || node.id.empty? ? "_"
|
28
|
+
node.nil? || node.id.nil? || node.id.empty? ? "_#{uuid}" : node.id
|
31
29
|
end
|
32
30
|
|
33
|
-
def asciidoc_sub(
|
34
|
-
return nil if
|
35
|
-
return "" if
|
36
|
-
|
31
|
+
def asciidoc_sub(text, flavour = :standoc)
|
32
|
+
return nil if text.nil?
|
33
|
+
return "" if text.empty?
|
34
|
+
|
35
|
+
d = Asciidoctor::Document.new(
|
36
|
+
text.lines.entries,
|
37
|
+
{ header_footer: false, backend: flavour }
|
38
|
+
)
|
37
39
|
b = d.parse.blocks.first
|
38
40
|
b.apply_subs(b.source)
|
39
41
|
end
|
40
42
|
|
41
43
|
def localdir(node)
|
42
44
|
docfile = node.attr("docfile")
|
43
|
-
docfile.nil? ?
|
45
|
+
docfile.nil? ? "./" : "#{Pathname.new(docfile).parent}/"
|
44
46
|
end
|
45
47
|
|
46
48
|
# TODO needs internationalisation
|
47
|
-
def smartformat(
|
48
|
-
|
49
|
-
gsub(/--/, "—").smart_format.gsub(/</, "<")
|
49
|
+
def smartformat(text)
|
50
|
+
text.gsub(/ --? /, " — ")
|
51
|
+
.gsub(/--/, "—").smart_format.gsub(/</, "<")
|
52
|
+
.gsub(/>/, ">")
|
50
53
|
end
|
51
54
|
|
52
55
|
def endash_date(elem)
|
53
56
|
elem.traverse do |n|
|
54
|
-
|
57
|
+
next unless n.text?
|
58
|
+
|
59
|
+
n.replace(n.text.gsub(/\s+--?\s+/, "–").gsub(/--/, "–"))
|
55
60
|
end
|
56
61
|
end
|
57
62
|
|
@@ -60,95 +65,34 @@ module Metanorma
|
|
60
65
|
def set_nested_value(hash, keys, new_val)
|
61
66
|
key = keys[0]
|
62
67
|
if keys.length == 1
|
63
|
-
hash[key] = hash[key].is_a?(Array)
|
64
|
-
|
68
|
+
hash[key] = if hash[key].is_a?(Array)
|
69
|
+
(hash[key] << new_val)
|
70
|
+
else
|
71
|
+
hash[key].nil? ? new_val : [hash[key], new_val]
|
72
|
+
end
|
73
|
+
elsif hash[key].is_a?(Array)
|
74
|
+
hash[key][-1] = {} if !hash[key].empty? && hash[key][-1].nil?
|
75
|
+
hash[key] << {} if hash[key].empty? || !hash[key][-1].is_a?(Hash)
|
76
|
+
set_nested_value(hash[key][-1], keys[1..-1], new_val)
|
77
|
+
elsif hash[key].nil? || hash[key].empty?
|
78
|
+
hash[key] = {}
|
79
|
+
set_nested_value(hash[key], keys[1..-1], new_val)
|
80
|
+
elsif hash[key].is_a?(Hash) && !hash[key][keys[1]]
|
81
|
+
set_nested_value(hash[key], keys[1..-1], new_val)
|
82
|
+
elsif !hash[key][keys[1]]
|
83
|
+
hash[key] = [hash[key], {}]
|
84
|
+
set_nested_value(hash[key][-1], keys[1..-1], new_val)
|
65
85
|
else
|
66
|
-
|
67
|
-
hash[key][-1] = {} if !hash[key].empty? && hash[key][-1].nil?
|
68
|
-
hash[key] << {} if hash[key].empty? || !hash[key][-1].is_a?(Hash)
|
69
|
-
set_nested_value(hash[key][-1], keys[1..-1], new_val)
|
70
|
-
elsif hash[key].nil? || hash[key].empty?
|
71
|
-
hash[key] = {}
|
72
|
-
set_nested_value(hash[key], keys[1..-1], new_val)
|
73
|
-
elsif hash[key].is_a?(Hash) && !hash[key][keys[1]]
|
74
|
-
set_nested_value(hash[key], keys[1..-1], new_val)
|
75
|
-
elsif !hash[key][keys[1]]
|
76
|
-
hash[key] = [hash[key], {}]
|
77
|
-
set_nested_value(hash[key][-1], keys[1..-1], new_val)
|
78
|
-
else
|
79
|
-
set_nested_value(hash[key], keys[1..-1], new_val)
|
80
|
-
end
|
86
|
+
set_nested_value(hash[key], keys[1..-1], new_val)
|
81
87
|
end
|
82
88
|
hash
|
83
89
|
end
|
84
90
|
|
85
|
-
class Namespace
|
86
|
-
def initialize(xmldoc)
|
87
|
-
@namespace = xmldoc.root.namespace
|
88
|
-
end
|
89
|
-
|
90
|
-
def ns(path)
|
91
|
-
return path if @namespace.nil?
|
92
|
-
path.gsub(%r{/([a-zA-z])}, "/xmlns:\\1").
|
93
|
-
gsub(%r{::([a-zA-z])}, "::xmlns:\\1").
|
94
|
-
gsub(%r{\[([a-zA-z][a-z0-9A-Z@/]* ?=)}, "[xmlns:\\1").
|
95
|
-
gsub(%r{\[([a-zA-z][a-z0-9A-Z@/]*\])}, "[xmlns:\\1")
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
def save_dataimage(uri)
|
100
|
-
%r{^data:(image|application)/(?<imgtype>[^;]+);base64,(?<imgdata>.+)$} =~ uri
|
101
|
-
imgtype.sub!(/\+[a-z0-9]+$/, '') # svg+xml
|
102
|
-
imgtype = 'png' unless /^[a-z0-9]+$/.match imgtype
|
103
|
-
Tempfile.open(['image', ".#{imgtype}"]) do |f|
|
104
|
-
f.binmode
|
105
|
-
f.write(Base64.strict_decode64(imgdata))
|
106
|
-
f.path
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
SVG_NS = "http://www.w3.org/2000/svg".freeze
|
111
|
-
|
112
|
-
def svgmap_rewrite(xmldoc, localdir = "")
|
113
|
-
n = Namespace.new(xmldoc)
|
114
|
-
xmldoc.xpath(n.ns("//svgmap")).each do |s|
|
115
|
-
next unless svgmap_rewrite0(s, n)
|
116
|
-
next if s.at(n.ns("./target/eref"))
|
117
|
-
s.replace(s.at(n.ns("./figure")))
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
def svgmap_rewrite0(s, n)
|
122
|
-
if i = s.at(n.ns(".//image")) and src = i["src"]
|
123
|
-
path = /^data:/.match(src) ? save_dataimage(src) : File.file?(src) ? src : localdir + src
|
124
|
-
File.file?(path) or return false
|
125
|
-
svgmap_rewrite1(s, Nokogiri::XML(File.read(path, encoding: "utf-8")), path, n)
|
126
|
-
/^data:/.match(src) and i["src"] = datauri(path)
|
127
|
-
elsif i = s.at(".//m:svg", "m" => SVG_NS)
|
128
|
-
svgmap_rewrite1(s, i, nil, n)
|
129
|
-
else
|
130
|
-
return false
|
131
|
-
end
|
132
|
-
true
|
133
|
-
end
|
134
|
-
|
135
|
-
def svgmap_rewrite1(s, svg, path, n)
|
136
|
-
targets = s.xpath(n.ns("./target")).each_with_object({}) do |t, m|
|
137
|
-
x = t.at(n.ns("./xref")) and m[File.expand_path(t["href"])] = "##{x['target']}"
|
138
|
-
x = t.at(n.ns("./link")) and m[File.expand_path(t["href"])] = x['target']
|
139
|
-
t.remove if t.at(n.ns("./xref | ./link"))
|
140
|
-
end
|
141
|
-
svg.xpath(".//m:a", "m" => SVG_NS).each do |a|
|
142
|
-
a["xlink:href"] and x = targets[File.expand_path(a["xlink:href"])] and a["xlink:href"] = x
|
143
|
-
a["href"] and x = targets[File.expand_path(a["href"])] and a["href"] = x
|
144
|
-
end
|
145
|
-
path and File.open(path, "w", encoding: "utf-8") { |f| f.write(svg.to_xml) }
|
146
|
-
end
|
147
|
-
|
148
91
|
# not currently used
|
149
92
|
def flatten_rawtext_lines(node, result)
|
150
93
|
node.lines.each do |x|
|
151
|
-
if node.respond_to?(:context) &&
|
94
|
+
if node.respond_to?(:context) &&
|
95
|
+
(node.context == :literal || node.context == :listing)
|
152
96
|
result << x.gsub(/</, "<").gsub(/>/, ">")
|
153
97
|
else
|
154
98
|
# strip not only HTML <tag>, and Asciidoc xrefs <<xref>>
|
@@ -174,42 +118,6 @@ module Metanorma
|
|
174
118
|
end
|
175
119
|
result.reject(&:empty?)
|
176
120
|
end
|
177
|
-
|
178
|
-
# FIXME: nested uri path error(
|
179
|
-
# sources/plantuml/plantuml20200524-90467-1iqek5i.png ->
|
180
|
-
# sources/sources/plantuml/plantuml20200524-90467-1iqek5i.png)
|
181
|
-
def datauri(uri, localdir = ".")
|
182
|
-
return uri if /^data:/.match(uri)
|
183
|
-
path = %r{^([A-Z]:)?/}.match?(uri) ? uri : File.join(localdir, uri)
|
184
|
-
types = MIME::Types.type_for(path)
|
185
|
-
type = types ? types.first.to_s : 'text/plain; charset="utf-8"'
|
186
|
-
bin = File.open(path, 'rb', &:read)
|
187
|
-
data = Base64.strict_encode64(bin)
|
188
|
-
"data:#{type};base64,#{data}"
|
189
|
-
end
|
190
|
-
|
191
|
-
def datauri2mime(uri)
|
192
|
-
%r{^data:image/(?<imgtype>[^;]+);base64,(?<imgdata>.+)$} =~ uri
|
193
|
-
type = nil
|
194
|
-
imgtype = "png" unless /^[a-z0-9]+$/.match imgtype
|
195
|
-
::Tempfile.open(["imageuri", ".#{imgtype}"]) do |file|
|
196
|
-
type = datauri2mime1(file, imgdata)
|
197
|
-
end
|
198
|
-
[type]
|
199
|
-
end
|
200
|
-
|
201
|
-
def datauri2mime1(file, imgdata)
|
202
|
-
type = nil
|
203
|
-
begin
|
204
|
-
file.binmode
|
205
|
-
file.write(Base64.strict_decode64(imgdata))
|
206
|
-
file.rewind
|
207
|
-
type = MimeMagic.by_magic(file)
|
208
|
-
ensure
|
209
|
-
file.close!
|
210
|
-
end
|
211
|
-
type
|
212
|
-
end
|
213
121
|
end
|
214
122
|
end
|
215
123
|
end
|