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.
Files changed (201) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +105 -0
  3. data/CLAUDE.md +173 -0
  4. data/Gemfile +2 -3
  5. data/README.adoc +456 -179
  6. data/Rakefile +100 -0
  7. data/TODO.roadmap/00-architecture.md +139 -0
  8. data/TODO.roadmap/01-autoload-migration.md +39 -0
  9. data/TODO.roadmap/02-isolate-dormant-code.md +51 -0
  10. data/TODO.roadmap/03-domain-model.md +66 -0
  11. data/TODO.roadmap/04-lexer.md +40 -0
  12. data/TODO.roadmap/05-parser.md +43 -0
  13. data/TODO.roadmap/06-graphics-state.md +45 -0
  14. data/TODO.roadmap/07-matrix-and-color.md +37 -0
  15. data/TODO.roadmap/08-svg-builder.md +51 -0
  16. data/TODO.roadmap/09-renderer.md +52 -0
  17. data/TODO.roadmap/10-visitor.md +58 -0
  18. data/TODO.roadmap/11-operator-coverage.md +103 -0
  19. data/TODO.roadmap/12-svg-domain.md +62 -0
  20. data/TODO.roadmap/13-translation-handlers.md +69 -0
  21. data/TODO.roadmap/14-ps-serializer.md +49 -0
  22. data/TODO.roadmap/15-cli-and-public-api.md +47 -0
  23. data/TODO.roadmap/16-specs.md +84 -0
  24. data/TODO.roadmap/17-docs-sync.md +47 -0
  25. data/TODO.roadmap/18-performance-and-determinism.md +47 -0
  26. data/TODO.roadmap/19-error-model.md +45 -0
  27. data/TODO.roadmap/20-font-and-text.md +46 -0
  28. data/TODO.roadmap/21-images.md +45 -0
  29. data/TODO.roadmap/22-forms-and-resources.md +25 -0
  30. data/TODO.roadmap/23-level2-level3.md +52 -0
  31. data/TODO.roadmap/24-ci-and-release.md +42 -0
  32. data/TODO.roadmap/README.md +77 -0
  33. data/docs/.gitignore +29 -0
  34. data/docs/CHANGELOG.md +114 -0
  35. data/docs/COMPLETE_DOCUMENTATION_STATUS.md +376 -0
  36. data/docs/DEPLOYMENT.md +456 -0
  37. data/docs/DEPLOYMENT_INSTRUCTIONS.md +229 -0
  38. data/docs/DOCUMENTATION_PLAN.md +425 -0
  39. data/docs/FINAL_SUMMARY.md +657 -0
  40. data/docs/Gemfile +15 -0
  41. data/docs/README.md +327 -0
  42. data/docs/_config.yml +99 -0
  43. data/docs/advanced-topics.adoc +370 -0
  44. data/docs/api-reference/colors.adoc +705 -0
  45. data/docs/api-reference/converter.adoc +699 -0
  46. data/docs/api-reference/execution-context.adoc +1210 -0
  47. data/docs/api-reference/graphics-state.adoc +1070 -0
  48. data/docs/api-reference/interpreter.adoc +810 -0
  49. data/docs/api-reference/matrix.adoc +1179 -0
  50. data/docs/api-reference/path-builder.adoc +1284 -0
  51. data/docs/api-reference/postsvg-module.adoc +388 -0
  52. data/docs/api-reference/svg-generator.adoc +891 -0
  53. data/docs/api-reference/tokenizer.adoc +925 -0
  54. data/docs/api-reference.adoc +221 -0
  55. data/docs/architecture/command-registry.adoc +1191 -0
  56. data/docs/architecture/conversion-pipeline.adoc +746 -0
  57. data/docs/architecture/design-decisions.adoc +999 -0
  58. data/docs/architecture/generator-stage.adoc +1115 -0
  59. data/docs/architecture/graphics-state-model.adoc +1089 -0
  60. data/docs/architecture/interpreter-stage.adoc +1125 -0
  61. data/docs/architecture/parser-stage.adoc +1051 -0
  62. data/docs/architecture.adoc +354 -0
  63. data/docs/cli-reference/batch-command.adoc +616 -0
  64. data/docs/cli-reference/check-command.adoc +677 -0
  65. data/docs/cli-reference/cli-options.adoc +802 -0
  66. data/docs/cli-reference/convert-command.adoc +462 -0
  67. data/docs/cli-reference/version-command.adoc +296 -0
  68. data/docs/cli-reference.adoc +317 -0
  69. data/docs/concepts/conversion-pipeline.adoc +903 -0
  70. data/docs/concepts/coordinate-systems.adoc +836 -0
  71. data/docs/concepts/graphics-state.adoc +861 -0
  72. data/docs/concepts/path-operations.adoc +1076 -0
  73. data/docs/concepts/postscript-language.adoc +859 -0
  74. data/docs/concepts/svg-generation.adoc +937 -0
  75. data/docs/concepts.adoc +198 -0
  76. data/docs/contributing.adoc +443 -0
  77. data/docs/development.adoc +420 -0
  78. data/docs/faq.adoc +493 -0
  79. data/docs/getting-started/basic-usage.adoc +538 -0
  80. data/docs/getting-started/common-workflows.adoc +577 -0
  81. data/docs/getting-started/first-conversion.adoc +492 -0
  82. data/docs/getting-started/installation.adoc +534 -0
  83. data/docs/getting-started.adoc +94 -0
  84. data/docs/index.adoc +248 -0
  85. data/docs/optimization.adoc +196 -0
  86. data/docs/ps2svg_compatibility.adoc +149 -0
  87. data/docs/quick-reference.adoc +453 -0
  88. data/docs/sitemap.adoc +337 -0
  89. data/docs/troubleshooting.adoc +486 -0
  90. data/docs/validation.adoc +772 -0
  91. data/exe/postsvg +1 -0
  92. data/lib/postsvg/cli.rb +104 -57
  93. data/lib/postsvg/color.rb +132 -0
  94. data/lib/postsvg/errors.rb +68 -3
  95. data/lib/postsvg/format_number.rb +22 -0
  96. data/lib/postsvg/graphics_context.rb +80 -0
  97. data/lib/postsvg/graphics_stack.rb +43 -0
  98. data/lib/postsvg/model/literals/array.rb +41 -0
  99. data/lib/postsvg/model/literals/dictionary.rb +34 -0
  100. data/lib/postsvg/model/literals/hex.rb +37 -0
  101. data/lib/postsvg/model/literals/name.rb +40 -0
  102. data/lib/postsvg/model/literals/number.rb +36 -0
  103. data/lib/postsvg/model/literals/procedure.rb +41 -0
  104. data/lib/postsvg/model/literals/string.rb +30 -0
  105. data/lib/postsvg/model/literals.rb +19 -0
  106. data/lib/postsvg/model/operator.rb +58 -0
  107. data/lib/postsvg/model/operators/arithmetic.rb +264 -0
  108. data/lib/postsvg/model/operators/boolean.rb +182 -0
  109. data/lib/postsvg/model/operators/color.rb +74 -0
  110. data/lib/postsvg/model/operators/container.rb +186 -0
  111. data/lib/postsvg/model/operators/control_flow.rb +119 -0
  112. data/lib/postsvg/model/operators/device.rb +21 -0
  113. data/lib/postsvg/model/operators/dictionary.rb +118 -0
  114. data/lib/postsvg/model/operators/font.rb +121 -0
  115. data/lib/postsvg/model/operators/graphics_state.rb +84 -0
  116. data/lib/postsvg/model/operators/painting.rb +29 -0
  117. data/lib/postsvg/model/operators/path.rb +169 -0
  118. data/lib/postsvg/model/operators/stack.rb +72 -0
  119. data/lib/postsvg/model/operators/transformations.rb +103 -0
  120. data/lib/postsvg/model/operators.rb +89 -0
  121. data/lib/postsvg/model/program.rb +68 -0
  122. data/lib/postsvg/model/token.rb +43 -0
  123. data/lib/postsvg/model.rb +17 -0
  124. data/lib/postsvg/options.rb +29 -0
  125. data/lib/postsvg/renderer.rb +85 -0
  126. data/lib/postsvg/serializer.rb +325 -0
  127. data/lib/postsvg/source/ast_builder.rb +308 -0
  128. data/lib/postsvg/source/lexer.rb +322 -0
  129. data/lib/postsvg/source/operand_stack.rb +55 -0
  130. data/lib/postsvg/source.rb +21 -0
  131. data/lib/postsvg/svg/attribute_parser.rb +45 -0
  132. data/lib/postsvg/svg/clip_path_registry.rb +44 -0
  133. data/lib/postsvg/svg/document.rb +22 -0
  134. data/lib/postsvg/svg/element.rb +84 -0
  135. data/lib/postsvg/svg/elements/circle.rb +36 -0
  136. data/lib/postsvg/svg/elements/clip_path.rb +26 -0
  137. data/lib/postsvg/svg/elements/defs.rb +24 -0
  138. data/lib/postsvg/svg/elements/ellipse.rb +38 -0
  139. data/lib/postsvg/svg/elements/group.rb +37 -0
  140. data/lib/postsvg/svg/elements/image.rb +35 -0
  141. data/lib/postsvg/svg/elements/line.rb +36 -0
  142. data/lib/postsvg/svg/elements/path.rb +32 -0
  143. data/lib/postsvg/svg/elements/polygon.rb +12 -0
  144. data/lib/postsvg/svg/elements/polyline.rb +32 -0
  145. data/lib/postsvg/svg/elements/rect.rb +44 -0
  146. data/lib/postsvg/svg/elements/svg.rb +39 -0
  147. data/lib/postsvg/svg/elements/text.rb +42 -0
  148. data/lib/postsvg/svg/elements.rb +31 -0
  149. data/lib/postsvg/svg/paint.rb +34 -0
  150. data/lib/postsvg/svg/parser.rb +39 -0
  151. data/lib/postsvg/svg/path_data/command.rb +27 -0
  152. data/lib/postsvg/svg/path_data/parser.rb +82 -0
  153. data/lib/postsvg/svg/path_data.rb +17 -0
  154. data/lib/postsvg/svg/stroke.rb +31 -0
  155. data/lib/postsvg/svg/transform_list.rb +59 -0
  156. data/lib/postsvg/svg.rb +22 -0
  157. data/lib/postsvg/svg_builder.rb +249 -0
  158. data/lib/postsvg/translation/arc_converter.rb +86 -0
  159. data/lib/postsvg/translation/bounding_box.rb +59 -0
  160. data/lib/postsvg/translation/context.rb +34 -0
  161. data/lib/postsvg/translation/handler_registry.rb +38 -0
  162. data/lib/postsvg/translation/handlers/circle_handler.rb +28 -0
  163. data/lib/postsvg/translation/handlers/clip_path_handler.rb +13 -0
  164. data/lib/postsvg/translation/handlers/defs_handler.rb +15 -0
  165. data/lib/postsvg/translation/handlers/ellipse_handler.rb +31 -0
  166. data/lib/postsvg/translation/handlers/group_handler.rb +21 -0
  167. data/lib/postsvg/translation/handlers/image_handler.rb +20 -0
  168. data/lib/postsvg/translation/handlers/line_handler.rb +23 -0
  169. data/lib/postsvg/translation/handlers/open_handler.rb +18 -0
  170. data/lib/postsvg/translation/handlers/path_handler.rb +356 -0
  171. data/lib/postsvg/translation/handlers/polygon_handler.rb +33 -0
  172. data/lib/postsvg/translation/handlers/polyline_handler.rb +31 -0
  173. data/lib/postsvg/translation/handlers/rect_handler.rb +27 -0
  174. data/lib/postsvg/translation/handlers/shared.rb +110 -0
  175. data/lib/postsvg/translation/handlers/svg_handler.rb +25 -0
  176. data/lib/postsvg/translation/handlers/text_handler.rb +56 -0
  177. data/lib/postsvg/translation/handlers.rb +25 -0
  178. data/lib/postsvg/translation/ps_renderer.rb +105 -0
  179. data/lib/postsvg/translation/record_emitter.rb +35 -0
  180. data/lib/postsvg/translation.rb +17 -0
  181. data/lib/postsvg/version.rb +1 -1
  182. data/lib/postsvg/visitors/ps_visitor/arithmetic.rb +125 -0
  183. data/lib/postsvg/visitors/ps_visitor/boolean.rb +105 -0
  184. data/lib/postsvg/visitors/ps_visitor/color.rb +53 -0
  185. data/lib/postsvg/visitors/ps_visitor/common.rb +66 -0
  186. data/lib/postsvg/visitors/ps_visitor/container.rb +164 -0
  187. data/lib/postsvg/visitors/ps_visitor/control_flow.rb +110 -0
  188. data/lib/postsvg/visitors/ps_visitor/device.rb +20 -0
  189. data/lib/postsvg/visitors/ps_visitor/dictionary.rb +89 -0
  190. data/lib/postsvg/visitors/ps_visitor/font.rb +93 -0
  191. data/lib/postsvg/visitors/ps_visitor/graphics_state.rb +55 -0
  192. data/lib/postsvg/visitors/ps_visitor/painting.rb +90 -0
  193. data/lib/postsvg/visitors/ps_visitor/path.rb +112 -0
  194. data/lib/postsvg/visitors/ps_visitor/stack.rb +47 -0
  195. data/lib/postsvg/visitors/ps_visitor/transformations.rb +101 -0
  196. data/lib/postsvg/visitors/ps_visitor.rb +208 -0
  197. data/lib/postsvg/visitors.rb +9 -0
  198. data/lib/postsvg.rb +93 -59
  199. data/lychee.toml +86 -0
  200. metadata +216 -11
  201. data/postsvg.gemspec +0 -38
