postsvg 0.1.0 → 0.3.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/CHANGELOG.md +105 -0
- data/CLAUDE.md +173 -0
- data/Gemfile +2 -3
- data/README.adoc +456 -179
- data/Rakefile +100 -0
- data/TODO.roadmap/00-architecture.md +139 -0
- data/TODO.roadmap/01-autoload-migration.md +39 -0
- data/TODO.roadmap/02-isolate-dormant-code.md +51 -0
- data/TODO.roadmap/03-domain-model.md +66 -0
- data/TODO.roadmap/04-lexer.md +40 -0
- data/TODO.roadmap/05-parser.md +43 -0
- data/TODO.roadmap/06-graphics-state.md +45 -0
- data/TODO.roadmap/07-matrix-and-color.md +37 -0
- data/TODO.roadmap/08-svg-builder.md +51 -0
- data/TODO.roadmap/09-renderer.md +52 -0
- data/TODO.roadmap/10-visitor.md +58 -0
- data/TODO.roadmap/11-operator-coverage.md +103 -0
- data/TODO.roadmap/12-svg-domain.md +62 -0
- data/TODO.roadmap/13-translation-handlers.md +69 -0
- data/TODO.roadmap/14-ps-serializer.md +49 -0
- data/TODO.roadmap/15-cli-and-public-api.md +47 -0
- data/TODO.roadmap/16-specs.md +84 -0
- data/TODO.roadmap/17-docs-sync.md +47 -0
- data/TODO.roadmap/18-performance-and-determinism.md +47 -0
- data/TODO.roadmap/19-error-model.md +45 -0
- data/TODO.roadmap/20-font-and-text.md +46 -0
- data/TODO.roadmap/21-images.md +45 -0
- data/TODO.roadmap/22-forms-and-resources.md +25 -0
- data/TODO.roadmap/23-level2-level3.md +52 -0
- data/TODO.roadmap/24-ci-and-release.md +42 -0
- data/TODO.roadmap/README.md +77 -0
- data/docs/.gitignore +29 -0
- data/docs/CHANGELOG.md +114 -0
- data/docs/COMPLETE_DOCUMENTATION_STATUS.md +376 -0
- data/docs/DEPLOYMENT.md +456 -0
- data/docs/DEPLOYMENT_INSTRUCTIONS.md +229 -0
- data/docs/DOCUMENTATION_PLAN.md +425 -0
- data/docs/FINAL_SUMMARY.md +657 -0
- data/docs/Gemfile +15 -0
- data/docs/README.md +327 -0
- data/docs/_config.yml +99 -0
- data/docs/advanced-topics.adoc +370 -0
- data/docs/api-reference/colors.adoc +705 -0
- data/docs/api-reference/converter.adoc +699 -0
- data/docs/api-reference/execution-context.adoc +1210 -0
- data/docs/api-reference/graphics-state.adoc +1070 -0
- data/docs/api-reference/interpreter.adoc +810 -0
- data/docs/api-reference/matrix.adoc +1179 -0
- data/docs/api-reference/path-builder.adoc +1284 -0
- data/docs/api-reference/postsvg-module.adoc +388 -0
- data/docs/api-reference/svg-generator.adoc +891 -0
- data/docs/api-reference/tokenizer.adoc +925 -0
- data/docs/api-reference.adoc +221 -0
- data/docs/architecture/command-registry.adoc +1191 -0
- data/docs/architecture/conversion-pipeline.adoc +746 -0
- data/docs/architecture/design-decisions.adoc +999 -0
- data/docs/architecture/generator-stage.adoc +1115 -0
- data/docs/architecture/graphics-state-model.adoc +1089 -0
- data/docs/architecture/interpreter-stage.adoc +1125 -0
- data/docs/architecture/parser-stage.adoc +1051 -0
- data/docs/architecture.adoc +354 -0
- data/docs/cli-reference/batch-command.adoc +616 -0
- data/docs/cli-reference/check-command.adoc +677 -0
- data/docs/cli-reference/cli-options.adoc +802 -0
- data/docs/cli-reference/convert-command.adoc +462 -0
- data/docs/cli-reference/version-command.adoc +296 -0
- data/docs/cli-reference.adoc +317 -0
- data/docs/concepts/conversion-pipeline.adoc +903 -0
- data/docs/concepts/coordinate-systems.adoc +836 -0
- data/docs/concepts/graphics-state.adoc +861 -0
- data/docs/concepts/path-operations.adoc +1076 -0
- data/docs/concepts/postscript-language.adoc +859 -0
- data/docs/concepts/svg-generation.adoc +937 -0
- data/docs/concepts.adoc +198 -0
- data/docs/contributing.adoc +443 -0
- data/docs/development.adoc +420 -0
- data/docs/faq.adoc +493 -0
- data/docs/getting-started/basic-usage.adoc +538 -0
- data/docs/getting-started/common-workflows.adoc +577 -0
- data/docs/getting-started/first-conversion.adoc +492 -0
- data/docs/getting-started/installation.adoc +534 -0
- data/docs/getting-started.adoc +94 -0
- data/docs/index.adoc +248 -0
- data/docs/optimization.adoc +196 -0
- data/docs/ps2svg_compatibility.adoc +149 -0
- data/docs/quick-reference.adoc +453 -0
- data/docs/sitemap.adoc +337 -0
- data/docs/troubleshooting.adoc +486 -0
- data/docs/validation.adoc +772 -0
- data/exe/postsvg +1 -0
- data/lib/postsvg/cli.rb +104 -57
- data/lib/postsvg/color.rb +132 -0
- data/lib/postsvg/errors.rb +68 -3
- data/lib/postsvg/format_number.rb +22 -0
- data/lib/postsvg/graphics_context.rb +80 -0
- data/lib/postsvg/graphics_stack.rb +43 -0
- data/lib/postsvg/model/literals/array.rb +41 -0
- data/lib/postsvg/model/literals/dictionary.rb +34 -0
- data/lib/postsvg/model/literals/hex.rb +37 -0
- data/lib/postsvg/model/literals/name.rb +40 -0
- data/lib/postsvg/model/literals/number.rb +36 -0
- data/lib/postsvg/model/literals/procedure.rb +41 -0
- data/lib/postsvg/model/literals/string.rb +30 -0
- data/lib/postsvg/model/literals.rb +19 -0
- data/lib/postsvg/model/operator.rb +58 -0
- data/lib/postsvg/model/operators/arithmetic.rb +264 -0
- data/lib/postsvg/model/operators/boolean.rb +182 -0
- data/lib/postsvg/model/operators/color.rb +74 -0
- data/lib/postsvg/model/operators/container.rb +186 -0
- data/lib/postsvg/model/operators/control_flow.rb +119 -0
- data/lib/postsvg/model/operators/device.rb +21 -0
- data/lib/postsvg/model/operators/dictionary.rb +118 -0
- data/lib/postsvg/model/operators/font.rb +121 -0
- data/lib/postsvg/model/operators/graphics_state.rb +84 -0
- data/lib/postsvg/model/operators/painting.rb +29 -0
- data/lib/postsvg/model/operators/path.rb +169 -0
- data/lib/postsvg/model/operators/stack.rb +72 -0
- data/lib/postsvg/model/operators/transformations.rb +103 -0
- data/lib/postsvg/model/operators.rb +89 -0
- data/lib/postsvg/model/program.rb +68 -0
- data/lib/postsvg/model/token.rb +43 -0
- data/lib/postsvg/model.rb +17 -0
- data/lib/postsvg/options.rb +29 -0
- data/lib/postsvg/renderer.rb +85 -0
- data/lib/postsvg/serializer.rb +325 -0
- data/lib/postsvg/source/ast_builder.rb +308 -0
- data/lib/postsvg/source/lexer.rb +322 -0
- data/lib/postsvg/source/operand_stack.rb +55 -0
- data/lib/postsvg/source.rb +21 -0
- data/lib/postsvg/svg/attribute_parser.rb +45 -0
- data/lib/postsvg/svg/clip_path_registry.rb +44 -0
- data/lib/postsvg/svg/document.rb +22 -0
- data/lib/postsvg/svg/element.rb +84 -0
- data/lib/postsvg/svg/elements/circle.rb +36 -0
- data/lib/postsvg/svg/elements/clip_path.rb +26 -0
- data/lib/postsvg/svg/elements/defs.rb +24 -0
- data/lib/postsvg/svg/elements/ellipse.rb +38 -0
- data/lib/postsvg/svg/elements/group.rb +37 -0
- data/lib/postsvg/svg/elements/image.rb +35 -0
- data/lib/postsvg/svg/elements/line.rb +36 -0
- data/lib/postsvg/svg/elements/path.rb +32 -0
- data/lib/postsvg/svg/elements/polygon.rb +12 -0
- data/lib/postsvg/svg/elements/polyline.rb +32 -0
- data/lib/postsvg/svg/elements/rect.rb +44 -0
- data/lib/postsvg/svg/elements/svg.rb +39 -0
- data/lib/postsvg/svg/elements/text.rb +42 -0
- data/lib/postsvg/svg/elements.rb +31 -0
- data/lib/postsvg/svg/paint.rb +34 -0
- data/lib/postsvg/svg/parser.rb +39 -0
- data/lib/postsvg/svg/path_data/command.rb +27 -0
- data/lib/postsvg/svg/path_data/parser.rb +82 -0
- data/lib/postsvg/svg/path_data.rb +17 -0
- data/lib/postsvg/svg/stroke.rb +31 -0
- data/lib/postsvg/svg/transform_list.rb +59 -0
- data/lib/postsvg/svg.rb +22 -0
- data/lib/postsvg/svg_builder.rb +249 -0
- data/lib/postsvg/translation/arc_converter.rb +86 -0
- data/lib/postsvg/translation/bounding_box.rb +59 -0
- data/lib/postsvg/translation/context.rb +34 -0
- data/lib/postsvg/translation/handler_registry.rb +38 -0
- data/lib/postsvg/translation/handlers/circle_handler.rb +28 -0
- data/lib/postsvg/translation/handlers/clip_path_handler.rb +13 -0
- data/lib/postsvg/translation/handlers/defs_handler.rb +15 -0
- data/lib/postsvg/translation/handlers/ellipse_handler.rb +31 -0
- data/lib/postsvg/translation/handlers/group_handler.rb +21 -0
- data/lib/postsvg/translation/handlers/image_handler.rb +20 -0
- data/lib/postsvg/translation/handlers/line_handler.rb +23 -0
- data/lib/postsvg/translation/handlers/open_handler.rb +18 -0
- data/lib/postsvg/translation/handlers/path_handler.rb +356 -0
- data/lib/postsvg/translation/handlers/polygon_handler.rb +33 -0
- data/lib/postsvg/translation/handlers/polyline_handler.rb +31 -0
- data/lib/postsvg/translation/handlers/rect_handler.rb +27 -0
- data/lib/postsvg/translation/handlers/shared.rb +110 -0
- data/lib/postsvg/translation/handlers/svg_handler.rb +25 -0
- data/lib/postsvg/translation/handlers/text_handler.rb +56 -0
- data/lib/postsvg/translation/handlers.rb +25 -0
- data/lib/postsvg/translation/ps_renderer.rb +105 -0
- data/lib/postsvg/translation/record_emitter.rb +35 -0
- data/lib/postsvg/translation.rb +17 -0
- data/lib/postsvg/version.rb +1 -1
- data/lib/postsvg/visitors/ps_visitor/arithmetic.rb +125 -0
- data/lib/postsvg/visitors/ps_visitor/boolean.rb +105 -0
- data/lib/postsvg/visitors/ps_visitor/color.rb +53 -0
- data/lib/postsvg/visitors/ps_visitor/common.rb +66 -0
- data/lib/postsvg/visitors/ps_visitor/container.rb +164 -0
- data/lib/postsvg/visitors/ps_visitor/control_flow.rb +110 -0
- data/lib/postsvg/visitors/ps_visitor/device.rb +20 -0
- data/lib/postsvg/visitors/ps_visitor/dictionary.rb +89 -0
- data/lib/postsvg/visitors/ps_visitor/font.rb +93 -0
- data/lib/postsvg/visitors/ps_visitor/graphics_state.rb +55 -0
- data/lib/postsvg/visitors/ps_visitor/painting.rb +90 -0
- data/lib/postsvg/visitors/ps_visitor/path.rb +112 -0
- data/lib/postsvg/visitors/ps_visitor/stack.rb +47 -0
- data/lib/postsvg/visitors/ps_visitor/transformations.rb +101 -0
- data/lib/postsvg/visitors/ps_visitor.rb +208 -0
- data/lib/postsvg/visitors.rb +9 -0
- data/lib/postsvg.rb +93 -59
- data/lychee.toml +86 -0
- metadata +216 -11
- data/postsvg.gemspec +0 -38
|
@@ -0,0 +1,538 @@
|
|
|
1
|
+
|
|
2
|
+
= Basic Usage
|
|
3
|
+
:page-nav_order: 2
|
|
4
|
+
:page-parent: Getting Started
|
|
5
|
+
|
|
6
|
+
== Purpose
|
|
7
|
+
|
|
8
|
+
This guide demonstrates the fundamental ways to use Postsvg for converting PostScript and EPS files to SVG format. You'll learn both command-line and Ruby API usage patterns that cover most common use cases.
|
|
9
|
+
|
|
10
|
+
== References
|
|
11
|
+
|
|
12
|
+
* link:../index.adoc[Documentation Home]
|
|
13
|
+
* link:../getting-started.adoc[Getting Started Overview]
|
|
14
|
+
* link:installation.adoc[Installation Guide]
|
|
15
|
+
* link:first-conversion.adoc[First Conversion Tutorial]
|
|
16
|
+
* link:../api-reference.adoc[API Reference]
|
|
17
|
+
* link:../cli-reference.adoc[CLI Reference]
|
|
18
|
+
|
|
19
|
+
== Concepts
|
|
20
|
+
|
|
21
|
+
**Command-Line Interface (CLI)**:: The `postsvg` command that allows conversion without writing Ruby code.
|
|
22
|
+
|
|
23
|
+
**Ruby API**:: Programmatic interface for integrating Postsvg into Ruby applications.
|
|
24
|
+
|
|
25
|
+
**PostScript File**:: Text file containing PostScript commands (`.ps` extension).
|
|
26
|
+
|
|
27
|
+
**EPS File**:: Encapsulated PostScript file designed for embedding graphics (`.eps` extension).
|
|
28
|
+
|
|
29
|
+
**SVG Output**:: Scalable Vector Graphics format, an XML-based vector image format.
|
|
30
|
+
|
|
31
|
+
== Command-Line Usage
|
|
32
|
+
|
|
33
|
+
=== Basic File Conversion
|
|
34
|
+
|
|
35
|
+
The simplest way to convert a file:
|
|
36
|
+
|
|
37
|
+
[source,sh]
|
|
38
|
+
----
|
|
39
|
+
postsvg convert input.ps output.svg <1>
|
|
40
|
+
----
|
|
41
|
+
<1> Convert `input.ps` to `output.svg`
|
|
42
|
+
|
|
43
|
+
Where,
|
|
44
|
+
|
|
45
|
+
`input.ps`:: Source PostScript or EPS file to convert
|
|
46
|
+
`output.svg`:: Destination SVG file to create
|
|
47
|
+
|
|
48
|
+
.Convert EPS to SVG
|
|
49
|
+
[example]
|
|
50
|
+
====
|
|
51
|
+
[source,sh]
|
|
52
|
+
----
|
|
53
|
+
# Convert diagram.eps to diagram.svg
|
|
54
|
+
postsvg convert diagram.eps diagram.svg
|
|
55
|
+
|
|
56
|
+
# Output:
|
|
57
|
+
# Successfully converted diagram.eps to diagram.svg
|
|
58
|
+
----
|
|
59
|
+
====
|
|
60
|
+
|
|
61
|
+
=== Convert to Standard Output
|
|
62
|
+
|
|
63
|
+
Output SVG to stdout instead of a file:
|
|
64
|
+
|
|
65
|
+
[source,sh]
|
|
66
|
+
----
|
|
67
|
+
postsvg convert input.ps <1>
|
|
68
|
+
----
|
|
69
|
+
<1> Writes SVG to stdout
|
|
70
|
+
|
|
71
|
+
.Redirect output to file
|
|
72
|
+
[example]
|
|
73
|
+
====
|
|
74
|
+
[source,sh]
|
|
75
|
+
----
|
|
76
|
+
# Convert and redirect to file
|
|
77
|
+
postsvg convert input.ps > output.svg
|
|
78
|
+
|
|
79
|
+
# Convert and pipe to another command
|
|
80
|
+
postsvg convert input.ps | xmllint --format - > formatted.svg
|
|
81
|
+
----
|
|
82
|
+
====
|
|
83
|
+
|
|
84
|
+
=== Batch Conversion
|
|
85
|
+
|
|
86
|
+
Convert multiple files at once:
|
|
87
|
+
|
|
88
|
+
[source,sh]
|
|
89
|
+
----
|
|
90
|
+
postsvg batch INPUT_DIR [OUTPUT_DIR] <1>
|
|
91
|
+
----
|
|
92
|
+
<1> Convert all PS/EPS files in `INPUT_DIR`
|
|
93
|
+
|
|
94
|
+
Where,
|
|
95
|
+
|
|
96
|
+
`INPUT_DIR`:: Directory containing `.ps` and `.eps` files
|
|
97
|
+
`OUTPUT_DIR`:: (Optional) Directory for SVG output. If omitted, SVG files are created in `INPUT_DIR`
|
|
98
|
+
|
|
99
|
+
.Batch convert directory
|
|
100
|
+
[example]
|
|
101
|
+
====
|
|
102
|
+
[source,sh]
|
|
103
|
+
----
|
|
104
|
+
# Convert all files in ps_files/ to svg_files/
|
|
105
|
+
postsvg batch ps_files/ svg_files/
|
|
106
|
+
|
|
107
|
+
# Output:
|
|
108
|
+
# Found 3 file(s) to convert
|
|
109
|
+
# ✓ ps_files/diagram1.ps → svg_files/diagram1.svg
|
|
110
|
+
# ✓ ps_files/diagram2.eps → svg_files/diagram2.svg
|
|
111
|
+
# ✓ ps_files/figure.ps → svg_files/figure.svg
|
|
112
|
+
----
|
|
113
|
+
====
|
|
114
|
+
|
|
115
|
+
=== File Validation
|
|
116
|
+
|
|
117
|
+
Check files before conversion:
|
|
118
|
+
|
|
119
|
+
[source,sh]
|
|
120
|
+
----
|
|
121
|
+
postsvg check FILE... <1>
|
|
122
|
+
----
|
|
123
|
+
<1> Validate one or more PostScript files
|
|
124
|
+
|
|
125
|
+
.Validate before converting
|
|
126
|
+
[example]
|
|
127
|
+
====
|
|
128
|
+
[source,sh]
|
|
129
|
+
----
|
|
130
|
+
# Validate single file
|
|
131
|
+
postsvg check document.ps
|
|
132
|
+
# ✓ document.ps - Valid PostScript file
|
|
133
|
+
|
|
134
|
+
# Validate multiple files
|
|
135
|
+
postsvg check *.ps
|
|
136
|
+
# ✓ file1.ps - Valid PostScript file
|
|
137
|
+
# ✓ file2.ps - Valid PostScript file
|
|
138
|
+
# ✗ file3.ps - Syntax error: Unmatched delimiter
|
|
139
|
+
----
|
|
140
|
+
====
|
|
141
|
+
|
|
142
|
+
== Ruby API Usage
|
|
143
|
+
|
|
144
|
+
=== Basic Conversion
|
|
145
|
+
|
|
146
|
+
Convert PostScript content to SVG:
|
|
147
|
+
|
|
148
|
+
[source,ruby]
|
|
149
|
+
----
|
|
150
|
+
require 'postsvg' <1>
|
|
151
|
+
|
|
152
|
+
ps_content = File.read('input.ps') <2>
|
|
153
|
+
svg_content = Postsvg.convert(ps_content) <3>
|
|
154
|
+
|
|
155
|
+
File.write('output.svg', svg_content) <4>
|
|
156
|
+
----
|
|
157
|
+
<1> Load the Postsvg library
|
|
158
|
+
<2> Read PostScript content
|
|
159
|
+
<3> Convert to SVG
|
|
160
|
+
<4> Save SVG to file
|
|
161
|
+
|
|
162
|
+
Where,
|
|
163
|
+
|
|
164
|
+
[`Postsvg.convert(ps_content)`](../../lib/postsvg.rb:13):: Converts PostScript string to SVG string
|
|
165
|
+
|
|
166
|
+
Returns:: SVG markup as a string
|
|
167
|
+
|
|
168
|
+
.Convert in-memory content
|
|
169
|
+
[example]
|
|
170
|
+
====
|
|
171
|
+
[source,ruby]
|
|
172
|
+
----
|
|
173
|
+
require 'postsvg'
|
|
174
|
+
|
|
175
|
+
ps_content = <<~PS
|
|
176
|
+
%!PS-Adobe-3.0 EPSF-3.0
|
|
177
|
+
%%BoundingBox: 0 0 100 100
|
|
178
|
+
newpath
|
|
179
|
+
50 50 moveto
|
|
180
|
+
90 50 lineto
|
|
181
|
+
stroke
|
|
182
|
+
PS
|
|
183
|
+
|
|
184
|
+
svg = Postsvg.convert(ps_content)
|
|
185
|
+
puts svg
|
|
186
|
+
# Outputs SVG markup
|
|
187
|
+
----
|
|
188
|
+
====
|
|
189
|
+
|
|
190
|
+
=== File-Based Conversion
|
|
191
|
+
|
|
192
|
+
Convert files directly:
|
|
193
|
+
|
|
194
|
+
[source,ruby]
|
|
195
|
+
----
|
|
196
|
+
require 'postsvg'
|
|
197
|
+
|
|
198
|
+
Postsvg.convert_file('input.ps', 'output.svg') <1>
|
|
199
|
+
----
|
|
200
|
+
<1> Read, convert, and save in one call
|
|
201
|
+
|
|
202
|
+
Where,
|
|
203
|
+
|
|
204
|
+
[`Postsvg.convert_file(input_path, output_path)`](../../lib/postsvg.rb:24):: Convert file to file
|
|
205
|
+
|
|
206
|
+
`input_path`:: Path to PostScript or EPS file
|
|
207
|
+
`output_path`:: (Optional) Path for SVG output. If omitted, returns SVG content without saving.
|
|
208
|
+
|
|
209
|
+
Returns:: SVG content string, or output path if `output_path` provided
|
|
210
|
+
|
|
211
|
+
.Get SVG content without saving
|
|
212
|
+
[example]
|
|
213
|
+
====
|
|
214
|
+
[source,ruby]
|
|
215
|
+
----
|
|
216
|
+
require 'postsvg'
|
|
217
|
+
|
|
218
|
+
# Get SVG content
|
|
219
|
+
svg_content = Postsvg.convert_file('input.ps')
|
|
220
|
+
|
|
221
|
+
# Process further
|
|
222
|
+
if svg_content.include?('<path')
|
|
223
|
+
puts "Conversion successful"
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
# Or save later
|
|
227
|
+
File.write('output.svg', svg_content)
|
|
228
|
+
----
|
|
229
|
+
====
|
|
230
|
+
|
|
231
|
+
=== Using the Converter Class
|
|
232
|
+
|
|
233
|
+
For more control over conversion:
|
|
234
|
+
|
|
235
|
+
[source,ruby]
|
|
236
|
+
----
|
|
237
|
+
require 'postsvg'
|
|
238
|
+
|
|
239
|
+
ps_content = File.read('input.ps')
|
|
240
|
+
converter = Postsvg::Converter.new(ps_content) <1>
|
|
241
|
+
svg_output = converter.convert <2>
|
|
242
|
+
|
|
243
|
+
File.write('output.svg', svg_output)
|
|
244
|
+
----
|
|
245
|
+
<1> Create converter instance
|
|
246
|
+
<2> Perform conversion
|
|
247
|
+
|
|
248
|
+
Where,
|
|
249
|
+
|
|
250
|
+
[`Postsvg::Converter.new(ps_content, strict_mode: false)`](../../lib/postsvg/converter.rb:12):: Create converter with options
|
|
251
|
+
|
|
252
|
+
`ps_content`:: PostScript content as string
|
|
253
|
+
`strict_mode`:: (Optional) Enable strict validation (default: `false`)
|
|
254
|
+
|
|
255
|
+
.Using strict mode
|
|
256
|
+
[example]
|
|
257
|
+
====
|
|
258
|
+
[source,ruby]
|
|
259
|
+
----
|
|
260
|
+
require 'postsvg'
|
|
261
|
+
|
|
262
|
+
ps_content = File.read('input.ps')
|
|
263
|
+
|
|
264
|
+
# Enable strict mode - fail on unknown operators
|
|
265
|
+
converter = Postsvg::Converter.new(
|
|
266
|
+
ps_content,
|
|
267
|
+
strict_mode: true
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
begin
|
|
271
|
+
svg = converter.convert
|
|
272
|
+
puts "Conversion successful"
|
|
273
|
+
rescue Postsvg::Error => e
|
|
274
|
+
puts "Error: #{e.message}"
|
|
275
|
+
end
|
|
276
|
+
----
|
|
277
|
+
====
|
|
278
|
+
|
|
279
|
+
== Common Usage Patterns
|
|
280
|
+
|
|
281
|
+
=== Workflow 1: Validate Then Convert
|
|
282
|
+
|
|
283
|
+
[source,sh]
|
|
284
|
+
----
|
|
285
|
+
# 1. Validate file
|
|
286
|
+
postsvg check document.ps
|
|
287
|
+
|
|
288
|
+
# 2. If valid, convert
|
|
289
|
+
if [ $? -eq 0 ]; then
|
|
290
|
+
postsvg convert document.ps document.svg
|
|
291
|
+
fi
|
|
292
|
+
----
|
|
293
|
+
|
|
294
|
+
=== Workflow 2: Batch Process Directory
|
|
295
|
+
|
|
296
|
+
[source,ruby]
|
|
297
|
+
----
|
|
298
|
+
require 'postsvg'
|
|
299
|
+
|
|
300
|
+
Dir.glob('*.ps').each do |ps_file|
|
|
301
|
+
svg_file = ps_file.sub('.ps', '.svg')
|
|
302
|
+
|
|
303
|
+
begin
|
|
304
|
+
Postsvg.convert_file(ps_file, svg_file)
|
|
305
|
+
puts "✓ Converted #{ps_file}"
|
|
306
|
+
rescue Postsvg::Error => e
|
|
307
|
+
puts "✗ Failed #{ps_file}: #{e.message}"
|
|
308
|
+
end
|
|
309
|
+
end
|
|
310
|
+
----
|
|
311
|
+
|
|
312
|
+
=== Workflow 3: Convert with Error Handling
|
|
313
|
+
|
|
314
|
+
[source,ruby]
|
|
315
|
+
----
|
|
316
|
+
require 'postsvg'
|
|
317
|
+
|
|
318
|
+
def safe_convert(input_file, output_file)
|
|
319
|
+
ps_content = File.read(input_file)
|
|
320
|
+
|
|
321
|
+
# Try strict mode first
|
|
322
|
+
converter = Postsvg::Converter.new(ps_content, strict_mode: true)
|
|
323
|
+
svg = converter.convert
|
|
324
|
+
|
|
325
|
+
File.write(output_file, svg)
|
|
326
|
+
puts "Success: #{output_file}"
|
|
327
|
+
rescue Postsvg::Error => e
|
|
328
|
+
puts "Error: #{e.message}"
|
|
329
|
+
puts "Trying lenient mode..."
|
|
330
|
+
|
|
331
|
+
# Fall back to lenient mode
|
|
332
|
+
converter = Postsvg::Converter.new(ps_content, strict_mode: false)
|
|
333
|
+
svg = converter.convert
|
|
334
|
+
File.write(output_file, svg)
|
|
335
|
+
operators ignored)"
|
|
336
|
+
rescue StandardError => e
|
|
337
|
+
puts "Failed: #{e.message}"
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
safe_convert('input.ps', 'output.svg')
|
|
341
|
+
----
|
|
342
|
+
====
|
|
343
|
+
|
|
344
|
+
=== Workflow 4: Process Web Uploads
|
|
345
|
+
|
|
346
|
+
[source,ruby]
|
|
347
|
+
----
|
|
348
|
+
require 'postsvg'
|
|
349
|
+
|
|
350
|
+
def convert_uploaded_file(upload)
|
|
351
|
+
# Read uploaded content
|
|
352
|
+
ps_content = upload.read
|
|
353
|
+
|
|
354
|
+
# Convert to SVG
|
|
355
|
+
svg = Postsvg.convert(ps_content)
|
|
356
|
+
|
|
357
|
+
# Create temporary SVG file
|
|
358
|
+
svg_file = Tempfile.new(['converted', '.svg'])
|
|
359
|
+
svg_file.write(svg)
|
|
360
|
+
svg_file.rewind
|
|
361
|
+
|
|
362
|
+
svg_file
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
# In Rails controller
|
|
366
|
+
def convert
|
|
367
|
+
uploaded = params[:file]
|
|
368
|
+
svg_file = convert_uploaded_file(uploaded)
|
|
369
|
+
send_file svg_file.path,
|
|
370
|
+
filename: 'converted.svg',
|
|
371
|
+
type: 'image/svg+xml'
|
|
372
|
+
end
|
|
373
|
+
----
|
|
374
|
+
|
|
375
|
+
== Output Examples
|
|
376
|
+
|
|
377
|
+
=== Simple Rectangle
|
|
378
|
+
|
|
379
|
+
**Input PostScript:**
|
|
380
|
+
[source,postscript]
|
|
381
|
+
----
|
|
382
|
+
%!PS-Adobe-3.0 EPSF-3.0
|
|
383
|
+
%%BoundingBox: 0 0 100 100
|
|
384
|
+
newpath
|
|
385
|
+
10 10 moveto
|
|
386
|
+
90 10 lineto
|
|
387
|
+
90 90 lineto
|
|
388
|
+
10 90 lineto
|
|
389
|
+
closepath
|
|
390
|
+
0.5 setgray
|
|
391
|
+
fill
|
|
392
|
+
----
|
|
393
|
+
|
|
394
|
+
**Output SVG:**
|
|
395
|
+
[source,xml]
|
|
396
|
+
----
|
|
397
|
+
<?xml version="1.0" standalone="no"?>
|
|
398
|
+
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
|
399
|
+
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
|
400
|
+
<svg xmlns="http://www.w3.org/2000/svg"
|
|
401
|
+
width="100" height="100"
|
|
402
|
+
viewBox="0 0 100 100">
|
|
403
|
+
<path d="M 10 90 L 90 90 L 90 10 L 10 10 Z"
|
|
404
|
+
fill="#808080"/>
|
|
405
|
+
</svg>
|
|
406
|
+
----
|
|
407
|
+
|
|
408
|
+
=== Stroked Path
|
|
409
|
+
|
|
410
|
+
**Input PostScript:**
|
|
411
|
+
[source,postscript]
|
|
412
|
+
----
|
|
413
|
+
%!PS-Adobe-3.0
|
|
414
|
+
%%BoundingBox: 0 0 200 200
|
|
415
|
+
newpath
|
|
416
|
+
50 50 moveto
|
|
417
|
+
150 150 lineto
|
|
418
|
+
2 setlinewidth
|
|
419
|
+
1 0 0 setrgbcolor
|
|
420
|
+
stroke
|
|
421
|
+
----
|
|
422
|
+
|
|
423
|
+
**Output SVG:**
|
|
424
|
+
[source,xml]
|
|
425
|
+
----
|
|
426
|
+
<svg xmlns="http://www.w3.org/2000/svg"
|
|
427
|
+
width="200" height="200"
|
|
428
|
+
viewBox="0 0 200 200">
|
|
429
|
+
<path d="M 50 150 L 150 50"
|
|
430
|
+
stroke="#ff0000"
|
|
431
|
+
stroke-width="2"
|
|
432
|
+
fill="none"/>
|
|
433
|
+
</svg>
|
|
434
|
+
----
|
|
435
|
+
|
|
436
|
+
== Error Handling
|
|
437
|
+
|
|
438
|
+
=== Handling Conversion Errors
|
|
439
|
+
|
|
440
|
+
[source,ruby]
|
|
441
|
+
----
|
|
442
|
+
require 'postsvg'
|
|
443
|
+
|
|
444
|
+
begin
|
|
445
|
+
svg = Postsvg.convert(ps_content)
|
|
446
|
+
File.write('output.svg', svg)
|
|
447
|
+
rescue Postsvg::ParseError => e
|
|
448
|
+
puts "Parse error: #{e.message}"
|
|
449
|
+
rescue Postsvg::ConversionError => e
|
|
450
|
+
puts "Conversion error: #{e.message}"
|
|
451
|
+
rescue Postsvg::Error => e
|
|
452
|
+
puts "Error: #{e.message}"
|
|
453
|
+
rescue StandardError => e
|
|
454
|
+
puts "Unexpected error: #{e.message}"
|
|
455
|
+
end
|
|
456
|
+
----
|
|
457
|
+
|
|
458
|
+
=== Validating Before Conversion
|
|
459
|
+
|
|
460
|
+
[source,ruby]
|
|
461
|
+
----
|
|
462
|
+
require 'postsvg'
|
|
463
|
+
|
|
464
|
+
def validate_and_convert(ps_file, svg_file)
|
|
465
|
+
# First validate
|
|
466
|
+
result = system("postsvg check #{ps_file}")
|
|
467
|
+
|
|
468
|
+
unless result
|
|
469
|
+
puts "Validation failed"
|
|
470
|
+
return false
|
|
471
|
+
end
|
|
472
|
+
|
|
473
|
+
# Then convert
|
|
474
|
+
Postsvg.convert_file(ps_file, svg_file)
|
|
475
|
+
true
|
|
476
|
+
rescue => e
|
|
477
|
+
puts "Error: #{e.message}"
|
|
478
|
+
false
|
|
479
|
+
end
|
|
480
|
+
----
|
|
481
|
+
|
|
482
|
+
== Performance Tips
|
|
483
|
+
|
|
484
|
+
=== Batch Processing Efficiently
|
|
485
|
+
|
|
486
|
+
[source,ruby]
|
|
487
|
+
----
|
|
488
|
+
require 'postsvg'
|
|
489
|
+
|
|
490
|
+
files = Dir.glob('*.ps')
|
|
491
|
+
|
|
492
|
+
# Process in batches to manage memory
|
|
493
|
+
files.each_slice(10) do |batch|
|
|
494
|
+
batch.each do |file|
|
|
495
|
+
Postsvg.convert_file(file, file.sub('.ps', '.svg'))
|
|
496
|
+
end
|
|
497
|
+
|
|
498
|
+
# Force garbage collection between batches
|
|
499
|
+
GC.start
|
|
500
|
+
end
|
|
501
|
+
----
|
|
502
|
+
|
|
503
|
+
=== Reusing Converter Instance
|
|
504
|
+
|
|
505
|
+
[source,ruby]
|
|
506
|
+
----
|
|
507
|
+
require 'postsvg'
|
|
508
|
+
|
|
509
|
+
# Don't do this - creates new instance each time
|
|
510
|
+
files.each do |file|
|
|
511
|
+
Postsvg.convert_file(file, file.sub('.ps', '.svg'))
|
|
512
|
+
end
|
|
513
|
+
|
|
514
|
+
# Better - though note Converter is not thread-safe
|
|
515
|
+
ps_files.map do |ps_content|
|
|
516
|
+
converter = Postsvg::Converter.new(ps_content)
|
|
517
|
+
converter.convert
|
|
518
|
+
end
|
|
519
|
+
----
|
|
520
|
+
|
|
521
|
+
== Next Steps
|
|
522
|
+
|
|
523
|
+
After mastering basic usage:
|
|
524
|
+
|
|
525
|
+
* Follow the link:first-conversion.adoc[First Conversion Tutorial] for a detailed walkthrough
|
|
526
|
+
* Learn link:common-workflows.adoc[Common Workflows] for real-world scenarios
|
|
527
|
+
* Explore link:../cli-reference.adoc[CLI Reference] for all command options
|
|
528
|
+
* Read link:../api-reference.adoc[API Reference] for advanced API usage
|
|
529
|
+
* Check link:../troubleshooting.adoc[Troubleshooting] if you encounter issues
|
|
530
|
+
|
|
531
|
+
== Bibliography
|
|
532
|
+
|
|
533
|
+
* link:installation.adoc[Installation Guide]
|
|
534
|
+
* link:first-conversion.adoc[First Conversion Tutorial]
|
|
535
|
+
* link:../api-reference.adoc[API Reference]
|
|
536
|
+
* link:../cli-reference.adoc[CLI Reference]
|
|
537
|
+
* link:https://rubygems.org/gems/postsvg[Postsvg on RubyGems]
|
|
538
|
+
puts "Partial success: #{output_file} (some
|