vectory 0.7.8 → 0.8.1
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/docs.yml +59 -0
- data/.github/workflows/links.yml +99 -0
- data/.github/workflows/rake.yml +5 -1
- data/.github/workflows/release.yml +7 -3
- data/.gitignore +5 -0
- data/.rubocop.yml +11 -3
- data/.rubocop_todo.yml +252 -0
- data/Gemfile +4 -2
- data/README.adoc +23 -1
- data/Rakefile +13 -0
- data/docs/Gemfile +18 -0
- data/docs/_config.yml +179 -0
- data/docs/features/conversion.adoc +205 -0
- data/docs/features/external-dependencies.adoc +305 -0
- data/docs/features/format-detection.adoc +173 -0
- data/docs/features/index.adoc +205 -0
- data/docs/getting-started/core-concepts.adoc +214 -0
- data/docs/getting-started/index.adoc +37 -0
- data/docs/getting-started/installation.adoc +318 -0
- data/docs/getting-started/quick-start.adoc +160 -0
- data/docs/guides/error-handling.adoc +400 -0
- data/docs/guides/index.adoc +197 -0
- data/docs/index.adoc +146 -0
- data/docs/lychee.toml +25 -0
- data/docs/reference/api.adoc +355 -0
- data/docs/reference/index.adoc +189 -0
- data/docs/understanding/architecture.adoc +277 -0
- data/docs/understanding/index.adoc +148 -0
- data/docs/understanding/inkscape-wrapper.adoc +270 -0
- data/lib/vectory/capture.rb +165 -37
- data/lib/vectory/cli.rb +2 -0
- data/lib/vectory/configuration.rb +177 -0
- data/lib/vectory/conversion/ghostscript_strategy.rb +77 -0
- data/lib/vectory/conversion/inkscape_strategy.rb +124 -0
- data/lib/vectory/conversion/strategy.rb +58 -0
- data/lib/vectory/conversion.rb +104 -0
- data/lib/vectory/datauri.rb +1 -1
- data/lib/vectory/emf.rb +17 -5
- data/lib/vectory/eps.rb +45 -3
- data/lib/vectory/errors.rb +25 -0
- data/lib/vectory/file_magic.rb +2 -2
- data/lib/vectory/ghostscript_wrapper.rb +160 -0
- data/lib/vectory/image_resize.rb +98 -12
- data/lib/vectory/inkscape_wrapper.rb +205 -0
- data/lib/vectory/pdf.rb +76 -0
- data/lib/vectory/platform.rb +105 -0
- data/lib/vectory/ps.rb +47 -3
- data/lib/vectory/svg.rb +46 -3
- data/lib/vectory/svg_document.rb +40 -24
- data/lib/vectory/system_call.rb +36 -9
- data/lib/vectory/vector.rb +3 -23
- data/lib/vectory/version.rb +1 -1
- data/lib/vectory.rb +16 -11
- metadata +34 -3
- data/lib/vectory/inkscape_converter.rb +0 -141
data/lib/vectory/vector.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "tempfile"
|
|
4
|
-
require_relative "
|
|
4
|
+
require_relative "inkscape_wrapper"
|
|
5
5
|
|
|
6
6
|
module Vectory
|
|
7
7
|
class Vector < Image
|
|
@@ -47,28 +47,17 @@ module Vectory
|
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
def height
|
|
50
|
-
|
|
50
|
+
InkscapeWrapper.instance.height(content, self.class.default_extension)
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
def width
|
|
54
|
-
|
|
54
|
+
InkscapeWrapper.instance.width(content, self.class.default_extension)
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
def to_uri
|
|
58
58
|
Datauri.from_vector(self)
|
|
59
59
|
end
|
|
60
60
|
|
|
61
|
-
def convert_with_inkscape(inkscape_options, target_class)
|
|
62
|
-
with_file(self.class.default_extension) do |input_path|
|
|
63
|
-
output_extension = target_class.default_extension
|
|
64
|
-
output_path = InkscapeConverter.instance.convert(input_path,
|
|
65
|
-
output_extension,
|
|
66
|
-
inkscape_options)
|
|
67
|
-
|
|
68
|
-
target_class.from_path(output_path)
|
|
69
|
-
end
|
|
70
|
-
end
|
|
71
|
-
|
|
72
61
|
def write(path = nil)
|
|
73
62
|
target_path = path || @path || tmp_path
|
|
74
63
|
File.binwrite(target_path, content)
|
|
@@ -83,15 +72,6 @@ module Vectory
|
|
|
83
72
|
|
|
84
73
|
private
|
|
85
74
|
|
|
86
|
-
def with_file(input_extension)
|
|
87
|
-
Dir.mktmpdir do |dir|
|
|
88
|
-
input_path = File.join(dir, "image.#{input_extension}")
|
|
89
|
-
File.binwrite(input_path, content)
|
|
90
|
-
|
|
91
|
-
yield input_path
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
|
-
|
|
95
75
|
def tmp_path
|
|
96
76
|
dir = Dir.mktmpdir
|
|
97
77
|
filename = "image.#{self.class.default_extension}"
|
data/lib/vectory/version.rb
CHANGED
data/lib/vectory.rb
CHANGED
|
@@ -3,10 +3,21 @@
|
|
|
3
3
|
require "logger"
|
|
4
4
|
require_relative "vectory/version"
|
|
5
5
|
require_relative "vectory/utils"
|
|
6
|
+
|
|
7
|
+
module Vectory
|
|
8
|
+
class Error < StandardError; end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
require_relative "vectory/errors"
|
|
12
|
+
require_relative "vectory/platform"
|
|
13
|
+
require_relative "vectory/configuration"
|
|
14
|
+
require_relative "vectory/conversion"
|
|
6
15
|
require_relative "vectory/image"
|
|
7
16
|
require_relative "vectory/image_resize"
|
|
8
17
|
require_relative "vectory/datauri"
|
|
9
18
|
require_relative "vectory/vector"
|
|
19
|
+
require_relative "vectory/ghostscript_wrapper"
|
|
20
|
+
require_relative "vectory/pdf"
|
|
10
21
|
require_relative "vectory/eps"
|
|
11
22
|
require_relative "vectory/ps"
|
|
12
23
|
require_relative "vectory/emf"
|
|
@@ -14,16 +25,8 @@ require_relative "vectory/svg"
|
|
|
14
25
|
require_relative "vectory/svg_mapping"
|
|
15
26
|
|
|
16
27
|
module Vectory
|
|
17
|
-
class Error < StandardError; end
|
|
18
|
-
|
|
19
|
-
class ConversionError < Error; end
|
|
20
|
-
|
|
21
28
|
class SystemCallError < Error; end
|
|
22
29
|
|
|
23
|
-
class InkscapeNotFoundError < Error; end
|
|
24
|
-
|
|
25
|
-
class InkscapeQueryError < Error; end
|
|
26
|
-
|
|
27
30
|
class NotImplementedError < Error; end
|
|
28
31
|
|
|
29
32
|
class NotWrittenToDiskError < Error; end
|
|
@@ -31,9 +34,11 @@ module Vectory
|
|
|
31
34
|
class ParsingError < Error; end
|
|
32
35
|
|
|
33
36
|
def self.ui
|
|
34
|
-
@ui ||= Logger.new(
|
|
35
|
-
logger.level = ENV[
|
|
36
|
-
logger.formatter = proc { |
|
|
37
|
+
@ui ||= Logger.new($stdout).tap do |logger|
|
|
38
|
+
logger.level = ENV["VECTORY_LOG"] || Logger::WARN
|
|
39
|
+
logger.formatter = proc { |_severity, _datetime, _progname, msg|
|
|
40
|
+
"#{msg}\n"
|
|
41
|
+
}
|
|
37
42
|
end
|
|
38
43
|
end
|
|
39
44
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: vectory
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.8.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-01-28 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: base64
|
|
@@ -105,25 +105,56 @@ extensions: []
|
|
|
105
105
|
extra_rdoc_files: []
|
|
106
106
|
files:
|
|
107
107
|
- ".github/workflows/automerge.yml"
|
|
108
|
+
- ".github/workflows/docs.yml"
|
|
109
|
+
- ".github/workflows/links.yml"
|
|
108
110
|
- ".github/workflows/rake.yml"
|
|
109
111
|
- ".github/workflows/release.yml"
|
|
110
112
|
- ".gitignore"
|
|
111
113
|
- ".hound.yml"
|
|
112
114
|
- ".rubocop.yml"
|
|
115
|
+
- ".rubocop_todo.yml"
|
|
113
116
|
- Gemfile
|
|
114
117
|
- README.adoc
|
|
115
118
|
- Rakefile
|
|
119
|
+
- docs/Gemfile
|
|
120
|
+
- docs/_config.yml
|
|
121
|
+
- docs/features/conversion.adoc
|
|
122
|
+
- docs/features/external-dependencies.adoc
|
|
123
|
+
- docs/features/format-detection.adoc
|
|
124
|
+
- docs/features/index.adoc
|
|
125
|
+
- docs/getting-started/core-concepts.adoc
|
|
126
|
+
- docs/getting-started/index.adoc
|
|
127
|
+
- docs/getting-started/installation.adoc
|
|
128
|
+
- docs/getting-started/quick-start.adoc
|
|
129
|
+
- docs/guides/error-handling.adoc
|
|
130
|
+
- docs/guides/index.adoc
|
|
131
|
+
- docs/index.adoc
|
|
132
|
+
- docs/lychee.toml
|
|
133
|
+
- docs/reference/api.adoc
|
|
134
|
+
- docs/reference/index.adoc
|
|
135
|
+
- docs/understanding/architecture.adoc
|
|
136
|
+
- docs/understanding/index.adoc
|
|
137
|
+
- docs/understanding/inkscape-wrapper.adoc
|
|
116
138
|
- exe/vectory
|
|
117
139
|
- lib/vectory.rb
|
|
118
140
|
- lib/vectory/capture.rb
|
|
119
141
|
- lib/vectory/cli.rb
|
|
142
|
+
- lib/vectory/configuration.rb
|
|
143
|
+
- lib/vectory/conversion.rb
|
|
144
|
+
- lib/vectory/conversion/ghostscript_strategy.rb
|
|
145
|
+
- lib/vectory/conversion/inkscape_strategy.rb
|
|
146
|
+
- lib/vectory/conversion/strategy.rb
|
|
120
147
|
- lib/vectory/datauri.rb
|
|
121
148
|
- lib/vectory/emf.rb
|
|
122
149
|
- lib/vectory/eps.rb
|
|
150
|
+
- lib/vectory/errors.rb
|
|
123
151
|
- lib/vectory/file_magic.rb
|
|
152
|
+
- lib/vectory/ghostscript_wrapper.rb
|
|
124
153
|
- lib/vectory/image.rb
|
|
125
154
|
- lib/vectory/image_resize.rb
|
|
126
|
-
- lib/vectory/
|
|
155
|
+
- lib/vectory/inkscape_wrapper.rb
|
|
156
|
+
- lib/vectory/pdf.rb
|
|
157
|
+
- lib/vectory/platform.rb
|
|
127
158
|
- lib/vectory/ps.rb
|
|
128
159
|
- lib/vectory/svg.rb
|
|
129
160
|
- lib/vectory/svg_document.rb
|
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "singleton"
|
|
4
|
-
require "tmpdir"
|
|
5
|
-
require_relative "system_call"
|
|
6
|
-
|
|
7
|
-
module Vectory
|
|
8
|
-
class InkscapeConverter
|
|
9
|
-
include Singleton
|
|
10
|
-
|
|
11
|
-
def self.convert(uri, output_extension, option)
|
|
12
|
-
instance.convert(uri, output_extension, option)
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def convert(uri, output_extension, option)
|
|
16
|
-
exe = inkscape_path_or_raise_error
|
|
17
|
-
uri = external_path uri
|
|
18
|
-
exe = external_path exe
|
|
19
|
-
cmd = %(#{exe} #{option} #{uri})
|
|
20
|
-
|
|
21
|
-
call = SystemCall.new(cmd).call
|
|
22
|
-
|
|
23
|
-
output_path = find_output(uri, output_extension)
|
|
24
|
-
raise_conversion_error(call) unless output_path
|
|
25
|
-
|
|
26
|
-
output_path
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def height(content, format)
|
|
30
|
-
query_integer(content, format, "--query-height")
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def width(content, format)
|
|
34
|
-
query_integer(content, format, "--query-width")
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
private
|
|
38
|
-
|
|
39
|
-
def inkscape_path_or_raise_error
|
|
40
|
-
inkscape_path or raise(InkscapeNotFoundError,
|
|
41
|
-
"Inkscape missing in PATH, unable to " \
|
|
42
|
-
"convert image. Aborting.")
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def inkscape_path
|
|
46
|
-
@inkscape_path ||= find_inkscape
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def find_inkscape
|
|
50
|
-
cmds.each do |cmd|
|
|
51
|
-
extensions.each do |ext|
|
|
52
|
-
paths.each do |path|
|
|
53
|
-
exe = File.join(path, "#{cmd}#{ext}")
|
|
54
|
-
|
|
55
|
-
return exe if File.executable?(exe) && !File.directory?(exe)
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
nil
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def cmds
|
|
64
|
-
["inkscapecom", "inkscape"]
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
def extensions
|
|
68
|
-
ENV["PATHEXT"] ? ENV["PATHEXT"].split(";") : [""]
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
def paths
|
|
72
|
-
ENV["PATH"].split(File::PATH_SEPARATOR)
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
def find_output(source_path, output_extension)
|
|
76
|
-
basenames = [File.basename(source_path, ".*"),
|
|
77
|
-
File.basename(source_path)]
|
|
78
|
-
|
|
79
|
-
paths = basenames.map do |basename|
|
|
80
|
-
"#{File.join(File.dirname(source_path), basename)}.#{output_extension}"
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
paths.find { |p| File.exist?(p) }
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
def raise_conversion_error(call)
|
|
87
|
-
raise Vectory::ConversionError,
|
|
88
|
-
"Could not convert with Inkscape. " \
|
|
89
|
-
"Inkscape cmd: '#{call.cmd}',\n" \
|
|
90
|
-
"status: '#{call.status}',\n" \
|
|
91
|
-
"stdout: '#{call.stdout.strip}',\n" \
|
|
92
|
-
"stderr: '#{call.stderr.strip}'."
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
def external_path(path)
|
|
96
|
-
win = !!((RUBY_PLATFORM =~ /(win|w)(32|64)$/) ||
|
|
97
|
-
(RUBY_PLATFORM =~ /mswin|mingw/))
|
|
98
|
-
if win
|
|
99
|
-
path.gsub!(%{/}, "\\")
|
|
100
|
-
path[/\s/] ? "\"#{path}\"" : path
|
|
101
|
-
else
|
|
102
|
-
path
|
|
103
|
-
end
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
def query_integer(content, format, options)
|
|
107
|
-
query(content, format, options).to_f.round
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
def query(content, format, options)
|
|
111
|
-
exe = inkscape_path_or_raise_error
|
|
112
|
-
|
|
113
|
-
with_file(content, format) do |path|
|
|
114
|
-
cmd = "#{external_path(exe)} #{options} #{external_path(path)}"
|
|
115
|
-
|
|
116
|
-
call = SystemCall.new(cmd).call
|
|
117
|
-
raise_query_error(call) if call.stdout.empty?
|
|
118
|
-
|
|
119
|
-
call.stdout
|
|
120
|
-
end
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
def with_file(content, extension)
|
|
124
|
-
Dir.mktmpdir do |dir|
|
|
125
|
-
path = File.join(dir, "image.#{extension}")
|
|
126
|
-
File.binwrite(path, content)
|
|
127
|
-
|
|
128
|
-
yield path
|
|
129
|
-
end
|
|
130
|
-
end
|
|
131
|
-
|
|
132
|
-
def raise_query_error(call)
|
|
133
|
-
raise Vectory::InkscapeQueryError,
|
|
134
|
-
"Could not query with Inkscape. " \
|
|
135
|
-
"Inkscape cmd: '#{call.cmd}',\n" \
|
|
136
|
-
"status: '#{call.status}',\n" \
|
|
137
|
-
"stdout: '#{call.stdout.strip}',\n" \
|
|
138
|
-
"stderr: '#{call.stderr.strip}'."
|
|
139
|
-
end
|
|
140
|
-
end
|
|
141
|
-
end
|