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,354 @@
1
+ = Architecture
2
+ :page-nav_order: 6
3
+
4
+ == Purpose
5
+
6
+ This section describes Postsvg's internal architecture, design patterns, and implementation details. Understanding the architecture helps developers contribute to Postsvg, extend its functionality, and troubleshoot complex issues.
7
+
8
+ == References
9
+
10
+ * link:index.adoc[Documentation Home]
11
+ * link:concepts.adoc[Core Concepts]
12
+ * link:api-reference.adoc[API Reference]
13
+ * link:development.adoc[Development Guide]
14
+
15
+ == Concepts
16
+
17
+ **Three-Stage Pipeline**:: Postsvg uses a clean separation between parsing, interpretation, and generation.
18
+
19
+ **Command Pattern**:: PostScript operators are implemented as command objects following the Command design pattern.
20
+
21
+ **Stack-Based Execution**:: Postsvg implements PostScript's stack-based execution model.
22
+
23
+ **State Management**:: Graphics state is managed through a stack of immutable state objects.
24
+
25
+ **Registry Pattern**:: Commands are registered and looked up through a central registry.
26
+
27
+ == Architecture Topics
28
+
29
+ link:architecture/conversion-pipeline.adoc[**Conversion Pipeline**]::
30
+ The three-stage architecture: tokenization/parsing, interpretation/execution, and SVG generation.
31
+
32
+ link:architecture/parser-stage.adoc[**Parser Stage**]::
33
+ Tokenization and parsing of PostScript syntax into executable tokens.
34
+
35
+ link:architecture/interpreter-stage.adoc[**Interpreter Stage**]::
36
+ Command execution, stack management, and graphics state manipulation.
37
+
38
+ link:architecture/generator-stage.adoc[**Generator Stage**]::
39
+ SVG generation from interpreted graphics operations.
40
+
41
+ link:architecture/command-registry.adoc[**Command Registry**]::
42
+ How PostScript operators are registered, looked up, and executed.
43
+
44
+ link:architecture/graphics-state-model.adoc[**Graphics State Model**]::
45
+ State management, transformation matrices, and the graphics state stack.
46
+
47
+ link:architecture/design-decisions.adoc[**Design Decisions**]::
48
+ Architectural choices, trade-offs, and rationale behind implementation decisions.
49
+
50
+ == High-Level Architecture
51
+
52
+ .Postsvg Architecture Overview
53
+ [source]
54
+ ----
55
+ ┌─────────────────────────────────────────────────────────────┐
56
+ │ Postsvg Module │
57
+ │ - convert(ps_content) → svg │
58
+ │ - convert_file(input, output) → svg │
59
+ └────────────────────────┬────────────────────────────────────┘
60
+
61
+
62
+ ┌─────────────────────────────────────────────────────────────┐
63
+ │ Converter Class │
64
+ │ - Initialize with PostScript content │
65
+ │ - Extract BoundingBox │
66
+ │ - Coordinate conversion pipeline │
67
+ └────┬──────────────────┬──────────────────┬──────────────────┘
68
+ │ │ │
69
+ ▼ ▼ ▼
70
+ ┌──────────┐ ┌──────────────┐ ┌─────────────┐
71
+ │Tokenizer │───>│ Interpreter │──>│SVG Generator│
72
+ └──────────┘ └──────────────┘ └─────────────┘
73
+ │ │ │
74
+ │ │ │
75
+ ▼ ▼ ▼
76
+ Tokens ExecutionContext SVG Document
77
+ │ │
78
+ ▼ ▼
79
+ ┌────────┐ ┌──────────────┐
80
+ │ Stack │ │GraphicsState │
81
+ └────────┘ └──────────────┘
82
+ ----
83
+
84
+ == Component Responsibilities
85
+
86
+ === Postsvg Module
87
+
88
+ **Location:** [`lib/postsvg.rb`](../lib/postsvg.rb:10)
89
+
90
+ **Responsibilities:**
91
+ * Provide simple API for quick conversions
92
+ * Extract BoundingBox from PostScript header
93
+ * Delegate to Converter for actual conversion
94
+
95
+ **Methods:**
96
+ * [`convert(ps_content)`](../lib/postsvg.rb:13) - Convert PostScript string to SVG
97
+ * [`convert_file(input_path, output_path)`](../lib/postsvg.rb:24) - Convert file to SVG
98
+
99
+ === Converter Class
100
+
101
+ **Location:** [`lib/postsvg/converter.rb`](../lib/postsvg/converter.rb:8)
102
+
103
+ **Responsibilities:**
104
+ * Orchestrate the conversion pipeline
105
+ * Extract BoundingBox information
106
+ * Configure strict mode
107
+ * Coordinate Tokenizer, Interpreter, and Generator
108
+
109
+ **Key Methods:**
110
+ * [`initialize(ps_content, strict_mode:)`](../lib/postsvg/converter.rb:12) - Set up converter
111
+ * [`convert`](../lib/postsvg/converter.rb:17) - Execute full conversion
112
+ * `extract_bounding_box` - Parse BoundingBox comment
113
+
114
+ === Tokenizer Class
115
+
116
+ **Location:** [`lib/postsvg/tokenizer.rb`](../lib/postsvg/tokenizer.rb:8)
117
+
118
+ **Responsibilities:**
119
+ * Lexical analysis of PostScript source
120
+ * Break input into tokens (numbers, operators, strings, etc.)
121
+ * Handle string and hex string parsing
122
+
123
+ **Token Types:**
124
+ * `:number` - Integer or float values
125
+ * `:operator` - PostScript commands
126
+ * `:name` - Named identifiers (starting with `/`)
127
+ * `:string` - String literals
128
+ * `:hex_string` - Hexadecimal strings
129
+ * `:array_start`, `:array_end` - Array delimiters
130
+ * `:proc_start`, `:proc_end` - Procedure delimiters
131
+
132
+ === Interpreter Class
133
+
134
+ **Location:** [`lib/postsvg/interpreter.rb`](../lib/postsvg/interpreter.rb:9)
135
+
136
+ **Responsibilities:**
137
+ * Execute PostScript commands
138
+ * Manage execution context
139
+ * Parse arrays and procedures
140
+ * Coordinate with ExecutionContext
141
+ * Generate final SVG document
142
+
143
+ **Key Methods:**
144
+ * [`interpret(tokens, bounding_box)`](../lib/postsvg/interpreter.rb:20) - Main interpretation loop
145
+ * `execute_operator` - Execute single operator
146
+ * `parse_procedure` - Parse procedure tokens
147
+ * `parse_array` - Parse array tokens
148
+ * `generate_svg_document` - Create final SVG
149
+
150
+ === ExecutionContext Class
151
+
152
+ **Location:** [`lib/postsvg/execution_context.rb`](../lib/postsvg/execution_context.rb:9)
153
+
154
+ **Responsibilities:**
155
+ * Maintain operand stack
156
+ * Manage dictionary stack
157
+ * Track graphics state
158
+ * Manage graphics state stack
159
+ * Generate SVG elements
160
+ * Handle clipPath deduplication
161
+
162
+ **Key Components:**
163
+ * Operand stack for values
164
+ * Dictionary stack for definitions
165
+ * Graphics state for drawing parameters
166
+ * Graphics state stack for `gsave`/`grestore`
167
+ * ClipPath registry for optimization
168
+
169
+ === GraphicsState Class
170
+
171
+ **Location:** [`lib/postsvg/graphics_state.rb`](../lib/postsvg/graphics_state.rb:5)
172
+
173
+ **Responsibilities:**
174
+ * Track current path
175
+ * Manage colors (fill and stroke)
176
+ * Store line attributes
177
+ * Maintain transformation matrix
178
+ * Handle path construction
179
+
180
+ **State Components:**
181
+ * Current path segments
182
+ * Current point (x, y)
183
+ * Fill and stroke colors
184
+ * Line width, cap, join, dash pattern
185
+ * Transformation matrix
186
+
187
+ === SvgGenerator Class
188
+
189
+ **Location:** [`lib/postsvg/svg_generator.rb`](../lib/postsvg/svg_generator.rb:7)
190
+
191
+ **Responsibilities:**
192
+ * Build SVG document structure
193
+ * Transform paths to SVG format
194
+ * Apply coordinate transformations
195
+ * Generate optimized output
196
+
197
+ **Generation Steps:**
198
+ 1. Create SVG root element
199
+ 2. Set viewBox from BoundingBox
200
+ 3. Generate `<defs>` section
201
+ 4. Transform and output paths
202
+ 5. Optimize clipPath references
203
+
204
+ === Command Registry
205
+
206
+ **Location:** [`lib/postsvg/commands/registry.rb`](../lib/postsvg/commands/registry.rb:1)
207
+
208
+ **Responsibilities:**
209
+ * Register all PostScript operators
210
+ * Look up command implementations
211
+ * Provide command execution interface
212
+
213
+ **Command Categories:**
214
+ * Path construction (moveto, lineto, curveto, etc.)
215
+ * Painting (stroke, fill, clip, etc.)
216
+ * Graphics state (gsave, grestore, setlinewidth, etc.)
217
+ * Transformations (translate, scale, rotate, etc.)
218
+ * Stack operations (dup, pop, exch, roll, etc.)
219
+ * Arithmetic (add, sub, mul, div, etc.)
220
+ * Control flow (if, ifelse, for, repeat, etc.)
221
+ * Dictionary (dict, begin, end, def, etc.)
222
+
223
+ === Matrix Class
224
+
225
+ **Location:** [`lib/postsvg/matrix.rb`](../lib/postsvg/matrix.rb:6)
226
+
227
+ **Responsibilities:**
228
+ * Represent 2D affine transformations
229
+ * Perform matrix operations
230
+ * Apply transformations to points
231
+ * Convert to SVG transform strings
232
+
233
+ **Operations:**
234
+ * Multiply matrices
235
+ * Translate, scale, rotate
236
+ * Transform points
237
+ * Invert transformations
238
+ * Decompose into components
239
+
240
+ == Design Patterns
241
+
242
+ === Command Pattern
243
+
244
+ Each PostScript operator is implemented as a command class:
245
+
246
+ [source,ruby]
247
+ ----
248
+ module Postsvg
249
+ module Commands
250
+ class Moveto < Base
251
+ def execute(context)
252
+ y = context.pop_number
253
+ x = context.pop_number
254
+ context.graphics_state.moveto(x, y)
255
+ end
256
+ end
257
+ end
258
+ end
259
+ ----
260
+
261
+ **Benefits:**
262
+ * Each operator is independently testable
263
+ * Easy to add new operators
264
+ * Clear separation of concerns
265
+ * Supports operator overriding
266
+
267
+ === Registry Pattern
268
+
269
+ Commands are registered centrally:
270
+
271
+ [source,ruby]
272
+ ----
273
+ Registry.register('moveto', Commands::Moveto.new)
274
+ Registry.register('lineto', Commands::Lineto.new)
275
+ # ...
276
+
277
+ # Later, look up and execute
278
+ command = Registry.lookup('moveto')
279
+ command.execute(context)
280
+ ----
281
+
282
+ === State Pattern
283
+
284
+ Graphics state is managed immutably:
285
+
286
+ [source,ruby]
287
+ ----
288
+ # Save state
289
+ saved_state = graphics_state.dup
290
+ state_stack.push(saved_state)
291
+
292
+ # Modify state
293
+ graphics_state.translate(10, 20)
294
+
295
+ # Restore state
296
+ graphics_state = state_stack.pop
297
+ ----
298
+
299
+ === Strategy Pattern
300
+
301
+ Different output formats use strategy pattern:
302
+
303
+ [source,ruby]
304
+ ----
305
+ # Text reporter
306
+ reporter = Reporters::TextReporter.new
307
+
308
+ # JSON reporter
309
+ reporter = Reporters::JsonReporter.new
310
+
311
+ # Both use same interface
312
+ reporter.report(validation_result)
313
+ ----
314
+
315
+ ## Data Flow
316
+
317
+ .Complete Data Flow
318
+ [source]
319
+ ----
320
+ PostScript File
321
+
322
+
323
+ [Tokenizer]
324
+
325
+
326
+ Tokens[]
327
+
328
+
329
+ [Interpreter] ──────> [ExecutionContext]
330
+ │ │
331
+ │ ├─> Operand Stack
332
+ │ ├─> Dictionary Stack
333
+ │ ├─> Graphics State
334
+ │ └─> SVG Output Buffer
335
+
336
+
337
+ [SvgGenerator]
338
+
339
+
340
+ SVG Document
341
+ ----
342
+
343
+ == Next Steps
344
+
345
+ * Review link:architecture/conversion-pipeline.adoc[Conversion Pipeline] details
346
+ * Explore link:architecture/command-registry.adoc[Command Registry] implementation
347
+ * See link:development.adoc[Development Guide] for contributing
348
+ * Check link:api-reference.adoc[API Reference] for class details
349
+
350
+ == Bibliography
351
+
352
+ * link:architecture/conversion-pipeline.adoc[Conversion Pipeline Documentation]
353
+ * link:architecture/design-decisions.adoc[Design Decisions]
354
+ * Design Patterns: Elements of Reusable Object-Oriented Software (Gang of Four)