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,616 @@
1
+ = batch Command
2
+ :page-nav_order: 2
3
+ :page-parent: CLI Reference
4
+
5
+ == Purpose
6
+
7
+ The `batch` command enables efficient conversion of multiple PostScript and EPS files in a directory. It's optimized for bulk processing and provides progress reporting for all conversions.
8
+
9
+ == References
10
+
11
+ * link:../index.adoc[Documentation Home]
12
+ * link:../cli-reference.adoc[CLI Reference Overview]
13
+ * link:convert-command.adoc[convert Command]
14
+ * link:check-command.adoc[check Command]
15
+ * link:../getting-started/common-workflows.adoc[Common Workflows]
16
+
17
+ == Concepts
18
+
19
+ **Batch Processing**:: Converting multiple files in a single operation.
20
+
21
+ **Directory Processing**:: Automatically finding and converting all matching files in a directory.
22
+
23
+ **Progress Reporting**:: Displaying status for each file as it's processed.
24
+
25
+ **Error Tolerance**:: Continuing to process remaining files even if some conversions fail.
26
+
27
+ == Command Syntax
28
+
29
+ [source,sh]
30
+ ----
31
+ postsvg batch [OPTIONS] INPUT_DIR [OUTPUT_DIR] <1>
32
+ ----
33
+ <1> Convert all PS/EPS files in INPUT_DIR, optionally saving to OUTPUT_DIR
34
+
35
+ **Where:**
36
+
37
+ `INPUT_DIR`:: Directory containing PostScript (`.ps`) and/or EPS (`.eps`) files (required)
38
+
39
+ `OUTPUT_DIR`:: Directory where SVG files should be saved (optional). If omitted, SVG files are saved in `INPUT_DIR` with `.svg` extension.
40
+
41
+ **Options:**
42
+
43
+ `--strict`:: Enable strict mode (fail on unknown operators)
44
+
45
+ **Exit Codes:**
46
+ * `0` - Success (all files converted successfully)
47
+ * `1` - Partial failure (one or more files failed to convert)
48
+
49
+ **Source:**
50
+ [`lib/postsvg/cli.rb:52-107`](../../lib/postsvg/cli.rb:52)
51
+
52
+ == Basic Usage
53
+
54
+ === Convert to Same Directory
55
+
56
+ Convert all files and save SVG in the same directory:
57
+
58
+ [source,sh]
59
+ ----
60
+ postsvg batch input_dir/ <1>
61
+ ----
62
+ <1> Converts all PS/EPS files, creates SVG files in `input_dir/`
63
+
64
+ **Output:**
65
+ [source]
66
+ ----
67
+ Found 3 file(s) to convert
68
+ ✓ input_dir/file1.ps → input_dir/file1.svg
69
+ ✓ input_dir/file2.eps → input_dir/file2.svg
70
+ ✓ input_dir/file3.ps → input_dir/file3.svg
71
+ ----
72
+
73
+ .In-place batch conversion
74
+ [example]
75
+ ====
76
+ [source,sh]
77
+ ----
78
+ $ ls ps_files/
79
+ diagram1.ps diagram2.eps figure.ps
80
+
81
+ $ postsvg batch ps_files/
82
+ Found 3 file(s) to convert
83
+ ✓ ps_files/diagram1.ps → ps_files/diagram1.svg
84
+ ✓ ps_files/diagram2.eps → ps_files/diagram2.svg
85
+ ✓ ps_files/figure.ps → ps_files/figure.svg
86
+
87
+ $ ls ps_files/
88
+ diagram1.ps diagram1.svg diagram2.eps diagram2.svg figure.ps figure.svg
89
+ ----
90
+
91
+ Original PS/EPS files are preserved.
92
+ ====
93
+
94
+ === Convert to Different Directory
95
+
96
+ Save converted SVG files to a separate directory:
97
+
98
+ [source,sh]
99
+ ----
100
+ postsvg batch input_dir/ output_dir/ <1>
101
+ ----
102
+ <1> Converts all PS/EPS files from `input_dir/`, saves SVG to `output_dir/`
103
+
104
+ **Behavior:**
105
+ * Output directory is created if it doesn't exist
106
+ * Original files remain untouched
107
+ * SVG files use same basename as source files
108
+
109
+ .Separate output directory
110
+ [example]
111
+ ====
112
+ [source,sh]
113
+ ----
114
+ $ ls ps_files/
115
+ file1.ps file2.eps
116
+
117
+ $ postsvg batch ps_files/ svg_files/
118
+ Found 2 file(s) to convert
119
+ ✓ ps_files/file1.ps → svg_files/file1.svg
120
+ ✓ ps_files/file2.eps → svg_files/file2.svg
121
+
122
+ $ ls svg_files/
123
+ file1.svg file2.svg
124
+ ----
125
+
126
+ Input directory (`ps_files/`) remains unchanged.
127
+ ====
128
+
129
+ == Command Options
130
+
131
+ === --strict
132
+
133
+ Enable strict mode for all conversions:
134
+
135
+ [source,sh]
136
+ ----
137
+ postsvg batch --strict input_dir/ output_dir/ <1>
138
+ ----
139
+ <1> All conversions use strict mode
140
+
141
+ **Effect:**
142
+ * Fails on any unknown operators
143
+ * More rigorous validation
144
+ * Helps identify compatibility issues
145
+
146
+ .Strict mode batch processing
147
+ [example]
148
+ ====
149
+ [source,sh]
150
+ ----
151
+ $ postsvg batch --strict test_files/
152
+ Found 3 file(s) to convert
153
+ ✓ test_files/simple.ps → test_files/simple.svg
154
+ ✗ test_files/complex.ps: Unknown operator: shfill
155
+ ✓ test_files/basic.eps → test_files/basic.svg
156
+ ----
157
+
158
+ With strict mode, files with unsupported operators fail conversion.
159
+ ====
160
+
161
+ == File Discovery
162
+
163
+ === Pattern Matching
164
+
165
+ The batch command finds files using case-insensitive pattern matching:
166
+
167
+ **Matched Extensions:**
168
+ * `.ps` (PostScript)
169
+ * `.PS` (uppercase)
170
+ * `.eps` (Encapsulated PostScript)
171
+ * `.EPS` (uppercase)
172
+ * `.Eps`, `.ePs`, etc. (mixed case)
173
+
174
+ .Case-insensitive matching
175
+ [example]
176
+ ====
177
+ [source,sh]
178
+ ----
179
+ $ ls mixed_case/
180
+ File1.PS file2.eps FILE3.EPS diagram.Ps
181
+
182
+ $ postsvg batch mixed_case/
183
+ Found 4 file(s) to convert
184
+ ✓ mixed_case/File1.PS → mixed_case/File1.svg
185
+ ✓ mixed_case/file2.eps → mixed_case/file2.svg
186
+ ✓ mixed_case/FILE3.EPS → mixed_case/FILE3.svg
187
+ ✓ mixed_case/diagram.Ps → mixed_case/diagram.svg
188
+ ----
189
+ ====
190
+
191
+ === Subdirectory Handling
192
+
193
+ **Current Behavior:**
194
+ Batch command only processes files in the top level of `INPUT_DIR`, **not** in subdirectories.
195
+
196
+ .Directory structure
197
+ [example]
198
+ ====
199
+ [source]
200
+ ----
201
+ input/
202
+ ├── file1.ps ← Converted ✓
203
+ ├── file2.eps ← Converted ✓
204
+ └── subdir/
205
+ └── file3.ps ← NOT converted (in subdirectory)
206
+ ----
207
+
208
+ [source,sh]
209
+ ----
210
+ $ postsvg batch input/
211
+ Found 2 file(s) to convert
212
+ ✓ input/file1.ps → input/file1.svg
213
+ ✓ input/file2.eps → input/file2.svg
214
+
215
+ # file3.ps in subdir/ is not processed
216
+ ----
217
+
218
+ **Workaround for subdirectories:**
219
+ [source,sh]
220
+ ----
221
+ # Process each subdirectory separately
222
+ for dir in input/*/; do
223
+ postsvg batch "$dir"
224
+ done
225
+
226
+ # Or use find + convert
227
+ find input/ -name "*.ps" -o -name "*.eps" | while read file; do
228
+ postsvg convert "$file" "${file%.*}.svg"
229
+ done
230
+ ----
231
+ ====
232
+
233
+ == Error Handling
234
+
235
+ === Partial Failures
236
+
237
+ The batch command continues processing even if some files fail:
238
+
239
+ [source,sh]
240
+ ----
241
+ $ postsvg batch mixed_quality/
242
+ Found 4 file(s) to convert
243
+ ✓ mixed_quality/good1.ps → mixed_quality/good1.svg
244
+ ✗ mixed_quality/broken.ps: Conversion error: Invalid syntax
245
+ ✓ mixed_quality/good2.eps → mixed_quality/good2.svg
246
+ ✗ mixed_quality/incomplete.ps: Conversion error: Stack underflow
247
+ ----
248
+
249
+ **Exit Code:** `1` (because some files failed)
250
+
251
+ **Behavior:**
252
+ * Successfully converted files are saved
253
+ * Failed files are skipped
254
+ * All files are attempted
255
+ * Summary shows which failed
256
+
257
+ === Empty Directory
258
+
259
+ [source,sh]
260
+ ----
261
+ $ postsvg batch empty_dir/
262
+ No PS or EPS files found in empty_dir/
263
+ ----
264
+
265
+ **Exit Code:** `0` (not an error)
266
+
267
+ === Missing Directory
268
+
269
+ [source,sh]
270
+ ----
271
+ $ postsvg batch nonexistent/
272
+ Error: Input directory 'nonexistent/' not found
273
+ ----
274
+
275
+ **Exit Code:** `1` (error)
276
+
277
+ == Output Control
278
+
279
+ === Output File Naming
280
+
281
+ SVG files use the same basename as input files:
282
+
283
+ [source]
284
+ ----
285
+ Input Output
286
+ ----------------------|------------------
287
+ diagram.ps → diagram.svg
288
+ FIGURE.EPS → FIGURE.svg
289
+ chart.PS → chart.svg
290
+ ----
291
+
292
+ **Extension Replacement:**
293
+ * `.ps` → `.svg`
294
+ * `.eps` → `.svg`
295
+ * `.PS` → `.svg`
296
+ * `.EPS` → `.svg`
297
+
298
+ .Filename preservation
299
+ [example]
300
+ ====
301
+ [source,sh]
302
+ ----
303
+ $ ls input/
304
+ My Diagram.ps
305
+ Report-2024.eps
306
+ file_v2.ps
307
+
308
+ $ postsvg batch input/ output/
309
+
310
+ $ ls output/
311
+ My Diagram.svg
312
+ Report-2024.svg
313
+ file_v2.svg
314
+ ----
315
+
316
+ Filenames (including spaces and special characters) are preserved.
317
+ ====
318
+
319
+ === Overwriting Behavior
320
+
321
+ **Existing SVG files are overwritten without warning:**
322
+
323
+ [source,sh]
324
+ ----
325
+ $ ls output/
326
+ diagram.svg # Existing file
327
+
328
+ $ postsvg batch input/ output/
329
+ Found 1 file(s) to convert
330
+ ✓ input/diagram.ps → output/diagram.svg # Overwrites existing
331
+
332
+ # Previous diagram.svg is replaced
333
+ ----
334
+
335
+ .Backup before batch conversion
336
+ [example]
337
+ ====
338
+ [source,sh]
339
+ ----
340
+ # Backup existing SVG files
341
+ if [ -d output/ ]; then
342
+ cp -r output/ output.backup/
343
+ fi
344
+
345
+ # Convert
346
+ postsvg batch input/ output/
347
+
348
+ # Verify results
349
+ if [ $? -eq 0 ]; then
350
+ rm -rf output.backup/
351
+ else
352
+ echo "Conversion had errors - backup preserved"
353
+ fi
354
+ ----
355
+ ====
356
+
357
+ == Performance
358
+
359
+ === Processing Speed
360
+
361
+ Batch command is optimized for multiple files:
362
+
363
+ **Advantages over multiple `convert` calls:**
364
+ * Single gem load
365
+ * Shared dependencies
366
+ * Progress reporting
367
+ * Batch error handling
368
+
369
+ .Performance comparison
370
+ [example]
371
+ ====
372
+ [source,sh]
373
+ ----
374
+ # Slower: Multiple convert commands
375
+ $ time for f in *.ps; do postsvg convert "$f" "${f%.ps}.svg"; done
376
+ real 0m15.234s
377
+
378
+ # Faster: Single batch command
379
+ $ time postsvg batch ./
380
+ real 0m8.123s
381
+ ----
382
+
383
+ Batch command is approximately **2x faster** for multiple files.
384
+ ====
385
+
386
+ === Memory Usage
387
+
388
+ **Per-File Processing:**
389
+ * Each file is processed independently
390
+ * Memory is released between files
391
+ * Suitable for large batches
392
+
393
+ [source,sh]
394
+ ----
395
+ # Memory-efficient even for many files
396
+ postsvg batch directory_with_1000_files/
397
+ ----
398
+
399
+ == Usage Patterns
400
+
401
+ === Pattern 1: Organize by Date
402
+
403
+ [source,sh]
404
+ ----
405
+ #!/bin/bash
406
+ # convert-by-date.sh
407
+
408
+ # Create dated output directory
409
+ OUTPUT_DIR="svg_$(date +%Y%m%d)"
410
+ mkdir -p "$OUTPUT_DIR"
411
+
412
+ # Convert all files
413
+ postsvg batch ps_files/ "$OUTPUT_DIR/"
414
+
415
+ echo "Converted files saved to: $OUTPUT_DIR"
416
+ ----
417
+
418
+ === Pattern 2: Selective Conversion
419
+
420
+ [source,sh]
421
+ ----
422
+ #!/bin/bash
423
+ # selective-convert.sh
424
+
425
+ # Create temp directory with only desired files
426
+ mkdir -p temp_input
427
+ cp input/diagram*.ps temp_input/
428
+ cp input/figure*.eps temp_input/
429
+
430
+ # Convert selected files
431
+ postsvg batch temp_input/ output/
432
+
433
+ # Cleanup
434
+ rm -rf temp_input
435
+ ----
436
+
437
+ === Pattern 3: Progress Logging
438
+
439
+ [source,sh]
440
+ ----
441
+ #!/bin/bash
442
+ # batch-with-log.sh
443
+
444
+ INPUT="$1"
445
+ OUTPUT="$2"
446
+ LOG="conversion_$(date +%Y%m%d_%H%M%S).log"
447
+
448
+ {
449
+ echo "Batch Conversion Started: $(date)"
450
+ echo "Input: $INPUT"
451
+ echo "Output: $OUTPUT"
452
+ echo "---"
453
+
454
+ postsvg batch "$INPUT" "$OUTPUT"
455
+
456
+ echo "---"
457
+ echo "Completed: $(date)"
458
+ } | tee "$LOG"
459
+
460
+ echo "Log saved to: $LOG"
461
+ ----
462
+
463
+ === Pattern 4: CI/CD Batch Processing
464
+
465
+ [source,yaml]
466
+ ----
467
+ # .github/workflows/batch-convert.yml
468
+ name: Batch Convert PS Files
469
+
470
+ on:
471
+ push:
472
+ paths:
473
+ - 'graphics/**.ps'
474
+ - 'graphics/**.eps'
475
+
476
+ jobs:
477
+ convert:
478
+ runs-on: ubuntu-latest
479
+ steps:
480
+ - uses: actions/checkout@v3
481
+
482
+ - name: Setup Ruby
483
+ uses: ruby/setup-ruby@v1
484
+ with:
485
+ ruby-version: '3.2'
486
+
487
+ - name: Install Postsvg
488
+ run: gem install postsvg
489
+
490
+ - name: Batch convert
491
+ run: postsvg batch graphics/ svg_output/
492
+
493
+ - name: Upload artifacts
494
+ uses: actions/upload-artifact@v3
495
+ with:
496
+ name: svg-files
497
+ path: svg_output/
498
+ ----
499
+
500
+ == Comparison with convert Command
501
+
502
+ [cols="1,2,2"]
503
+ |===
504
+ | Feature | batch | convert
505
+
506
+ | File count
507
+ | Multiple (directory)
508
+ | Single file
509
+
510
+ | Output location
511
+ | Directory-based
512
+ | Specified or stdout
513
+
514
+ | Error handling
515
+ | Continue on failure
516
+ | Exit on failure
517
+
518
+ | Progress reporting
519
+ | Shows each file
520
+ | Success/error only
521
+
522
+ | Performance
523
+ | Optimized for bulk
524
+ | Per-file overhead
525
+
526
+ | Use case
527
+ | Bulk operations
528
+ | Individual files
529
+ |===
530
+
531
+ **When to use `batch`:**
532
+ - ✅ Converting entire directories
533
+ - ✅ Bulk migration projects
534
+ - ✅ Automated workflows
535
+ - ✅ Want progress tracking
536
+
537
+ **When to use `convert`:**
538
+ - ✅ Single file conversions
539
+ - ✅ Need stdout output
540
+ - ✅ Precise output control
541
+ - ✅ Scripted individual files
542
+
543
+ == Troubleshooting
544
+
545
+ === No Files Found
546
+
547
+ **Problem:**
548
+ [source]
549
+ ----
550
+ No PS or EPS files found in input_dir/
551
+ ----
552
+
553
+ **Solutions:**
554
+ 1. Check directory path is correct
555
+ 2. Verify files have `.ps` or `.eps` extension
556
+ 3. Ensure you have read permissions
557
+
558
+ === Some Files Failed
559
+
560
+ **Problem:**
561
+ [source]
562
+ ----
563
+ ✓ file1.ps → file1.svg
564
+ ✗ file2.ps: Conversion error
565
+ ✓ file3.ps → file3.svg
566
+ ----
567
+
568
+ **Solutions:**
569
+ 1. Check individual failing files:
570
+ [source,sh]
571
+ ----
572
+ postsvg check file2.ps
573
+ ----
574
+
575
+ 2. Try converting individually with strict mode:
576
+ [source,sh]
577
+ ----
578
+ postsvg convert --strict file2.ps file2.svg
579
+ ----
580
+
581
+ 3. Review error message for specific issue
582
+
583
+ === Permission Denied
584
+
585
+ **Problem:**
586
+ [source]
587
+ ----
588
+ Error: Cannot write to output_dir/
589
+ ----
590
+
591
+ **Solutions:**
592
+ [source,sh]
593
+ ----
594
+ # Check permissions
595
+ ls -ld output_dir/
596
+
597
+ # Fix permissions
598
+ chmod +w output_dir/
599
+
600
+ # Or use different output directory
601
+ postsvg batch input/ ~/output/
602
+ ----
603
+
604
+ == Next Steps
605
+
606
+ * Learn link:convert-command.adoc[convert command] for single files
607
+ * Review link:check-command.adoc[check command] for validation
608
+ * See link:../getting-started/common-workflows.adoc#workflow-2-batch-conversion-with-error-logging[Batch Workflows]
609
+ * Check link:../api-reference/converter.adoc[Converter Class] for API equivalent
610
+
611
+ == Bibliography
612
+
613
+ * link:convert-command.adoc[convert Command Documentation]
614
+ * link:check-command.adoc[check Command Documentation]
615
+ * link:../getting-started/common-workflows.adoc[Common Workflows]
616
+ * link:../getting-started/basic-usage.adoc[Basic Usage Guide]