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.
- checksums.yaml +7 -0
- data/.rubocop.yml +19 -0
- data/.rubocop_todo.yml +141 -0
- data/Gemfile +15 -0
- data/LICENSE +25 -0
- data/README.adoc +473 -0
- data/Rakefile +10 -0
- data/docs/POSTSCRIPT.adoc +13 -0
- data/docs/postscript/fundamentals.adoc +356 -0
- data/docs/postscript/graphics-model.adoc +406 -0
- data/docs/postscript/implementation-notes.adoc +314 -0
- data/docs/postscript/index.adoc +153 -0
- data/docs/postscript/operators/arithmetic.adoc +461 -0
- data/docs/postscript/operators/control-flow.adoc +230 -0
- data/docs/postscript/operators/dictionary.adoc +191 -0
- data/docs/postscript/operators/graphics-state.adoc +528 -0
- data/docs/postscript/operators/index.adoc +288 -0
- data/docs/postscript/operators/painting.adoc +475 -0
- data/docs/postscript/operators/path-construction.adoc +553 -0
- data/docs/postscript/operators/stack-manipulation.adoc +374 -0
- data/docs/postscript/operators/transformations.adoc +479 -0
- data/docs/postscript/svg-mapping.adoc +369 -0
- data/exe/postsvg +6 -0
- data/lib/postsvg/cli.rb +103 -0
- data/lib/postsvg/colors.rb +33 -0
- data/lib/postsvg/converter.rb +214 -0
- data/lib/postsvg/errors.rb +11 -0
- data/lib/postsvg/graphics_state.rb +158 -0
- data/lib/postsvg/interpreter.rb +891 -0
- data/lib/postsvg/matrix.rb +106 -0
- data/lib/postsvg/parser/postscript_parser.rb +87 -0
- data/lib/postsvg/parser/transform.rb +21 -0
- data/lib/postsvg/parser.rb +18 -0
- data/lib/postsvg/path_builder.rb +101 -0
- data/lib/postsvg/svg_generator.rb +78 -0
- data/lib/postsvg/tokenizer.rb +161 -0
- data/lib/postsvg/version.rb +5 -0
- data/lib/postsvg.rb +78 -0
- data/postsvg.gemspec +38 -0
- data/scripts/regenerate_fixtures.rb +28 -0
- metadata +118 -0
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
= Control Flow Operators
|
|
2
|
+
|
|
3
|
+
== General
|
|
4
|
+
|
|
5
|
+
Control flow operators enable conditional execution, loops, and procedure
|
|
6
|
+
execution in PostScript programs. These operators use procedures (executable
|
|
7
|
+
arrays enclosed in curly braces) to define code blocks.
|
|
8
|
+
|
|
9
|
+
[[if]]
|
|
10
|
+
== if
|
|
11
|
+
|
|
12
|
+
=== General
|
|
13
|
+
|
|
14
|
+
The `if` operator executes a procedure if a boolean condition is true.
|
|
15
|
+
|
|
16
|
+
=== Syntax
|
|
17
|
+
|
|
18
|
+
[source,postscript]
|
|
19
|
+
----
|
|
20
|
+
bool {procedure} if <1> <2> <3>
|
|
21
|
+
----
|
|
22
|
+
<1> Boolean value (true or false)
|
|
23
|
+
<2> Procedure to execute if true
|
|
24
|
+
<3> Operator that conditionally executes
|
|
25
|
+
|
|
26
|
+
Where,
|
|
27
|
+
|
|
28
|
+
`bool`:: Boolean value (true or false)
|
|
29
|
+
`procedure`:: Code to execute if bool is true
|
|
30
|
+
|
|
31
|
+
Stack effect: `bool proc -- `
|
|
32
|
+
|
|
33
|
+
=== Examples
|
|
34
|
+
|
|
35
|
+
[example]
|
|
36
|
+
====
|
|
37
|
+
[source,postscript]
|
|
38
|
+
----
|
|
39
|
+
5 3 gt { % If 5 > 3
|
|
40
|
+
(5 is greater) show
|
|
41
|
+
} if
|
|
42
|
+
----
|
|
43
|
+
|
|
44
|
+
Executes procedure only when condition is true.
|
|
45
|
+
====
|
|
46
|
+
|
|
47
|
+
[[ifelse]]
|
|
48
|
+
== ifelse
|
|
49
|
+
|
|
50
|
+
=== General
|
|
51
|
+
|
|
52
|
+
The `ifelse` operator executes one procedure if true, another if false.
|
|
53
|
+
|
|
54
|
+
=== Syntax
|
|
55
|
+
|
|
56
|
+
[source,postscript]
|
|
57
|
+
----
|
|
58
|
+
bool {proc1} {proc2} ifelse <1> <2> <3> <4>
|
|
59
|
+
----
|
|
60
|
+
<1> Boolean condition
|
|
61
|
+
<2> Procedure for true case
|
|
62
|
+
<3> Procedure for false case
|
|
63
|
+
<4> Operator that branches
|
|
64
|
+
|
|
65
|
+
Where,
|
|
66
|
+
|
|
67
|
+
`bool`:: Boolean value
|
|
68
|
+
`proc1`:: Execute if true
|
|
69
|
+
`proc2`:: Execute if false
|
|
70
|
+
|
|
71
|
+
Stack effect: `bool proc1 proc2 -- `
|
|
72
|
+
|
|
73
|
+
=== Examples
|
|
74
|
+
|
|
75
|
+
[example]
|
|
76
|
+
====
|
|
77
|
+
[source,postscript]
|
|
78
|
+
----
|
|
79
|
+
x 0 lt {
|
|
80
|
+
x neg % Absolute value
|
|
81
|
+
} {
|
|
82
|
+
x
|
|
83
|
+
} ifelse
|
|
84
|
+
----
|
|
85
|
+
|
|
86
|
+
Conditional branching.
|
|
87
|
+
====
|
|
88
|
+
|
|
89
|
+
[[for]]
|
|
90
|
+
== for
|
|
91
|
+
|
|
92
|
+
=== General
|
|
93
|
+
|
|
94
|
+
The `for` operator executes a procedure for each value in a numeric range.
|
|
95
|
+
|
|
96
|
+
=== Syntax
|
|
97
|
+
|
|
98
|
+
[source,postscript]
|
|
99
|
+
----
|
|
100
|
+
initial increment limit {procedure} for <1> <2> <3> <4> <5>
|
|
101
|
+
----
|
|
102
|
+
<1> Starting value
|
|
103
|
+
<2> Increment value
|
|
104
|
+
<3> Ending value (inclusive)
|
|
105
|
+
<4> Procedure to execute
|
|
106
|
+
<5> Loop operator
|
|
107
|
+
|
|
108
|
+
Where,
|
|
109
|
+
|
|
110
|
+
`initial`:: Starting value (number)
|
|
111
|
+
`increment`:: Step size (number)
|
|
112
|
+
`limit`:: Ending value (number)
|
|
113
|
+
`procedure`:: Code to execute (receives current value)
|
|
114
|
+
|
|
115
|
+
Stack effect: `init incr limit proc -- `
|
|
116
|
+
|
|
117
|
+
=== Examples
|
|
118
|
+
|
|
119
|
+
[example]
|
|
120
|
+
====
|
|
121
|
+
[source,postscript]
|
|
122
|
+
----
|
|
123
|
+
1 1 10 { % Loop from 1 to 10, step 1
|
|
124
|
+
dup mul % Square each number
|
|
125
|
+
= % Print
|
|
126
|
+
} for
|
|
127
|
+
----
|
|
128
|
+
|
|
129
|
+
Prints squares 1, 4, 9, ..., 100.
|
|
130
|
+
====
|
|
131
|
+
|
|
132
|
+
[[repeat]]
|
|
133
|
+
== repeat
|
|
134
|
+
|
|
135
|
+
=== General
|
|
136
|
+
|
|
137
|
+
The `repeat` operator executes a procedure a specified number of times.
|
|
138
|
+
|
|
139
|
+
=== Syntax
|
|
140
|
+
|
|
141
|
+
[source,postscript]
|
|
142
|
+
----
|
|
143
|
+
n {procedure} repeat <1> <2> <3>
|
|
144
|
+
----
|
|
145
|
+
<1> Number of iterations
|
|
146
|
+
<2> Procedure to execute
|
|
147
|
+
<3> Repeat operator
|
|
148
|
+
|
|
149
|
+
Where,
|
|
150
|
+
|
|
151
|
+
`n`:: Number of times to execute (integer)
|
|
152
|
+
`procedure`:: Code to execute
|
|
153
|
+
|
|
154
|
+
Stack effect: `n proc -- `
|
|
155
|
+
|
|
156
|
+
=== Examples
|
|
157
|
+
|
|
158
|
+
[example]
|
|
159
|
+
====
|
|
160
|
+
[source,postscript]
|
|
161
|
+
----
|
|
162
|
+
5 {
|
|
163
|
+
(Hello) show
|
|
164
|
+
} repeat
|
|
165
|
+
----
|
|
166
|
+
|
|
167
|
+
Executes procedure 5 times.
|
|
168
|
+
====
|
|
169
|
+
|
|
170
|
+
[[loop]]
|
|
171
|
+
== loop
|
|
172
|
+
|
|
173
|
+
=== General
|
|
174
|
+
|
|
175
|
+
The `loop` operator executes a procedure indefinitely until `exit` is called.
|
|
176
|
+
|
|
177
|
+
=== Syntax
|
|
178
|
+
|
|
179
|
+
[source,postscript]
|
|
180
|
+
----
|
|
181
|
+
{procedure} loop <1> <2>
|
|
182
|
+
----
|
|
183
|
+
<1> Procedure to execute repeatedly
|
|
184
|
+
<2> Loop operator
|
|
185
|
+
|
|
186
|
+
Where,
|
|
187
|
+
|
|
188
|
+
`procedure`:: Code to execute (must contain `exit` to terminate)
|
|
189
|
+
|
|
190
|
+
Stack effect: `proc -- `
|
|
191
|
+
|
|
192
|
+
=== Examples
|
|
193
|
+
|
|
194
|
+
[example]
|
|
195
|
+
====
|
|
196
|
+
[source,postscript]
|
|
197
|
+
----
|
|
198
|
+
0 % Counter
|
|
199
|
+
{
|
|
200
|
+
dup 10 ge {exit} if % Exit when >= 10
|
|
201
|
+
1 add % Increment
|
|
202
|
+
} loop
|
|
203
|
+
----
|
|
204
|
+
|
|
205
|
+
Infinite loop with exit condition.
|
|
206
|
+
====
|
|
207
|
+
|
|
208
|
+
[[exit]]
|
|
209
|
+
== exit
|
|
210
|
+
|
|
211
|
+
=== General
|
|
212
|
+
|
|
213
|
+
The `exit` operator terminates the innermost enclosing loop (`for`, `repeat`,
|
|
214
|
+
or `loop`).
|
|
215
|
+
|
|
216
|
+
=== Syntax
|
|
217
|
+
|
|
218
|
+
[source,postscript]
|
|
219
|
+
----
|
|
220
|
+
exit <1>
|
|
221
|
+
----
|
|
222
|
+
<1> Exit from loop
|
|
223
|
+
|
|
224
|
+
Stack effect: `-- `
|
|
225
|
+
|
|
226
|
+
== See Also
|
|
227
|
+
|
|
228
|
+
* link:../fundamentals.adoc#execution-model[Execution Model]
|
|
229
|
+
* link:dictionary.adoc[Dictionary Operators]
|
|
230
|
+
* link:index.adoc[Back to Operator Reference]
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
= Dictionary Operators
|
|
2
|
+
|
|
3
|
+
== General
|
|
4
|
+
|
|
5
|
+
Dictionary operators manage PostScript dictionaries, which are associative
|
|
6
|
+
arrays that map keys to values. Dictionaries implement variable storage and
|
|
7
|
+
scoping in PostScript.
|
|
8
|
+
|
|
9
|
+
[[def]]
|
|
10
|
+
== def
|
|
11
|
+
|
|
12
|
+
=== General
|
|
13
|
+
|
|
14
|
+
The `def` operator defines a key-value pair in the current dictionary (the
|
|
15
|
+
topmost dictionary on the dictionary stack).
|
|
16
|
+
|
|
17
|
+
=== Syntax
|
|
18
|
+
|
|
19
|
+
[source,postscript]
|
|
20
|
+
----
|
|
21
|
+
key value def <1> <2> <3>
|
|
22
|
+
----
|
|
23
|
+
<1> Key (typically a literal name)
|
|
24
|
+
<2> Value (any PostScript object)
|
|
25
|
+
<3> Operator that stores the association
|
|
26
|
+
|
|
27
|
+
Where,
|
|
28
|
+
|
|
29
|
+
`key`:: Key for the entry (typically a name)
|
|
30
|
+
`value`:: Value to associate with the key
|
|
31
|
+
|
|
32
|
+
Stack effect: `key value -- `
|
|
33
|
+
|
|
34
|
+
=== Examples
|
|
35
|
+
|
|
36
|
+
[example]
|
|
37
|
+
====
|
|
38
|
+
[source,postscript]
|
|
39
|
+
----
|
|
40
|
+
/x 100 def % Define x = 100
|
|
41
|
+
/mycolor [1 0 0] def % Define color array
|
|
42
|
+
----
|
|
43
|
+
|
|
44
|
+
Creates variables in the current dictionary.
|
|
45
|
+
====
|
|
46
|
+
|
|
47
|
+
[[dict]]
|
|
48
|
+
== dict
|
|
49
|
+
|
|
50
|
+
=== General
|
|
51
|
+
|
|
52
|
+
The `dict` operator creates a new dictionary with space for n key-value pairs.
|
|
53
|
+
|
|
54
|
+
=== Syntax
|
|
55
|
+
|
|
56
|
+
[source,postscript]
|
|
57
|
+
----
|
|
58
|
+
int dict <1> <2>
|
|
59
|
+
----
|
|
60
|
+
<1> Initial capacity (number of entries)
|
|
61
|
+
<2> Operator that creates dictionary
|
|
62
|
+
|
|
63
|
+
Where,
|
|
64
|
+
|
|
65
|
+
`int`:: Initial capacity (integer)
|
|
66
|
+
|
|
67
|
+
Stack effect: `int -- dict`
|
|
68
|
+
|
|
69
|
+
=== Examples
|
|
70
|
+
|
|
71
|
+
[example]
|
|
72
|
+
====
|
|
73
|
+
[source,postscript]
|
|
74
|
+
----
|
|
75
|
+
20 dict % Create dictionary for 20 entries
|
|
76
|
+
----
|
|
77
|
+
|
|
78
|
+
The dictionary grows automatically if needed.
|
|
79
|
+
====
|
|
80
|
+
|
|
81
|
+
[[begin]]
|
|
82
|
+
== begin
|
|
83
|
+
|
|
84
|
+
=== General
|
|
85
|
+
|
|
86
|
+
The `begin` operator pushes a dictionary onto the dictionary stack, making it
|
|
87
|
+
the current dictionary for name lookups and `def` operations.
|
|
88
|
+
|
|
89
|
+
=== Syntax
|
|
90
|
+
|
|
91
|
+
[source,postscript]
|
|
92
|
+
----
|
|
93
|
+
dict begin <1> <2>
|
|
94
|
+
----
|
|
95
|
+
<1> Dictionary to activate
|
|
96
|
+
<2> Operator that pushes dictionary
|
|
97
|
+
|
|
98
|
+
Where,
|
|
99
|
+
|
|
100
|
+
`dict`:: Dictionary to make current
|
|
101
|
+
|
|
102
|
+
Stack effect: `dict -- `
|
|
103
|
+
|
|
104
|
+
=== Examples
|
|
105
|
+
|
|
106
|
+
[example]
|
|
107
|
+
====
|
|
108
|
+
[source,postscript]
|
|
109
|
+
----
|
|
110
|
+
10 dict begin % Create and activate new scope
|
|
111
|
+
/x 5 def % Define in local dictionary
|
|
112
|
+
/y 10 def
|
|
113
|
+
x y add % Use local variables
|
|
114
|
+
end % Exit scope
|
|
115
|
+
----
|
|
116
|
+
|
|
117
|
+
Creates a local variable scope.
|
|
118
|
+
====
|
|
119
|
+
|
|
120
|
+
[[end]]
|
|
121
|
+
== end
|
|
122
|
+
|
|
123
|
+
=== General
|
|
124
|
+
|
|
125
|
+
The `end` operator pops the topmost dictionary from the dictionary stack,
|
|
126
|
+
ending the current scope.
|
|
127
|
+
|
|
128
|
+
=== Syntax
|
|
129
|
+
|
|
130
|
+
[source,postscript]
|
|
131
|
+
----
|
|
132
|
+
end <1>
|
|
133
|
+
----
|
|
134
|
+
<1> Operator that pops dictionary
|
|
135
|
+
|
|
136
|
+
Stack effect: `-- `
|
|
137
|
+
|
|
138
|
+
=== Examples
|
|
139
|
+
|
|
140
|
+
See `begin` example above.
|
|
141
|
+
|
|
142
|
+
== Dictionary Usage Patterns
|
|
143
|
+
|
|
144
|
+
=== Local variables
|
|
145
|
+
|
|
146
|
+
[example]
|
|
147
|
+
====
|
|
148
|
+
[source,postscript]
|
|
149
|
+
----
|
|
150
|
+
% Define a procedure with local variables
|
|
151
|
+
/myproc {
|
|
152
|
+
10 dict begin % Local scope
|
|
153
|
+
/a exch def % Store parameters
|
|
154
|
+
/b exch def
|
|
155
|
+
a b add % Use locals
|
|
156
|
+
end % Clean up scope
|
|
157
|
+
} def
|
|
158
|
+
|
|
159
|
+
% Call with arguments
|
|
160
|
+
5 3 myproc % Returns 8
|
|
161
|
+
----
|
|
162
|
+
|
|
163
|
+
Procedures often use local dictionaries for parameters.
|
|
164
|
+
====
|
|
165
|
+
|
|
166
|
+
=== Configuration dictionaries
|
|
167
|
+
|
|
168
|
+
[example]
|
|
169
|
+
====
|
|
170
|
+
[source,postscript]
|
|
171
|
+
----
|
|
172
|
+
% Create configuration
|
|
173
|
+
/config 5 dict def
|
|
174
|
+
config begin
|
|
175
|
+
/width 100 def
|
|
176
|
+
/height 200 def
|
|
177
|
+
/color [1 0 0] def
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
% Use configuration
|
|
181
|
+
config /width get % Retrieve width
|
|
182
|
+
----
|
|
183
|
+
|
|
184
|
+
Dictionaries as data structures.
|
|
185
|
+
====
|
|
186
|
+
|
|
187
|
+
== See Also
|
|
188
|
+
|
|
189
|
+
* link:../fundamentals.adoc#dictionaries-and-scopes[Dictionaries and Scopes]
|
|
190
|
+
* link:control-flow.adoc[Control Flow]
|
|
191
|
+
* link:index.adoc[Back to Operator Reference]
|