postsvg 0.1.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 (41) hide show
  1. checksums.yaml +7 -0
  2. data/.rubocop.yml +19 -0
  3. data/.rubocop_todo.yml +141 -0
  4. data/Gemfile +15 -0
  5. data/LICENSE +25 -0
  6. data/README.adoc +473 -0
  7. data/Rakefile +10 -0
  8. data/docs/POSTSCRIPT.adoc +13 -0
  9. data/docs/postscript/fundamentals.adoc +356 -0
  10. data/docs/postscript/graphics-model.adoc +406 -0
  11. data/docs/postscript/implementation-notes.adoc +314 -0
  12. data/docs/postscript/index.adoc +153 -0
  13. data/docs/postscript/operators/arithmetic.adoc +461 -0
  14. data/docs/postscript/operators/control-flow.adoc +230 -0
  15. data/docs/postscript/operators/dictionary.adoc +191 -0
  16. data/docs/postscript/operators/graphics-state.adoc +528 -0
  17. data/docs/postscript/operators/index.adoc +288 -0
  18. data/docs/postscript/operators/painting.adoc +475 -0
  19. data/docs/postscript/operators/path-construction.adoc +553 -0
  20. data/docs/postscript/operators/stack-manipulation.adoc +374 -0
  21. data/docs/postscript/operators/transformations.adoc +479 -0
  22. data/docs/postscript/svg-mapping.adoc +369 -0
  23. data/exe/postsvg +6 -0
  24. data/lib/postsvg/cli.rb +103 -0
  25. data/lib/postsvg/colors.rb +33 -0
  26. data/lib/postsvg/converter.rb +214 -0
  27. data/lib/postsvg/errors.rb +11 -0
  28. data/lib/postsvg/graphics_state.rb +158 -0
  29. data/lib/postsvg/interpreter.rb +891 -0
  30. data/lib/postsvg/matrix.rb +106 -0
  31. data/lib/postsvg/parser/postscript_parser.rb +87 -0
  32. data/lib/postsvg/parser/transform.rb +21 -0
  33. data/lib/postsvg/parser.rb +18 -0
  34. data/lib/postsvg/path_builder.rb +101 -0
  35. data/lib/postsvg/svg_generator.rb +78 -0
  36. data/lib/postsvg/tokenizer.rb +161 -0
  37. data/lib/postsvg/version.rb +5 -0
  38. data/lib/postsvg.rb +78 -0
  39. data/postsvg.gemspec +38 -0
  40. data/scripts/regenerate_fixtures.rb +28 -0
  41. metadata +118 -0