@@ -0,0 +1,388 @@
1
+ = Postsvg Module
2
+ :page-nav_order: 1
3
+ :page-parent: API Reference
4
+
5
+ == Purpose
6
+
7
+ This document details the main [`Postsvg`](../../lib/postsvg.rb:10) module which provides the primary Ruby API for converting PostScript and EPS files to SVG format. The module offers simple, high-level methods for quick conversions.
8
+
9
+ == References
10
+
11
+ * link:../index.adoc[Documentation Home]
12
+ * link:../api-reference.adoc[API Reference Overview]
13
+ * link:converter.adoc[Converter Class]
14
+ * link:../getting-started/basic-usage.adoc[Basic Usage Guide]
15
+
16
+ == Concepts
17
+
18
+ **Module Method**:: A method defined at the module level that can be called directly without instantiating a class.
19
+
20
+ **Convenience Method**:: A simplified interface that handles common use cases with minimal code.
21
+
22
+ **BoundingBox**:: The rectangular area containing all graphics, defined by `%%BoundingBox` comment in PostScript files.
23
+
24
+ == Module Overview
25
+
26
+ The [`Postsvg`](../../lib/postsvg.rb:10) module provides two main convenience methods:
27
+
28
+ * [`convert(ps_content)`](../../lib/postsvg.rb:13) - Convert PostScript string to SVG string
29
+ * [`convert_file(input_path, output_path)`](../../lib/postsvg.rb:24) - Convert PostScript file to SVG file
30
+
31
+ These methods are designed for simplicity and cover most common use cases.
32
+
33
+ == Methods
34
+
35
+ === convert
36
+
37
+ Convert PostScript content (as a string) to SVG format.
38
+
39
+ **Syntax:**
40
+
41
+ [source,ruby]
42
+ ----
43
+ svg_string = Postsvg.convert(ps_content) <1>
44
+ ----
45
+ <1> Returns SVG markup as a string
46
+
47
+ **Where:**
48
+
49
+ `ps_content`:: String containing PostScript or EPS content. Should include proper PostScript header and ideally a `%%BoundingBox` comment.
50
+
51
+ **Returns:**
52
+ String containing SVG markup (XML format)
53
+
54
+ **Source:**
55
+ [`lib/postsvg.rb:13-21`](../../lib/postsvg.rb:13)
56
+
57
+ .Convert PostScript string to SVG
58
+ [example]
59
+ ====
60
+ [source,ruby]
61
+ ----
62
+ require 'postsvg'
63
+
64
+ ps_content = <<~PS
65
+ %!PS-Adobe-3.0 EPSF-3.0
66
+ %%BoundingBox: 0 0 100 100
67
+ newpath
68
+ 50 50 moveto
69
+ 90 50 lineto
70
+ stroke
71
+ PS
72
+
73
+ svg = Postsvg.convert(ps_content)
74
+ puts svg
75
+ # Output: <?xml version="1.0"...><svg...><path.../></svg>
76
+ ----
77
+
78
+ This converts the PostScript content directly to SVG without saving to disk.
79
+ ====
80
+
81
+ .Handle conversion errors
82
+ [example]
83
+ ====
84
+ [source,ruby]
85
+ ----
86
+ require 'postsvg'
87
+
88
+ ps_content = File.read('input.ps')
89
+
90
+ begin
91
+ svg = Postsvg.convert(ps_content)
92
+ File.write('output.svg', svg)
93
+ puts "Conversion successful"
94
+ rescue Postsvg::Error => e
95
+ puts "Conversion failed: #{e.message}"
96
+ end
97
+ ----
98
+ ====
99
+
100
+ **Implementation Details:**
101
+
102
+ The `convert` method:
103
+ 1. Extracts BoundingBox from PostScript content
104
+ 2. Tokenizes the PostScript using [`Tokenizer`](../../lib/postsvg/tokenizer.rb:8)
105
+ 3. Creates an [`Interpreter`](../../lib/postsvg/interpreter.rb:9) instance
106
+ 4. Interprets tokens with the BoundingBox
107
+ 5. Returns generated SVG from the result
108
+
109
+ === convert_file
110
+
111
+ Convert a PostScript file to an SVG file.
112
+
113
+ **Syntax:**
114
+
115
+ [source,ruby]
116
+ ----
117
+ Postsvg.convert_file(input_path, output_path) <1>
118
+ svg_content = Postsvg.convert_file(input_path) <2>
119
+ ----
120
+ <1> Read input file, convert, and save to output file
121
+ <2> Read input file, convert, and return SVG content (don't save)
122
+
123
+ **Where:**
124
+
125
+ `input_path`:: Path to input PostScript (`.ps`) or EPS (`.eps`) file
126
+
127
+ `output_path`:: (Optional) Path where SVG file should be saved. If omitted, SVG content is returned without saving.
128
+
129
+ **Returns:**
130
+ * When `output_path` provided: SVG content string
131
+ * When `output_path` omitted: SVG content string
132
+
133
+ **Source:**
134
+ [`lib/postsvg.rb:24-31`](../../lib/postsvg.rb:24)
135
+
136
+ .Convert file and save
137
+ [example]
138
+ ====
139
+ [source,ruby]
140
+ ----
141
+ require 'postsvg'
142
+
143
+ # Convert and save in one step
144
+ Postsvg.convert_file('diagram.eps', 'diagram.svg')
145
+ puts "Conversion complete"
146
+ ----
147
+ ====
148
+
149
+ .Convert file without saving
150
+ [example]
151
+ ====
152
+ [source,ruby]
153
+ ----
154
+ require 'postsvg'
155
+
156
+ # Get SVG content for further processing
157
+ svg_content = Postsvg.convert_file('input.ps')
158
+
159
+ # Modify or analyze content
160
+ if svg_content.include?('<path')
161
+ puts "Contains path elements"
162
+ end
163
+
164
+ # Save later or send to user
165
+ File.write('output.svg', svg_content)
166
+ ----
167
+ ====
168
+
169
+ .Batch file conversion
170
+ [example]
171
+ ====
172
+ [source,ruby]
173
+ ----
174
+ require 'postsvg'
175
+
176
+ Dir.glob('*.ps').each do |ps_file|
177
+ svg_file = ps_file.sub('.ps', '.svg')
178
+
179
+ begin
180
+ Postsvg.convert_file(ps_file, svg_file)
181
+ puts "✓ Converted #{ps_file}"
182
+ rescue Postsvg::Error => e
183
+ puts "✗ Failed #{ps_file}: #{e.message}"
184
+ end
185
+ end
186
+ ----
187
+ ====
188
+
189
+ **Implementation Details:**
190
+
191
+ The `convert_file` method:
192
+ 1. Reads the input file content
193
+ 2. Calls `convert(ps_content)` to perform conversion
194
+ 3. Writes SVG to output file if `output_path` provided
195
+ 4. Returns SVG content
196
+
197
+ == Error Handling
198
+
199
+ Both methods can raise [`Postsvg::Error`](../../lib/postsvg/errors.rb:1) or its subclasses:
200
+
201
+ **Error Types:**
202
+
203
+ * `Postsvg::ParseError` - PostScript syntax errors
204
+ * `Postsvg::ConversionError` - Conversion failures
205
+ * `Postsvg::ValidationError` - Validation failures
206
+
207
+ .Comprehensive error handling
208
+ [example]
209
+ ====
210
+ [source,ruby]
211
+ ----
212
+ require 'postsvg'
213
+
214
+ def safe_convert(input_file, output_file)
215
+ ps_content = File.read(input_file)
216
+ svg = Postsvg.convert(ps_content)
217
+ File.write(output_file, svg)
218
+
219
+ { success: true, file: output_file }
220
+ rescue Postsvg::ParseError => e
221
+ { success: false, error: "Parse error: #{e.message}" }
222
+ rescue Postsvg::ConversionError => e
223
+ { success: false, error: "Conversion error: #{e.message}" }
224
+ rescue Postsvg::Error => e
225
+ { success: false, error: "Postsvg error: #{e.message}" }
226
+ rescue StandardError => e
227
+ { success: false, error: "Unexpected error: #{e.message}" }
228
+ end
229
+
230
+ result = safe_convert('input.ps', 'output.svg')
231
+ puts result[:success] ? "Success!" : result[:error]
232
+ ----
233
+ ====
234
+
235
+ == BoundingBox Handling
236
+
237
+ Both methods extract the BoundingBox from PostScript content:
238
+
239
+ **BoundingBox Format:**
240
+
241
+ [source,postscript]
242
+ ----
243
+ %%BoundingBox: llx lly urx ury
244
+ ----
245
+
246
+ **Where:**
247
+
248
+ * `llx` - Lower-left X coordinate
249
+ * `lly` - Lower-left Y coordinate
250
+ * `urx` - Upper-right X coordinate
251
+ * `ury` - Upper-right Y coordinate
252
+
253
+ **Default Behavior:**
254
+
255
+ If no BoundingBox is found, Postsvg uses default dimensions:
256
+
257
+ [source,ruby]
258
+ ----
259
+ {
260
+ llx: 0,
261
+ lly: 0,
262
+ urx: 1920,
263
+ ury: 1080,
264
+ width: 1920,
265
+ height: 1080
266
+ }
267
+ ----
268
+
269
+ .Specify custom BoundingBox
270
+ [example]
271
+ ====
272
+ If your PostScript file lacks a BoundingBox, add one:
273
+
274
+ [source,postscript]
275
+ ----
276
+ %!PS-Adobe-3.0 EPSF-3.0
277
+ %%BoundingBox: 0 0 612 792
278
+ % Rest of PostScript content...
279
+ ----
280
+
281
+ Or use the link:converter.adoc[Converter class] for more control over BoundingBox handling.
282
+ ====
283
+
284
+ == Performance Considerations
285
+
286
+ **Memory Usage:**
287
+
288
+ Both methods load entire file into memory:
289
+
290
+ [source,ruby]
291
+ ----
292
+ # Good for small files
293
+ svg = Postsvg.convert(small_ps_content)
294
+
295
+ # May use significant memory for large files
296
+ svg = Postsvg.convert(large_ps_content) # 10MB+ content
297
+ ----
298
+
299
+ **Optimization Tips:**
300
+
301
+ 1. **Batch Processing:**
302
+ Process files sequentially with garbage collection:
303
+ [source,ruby]
304
+ ----
305
+ files.each do |file|
306
+ Postsvg.convert_file(file, file.sub('.ps', '.svg'))
307
+ GC.start # Force garbage collection
308
+ end
309
+ ----
310
+
311
+ 2. **Stream Processing:**
312
+ For very large files, consider processing in chunks (if applicable).
313
+
314
+ 3. **Caching:**
315
+ Cache conversion results if converting same content multiple times.
316
+
317
+ == Thread Safety
318
+
319
+ **Not Thread-Safe:**
320
+
321
+ The module methods are not thread-safe. Create separate instances for concurrent operations:
322
+
323
+ .Incorrect - sharing conversion
324
+ [source,ruby]
325
+ ----
326
+ # Bad: parallel conversion with shared module methods
327
+ threads = files.map do |file|
328
+ Thread.new { Postsvg.convert_file(file) } # May conflict
329
+ end
330
+ ----
331
+
332
+ .Correct - isolated conversions
333
+ [source,ruby]
334
+ ----
335
+ # Good: each thread has isolated conversion
336
+ threads = files.map do |file|
337
+ Thread.new do
338
+ # Each thread reads and converts independently
339
+ ps_content = File.read(file)
340
+ Postsvg.convert(ps_content)
341
+ end
342
+ end
343
+ ----
344
+
345
+ == Comparison with Converter Class
346
+
347
+ **Use Module Methods When:**
348
+ * ✅ Quick, simple conversions
349
+ * ✅ Default settings are sufficient
350
+ * ✅ No need for strict mode
351
+ * ✅ Scripting or one-off conversions
352
+
353
+ **Use link:converter.adoc[Converter Class] When:**
354
+ * ✅ Need strict mode validation
355
+ * ✅ Want more control over process
356
+ * ✅ Building a service or application
357
+ * ✅ Require custom error handling
358
+
359
+ .Module method vs Converter class
360
+ [example]
361
+ ====
362
+ [source,ruby]
363
+ ----
364
+ # Using module method (simple)
365
+ svg = Postsvg.convert(ps_content)
366
+
367
+ # Using Converter class (more control)
368
+ converter = Postsvg::Converter.new(
369
+ ps_content,
370
+ strict_mode: true
371
+ )
372
+ svg = converter.convert
373
+ ----
374
+ ====
375
+
376
+ == Next Steps
377
+
378
+ * Learn about link:converter.adoc[Converter Class] for advanced options
379
+ * Review link:interpreter.adoc[Interpreter Class] for execution details
380
+ * See link:../getting-started/basic-usage.adoc[Basic Usage] for practical examples
381
+ * Check link:../cli-reference.adoc[CLI Reference] for command-line usage
382
+
383
+ == Bibliography
384
+
385
+ * link:converter.adoc[Converter Class Documentation]
386
+ * link:interpreter.adoc[Interpreter Class Documentation]
387
+ * link:../getting-started/basic-usage.adoc[Basic Usage Guide]
388
+ * link:https://rubygems.org/gems/postsvg[Postsvg on RubyGems]