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
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: default
|
|
3
|
+
title: Format Detection
|
|
4
|
+
parent: Features
|
|
5
|
+
nav_order: 2
|
|
6
|
+
---
|
|
7
|
+
= Format Detection
|
|
8
|
+
|
|
9
|
+
How Vectory automatically detects vector image formats.
|
|
10
|
+
|
|
11
|
+
== Overview
|
|
12
|
+
|
|
13
|
+
Vectory can automatically detect image formats from file content, not just file extensions. This ensures reliable format identification even when files have incorrect or missing extensions.
|
|
14
|
+
|
|
15
|
+
== Detection Methods
|
|
16
|
+
|
|
17
|
+
=== Magic Number Detection
|
|
18
|
+
|
|
19
|
+
Vectory uses file signatures (magic numbers) to identify binary formats:
|
|
20
|
+
|
|
21
|
+
[cols="1,2a"]
|
|
22
|
+
|===
|
|
23
|
+
|Format|Magic Number
|
|
24
|
+
|
|
25
|
+
|EPS
|
|
26
|
+
|%!PS-Adobe-3.0 EPSF-3.0
|
|
27
|
+
|
|
28
|
+
|PS
|
|
29
|
+
|%!PS-Adobe-3.0 (without EPSF)
|
|
30
|
+
|
|
31
|
+
|EMF
|
|
32
|
+
|\x01\x00\x00\x00 (EMF header signature)
|
|
33
|
+
|===
|
|
34
|
+
|
|
35
|
+
[source,ruby]
|
|
36
|
+
----
|
|
37
|
+
# Automatic detection from file
|
|
38
|
+
image = Vectory::Image.from_path("unknown_file")
|
|
39
|
+
puts image.class # => Vectory::Eps, Vectory::Ps, Vectory::Emf, etc.
|
|
40
|
+
----
|
|
41
|
+
|
|
42
|
+
=== Content Inspection
|
|
43
|
+
|
|
44
|
+
SVG files are detected by XML content inspection:
|
|
45
|
+
|
|
46
|
+
[source,ruby]
|
|
47
|
+
----
|
|
48
|
+
# Detects <svg> tag in XML content
|
|
49
|
+
svg = Vectory::Image.from_path("no_extension_file")
|
|
50
|
+
puts svg.class # => Vectory::Svg
|
|
51
|
+
----
|
|
52
|
+
|
|
53
|
+
=== Explicit Factory Methods
|
|
54
|
+
|
|
55
|
+
You can also explicitly specify the format:
|
|
56
|
+
|
|
57
|
+
[source,ruby]
|
|
58
|
+
----
|
|
59
|
+
# Explicit format selection
|
|
60
|
+
eps = Vectory::Eps.from_path("diagram")
|
|
61
|
+
svg = Vectory::Svg.from_path("diagram")
|
|
62
|
+
----
|
|
63
|
+
|
|
64
|
+
== Format Detection API
|
|
65
|
+
|
|
66
|
+
=== FileMagic.detect_format
|
|
67
|
+
|
|
68
|
+
Detect format from content string:
|
|
69
|
+
|
|
70
|
+
[source,ruby]
|
|
71
|
+
----
|
|
72
|
+
content = File.read("unknown_file")
|
|
73
|
+
format = Vectory::FileMagic.detect_format(content)
|
|
74
|
+
|
|
75
|
+
case format
|
|
76
|
+
when :eps
|
|
77
|
+
puts "This is an EPS file"
|
|
78
|
+
when :ps
|
|
79
|
+
puts "This is a PS file"
|
|
80
|
+
when :emf
|
|
81
|
+
puts "This is an EMF file"
|
|
82
|
+
when :svg
|
|
83
|
+
puts "This is an SVG file"
|
|
84
|
+
else
|
|
85
|
+
puts "Unknown format"
|
|
86
|
+
end
|
|
87
|
+
----
|
|
88
|
+
|
|
89
|
+
=== from_path Auto-Detection
|
|
90
|
+
|
|
91
|
+
[source,ruby]
|
|
92
|
+
----
|
|
93
|
+
# Auto-detects format from file path and content
|
|
94
|
+
image = Vectory::Image.from_path("diagram")
|
|
95
|
+
|
|
96
|
+
if image.is_a?(Vectory::Eps)
|
|
97
|
+
puts "Detected EPS format"
|
|
98
|
+
elsif image.is_a?(Vectory::Svg)
|
|
99
|
+
puts "Detected SVG format"
|
|
100
|
+
end
|
|
101
|
+
----
|
|
102
|
+
|
|
103
|
+
== Detection Priority
|
|
104
|
+
|
|
105
|
+
Vectory uses a cascading detection strategy:
|
|
106
|
+
|
|
107
|
+
. **Magic numbers** for EPS, PS, EMF (most reliable)
|
|
108
|
+
. **XML content inspection** for SVG (looks for `<svg>` tag)
|
|
109
|
+
. **File extension** as fallback (`.eps`, `.ps`, `.emf`, `.svg`)
|
|
110
|
+
|
|
111
|
+
[source,ruby]
|
|
112
|
+
----
|
|
113
|
+
# Detection priority example
|
|
114
|
+
content = "%!PS-Adobe-3.0 EPSF-3.0"
|
|
115
|
+
format = Vectory::FileMagic.detect_format(content)
|
|
116
|
+
puts format # => :eps (magic number detected)
|
|
117
|
+
----
|
|
118
|
+
|
|
119
|
+
== Edge Cases
|
|
120
|
+
|
|
121
|
+
=== EPS vs PS Detection
|
|
122
|
+
|
|
123
|
+
The presence of `EPSF-3.0` distinguishes EPS from PS:
|
|
124
|
+
|
|
125
|
+
[source,ruby]
|
|
126
|
+
----
|
|
127
|
+
eps_content = "%!PS-Adobe-3.0 EPSF-3.0"
|
|
128
|
+
ps_content = "%!PS-Adobe-3.0"
|
|
129
|
+
|
|
130
|
+
Vectory::FileMagic.detect_format(eps_content) # => :eps
|
|
131
|
+
Vectory::FileMagic.detect_format(ps_content) # => :ps
|
|
132
|
+
----
|
|
133
|
+
|
|
134
|
+
=== Invalid Files
|
|
135
|
+
|
|
136
|
+
[source,ruby]
|
|
137
|
+
----
|
|
138
|
+
begin
|
|
139
|
+
image = Vectory::Image.from_path("corrupt_file")
|
|
140
|
+
rescue Vectory::ParsingError => e
|
|
141
|
+
puts "Failed to detect format: #{e.message}"
|
|
142
|
+
end
|
|
143
|
+
----
|
|
144
|
+
|
|
145
|
+
=== Empty Files
|
|
146
|
+
|
|
147
|
+
[source,ruby]
|
|
148
|
+
----
|
|
149
|
+
empty_content = ""
|
|
150
|
+
format = Vectory::FileMagic.detect_format(empty_content)
|
|
151
|
+
puts format # => :unknown
|
|
152
|
+
----
|
|
153
|
+
|
|
154
|
+
== Performance
|
|
155
|
+
|
|
156
|
+
Format detection is fast and efficient:
|
|
157
|
+
|
|
158
|
+
* **Magic number check**: First few bytes only
|
|
159
|
+
* **XML inspection**: Checks for `<svg>` tag
|
|
160
|
+
* **No full file parsing**: Detection is separate from conversion
|
|
161
|
+
|
|
162
|
+
[source,ruby]
|
|
163
|
+
----
|
|
164
|
+
# Detection is fast even for large files
|
|
165
|
+
large_eps = Vectory::Image.from_path("100mb_diagram.eps")
|
|
166
|
+
# Detection completes in milliseconds
|
|
167
|
+
----
|
|
168
|
+
|
|
169
|
+
== See Also
|
|
170
|
+
|
|
171
|
+
* link:conversion/[Conversion Features] - What happens after detection
|
|
172
|
+
* link:../understanding/magic-numbers/[Magic Numbers] - Technical details
|
|
173
|
+
* link:../reference/api/[API Reference] - Detection methods
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: default
|
|
3
|
+
title: Features
|
|
4
|
+
nav_order: 4
|
|
5
|
+
has_children: true
|
|
6
|
+
---
|
|
7
|
+
= Features
|
|
8
|
+
|
|
9
|
+
Explore Vectory's conversion capabilities and format support.
|
|
10
|
+
|
|
11
|
+
== Overview
|
|
12
|
+
|
|
13
|
+
Vectory provides pairwise vector image conversion between EPS, PS, EMF, SVG, and PDF formats. This section covers all supported formats, conversion methods, and special features.
|
|
14
|
+
|
|
15
|
+
== Supported Formats
|
|
16
|
+
|
|
17
|
+
=== Input Formats
|
|
18
|
+
|
|
19
|
+
link:formats/eps[**EPS (Encapsulated PostScript)**]::
|
|
20
|
+
PostScript-based vector format with bounding box support.
|
|
21
|
+
|
|
22
|
+
link:formats/ps[**PS (PostScript)**]::
|
|
23
|
+
Full PostScript document format.
|
|
24
|
+
|
|
25
|
+
link:formats/emf[**EMF (Enhanced Metafile)**]::
|
|
26
|
+
Windows vector metafile format.
|
|
27
|
+
|
|
28
|
+
link:formats/svg[**SVG (Scalable Vector Graphics)**]::
|
|
29
|
+
XML-based vector format for web graphics.
|
|
30
|
+
|
|
31
|
+
=== Output Formats
|
|
32
|
+
|
|
33
|
+
All input formats can be converted to:
|
|
34
|
+
* link:formats/eps[EPS]
|
|
35
|
+
* link:formats/ps[PS]
|
|
36
|
+
* link:formats/emf[EMF]
|
|
37
|
+
* link:formats/svg[SVG]
|
|
38
|
+
* link:formats/pdf[PDF] (intermediate format)
|
|
39
|
+
|
|
40
|
+
== Key Features
|
|
41
|
+
|
|
42
|
+
link:conversion/[**Pairwise Conversion**]::
|
|
43
|
+
Convert any supported format to any other format.
|
|
44
|
+
+
|
|
45
|
+
Transparent conversion through PDF intermediate format when needed.
|
|
46
|
+
|
|
47
|
+
link:format-detection/[**Automatic Format Detection**]::
|
|
48
|
+
Detect image format from file content, not just extension.
|
|
49
|
+
+
|
|
50
|
+
Uses magic numbers for EPS, PS, EMF; content inspection for SVG.
|
|
51
|
+
|
|
52
|
+
link:dimension-query/[**Dimension Queries**]::
|
|
53
|
+
Query image dimensions without full rendering.
|
|
54
|
+
+
|
|
55
|
+
Fast dimension retrieval using external tools.
|
|
56
|
+
|
|
57
|
+
link:content-sources/[**Multiple Input Sources**]::
|
|
58
|
+
Load images from files, content strings, or data URIs.
|
|
59
|
+
|
|
60
|
+
link:speed/[**Performance**]::
|
|
61
|
+
Efficient caching and external tool management.
|
|
62
|
+
+
|
|
63
|
+
Singleton pattern for Inkscape wrapper, version detection.
|
|
64
|
+
|
|
65
|
+
== Conversion Paths
|
|
66
|
+
|
|
67
|
+
Vectory uses different external tools depending on the source and target formats.
|
|
68
|
+
|
|
69
|
+
=== Direct Conversions (via Inkscape)
|
|
70
|
+
|
|
71
|
+
* **SVG → EPS/PS/EMF/PDF** (via Inkscape export)
|
|
72
|
+
* **EPS/PS/EMF/PDF → SVG** (via Inkscape import)
|
|
73
|
+
|
|
74
|
+
Inkscape handles direct conversions to and from SVG format.
|
|
75
|
+
|
|
76
|
+
=== Direct Conversions (via emf2svg)
|
|
77
|
+
|
|
78
|
+
* **EMF → SVG** (via emf2svg gem)
|
|
79
|
+
|
|
80
|
+
The emf2svg gem provides native EMF to SVG conversion without external tool dependencies.
|
|
81
|
+
|
|
82
|
+
=== Two-Step Conversions (via Ghostscript + Inkscape)
|
|
83
|
+
|
|
84
|
+
* **EPS → PDF → SVG** (Ghostscript for EPS→PDF, Inkscape for PDF→SVG)
|
|
85
|
+
* **PS → PDF → SVG** (Ghostscript for PS→PDF, Inkscape for PDF→SVG)
|
|
86
|
+
|
|
87
|
+
This two-step process preserves BoundingBox information from EPS/PS files.
|
|
88
|
+
|
|
89
|
+
=== Conversion Tool Matrix
|
|
90
|
+
|
|
91
|
+
[cols="2,2a"]
|
|
92
|
+
|===
|
|
93
|
+
|Conversion|Tool Used
|
|
94
|
+
|
|
95
|
+
|SVG ↔ EPS
|
|
96
|
+
|Inkscape
|
|
97
|
+
|
|
98
|
+
|SVG ↔ PS
|
|
99
|
+
|Inkscape
|
|
100
|
+
|
|
101
|
+
|SVG ↔ EMF
|
|
102
|
+
|Inkscape (SVG→EMF), emf2svg (EMF→SVG)
|
|
103
|
+
|
|
104
|
+
|SVG ↔ PDF
|
|
105
|
+
|Inkscape
|
|
106
|
+
|
|
107
|
+
|EPS → PDF
|
|
108
|
+
|Ghostscript (preserves BoundingBox)
|
|
109
|
+
|
|
110
|
+
|PS → PDF
|
|
111
|
+
|Ghostscript (preserves BoundingBox)
|
|
112
|
+
|
|
113
|
+
|EPS/PS → SVG
|
|
114
|
+
|Ghostscript + Inkscape (two-step)
|
|
115
|
+
|
|
116
|
+
|EMF → SVG
|
|
117
|
+
|emf2svg gem
|
|
118
|
+
|===
|
|
119
|
+
|
|
120
|
+
See link:conversion/[Conversion Features] for detailed conversion paths and options.
|
|
121
|
+
|
|
122
|
+
== External Tool Integration
|
|
123
|
+
|
|
124
|
+
Vectory relies on external tools for actual conversion operations. The library provides a unified Ruby interface while delegating the heavy lifting to specialized tools.
|
|
125
|
+
|
|
126
|
+
link:inkscape-version/[**Inkscape Version Handling**]::
|
|
127
|
+
Automatic version detection for 0.x vs 1.x+ syntax differences.
|
|
128
|
+
+
|
|
129
|
+
Vectory detects the installed Inkscape version and uses appropriate command-line syntax.
|
|
130
|
+
|
|
131
|
+
link:external-dependencies/[**External Dependencies**]::
|
|
132
|
+
Comprehensive guide to all external tools and gems.
|
|
133
|
+
+
|
|
134
|
+
* **Inkscape** - Primary conversion engine for SVG, EPS, PS, EMF, PDF
|
|
135
|
+
* **Ghostscript** - EPS/PS to PDF conversion with BoundingBox preservation
|
|
136
|
+
* **emf2svg** - EMF format support via Ruby gem
|
|
137
|
+
* **moxml** - XML/HTML parsing for Metanorma integration
|
|
138
|
+
|
|
139
|
+
link:timeout-handling/[**Timeout and Error Handling**]::
|
|
140
|
+
Robust error handling for external tool failures.
|
|
141
|
+
+
|
|
142
|
+
Automatic tool discovery, timeout management, platform-specific process handling.
|
|
143
|
+
|
|
144
|
+
== Special Features
|
|
145
|
+
|
|
146
|
+
link:metadata/[**Metadata Preservation**]::
|
|
147
|
+
Preserves document metadata during conversions.
|
|
148
|
+
|
|
149
|
+
link:bounding-box/[**Bounding Box Handling**]::
|
|
150
|
+
Maintains EPS/PS bounding box information through conversion pipeline.
|
|
151
|
+
|
|
152
|
+
link:metanorma-integration/[**Metanorma Integration**]::
|
|
153
|
+
SVG mapping features for XML/HTML document processing.
|
|
154
|
+
+
|
|
155
|
+
Link rewriting, ID preservation, namespace handling.
|
|
156
|
+
|
|
157
|
+
== Quick Examples
|
|
158
|
+
|
|
159
|
+
=== Convert EPS to SVG
|
|
160
|
+
|
|
161
|
+
[source,ruby]
|
|
162
|
+
----
|
|
163
|
+
require 'vectory'
|
|
164
|
+
|
|
165
|
+
svg = Vectory::Eps.from_path("diagram.eps").to_svg
|
|
166
|
+
svg.write("diagram.svg")
|
|
167
|
+
----
|
|
168
|
+
|
|
169
|
+
=== Detect Format from Content
|
|
170
|
+
|
|
171
|
+
[source,ruby]
|
|
172
|
+
----
|
|
173
|
+
content = File.read("unknown_file")
|
|
174
|
+
format = Vectory::FileMagic.detect_format(content)
|
|
175
|
+
# => :eps, :ps, :emf, :svg, or :unknown
|
|
176
|
+
----
|
|
177
|
+
|
|
178
|
+
=== Query Dimensions
|
|
179
|
+
|
|
180
|
+
[source,ruby]
|
|
181
|
+
----
|
|
182
|
+
eps = Vectory::Eps.from_path("diagram.eps")
|
|
183
|
+
width, height = eps.dimensions
|
|
184
|
+
puts "Size: #{width}x#{height}"
|
|
185
|
+
----
|
|
186
|
+
|
|
187
|
+
== Common Use Cases
|
|
188
|
+
|
|
189
|
+
**Batch conversion**::
|
|
190
|
+
Use link:guides/batch-processing[batch processing guide] for multiple files.
|
|
191
|
+
|
|
192
|
+
**Format validation**::
|
|
193
|
+
Use link:format-detection[format detection] to verify file types.
|
|
194
|
+
|
|
195
|
+
**Dimension extraction**::
|
|
196
|
+
Use link:dimension-query[dimension queries] for fast size retrieval.
|
|
197
|
+
|
|
198
|
+
**Metanorma documents**::
|
|
199
|
+
Use link:metanorma-integration[SVG mapping] for XML integration.
|
|
200
|
+
|
|
201
|
+
== See Also
|
|
202
|
+
|
|
203
|
+
* link:../understanding/[Understanding Vectory] - How features work internally
|
|
204
|
+
* link:../guides/[Guides] - Practical how-to guides
|
|
205
|
+
* link:../reference/[Reference] - Complete API documentation
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: default
|
|
3
|
+
title: Core Concepts
|
|
4
|
+
parent: Getting Started
|
|
5
|
+
nav_order: 3
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Understanding Vectory's architecture and design principles.
|
|
9
|
+
|
|
10
|
+
== Purpose
|
|
11
|
+
|
|
12
|
+
This section explains Vectory's core concepts including its class hierarchy, conversion pipeline, and design patterns. Understanding these concepts will help you use Vectory effectively.
|
|
13
|
+
|
|
14
|
+
== Class Hierarchy
|
|
15
|
+
|
|
16
|
+
Vectory uses an object-oriented, inheritance-based architecture:
|
|
17
|
+
|
|
18
|
+
[source,ruby]
|
|
19
|
+
----
|
|
20
|
+
Vectory::Image # Base class for all images
|
|
21
|
+
└── Vectory::Vector # Abstract base for vector formats
|
|
22
|
+
├── Vectory::Eps # Encapsulated PostScript
|
|
23
|
+
├── Vectory::Ps # PostScript
|
|
24
|
+
├── Vectory::Emf # Enhanced Metafile
|
|
25
|
+
├── Vectory::Svg # Scalable Vector Graphics
|
|
26
|
+
└── Vectory::Pdf # PDF (intermediate format)
|
|
27
|
+
----
|
|
28
|
+
|
|
29
|
+
Each format class inherits from `Vectory::Vector`, which provides common functionality for vector image manipulation.
|
|
30
|
+
|
|
31
|
+
== Factory Methods
|
|
32
|
+
|
|
33
|
+
All format classes support four factory methods for creating image objects:
|
|
34
|
+
|
|
35
|
+
=== from_path
|
|
36
|
+
|
|
37
|
+
Load from a file path:
|
|
38
|
+
|
|
39
|
+
[source,ruby]
|
|
40
|
+
----
|
|
41
|
+
eps = Vectory::Eps.from_path("diagram.eps")
|
|
42
|
+
----
|
|
43
|
+
|
|
44
|
+
=== from_content
|
|
45
|
+
|
|
46
|
+
Load from a content string:
|
|
47
|
+
|
|
48
|
+
[source,ruby]
|
|
49
|
+
----
|
|
50
|
+
content = File.read("diagram.eps")
|
|
51
|
+
eps = Vectory::Eps.from_content(content)
|
|
52
|
+
----
|
|
53
|
+
|
|
54
|
+
=== from_datauri
|
|
55
|
+
|
|
56
|
+
Load from a data URI:
|
|
57
|
+
|
|
58
|
+
[source,ruby]
|
|
59
|
+
----
|
|
60
|
+
uri = "data:image/svg+xml;base64,PHN2Zy..."
|
|
61
|
+
svg = Vectory::Svg.from_datauri(uri)
|
|
62
|
+
----
|
|
63
|
+
|
|
64
|
+
=== from_node
|
|
65
|
+
|
|
66
|
+
Load from an XML node (Metanorma integration):
|
|
67
|
+
|
|
68
|
+
[source,ruby]
|
|
69
|
+
----
|
|
70
|
+
# Used internally by Metanorma's SVG mapping
|
|
71
|
+
----
|
|
72
|
+
|
|
73
|
+
== Conversion Methods
|
|
74
|
+
|
|
75
|
+
Each format class can convert to any other format:
|
|
76
|
+
|
|
77
|
+
[source,ruby]
|
|
78
|
+
----
|
|
79
|
+
# Convert EPS to SVG
|
|
80
|
+
svg = Vectory::Eps.from_path("diagram.eps").to_svg
|
|
81
|
+
|
|
82
|
+
# Convert SVG to EMF
|
|
83
|
+
emf = Vectory::Svg.from_path("drawing.svg").to_emf
|
|
84
|
+
|
|
85
|
+
# Convert EMF to PDF
|
|
86
|
+
pdf = Vectory::Emf.from_path("chart.emf").to_pdf
|
|
87
|
+
----
|
|
88
|
+
|
|
89
|
+
== Conversion Pipeline
|
|
90
|
+
|
|
91
|
+
Vectory uses a flexible conversion pipeline:
|
|
92
|
+
|
|
93
|
+
=== Direct Conversions
|
|
94
|
+
|
|
95
|
+
Some conversions are direct:
|
|
96
|
+
* **SVG → EPS/PS/EMF/PDF**: Via Inkscape
|
|
97
|
+
* **EMF → SVG**: Via emf2svg
|
|
98
|
+
|
|
99
|
+
=== Two-Step Conversions
|
|
100
|
+
|
|
101
|
+
Other conversions use an intermediate PDF format:
|
|
102
|
+
* **EPS/PS → PDF → SVG**: Via Ghostscript + Inkscape
|
|
103
|
+
|
|
104
|
+
This two-step conversion ensures:
|
|
105
|
+
* BoundingBox preservation from EPS/PS
|
|
106
|
+
* High-quality output from Inkscape
|
|
107
|
+
|
|
108
|
+
== Properties
|
|
109
|
+
|
|
110
|
+
All image objects have these properties:
|
|
111
|
+
|
|
112
|
+
[source,ruby]
|
|
113
|
+
----
|
|
114
|
+
eps = Vectory::Eps.from_path("diagram.eps")
|
|
115
|
+
|
|
116
|
+
# Raw content
|
|
117
|
+
content = eps.content
|
|
118
|
+
|
|
119
|
+
# Original file location
|
|
120
|
+
original_path = eps.initial_path
|
|
121
|
+
|
|
122
|
+
# Current file location (raises error if not written)
|
|
123
|
+
current_path = eps.path # => NotWrittenToDiskError
|
|
124
|
+
|
|
125
|
+
# Image dimensions
|
|
126
|
+
width, height = eps.dimensions
|
|
127
|
+
|
|
128
|
+
# Write to file
|
|
129
|
+
output_path = eps.write("output.eps")
|
|
130
|
+
----
|
|
131
|
+
|
|
132
|
+
== File System Operations
|
|
133
|
+
|
|
134
|
+
Vectory distinguishes between two file paths:
|
|
135
|
+
|
|
136
|
+
* **`initial_path`**: Where the file was originally loaded from (read-only)
|
|
137
|
+
* **`path`**: Where the file is currently written (raises error if not yet written)
|
|
138
|
+
|
|
139
|
+
[source,ruby]
|
|
140
|
+
----
|
|
141
|
+
eps = Vectory::Eps.from_path("input.eps")
|
|
142
|
+
puts eps.initial_path # => "input.eps"
|
|
143
|
+
|
|
144
|
+
puts eps.path # => raises NotWrittenToDiskError
|
|
145
|
+
|
|
146
|
+
eps.write("output.eps")
|
|
147
|
+
puts eps.path # => "output.eps"
|
|
148
|
+
----
|
|
149
|
+
|
|
150
|
+
Writing without arguments uses a temporary directory:
|
|
151
|
+
|
|
152
|
+
[source,ruby]
|
|
153
|
+
----
|
|
154
|
+
eps = Vectory::Eps.from_path("input.eps")
|
|
155
|
+
temp_path = eps.write # => "/tmp/vectory_20250119..."
|
|
156
|
+
----
|
|
157
|
+
|
|
158
|
+
== Format Detection
|
|
159
|
+
|
|
160
|
+
Vectory detects formats using:
|
|
161
|
+
* **Magic numbers** for EPS, PS, EMF (file signatures)
|
|
162
|
+
* **Content inspection** for SVG (XML structure)
|
|
163
|
+
* **File extension** as fallback
|
|
164
|
+
|
|
165
|
+
[source,ruby]
|
|
166
|
+
----
|
|
167
|
+
# Auto-detect from file
|
|
168
|
+
image = Vectory::Image.from_path("unknown_file")
|
|
169
|
+
puts image.class # => Vectory::Eps, Vectory::Svg, etc.
|
|
170
|
+
|
|
171
|
+
# Detect format from content
|
|
172
|
+
content = File.read("unknown_file")
|
|
173
|
+
format = Vectory::FileMagic.detect_format(content)
|
|
174
|
+
puts format # => :eps, :ps, :emf, :svg, or :unknown
|
|
175
|
+
----
|
|
176
|
+
|
|
177
|
+
== Error Handling
|
|
178
|
+
|
|
179
|
+
Vectory uses a structured error hierarchy:
|
|
180
|
+
|
|
181
|
+
[source,ruby]
|
|
182
|
+
----
|
|
183
|
+
Vectory::Error # Base error class
|
|
184
|
+
├── SystemCallError # External tool execution failures
|
|
185
|
+
├── NotWrittenToDiskError # Accessing path before write
|
|
186
|
+
├── ParsingError # Content parsing failures
|
|
187
|
+
├── InkscapeNotFoundError # Inkscape not available
|
|
188
|
+
├── ConversionError # Conversion failures with diagnostics
|
|
189
|
+
└── InkscapeQueryError # Dimension query failures
|
|
190
|
+
----
|
|
191
|
+
|
|
192
|
+
== External Tool Integration
|
|
193
|
+
|
|
194
|
+
Vectory uses the https://en.wikipedia.org/wiki/Singleton_pattern[Singleton pattern] for external tool wrappers:
|
|
195
|
+
|
|
196
|
+
[source,ruby]
|
|
197
|
+
----
|
|
198
|
+
# Shared Inkscape instance across conversions
|
|
199
|
+
inkscape = Vectory::InkscapeWrapper.instance
|
|
200
|
+
|
|
201
|
+
# Version is cached
|
|
202
|
+
puts inkscape.version # => "1.3.0" (cached)
|
|
203
|
+
|
|
204
|
+
# Tool discovery is done once
|
|
205
|
+
puts inkscape.executable # => "/usr/bin/inkscape"
|
|
206
|
+
----
|
|
207
|
+
|
|
208
|
+
This design improves performance and ensures consistent behavior.
|
|
209
|
+
|
|
210
|
+
== Next Steps
|
|
211
|
+
|
|
212
|
+
. Explore link:../features/[Features] for supported formats and conversions
|
|
213
|
+
. Check link:../guides/[Guides] for practical examples
|
|
214
|
+
. See link:../understanding/[Understanding] for internal architecture details
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: default
|
|
3
|
+
title: Getting Started
|
|
4
|
+
nav_order: 2
|
|
5
|
+
has_children: true
|
|
6
|
+
---
|
|
7
|
+
= Getting Started
|
|
8
|
+
|
|
9
|
+
Get up and running with Vectory quickly.
|
|
10
|
+
|
|
11
|
+
== Overview
|
|
12
|
+
|
|
13
|
+
This section will help you install Vectory and perform your first vector image conversions.
|
|
14
|
+
|
|
15
|
+
== Prerequisites
|
|
16
|
+
|
|
17
|
+
Before installing Vectory, ensure you have the following:
|
|
18
|
+
|
|
19
|
+
* **Ruby** 3.1 or later
|
|
20
|
+
* **Inkscape** 0.92 or later (recommended: 1.x)
|
|
21
|
+
* **Ghostscript** (for EPS/PS conversions)
|
|
22
|
+
|
|
23
|
+
See link:installation[Installation] for detailed setup instructions.
|
|
24
|
+
|
|
25
|
+
== Quick Start Path
|
|
26
|
+
|
|
27
|
+
. link:installation[Install Vectory]
|
|
28
|
+
. link:quick-start[Try basic conversions]
|
|
29
|
+
. link:core-concepts[Understand core concepts]
|
|
30
|
+
|
|
31
|
+
== Next Steps
|
|
32
|
+
|
|
33
|
+
After getting started, explore:
|
|
34
|
+
|
|
35
|
+
* link:../features/[Features] - All supported formats and conversions
|
|
36
|
+
* link:../guides/[Guides] - Practical how-to guides
|
|
37
|
+
* link:../reference/[Reference] - Complete API documentation
|