@@ -0,0 +1,153 @@
1
+ = PostScript Language Quick Reference
2
+
3
+ == Purpose
4
+
5
+ This guide provides a comprehensive reference to the PostScript language as
6
+ implemented in the Postsvg library. PostScript is a stack-based, interpreted
7
+ programming language designed for describing vector graphics and page layouts.
8
+
9
+ Postsvg focuses on the graphics subset of PostScript needed to convert
10
+ PostScript (PS) and Encapsulated PostScript (EPS) files to Scalable Vector
11
+ Graphics (SVG) format.
12
+
13
+ == Documentation Structure
14
+
15
+ === Core Concepts
16
+
17
+ * link:fundamentals.adoc[Language Fundamentals]
18
+ - Stack-based execution model
19
+ - Data types (numbers, strings, names, arrays, procedures)
20
+ - Coordinate system and units
21
+ - Syntax rules and comments
22
+
23
+ * link:graphics-model.adoc[Graphics Model]
24
+ - Current path concept
25
+ - Graphics state parameters
26
+ - Painting model (fill vs stroke)
27
+ - Transformation matrices
28
+
29
+ === Operator Reference
30
+
31
+ * link:operators/index.adoc[All Operators] - Complete reference
32
+
33
+ By category:
34
+
35
+ * link:operators/path-construction.adoc[Path Construction Operators]
36
+ - `newpath`, `moveto`, `lineto`, `curveto`, `closepath`, `arc`, `arcn`
37
+
38
+ * link:operators/painting.adoc[Painting Operators]
39
+ - `stroke`, `fill`, `eofill`, `clip`, `eoclip`
40
+
41
+ * link:operators/graphics-state.adoc[Graphics State Operators]
42
+ - `gsave`, `grestore`, `setlinewidth`, `setrgbcolor`, `setgray`,
43
+ `setlinecap`, `setlinejoin`, `setmiterlimit`, `setdash`
44
+
45
+ * link:operators/transformations.adoc[Transformation Operators]
46
+ - `translate`, `scale`, `rotate`, `concat`, `matrix`, `currentmatrix`,
47
+ `setmatrix`
48
+
49
+ * link:operators/stack-manipulation.adoc[Stack Manipulation Operators]
50
+ - `dup`, `pop`, `exch`, `roll`, `copy`, `clear`, `count`, `index`
51
+
52
+ * link:operators/arithmetic.adoc[Arithmetic Operators]
53
+ - `add`, `sub`, `mul`, `div`, `mod`, `abs`, `neg`, `sqrt`, `sin`, `cos`
54
+
55
+ * link:operators/control-flow.adoc[Control Flow Operators]
56
+ - `if`, `ifelse`, `for`, `repeat`, `loop`, `exit`, `forall`
57
+
58
+ * link:operators/dictionary.adoc[Dictionary Operators]
59
+ - `def`, `dict`, `begin`, `end`, `load`, `store`
60
+
61
+ === Conversion Guide
62
+
63
+ * link:svg-mapping.adoc[PostScript to SVG Mapping]
64
+ - Coordinate system conversion
65
+ - Path data conversion
66
+ - Color mapping
67
+ - Transformation matrices
68
+
69
+ * link:implementation-notes.adoc[Postsvg Implementation Notes]
70
+ - Supported features
71
+ - Current limitations
72
+ - Architecture overview
73
+ - Testing approach
74
+
75
+ == Quick Start Examples
76
+
77
+ === Drawing a rectangle
78
+
79
+ [example]
80
+ ====
81
+ [source,postscript]
82
+ ----
83
+ newpath % Initialize empty path
84
+ 50 50 moveto % Start at bottom-left corner
85
+ 150 50 lineto % Draw to bottom-right
86
+ 150 150 lineto % Draw to top-right
87
+ 50 150 lineto % Draw to top-left
88
+ closepath % Close the path
89
+ 0 0 0 setrgbcolor % Set color to black
90
+ stroke % Render the outline
91
+ ----
92
+
93
+ This creates a 100x100 point rectangle starting at coordinates (50, 50).
94
+ ====
95
+
96
+ === Drawing a filled circle
97
+
98
+ [example]
99
+ ====
100
+ [source,postscript]
101
+ ----
102
+ newpath % Initialize empty path
103
+ 100 100 50 0 360 arc % Circle at (100,100) radius 50
104
+ 0.5 0.5 0.5 setrgbcolor % Set gray fill color
105
+ fill % Fill the circle
106
+ ----
107
+
108
+ The `arc` operator draws a circular arc from 0 to 360 degrees (a full circle)
109
+ centered at (100, 100) with radius 50.
110
+ ====
111
+
112
+ === Using transformations
113
+
114
+ [example]
115
+ ====
116
+ [source,postscript]
117
+ ----
118
+ gsave % Save current graphics state
119
+ 100 100 translate % Move origin to (100, 100)
120
+ 45 rotate % Rotate 45 degrees
121
+ newpath
122
+ 0 0 moveto % Now at rotated origin
123
+ 50 0 lineto % Draw 50 units right
124
+ stroke
125
+ grestore % Restore original state
126
+ ----
127
+
128
+ Transformations affect all subsequent drawing operations until the graphics
129
+ state is restored.
130
+ ====
131
+
132
+ == Notation Conventions
133
+
134
+ Throughout this documentation:
135
+
136
+ * `x y operator` - Stack notation shows operands before operator
137
+ * `--` - Represents empty stack or no return value
138
+ * `→` - Shows stack transformation (before → after)
139
+ * Comments use `%` character
140
+
141
+ Stack effect notation example:
142
+
143
+ [source]
144
+ ----
145
+ num1 num2 add → sum
146
+ ----
147
+
148
+ This means `add` consumes two numbers from the stack and pushes their sum.
149
+
150
+ == See Also
151
+
152
+ * link:../POSTSCRIPT.adoc[Back to main PostScript reference]
153
+ * link:../../README.adoc[Postsvg README]
@@ -0,0 +1,461 @@
1
+ = Arithmetic Operators
2
+
3
+ == General
4
+
5
+ Arithmetic operators perform mathematical calculations on numbers from the
6
+ operand stack. They consume their operands and push the result back onto the
7
+ stack.
8
+
9
+ PostScript supports both integer and real (floating-point) arithmetic, with
10
+ automatic type promotion when mixing types.
11
+
12
+ [[add]]
13
+ == add
14
+
15
+ === General
16
+
17
+ The `add` operator adds two numbers.
18
+
19
+ === Syntax
20
+
21
+ [source,postscript]
22
+ ----
23
+ num1 num2 add <1> <2> <3>
24
+ ----
25
+ <1> First number
26
+ <2> Second number
27
+ <3> Operator that adds them
28
+
29
+ Where,
30
+
31
+ `num1, num2`:: Numbers to add
32
+
33
+ Stack effect: `num1 num2 -- sum`
34
+
35
+ === Examples
36
+
37
+ [example]
38
+ ====
39
+ [source,postscript]
40
+ ----
41
+ 5 3 add % 8
42
+ 2.5 1.5 add % 4.0
43
+ ----
44
+ ====
45
+
46
+ [[sub]]
47
+ == sub
48
+
49
+ === General
50
+
51
+ The `sub` operator subtracts the second number from the first.
52
+
53
+ === Syntax
54
+
55
+ [source,postscript]
56
+ ----
57
+ num1 num2 sub <1> <2> <3>
58
+ ----
59
+ <1> Minuend
60
+ <2> Subtrahend
61
+ <3> Operator that subtracts
62
+
63
+ Where,
64
+
65
+ `num1`:: Number to subtract from
66
+ `num2`:: Number to subtract
67
+
68
+ Stack effect: `num1 num2 -- difference`
69
+
70
+ === Examples
71
+
72
+ [example]
73
+ ====
74
+ [source,postscript]
75
+ ----
76
+ 10 3 sub % 7 (10 - 3)
77
+ 5 8 sub % -3 (5 - 8)
78
+ ----
79
+ ====
80
+
81
+ [[mul]]
82
+ == mul
83
+
84
+ === General
85
+
86
+ The `mul` operator multiplies two numbers.
87
+
88
+ === Syntax
89
+
90
+ [source,postscript]
91
+ ----
92
+ num1 num2 mul <1> <2> <3>
93
+ ----
94
+ <1> First factor
95
+ <2> Second factor
96
+ <3> Operator that multiplies
97
+
98
+ Where,
99
+
100
+ `num1, num2`:: Numbers to multiply
101
+
102
+ Stack effect: `num1 num2 -- product`
103
+
104
+ === Examples
105
+
106
+ [example]
107
+ ====
108
+ [source,postscript]
109
+ ----
110
+ 6 7 mul % 42
111
+ 2.5 4 mul % 10.0
112
+ ----
113
+ ====
114
+
115
+ [[div]]
116
+ == div
117
+
118
+ === General
119
+
120
+ The `div` operator divides two numbers, always producing a real result.
121
+
122
+ === Syntax
123
+
124
+ [source,postscript]
125
+ ----
126
+ num1 num2 div <1> <2> <3>
127
+ ----
128
+ <1> Dividend
129
+ <2> Divisor
130
+ <3> Operator that divides
131
+
132
+ Where,
133
+
134
+ `num1`:: Number to divide
135
+ `num2`:: Divisor (must not be zero)
136
+
137
+ Stack effect: `num1 num2 -- quotient`
138
+
139
+ === Examples
140
+
141
+ [example]
142
+ ====
143
+ [source,postscript]
144
+ ----
145
+ 10 4 div % 2.5
146
+ 15 3 div % 5.0
147
+ ----
148
+
149
+ Always returns a real number.
150
+ ====
151
+
152
+ [[idiv]]
153
+ == idiv
154
+
155
+ === General
156
+
157
+ The `idiv` operator performs integer division, truncating toward zero.
158
+
159
+ === Syntax
160
+
161
+ [source,postscript]
162
+ ----
163
+ int1 int2 idiv <1> <2> <3>
164
+ ----
165
+ <1> Dividend (integer)
166
+ <2> Divisor (integer)
167
+ <3> Operator for integer division
168
+
169
+ Where,
170
+
171
+ `int1, int2`:: Integer operands
172
+
173
+ Stack effect: `int1 int2 -- quotient`
174
+
175
+ === Examples
176
+
177
+ [example]
178
+ ====
179
+ [source,postscript]
180
+ ----
181
+ 10 3 idiv % 3 (truncated)
182
+ -10 3 idiv % -3 (toward zero)
183
+ ----
184
+ ====
185
+
186
+ [[mod]]
187
+ == mod
188
+
189
+ === General
190
+
191
+ The `mod` operator returns the remainder after integer division.
192
+
193
+ === Syntax
194
+
195
+ [source,postscript]
196
+ ----
197
+ int1 int2 mod <1> <2> <3>
198
+ ----
199
+ <1> Dividend
200
+ <2> Divisor
201
+ <3> Operator for modulo
202
+
203
+ Where,
204
+
205
+ `int1, int2`:: Integer operands
206
+
207
+ Stack effect: `int1 int2 -- remainder`
208
+
209
+ === Examples
210
+
211
+ [example]
212
+ ====
213
+ [source,postscript]
214
+ ----
215
+ 10 3 mod % 1 (10 = 3×3 + 1)
216
+ 17 5 mod % 2
217
+ ----
218
+ ====
219
+
220
+ [[abs]]
221
+ == abs
222
+
223
+ === General
224
+
225
+ The `abs` operator returns the absolute value of a number.
226
+
227
+ === Syntax
228
+
229
+ [source,postscript]
230
+ ----
231
+ num abs <1> <2>
232
+ ----
233
+ <1> Number
234
+ <2> Operator for absolute value
235
+
236
+ Where,
237
+
238
+ `num`:: Any number
239
+
240
+ Stack effect: `num -- |num|`
241
+
242
+ === Examples
243
+
244
+ [example]
245
+ ====
246
+ [source,postscript]
247
+ ----
248
+ -5 abs % 5
249
+ 3.14 abs % 3.14
250
+ ----
251
+ ====
252
+
253
+ [[neg]]
254
+ == neg
255
+
256
+ === General
257
+
258
+ The `neg` operator negates a number (multiplies by -1).
259
+
260
+ === Syntax
261
+
262
+ [source,postscript]
263
+ ----
264
+ num neg <1> <2>
265
+ ----
266
+ <1> Number to negate
267
+ <2> Operator that negates
268
+
269
+ Where,
270
+
271
+ `num`:: Any number
272
+
273
+ Stack effect: `num -- -num`
274
+
275
+ === Examples
276
+
277
+ [example]
278
+ ====
279
+ [source,postscript]
280
+ ----
281
+ 5 neg % -5
282
+ -3 neg % 3
283
+ ----
284
+ ====
285
+
286
+ [[sqrt]]
287
+ == sqrt
288
+
289
+ === General
290
+
291
+ The `sqrt` operator returns the square root of a number.
292
+
293
+ === Syntax
294
+
295
+ [source,postscript]
296
+ ----
297
+ num sqrt <1> <2>
298
+ ----
299
+ <1> Number (non-negative)
300
+ <2> Operator for square root
301
+
302
+ Where,
303
+
304
+ `num`:: Non-negative number
305
+
306
+ Stack effect: `num -- √num`
307
+
308
+ === Examples
309
+
310
+ [example]
311
+ ====
312
+ [source,postscript]
313
+ ----
314
+ 16 sqrt % 4.0
315
+ 2 sqrt % 1.41421...
316
+ ----
317
+ ====
318
+
319
+ [[sin]]
320
+ == sin
321
+
322
+ === General
323
+
324
+ The `sin` operator returns the sine of an angle in degrees.
325
+
326
+ === Syntax
327
+
328
+ [source,postscript]
329
+ ----
330
+ angle sin <1> <2>
331
+ ----
332
+ <1> Angle in degrees
333
+ <2> Operator for sine
334
+
335
+ Where,
336
+
337
+ `angle`:: Angle in degrees (number)
338
+
339
+ Stack effect: `angle -- sine`
340
+
341
+ === Examples
342
+
343
+ [example]
344
+ ====
345
+ [source,postscript]
346
+ ----
347
+ 0 sin % 0.0
348
+ 90 sin % 1.0
349
+ 30 sin % 0.5
350
+ ----
351
+ ====
352
+
353
+ [[cos]]
354
+ == cos
355
+
356
+ === General
357
+
358
+ The `cos` operator returns the cosine of an angle in degrees.
359
+
360
+ === Syntax
361
+
362
+ [source,postscript]
363
+ ----
364
+ angle cos <1> <2>
365
+ ----
366
+ <1> Angle in degrees
367
+ <2> Operator for cosine
368
+
369
+ Where,
370
+
371
+ `angle`:: Angle in degrees (number)
372
+
373
+ Stack effect: `angle -- cosine`
374
+
375
+ === Examples
376
+
377
+ [example]
378
+ ====
379
+ [source,postscript]
380
+ ----
381
+ 0 cos % 1.0
382
+ 90 cos % 0.0
383
+ 60 cos % 0.5
384
+ ----
385
+ ====
386
+
387
+ [[atan]]
388
+ == atan
389
+
390
+ === General
391
+
392
+ The `atan` operator returns the arctangent of num1/num2 in degrees, with
393
+ proper handling of the quadrant.
394
+
395
+ === Syntax
396
+
397
+ [source,postscript]
398
+ ----
399
+ num1 num2 atan <1> <2> <3>
400
+ ----
401
+ <1> Numerator (Y value)
402
+ <2> Denominator (X value)
403
+ <3> Operator for arctangent
404
+
405
+ Where,
406
+
407
+ `num1, num2`:: Numbers (num2 cannot be zero unless num1 is also zero)
408
+
409
+ Stack effect: `num1 num2 -- angle`
410
+
411
+ === Examples
412
+
413
+ [example]
414
+ ====
415
+ [source,postscript]
416
+ ----
417
+ 1 1 atan % 45.0 (first quadrant)
418
+ 1 -1 atan % 135.0 (second quadrant)
419
+ ----
420
+ ====
421
+
422
+ == Arithmetic Patterns
423
+
424
+ === Calculating distances
425
+
426
+ [example]
427
+ ====
428
+ [source,postscript]
429
+ ----
430
+ % Distance between (x1,y1) and (x2,y2)
431
+ /x1 10 def /y1 20 def
432
+ /x2 40 def /y2 60 def
433
+
434
+ x2 x1 sub dup mul % (x2-x1)²
435
+ y2 y1 sub dup mul % (y2-y1)²
436
+ add sqrt % √((x2-x1)² + (y2-y1)²)
437
+ % Result: 50.0
438
+ ----
439
+
440
+ Pythagorean theorem for distance.
441
+ ====
442
+
443
+ === Converting units
444
+
445
+ [example]
446
+ ====
447
+ [source,postscript]
448
+ ----
449
+ % Inches to points (72 points per inch)
450
+ 2.5 72 mul % 180.0 points
451
+
452
+ % Degrees to radians (approximately)
453
+ 90 3.14159 mul 180 div % π/2 radians
454
+ ----
455
+ ====
456
+
457
+ == See Also
458
+
459
+ * link:../fundamentals.adoc#stack-based-execution-model[Stack Execution]
460
+ * link:stack-manipulation.adoc[Stack Operators]
461
+ * link:index.adoc[Back to Operator Reference]