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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +105 -0
- data/CLAUDE.md +173 -0
- data/Gemfile +2 -3
- data/README.adoc +456 -179
- data/Rakefile +100 -0
- data/TODO.roadmap/00-architecture.md +139 -0
- data/TODO.roadmap/01-autoload-migration.md +39 -0
- data/TODO.roadmap/02-isolate-dormant-code.md +51 -0
- data/TODO.roadmap/03-domain-model.md +66 -0
- data/TODO.roadmap/04-lexer.md +40 -0
- data/TODO.roadmap/05-parser.md +43 -0
- data/TODO.roadmap/06-graphics-state.md +45 -0
- data/TODO.roadmap/07-matrix-and-color.md +37 -0
- data/TODO.roadmap/08-svg-builder.md +51 -0
- data/TODO.roadmap/09-renderer.md +52 -0
- data/TODO.roadmap/10-visitor.md +58 -0
- data/TODO.roadmap/11-operator-coverage.md +103 -0
- data/TODO.roadmap/12-svg-domain.md +62 -0
- data/TODO.roadmap/13-translation-handlers.md +69 -0
- data/TODO.roadmap/14-ps-serializer.md +49 -0
- data/TODO.roadmap/15-cli-and-public-api.md +47 -0
- data/TODO.roadmap/16-specs.md +84 -0
- data/TODO.roadmap/17-docs-sync.md +47 -0
- data/TODO.roadmap/18-performance-and-determinism.md +47 -0
- data/TODO.roadmap/19-error-model.md +45 -0
- data/TODO.roadmap/20-font-and-text.md +46 -0
- data/TODO.roadmap/21-images.md +45 -0
- data/TODO.roadmap/22-forms-and-resources.md +25 -0
- data/TODO.roadmap/23-level2-level3.md +52 -0
- data/TODO.roadmap/24-ci-and-release.md +42 -0
- data/TODO.roadmap/README.md +77 -0
- data/docs/.gitignore +29 -0
- data/docs/CHANGELOG.md +114 -0
- data/docs/COMPLETE_DOCUMENTATION_STATUS.md +376 -0
- data/docs/DEPLOYMENT.md +456 -0
- data/docs/DEPLOYMENT_INSTRUCTIONS.md +229 -0
- data/docs/DOCUMENTATION_PLAN.md +425 -0
- data/docs/FINAL_SUMMARY.md +657 -0
- data/docs/Gemfile +15 -0
- data/docs/README.md +327 -0
- data/docs/_config.yml +99 -0
- data/docs/advanced-topics.adoc +370 -0
- data/docs/api-reference/colors.adoc +705 -0
- data/docs/api-reference/converter.adoc +699 -0
- data/docs/api-reference/execution-context.adoc +1210 -0
- data/docs/api-reference/graphics-state.adoc +1070 -0
- data/docs/api-reference/interpreter.adoc +810 -0
- data/docs/api-reference/matrix.adoc +1179 -0
- data/docs/api-reference/path-builder.adoc +1284 -0
- data/docs/api-reference/postsvg-module.adoc +388 -0
- data/docs/api-reference/svg-generator.adoc +891 -0
- data/docs/api-reference/tokenizer.adoc +925 -0
- data/docs/api-reference.adoc +221 -0
- data/docs/architecture/command-registry.adoc +1191 -0
- data/docs/architecture/conversion-pipeline.adoc +746 -0
- data/docs/architecture/design-decisions.adoc +999 -0
- data/docs/architecture/generator-stage.adoc +1115 -0
- data/docs/architecture/graphics-state-model.adoc +1089 -0
- data/docs/architecture/interpreter-stage.adoc +1125 -0
- data/docs/architecture/parser-stage.adoc +1051 -0
- data/docs/architecture.adoc +354 -0
- data/docs/cli-reference/batch-command.adoc +616 -0
- data/docs/cli-reference/check-command.adoc +677 -0
- data/docs/cli-reference/cli-options.adoc +802 -0
- data/docs/cli-reference/convert-command.adoc +462 -0
- data/docs/cli-reference/version-command.adoc +296 -0
- data/docs/cli-reference.adoc +317 -0
- data/docs/concepts/conversion-pipeline.adoc +903 -0
- data/docs/concepts/coordinate-systems.adoc +836 -0
- data/docs/concepts/graphics-state.adoc +861 -0
- data/docs/concepts/path-operations.adoc +1076 -0
- data/docs/concepts/postscript-language.adoc +859 -0
- data/docs/concepts/svg-generation.adoc +937 -0
- data/docs/concepts.adoc +198 -0
- data/docs/contributing.adoc +443 -0
- data/docs/development.adoc +420 -0
- data/docs/faq.adoc +493 -0
- data/docs/getting-started/basic-usage.adoc +538 -0
- data/docs/getting-started/common-workflows.adoc +577 -0
- data/docs/getting-started/first-conversion.adoc +492 -0
- data/docs/getting-started/installation.adoc +534 -0
- data/docs/getting-started.adoc +94 -0
- data/docs/index.adoc +248 -0
- data/docs/optimization.adoc +196 -0
- data/docs/ps2svg_compatibility.adoc +149 -0
- data/docs/quick-reference.adoc +453 -0
- data/docs/sitemap.adoc +337 -0
- data/docs/troubleshooting.adoc +486 -0
- data/docs/validation.adoc +772 -0
- data/exe/postsvg +1 -0
- data/lib/postsvg/cli.rb +104 -57
- data/lib/postsvg/color.rb +132 -0
- data/lib/postsvg/errors.rb +68 -3
- data/lib/postsvg/format_number.rb +22 -0
- data/lib/postsvg/graphics_context.rb +80 -0
- data/lib/postsvg/graphics_stack.rb +43 -0
- data/lib/postsvg/model/literals/array.rb +41 -0
- data/lib/postsvg/model/literals/dictionary.rb +34 -0
- data/lib/postsvg/model/literals/hex.rb +37 -0
- data/lib/postsvg/model/literals/name.rb +40 -0
- data/lib/postsvg/model/literals/number.rb +36 -0
- data/lib/postsvg/model/literals/procedure.rb +41 -0
- data/lib/postsvg/model/literals/string.rb +30 -0
- data/lib/postsvg/model/literals.rb +19 -0
- data/lib/postsvg/model/operator.rb +58 -0
- data/lib/postsvg/model/operators/arithmetic.rb +264 -0
- data/lib/postsvg/model/operators/boolean.rb +182 -0
- data/lib/postsvg/model/operators/color.rb +74 -0
- data/lib/postsvg/model/operators/container.rb +186 -0
- data/lib/postsvg/model/operators/control_flow.rb +119 -0
- data/lib/postsvg/model/operators/device.rb +21 -0
- data/lib/postsvg/model/operators/dictionary.rb +118 -0
- data/lib/postsvg/model/operators/font.rb +121 -0
- data/lib/postsvg/model/operators/graphics_state.rb +84 -0
- data/lib/postsvg/model/operators/painting.rb +29 -0
- data/lib/postsvg/model/operators/path.rb +169 -0
- data/lib/postsvg/model/operators/stack.rb +72 -0
- data/lib/postsvg/model/operators/transformations.rb +103 -0
- data/lib/postsvg/model/operators.rb +89 -0
- data/lib/postsvg/model/program.rb +68 -0
- data/lib/postsvg/model/token.rb +43 -0
- data/lib/postsvg/model.rb +17 -0
- data/lib/postsvg/options.rb +29 -0
- data/lib/postsvg/renderer.rb +85 -0
- data/lib/postsvg/serializer.rb +325 -0
- data/lib/postsvg/source/ast_builder.rb +308 -0
- data/lib/postsvg/source/lexer.rb +322 -0
- data/lib/postsvg/source/operand_stack.rb +55 -0
- data/lib/postsvg/source.rb +21 -0
- data/lib/postsvg/svg/attribute_parser.rb +45 -0
- data/lib/postsvg/svg/clip_path_registry.rb +44 -0
- data/lib/postsvg/svg/document.rb +22 -0
- data/lib/postsvg/svg/element.rb +84 -0
- data/lib/postsvg/svg/elements/circle.rb +36 -0
- data/lib/postsvg/svg/elements/clip_path.rb +26 -0
- data/lib/postsvg/svg/elements/defs.rb +24 -0
- data/lib/postsvg/svg/elements/ellipse.rb +38 -0
- data/lib/postsvg/svg/elements/group.rb +37 -0
- data/lib/postsvg/svg/elements/image.rb +35 -0
- data/lib/postsvg/svg/elements/line.rb +36 -0
- data/lib/postsvg/svg/elements/path.rb +32 -0
- data/lib/postsvg/svg/elements/polygon.rb +12 -0
- data/lib/postsvg/svg/elements/polyline.rb +32 -0
- data/lib/postsvg/svg/elements/rect.rb +44 -0
- data/lib/postsvg/svg/elements/svg.rb +39 -0
- data/lib/postsvg/svg/elements/text.rb +42 -0
- data/lib/postsvg/svg/elements.rb +31 -0
- data/lib/postsvg/svg/paint.rb +34 -0
- data/lib/postsvg/svg/parser.rb +39 -0
- data/lib/postsvg/svg/path_data/command.rb +27 -0
- data/lib/postsvg/svg/path_data/parser.rb +82 -0
- data/lib/postsvg/svg/path_data.rb +17 -0
- data/lib/postsvg/svg/stroke.rb +31 -0
- data/lib/postsvg/svg/transform_list.rb +59 -0
- data/lib/postsvg/svg.rb +22 -0
- data/lib/postsvg/svg_builder.rb +249 -0
- data/lib/postsvg/translation/arc_converter.rb +86 -0
- data/lib/postsvg/translation/bounding_box.rb +59 -0
- data/lib/postsvg/translation/context.rb +34 -0
- data/lib/postsvg/translation/handler_registry.rb +38 -0
- data/lib/postsvg/translation/handlers/circle_handler.rb +28 -0
- data/lib/postsvg/translation/handlers/clip_path_handler.rb +13 -0
- data/lib/postsvg/translation/handlers/defs_handler.rb +15 -0
- data/lib/postsvg/translation/handlers/ellipse_handler.rb +31 -0
- data/lib/postsvg/translation/handlers/group_handler.rb +21 -0
- data/lib/postsvg/translation/handlers/image_handler.rb +20 -0
- data/lib/postsvg/translation/handlers/line_handler.rb +23 -0
- data/lib/postsvg/translation/handlers/open_handler.rb +18 -0
- data/lib/postsvg/translation/handlers/path_handler.rb +356 -0
- data/lib/postsvg/translation/handlers/polygon_handler.rb +33 -0
- data/lib/postsvg/translation/handlers/polyline_handler.rb +31 -0
- data/lib/postsvg/translation/handlers/rect_handler.rb +27 -0
- data/lib/postsvg/translation/handlers/shared.rb +110 -0
- data/lib/postsvg/translation/handlers/svg_handler.rb +25 -0
- data/lib/postsvg/translation/handlers/text_handler.rb +56 -0
- data/lib/postsvg/translation/handlers.rb +25 -0
- data/lib/postsvg/translation/ps_renderer.rb +105 -0
- data/lib/postsvg/translation/record_emitter.rb +35 -0
- data/lib/postsvg/translation.rb +17 -0
- data/lib/postsvg/version.rb +1 -1
- data/lib/postsvg/visitors/ps_visitor/arithmetic.rb +125 -0
- data/lib/postsvg/visitors/ps_visitor/boolean.rb +105 -0
- data/lib/postsvg/visitors/ps_visitor/color.rb +53 -0
- data/lib/postsvg/visitors/ps_visitor/common.rb +66 -0
- data/lib/postsvg/visitors/ps_visitor/container.rb +164 -0
- data/lib/postsvg/visitors/ps_visitor/control_flow.rb +110 -0
- data/lib/postsvg/visitors/ps_visitor/device.rb +20 -0
- data/lib/postsvg/visitors/ps_visitor/dictionary.rb +89 -0
- data/lib/postsvg/visitors/ps_visitor/font.rb +93 -0
- data/lib/postsvg/visitors/ps_visitor/graphics_state.rb +55 -0
- data/lib/postsvg/visitors/ps_visitor/painting.rb +90 -0
- data/lib/postsvg/visitors/ps_visitor/path.rb +112 -0
- data/lib/postsvg/visitors/ps_visitor/stack.rb +47 -0
- data/lib/postsvg/visitors/ps_visitor/transformations.rb +101 -0
- data/lib/postsvg/visitors/ps_visitor.rb +208 -0
- data/lib/postsvg/visitors.rb +9 -0
- data/lib/postsvg.rb +93 -59
- data/lychee.toml +86 -0
- metadata +216 -11
- data/postsvg.gemspec +0 -38
|
@@ -0,0 +1,859 @@
|
|
|
1
|
+
= PostScript Language Fundamentals
|
|
2
|
+
:page-nav_order: 6
|
|
3
|
+
:page-parent: Core Concepts
|
|
4
|
+
|
|
5
|
+
== Purpose
|
|
6
|
+
|
|
7
|
+
This document provides an introduction to the PostScript language fundamentals that are essential for understanding how Postsvg interprets PostScript code. While not a complete PostScript reference, it covers the core concepts needed to work effectively with Postsvg.
|
|
8
|
+
|
|
9
|
+
== References
|
|
10
|
+
|
|
11
|
+
* link:../index.adoc[Documentation Home]
|
|
12
|
+
* link:../concepts.adoc[Core Concepts Overview]
|
|
13
|
+
* link:conversion-pipeline.adoc[Conversion Pipeline]
|
|
14
|
+
* link:path-operations.adoc[Path Operations]
|
|
15
|
+
* link:graphics-state.adoc[Graphics State Management]
|
|
16
|
+
|
|
17
|
+
== Concepts
|
|
18
|
+
|
|
19
|
+
**Stack-Based Execution**:: PostScript uses a Last-In-First-Out (LIFO) stack for storing and manipulating values.
|
|
20
|
+
|
|
21
|
+
**Postfix Notation**:: Operators follow their operands (reverse Polish notation).
|
|
22
|
+
|
|
23
|
+
**Operator**:: A command that performs an operation, typically consuming operands from the stack.
|
|
24
|
+
|
|
25
|
+
**Operand**:: A value (number, string, array, etc.) that operators work with.
|
|
26
|
+
|
|
27
|
+
**Dictionary**:: A key-value data structure for storing definitions and variables.
|
|
28
|
+
|
|
29
|
+
== PostScript Language Overview
|
|
30
|
+
|
|
31
|
+
=== What is PostScript?
|
|
32
|
+
|
|
33
|
+
PostScript is a page description language developed by Adobe Systems in 1984. It's:
|
|
34
|
+
|
|
35
|
+
* **Stack-based** - Uses a LIFO stack for operations
|
|
36
|
+
* **Interpreted** - Executed line-by-line or token-by-token
|
|
37
|
+
* **Turing-complete** - Can perform any computation
|
|
38
|
+
* **Device-independent** - Same code produces same result on any device
|
|
39
|
+
|
|
40
|
+
**Primary Uses:**
|
|
41
|
+
|
|
42
|
+
* Printer control language
|
|
43
|
+
* Vector graphics description
|
|
44
|
+
* Font rendering
|
|
45
|
+
* Page layout for professional printing
|
|
46
|
+
|
|
47
|
+
=== PostScript vs. Other Languages
|
|
48
|
+
|
|
49
|
+
.Language Comparison
|
|
50
|
+
[source]
|
|
51
|
+
----
|
|
52
|
+
Infix (Most Languages): PostScript (Postfix):
|
|
53
|
+
a = 2 + 3 2 3 add
|
|
54
|
+
result = (a + b) * c a b add c mul
|
|
55
|
+
if (x > 0) { ... } x 0 gt { ... } if
|
|
56
|
+
----
|
|
57
|
+
|
|
58
|
+
**Advantages of Postfix:**
|
|
59
|
+
|
|
60
|
+
* No operator precedence ambiguity
|
|
61
|
+
* No parentheses needed for grouping
|
|
62
|
+
* Natural for stack-based execution
|
|
63
|
+
* Efficient for interpreters
|
|
64
|
+
|
|
65
|
+
== Stack Model
|
|
66
|
+
|
|
67
|
+
=== The Operand Stack
|
|
68
|
+
|
|
69
|
+
The **operand stack** is the primary data structure in PostScript execution.
|
|
70
|
+
|
|
71
|
+
.Stack Visualization
|
|
72
|
+
[source]
|
|
73
|
+
----
|
|
74
|
+
Bottom of Stack
|
|
75
|
+
│
|
|
76
|
+
▼
|
|
77
|
+
┌─────┐
|
|
78
|
+
│ 10 │ ← First value pushed
|
|
79
|
+
├─────┤
|
|
80
|
+
│ 20 │ ← Second value pushed
|
|
81
|
+
├─────┤
|
|
82
|
+
│ 30 │ ← Third value pushed (top)
|
|
83
|
+
└─────┘
|
|
84
|
+
▲
|
|
85
|
+
│
|
|
86
|
+
Top of Stack
|
|
87
|
+
----
|
|
88
|
+
|
|
89
|
+
**Stack Operations:**
|
|
90
|
+
|
|
91
|
+
* **Push** - Add value to top
|
|
92
|
+
* **Pop** - Remove value from top
|
|
93
|
+
* **Peek** - Look at top value without removing
|
|
94
|
+
|
|
95
|
+
=== Stack Execution Example
|
|
96
|
+
|
|
97
|
+
.Stack Evolution
|
|
98
|
+
[example]
|
|
99
|
+
====
|
|
100
|
+
[source,postscript]
|
|
101
|
+
----
|
|
102
|
+
10 % Push 10
|
|
103
|
+
20 % Push 20
|
|
104
|
+
add % Pop 20 and 10, push 30
|
|
105
|
+
3 % Push 3
|
|
106
|
+
mul % Pop 3 and 30, push 90
|
|
107
|
+
----
|
|
108
|
+
|
|
109
|
+
Step-by-step stack evolution:
|
|
110
|
+
|
|
111
|
+
[source]
|
|
112
|
+
----
|
|
113
|
+
Command Stack State Operation
|
|
114
|
+
─────────────────────────────────────────
|
|
115
|
+
10 [10] Push 10
|
|
116
|
+
20 [10, 20] Push 20
|
|
117
|
+
add [30] Pop 20,10 → Push 10+20
|
|
118
|
+
3 [30, 3] Push 3
|
|
119
|
+
mul [90] Pop 3,30 → Push 30×3
|
|
120
|
+
----
|
|
121
|
+
|
|
122
|
+
Final result: 90 on stack
|
|
123
|
+
====
|
|
124
|
+
|
|
125
|
+
=== Stack Manipulation Operators
|
|
126
|
+
|
|
127
|
+
**Basic Stack Operations:**
|
|
128
|
+
|
|
129
|
+
`pop`:: Remove top item
|
|
130
|
+
|
|
131
|
+
[source,postscript]
|
|
132
|
+
----
|
|
133
|
+
10 20 pop % Stack: [10]
|
|
134
|
+
----
|
|
135
|
+
|
|
136
|
+
`dup`:: Duplicate top item
|
|
137
|
+
|
|
138
|
+
[source,postscript]
|
|
139
|
+
----
|
|
140
|
+
10 dup % Stack: [10, 10]
|
|
141
|
+
----
|
|
142
|
+
|
|
143
|
+
`exch`:: Exchange top two items
|
|
144
|
+
|
|
145
|
+
[source,postscript]
|
|
146
|
+
----
|
|
147
|
+
10 20 exch % Stack: [20, 10]
|
|
148
|
+
----
|
|
149
|
+
|
|
150
|
+
`roll`:: Rotate n items j times
|
|
151
|
+
|
|
152
|
+
[source,postscript]
|
|
153
|
+
----
|
|
154
|
+
1 2 3 4 5 % Stack: [1,2,3,4,5]
|
|
155
|
+
3 1 roll % Rotate top 3 items once
|
|
156
|
+
% Stack: [1,2,5,3,4]
|
|
157
|
+
----
|
|
158
|
+
|
|
159
|
+
`copy`:: Duplicate top n items
|
|
160
|
+
|
|
161
|
+
[source,postscript]
|
|
162
|
+
----
|
|
163
|
+
10 20 30 % Stack: [10,20,30]
|
|
164
|
+
2 copy % Stack: [10,20,30,20,30]
|
|
165
|
+
----
|
|
166
|
+
|
|
167
|
+
`index`:: Copy nth item to top
|
|
168
|
+
|
|
169
|
+
[source,postscript]
|
|
170
|
+
----
|
|
171
|
+
10 20 30 40 % Stack: [10,20,30,40]
|
|
172
|
+
2 index % Stack: [10,20,30,40,20]
|
|
173
|
+
----
|
|
174
|
+
|
|
175
|
+
`clear`:: Clear entire stack
|
|
176
|
+
|
|
177
|
+
[source,postscript]
|
|
178
|
+
----
|
|
179
|
+
1 2 3 4 5 % Stack: [1,2,3,4,5]
|
|
180
|
+
clear % Stack: []
|
|
181
|
+
----
|
|
182
|
+
|
|
183
|
+
`count`:: Count items on stack
|
|
184
|
+
|
|
185
|
+
[source,postscript]
|
|
186
|
+
----
|
|
187
|
+
10 20 30 % Stack: [10,20,30]
|
|
188
|
+
count % Stack: [10,20,30,3]
|
|
189
|
+
----
|
|
190
|
+
|
|
191
|
+
== Data Types
|
|
192
|
+
|
|
193
|
+
=== Numbers
|
|
194
|
+
|
|
195
|
+
**Integers:**
|
|
196
|
+
|
|
197
|
+
[source,postscript]
|
|
198
|
+
----
|
|
199
|
+
42 % Decimal integer
|
|
200
|
+
-17 % Negative integer
|
|
201
|
+
0 % Zero
|
|
202
|
+
16#FF % Hexadecimal (255 decimal)
|
|
203
|
+
8#77 % Octal (63 decimal)
|
|
204
|
+
----
|
|
205
|
+
|
|
206
|
+
**Real Numbers (Floats):**
|
|
207
|
+
|
|
208
|
+
[source,postscript]
|
|
209
|
+
----
|
|
210
|
+
3.14159 % Decimal float
|
|
211
|
+
-0.5 % Negative float
|
|
212
|
+
1.5e-3 % Scientific notation (0.0015)
|
|
213
|
+
6.02e23 % Large number
|
|
214
|
+
----
|
|
215
|
+
|
|
216
|
+
=== Strings
|
|
217
|
+
|
|
218
|
+
**Literal Strings:**
|
|
219
|
+
|
|
220
|
+
[source,postscript]
|
|
221
|
+
----
|
|
222
|
+
(Hello World) % Simple string
|
|
223
|
+
(Line 1\nLine 2) % With newline
|
|
224
|
+
(It's a nice day) % Single quotes OK
|
|
225
|
+
(Backslash: \\) % Escaped backslash
|
|
226
|
+
(Parentheses: \( and \)) % Escaped parens
|
|
227
|
+
----
|
|
228
|
+
|
|
229
|
+
**Hexadecimal Strings:**
|
|
230
|
+
|
|
231
|
+
[source,postscript]
|
|
232
|
+
----
|
|
233
|
+
<48656C6C6F> % "Hello" in hex
|
|
234
|
+
<> % Empty string
|
|
235
|
+
<48 65 6C> % Same as <48656C>
|
|
236
|
+
----
|
|
237
|
+
|
|
238
|
+
=== Names
|
|
239
|
+
|
|
240
|
+
Names start with `/` and are used for variables and dictionary keys:
|
|
241
|
+
|
|
242
|
+
[source,postscript]
|
|
243
|
+
----
|
|
244
|
+
/MyVariable % Name literal
|
|
245
|
+
/x % Short name
|
|
246
|
+
/CamelCase % Valid name
|
|
247
|
+
/with-dashes % Valid name
|
|
248
|
+
/name_123 % Valid name
|
|
249
|
+
----
|
|
250
|
+
|
|
251
|
+
=== Boolean
|
|
252
|
+
|
|
253
|
+
[source,postscript]
|
|
254
|
+
----
|
|
255
|
+
true % Boolean true
|
|
256
|
+
false % Boolean false
|
|
257
|
+
----
|
|
258
|
+
|
|
259
|
+
=== Arrays
|
|
260
|
+
|
|
261
|
+
**Array Syntax:**
|
|
262
|
+
|
|
263
|
+
[source,postscript]
|
|
264
|
+
----
|
|
265
|
+
[1 2 3 4 5] % Array of numbers
|
|
266
|
+
[/name1 /name2 /name3] % Array of names
|
|
267
|
+
[(Hello) (World)] % Array of strings
|
|
268
|
+
[1 (two) /three true] % Mixed types
|
|
269
|
+
[] % Empty array
|
|
270
|
+
----
|
|
271
|
+
|
|
272
|
+
**Nested Arrays:**
|
|
273
|
+
|
|
274
|
+
[source,postscript]
|
|
275
|
+
----
|
|
276
|
+
[[1 2] [3 4] [5 6]] % 2D array
|
|
277
|
+
[1 [2 [3 [4 [5]]]]] % Nested array
|
|
278
|
+
----
|
|
279
|
+
|
|
280
|
+
=== Procedures
|
|
281
|
+
|
|
282
|
+
Procedures are executable arrays enclosed in braces:
|
|
283
|
+
|
|
284
|
+
[source,postscript]
|
|
285
|
+
----
|
|
286
|
+
{ 2 mul } % Procedure: multiply by 2
|
|
287
|
+
{ dup mul } % Procedure: square (x → x²)
|
|
288
|
+
{ 100 100 moveto } % Graphics procedure
|
|
289
|
+
{ exch sub } % Subtract reversed (b a → a-b)
|
|
290
|
+
----
|
|
291
|
+
|
|
292
|
+
=== Dictionaries
|
|
293
|
+
|
|
294
|
+
Dictionaries store key-value pairs:
|
|
295
|
+
|
|
296
|
+
[source,postscript]
|
|
297
|
+
----
|
|
298
|
+
% Create dictionary with 10 entries
|
|
299
|
+
10 dict begin
|
|
300
|
+
/x 100 def
|
|
301
|
+
/y 200 def
|
|
302
|
+
/name (MyName) def
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
% Inline dictionary (PostScript Level 2+)
|
|
306
|
+
<< /x 100 /y 200 /name (MyName) >>
|
|
307
|
+
----
|
|
308
|
+
|
|
309
|
+
== Operators
|
|
310
|
+
|
|
311
|
+
=== Arithmetic Operators
|
|
312
|
+
|
|
313
|
+
**Basic Arithmetic:**
|
|
314
|
+
|
|
315
|
+
[source,postscript]
|
|
316
|
+
----
|
|
317
|
+
3 4 add % Addition: 3 + 4 = 7
|
|
318
|
+
10 3 sub % Subtraction: 10 - 3 = 7
|
|
319
|
+
5 6 mul % Multiplication: 5 × 6 = 30
|
|
320
|
+
20 4 div % Division: 20 ÷ 4 = 5
|
|
321
|
+
17 5 mod % Modulo: 17 % 5 = 2
|
|
322
|
+
----
|
|
323
|
+
|
|
324
|
+
**Advanced Math:**
|
|
325
|
+
|
|
326
|
+
[source,postscript]
|
|
327
|
+
----
|
|
328
|
+
25 sqrt % Square root: √25 = 5
|
|
329
|
+
2 8 exp % Exponentiation: 2⁸ = 256
|
|
330
|
+
45 sin % Sine (degrees)
|
|
331
|
+
45 cos % Cosine (degrees)
|
|
332
|
+
1 atan % Arctangent
|
|
333
|
+
100 ln % Natural logarithm
|
|
334
|
+
10 log % Base-10 logarithm
|
|
335
|
+
-5 abs % Absolute value: |-5| = 5
|
|
336
|
+
----
|
|
337
|
+
|
|
338
|
+
=== Comparison Operators
|
|
339
|
+
|
|
340
|
+
[source,postscript]
|
|
341
|
+
----
|
|
342
|
+
3 4 eq % Equal: false
|
|
343
|
+
3 3 eq % Equal: true
|
|
344
|
+
5 3 ne % Not equal: true
|
|
345
|
+
5 3 gt % Greater than: true
|
|
346
|
+
3 5 lt % Less than: true
|
|
347
|
+
5 5 ge % Greater or equal: true
|
|
348
|
+
3 5 le % Less or equal: true
|
|
349
|
+
----
|
|
350
|
+
|
|
351
|
+
=== Logical Operators
|
|
352
|
+
|
|
353
|
+
[source,postscript]
|
|
354
|
+
----
|
|
355
|
+
true true and % Logical AND: true
|
|
356
|
+
true false or % Logical OR: true
|
|
357
|
+
true not % Logical NOT: false
|
|
358
|
+
true false xor % Logical XOR: true
|
|
359
|
+
----
|
|
360
|
+
|
|
361
|
+
=== String Operators
|
|
362
|
+
|
|
363
|
+
[source,postscript]
|
|
364
|
+
----
|
|
365
|
+
(Hello) length % String length: 5
|
|
366
|
+
(Hello) 0 get % Get char at index 0: H
|
|
367
|
+
(Hello) (World) eq % String equality: false
|
|
368
|
+
----
|
|
369
|
+
|
|
370
|
+
=== Array Operators
|
|
371
|
+
|
|
372
|
+
[source,postscript]
|
|
373
|
+
----
|
|
374
|
+
[1 2 3 4] length % Array length: 4
|
|
375
|
+
[1 2 3] 1 get % Get element at index 1: 2
|
|
376
|
+
[10 20 30] 0 10 put % Set element 0 to 10
|
|
377
|
+
----
|
|
378
|
+
|
|
379
|
+
== Control Flow
|
|
380
|
+
|
|
381
|
+
=== Conditional Execution
|
|
382
|
+
|
|
383
|
+
**if:**
|
|
384
|
+
|
|
385
|
+
[source,postscript]
|
|
386
|
+
----
|
|
387
|
+
condition { true-actions } if
|
|
388
|
+
|
|
389
|
+
% Example:
|
|
390
|
+
x 0 gt { (Positive) print } if
|
|
391
|
+
----
|
|
392
|
+
|
|
393
|
+
**ifelse:**
|
|
394
|
+
|
|
395
|
+
[source,postscript]
|
|
396
|
+
----
|
|
397
|
+
condition { true-actions } { false-actions } ifelse
|
|
398
|
+
|
|
399
|
+
% Example:
|
|
400
|
+
x 0 gt
|
|
401
|
+
{ (Positive) print }
|
|
402
|
+
{ (Not positive) print }
|
|
403
|
+
ifelse
|
|
404
|
+
----
|
|
405
|
+
|
|
406
|
+
.Conditional Example
|
|
407
|
+
[example]
|
|
408
|
+
====
|
|
409
|
+
[source,postscript]
|
|
410
|
+
----
|
|
411
|
+
/x 10 def
|
|
412
|
+
|
|
413
|
+
% Test if x is positive
|
|
414
|
+
x 0 gt
|
|
415
|
+
{
|
|
416
|
+
% x > 0
|
|
417
|
+
x 0 moveto
|
|
418
|
+
x x lineto
|
|
419
|
+
stroke
|
|
420
|
+
}
|
|
421
|
+
{
|
|
422
|
+
% x ≤ 0
|
|
423
|
+
(x is not positive) print
|
|
424
|
+
}
|
|
425
|
+
ifelse
|
|
426
|
+
----
|
|
427
|
+
====
|
|
428
|
+
|
|
429
|
+
=== Loops
|
|
430
|
+
|
|
431
|
+
**repeat:**
|
|
432
|
+
|
|
433
|
+
[source,postscript]
|
|
434
|
+
----
|
|
435
|
+
n { actions } repeat
|
|
436
|
+
|
|
437
|
+
% Example: Print 1 to 5
|
|
438
|
+
1 1 5 { dup = 1 add } repeat pop
|
|
439
|
+
----
|
|
440
|
+
|
|
441
|
+
**for:**
|
|
442
|
+
|
|
443
|
+
[source,postscript]
|
|
444
|
+
----
|
|
445
|
+
initial increment limit { actions } for
|
|
446
|
+
|
|
447
|
+
% Example: Count 0 to 10 by 2
|
|
448
|
+
0 2 10 { = } for
|
|
449
|
+
% Output: 0 2 4 6 8 10
|
|
450
|
+
----
|
|
451
|
+
|
|
452
|
+
**loop:**
|
|
453
|
+
|
|
454
|
+
[source,postscript]
|
|
455
|
+
----
|
|
456
|
+
{ actions exit-condition { exit } if } loop
|
|
457
|
+
|
|
458
|
+
% Example: Infinite loop with break
|
|
459
|
+
0
|
|
460
|
+
{
|
|
461
|
+
dup = % Print current value
|
|
462
|
+
1 add % Increment
|
|
463
|
+
dup 5 gt % Check if > 5
|
|
464
|
+
{ exit } % Exit if true
|
|
465
|
+
if
|
|
466
|
+
} loop
|
|
467
|
+
----
|
|
468
|
+
|
|
469
|
+
**forall:**
|
|
470
|
+
|
|
471
|
+
[source,postscript]
|
|
472
|
+
----
|
|
473
|
+
array { actions } forall
|
|
474
|
+
|
|
475
|
+
% Example: Print array elements
|
|
476
|
+
[10 20 30 40] { = } forall
|
|
477
|
+
% Output: 10 20 30 40
|
|
478
|
+
----
|
|
479
|
+
|
|
480
|
+
.Loop Examples
|
|
481
|
+
[example]
|
|
482
|
+
====
|
|
483
|
+
[source,postscript]
|
|
484
|
+
----
|
|
485
|
+
% Draw 10 circles
|
|
486
|
+
newpath
|
|
487
|
+
10 {
|
|
488
|
+
100 100 50 0 360 arc
|
|
489
|
+
stroke
|
|
490
|
+
0 20 translate % Move down for next circle
|
|
491
|
+
} repeat
|
|
492
|
+
|
|
493
|
+
% Draw grid
|
|
494
|
+
0 10 100 { % x from 0 to 100 by 10
|
|
495
|
+
0 10 100 { % y from 0 to 100 by 10
|
|
496
|
+
2 index % Get x
|
|
497
|
+
1 index % Get y
|
|
498
|
+
moveto
|
|
499
|
+
2 0 rlineto % Draw small mark
|
|
500
|
+
stroke
|
|
501
|
+
} for
|
|
502
|
+
pop % Remove y
|
|
503
|
+
} for
|
|
504
|
+
pop % Remove x
|
|
505
|
+
----
|
|
506
|
+
====
|
|
507
|
+
|
|
508
|
+
== Procedures and Functions
|
|
509
|
+
|
|
510
|
+
=== Defining Procedures
|
|
511
|
+
|
|
512
|
+
[source,postscript]
|
|
513
|
+
----
|
|
514
|
+
/name { procedure-body } def
|
|
515
|
+
|
|
516
|
+
% Examples:
|
|
517
|
+
/square { dup mul } def
|
|
518
|
+
/double { 2 mul } def
|
|
519
|
+
/greet { (Hello) print } def
|
|
520
|
+
----
|
|
521
|
+
|
|
522
|
+
=== Using Procedures
|
|
523
|
+
|
|
524
|
+
[source,postscript]
|
|
525
|
+
----
|
|
526
|
+
% Define
|
|
527
|
+
/square { dup mul } def
|
|
528
|
+
|
|
529
|
+
% Use
|
|
530
|
+
5 square % Result: 25
|
|
531
|
+
10 square % Result: 100
|
|
532
|
+
----
|
|
533
|
+
|
|
534
|
+
=== Procedures with Parameters
|
|
535
|
+
|
|
536
|
+
.Procedure Parameter Pattern
|
|
537
|
+
[example]
|
|
538
|
+
====
|
|
539
|
+
[source,postscript]
|
|
540
|
+
----
|
|
541
|
+
% Define procedure that draws a rectangle
|
|
542
|
+
/rectangle { % x y width height
|
|
543
|
+
/h exch def
|
|
544
|
+
/w exch def
|
|
545
|
+
/y exch def
|
|
546
|
+
/x exch def
|
|
547
|
+
|
|
548
|
+
newpath
|
|
549
|
+
x y moveto
|
|
550
|
+
w 0 rlineto
|
|
551
|
+
0 h rlineto
|
|
552
|
+
w neg 0 rlineto
|
|
553
|
+
closepath
|
|
554
|
+
} def
|
|
555
|
+
|
|
556
|
+
% Use
|
|
557
|
+
100 100 200 150 rectangle
|
|
558
|
+
fill
|
|
559
|
+
----
|
|
560
|
+
|
|
561
|
+
The pattern:
|
|
562
|
+
|
|
563
|
+
1. Pop parameters from stack
|
|
564
|
+
2. Store in local variables (`def`)
|
|
565
|
+
3. Use variables in procedure body
|
|
566
|
+
====
|
|
567
|
+
|
|
568
|
+
=== Recursive Procedures
|
|
569
|
+
|
|
570
|
+
[source,postscript]
|
|
571
|
+
----
|
|
572
|
+
% Factorial function
|
|
573
|
+
/factorial {
|
|
574
|
+
dup 1 le
|
|
575
|
+
{ pop 1 } % Base case: n ≤ 1 → 1
|
|
576
|
+
{ dup 1 sub % Recursive case:
|
|
577
|
+
factorial % factorial(n-1)
|
|
578
|
+
mul } % × n
|
|
579
|
+
ifelse
|
|
580
|
+
} def
|
|
581
|
+
|
|
582
|
+
% Use
|
|
583
|
+
5 factorial % Result: 120
|
|
584
|
+
----
|
|
585
|
+
|
|
586
|
+
== Dictionaries and Scope
|
|
587
|
+
|
|
588
|
+
=== Dictionary Operations
|
|
589
|
+
|
|
590
|
+
**Create Dictionary:**
|
|
591
|
+
|
|
592
|
+
[source,postscript]
|
|
593
|
+
----
|
|
594
|
+
10 dict % Create dict with 10 slots
|
|
595
|
+
----
|
|
596
|
+
|
|
597
|
+
**Define Entry:**
|
|
598
|
+
|
|
599
|
+
[source,postscript]
|
|
600
|
+
----
|
|
601
|
+
/mydict 10 dict def
|
|
602
|
+
mydict begin
|
|
603
|
+
/x 100 def
|
|
604
|
+
/y 200 def
|
|
605
|
+
end
|
|
606
|
+
----
|
|
607
|
+
|
|
608
|
+
**Access Entry:**
|
|
609
|
+
|
|
610
|
+
[source,postscript]
|
|
611
|
+
----
|
|
612
|
+
/x load % Load x's value
|
|
613
|
+
mydict /x get % Get x from mydict
|
|
614
|
+
----
|
|
615
|
+
|
|
616
|
+
=== Dictionary Stack
|
|
617
|
+
|
|
618
|
+
PostScript maintains a **dictionary stack** for variable scope:
|
|
619
|
+
|
|
620
|
+
.Dictionary Stack
|
|
621
|
+
[source]
|
|
622
|
+
----
|
|
623
|
+
Top ┌──────────────┐
|
|
624
|
+
│ Current Dict │ ← Definitions here
|
|
625
|
+
├──────────────┤
|
|
626
|
+
│ User Dict │ ← User definitions
|
|
627
|
+
├──────────────┤
|
|
628
|
+
Bottom │ System Dict │ ← Built-in operators
|
|
629
|
+
└──────────────┘
|
|
630
|
+
----
|
|
631
|
+
|
|
632
|
+
**Dictionary Scope:**
|
|
633
|
+
|
|
634
|
+
[source,postscript]
|
|
635
|
+
----
|
|
636
|
+
/x 10 def % Define in userdict
|
|
637
|
+
|
|
638
|
+
100 dict begin % Push new dict
|
|
639
|
+
/x 20 def % Shadows outer x
|
|
640
|
+
x = % Prints: 20
|
|
641
|
+
end % Pop dict
|
|
642
|
+
|
|
643
|
+
x = % Prints: 10
|
|
644
|
+
----
|
|
645
|
+
|
|
646
|
+
=== Built-in Dictionaries
|
|
647
|
+
|
|
648
|
+
`systemdict`:: Built-in operators and constants
|
|
649
|
+
|
|
650
|
+
`userdict`:: User-defined variables (default)
|
|
651
|
+
|
|
652
|
+
`globaldict`:: Level 2+ global definitions
|
|
653
|
+
|
|
654
|
+
== Graphics Operators
|
|
655
|
+
|
|
656
|
+
=== Path Construction
|
|
657
|
+
|
|
658
|
+
[source,postscript]
|
|
659
|
+
----
|
|
660
|
+
newpath % Clear current path
|
|
661
|
+
x y moveto % Start subpath at (x,y)
|
|
662
|
+
x y lineto % Line to (x,y)
|
|
663
|
+
x y rmoveto % Relative move
|
|
664
|
+
dx dy rlineto % Relative line
|
|
665
|
+
x1 y1 x2 y2 x3 y3 curveto % Cubic curve
|
|
666
|
+
closepath % Close current subpath
|
|
667
|
+
----
|
|
668
|
+
|
|
669
|
+
=== Path Painting
|
|
670
|
+
|
|
671
|
+
[source,postscript]
|
|
672
|
+
----
|
|
673
|
+
stroke % Paint path outline
|
|
674
|
+
fill % Fill path interior
|
|
675
|
+
eofill % Even-odd fill
|
|
676
|
+
clip % Set clipping path
|
|
677
|
+
----
|
|
678
|
+
|
|
679
|
+
=== Graphics State
|
|
680
|
+
|
|
681
|
+
[source,postscript]
|
|
682
|
+
----
|
|
683
|
+
gsave % Save graphics state
|
|
684
|
+
grestore % Restore graphics state
|
|
685
|
+
----
|
|
686
|
+
|
|
687
|
+
=== Color
|
|
688
|
+
|
|
689
|
+
[source,postscript]
|
|
690
|
+
----
|
|
691
|
+
gray setgray % Grayscale (0-1)
|
|
692
|
+
r g b setrgbcolor % RGB (0-1 each)
|
|
693
|
+
c m y k setcmykcolor % CMYK (0-1 each)
|
|
694
|
+
----
|
|
695
|
+
|
|
696
|
+
=== Line Attributes
|
|
697
|
+
|
|
698
|
+
[source,postscript]
|
|
699
|
+
----
|
|
700
|
+
width setlinewidth % Line thickness
|
|
701
|
+
cap setlinecap % 0=butt, 1=round, 2=square
|
|
702
|
+
join setlinejoin % 0=miter, 1=round, 2=bevel
|
|
703
|
+
[array] offset setdash % Dash pattern
|
|
704
|
+
----
|
|
705
|
+
|
|
706
|
+
=== Transformations
|
|
707
|
+
|
|
708
|
+
[source,postscript]
|
|
709
|
+
----
|
|
710
|
+
tx ty translate % Translate origin
|
|
711
|
+
sx sy scale % Scale axes
|
|
712
|
+
angle rotate % Rotate (degrees)
|
|
713
|
+
----
|
|
714
|
+
|
|
715
|
+
== Comments
|
|
716
|
+
|
|
717
|
+
[source,postscript]
|
|
718
|
+
----
|
|
719
|
+
% This is a comment to end of line
|
|
720
|
+
|
|
721
|
+
100 100 moveto % Move to (100,100)
|
|
722
|
+
|
|
723
|
+
% Comments can be on their own line
|
|
724
|
+
% or at the end of code lines
|
|
725
|
+
----
|
|
726
|
+
|
|
727
|
+
== Program Structure
|
|
728
|
+
|
|
729
|
+
=== PostScript File Structure
|
|
730
|
+
|
|
731
|
+
[source,postscript]
|
|
732
|
+
----
|
|
733
|
+
%!PS-Adobe-3.0
|
|
734
|
+
%%BoundingBox: 0 0 612 792
|
|
735
|
+
%%Title: My Document
|
|
736
|
+
%%Creator: Me
|
|
737
|
+
%%Pages: 1
|
|
738
|
+
%%EndComments
|
|
739
|
+
|
|
740
|
+
%%BeginProlog
|
|
741
|
+
% Procedure definitions
|
|
742
|
+
/square { dup mul } def
|
|
743
|
+
%%EndProlog
|
|
744
|
+
|
|
745
|
+
%%Page: 1 1
|
|
746
|
+
% Page content
|
|
747
|
+
100 100 moveto
|
|
748
|
+
200 200 lineto
|
|
749
|
+
stroke
|
|
750
|
+
showpage
|
|
751
|
+
%%EOF
|
|
752
|
+
----
|
|
753
|
+
|
|
754
|
+
**Document Structure Comments:**
|
|
755
|
+
|
|
756
|
+
* `%!PS-Adobe-3.0` - File identifier
|
|
757
|
+
* `%%BoundingBox:` - Page dimensions
|
|
758
|
+
* `%%BeginProlog` / `%%EndProlog` - Definitions section
|
|
759
|
+
* `%%Page:` - Page marker
|
|
760
|
+
* `%%EOF` - End of file
|
|
761
|
+
|
|
762
|
+
=== showpage
|
|
763
|
+
|
|
764
|
+
The `showpage` operator:
|
|
765
|
+
|
|
766
|
+
* Prints the current page
|
|
767
|
+
* Resets graphics state
|
|
768
|
+
* Advances to next page
|
|
769
|
+
|
|
770
|
+
[source,postscript]
|
|
771
|
+
----
|
|
772
|
+
% Draw on page
|
|
773
|
+
newpath
|
|
774
|
+
100 100 moveto
|
|
775
|
+
200 200 lineto
|
|
776
|
+
stroke
|
|
777
|
+
|
|
778
|
+
showpage % Print page and reset
|
|
779
|
+
----
|
|
780
|
+
|
|
781
|
+
== Common Patterns
|
|
782
|
+
|
|
783
|
+
=== Drawing a Rectangle
|
|
784
|
+
|
|
785
|
+
[source,postscript]
|
|
786
|
+
----
|
|
787
|
+
newpath
|
|
788
|
+
x y moveto
|
|
789
|
+
width 0 rlineto
|
|
790
|
+
0 height rlineto
|
|
791
|
+
width neg 0 rlineto
|
|
792
|
+
closepath
|
|
793
|
+
----
|
|
794
|
+
|
|
795
|
+
=== Drawing a Circle
|
|
796
|
+
|
|
797
|
+
[source,postscript]
|
|
798
|
+
----
|
|
799
|
+
cx cy radius 0 360 arc
|
|
800
|
+
----
|
|
801
|
+
|
|
802
|
+
=== Rounded Rectangle
|
|
803
|
+
|
|
804
|
+
[source,postscript]
|
|
805
|
+
----
|
|
806
|
+
/roundrect {
|
|
807
|
+
/r exch def /h exch def /w exch def /y exch def /x exch def
|
|
808
|
+
newpath
|
|
809
|
+
x r add y moveto
|
|
810
|
+
x w add y x w add y r add r arcto 4 {pop} repeat
|
|
811
|
+
x w add y h add x w add r sub y h add r arcto 4 {pop} repeat
|
|
812
|
+
x y h add x r add y h add r arcto 4 {pop} repeat
|
|
813
|
+
x y x y r add r arcto 4 {pop} repeat
|
|
814
|
+
closepath
|
|
815
|
+
} def
|
|
816
|
+
----
|
|
817
|
+
|
|
818
|
+
== PostScript Limitations in Postsvg
|
|
819
|
+
|
|
820
|
+
Postsvg supports a subset of PostScript focused on vector graphics:
|
|
821
|
+
|
|
822
|
+
**Supported:**
|
|
823
|
+
|
|
824
|
+
* Basic arithmetic and logic
|
|
825
|
+
* Path construction and painting
|
|
826
|
+
* Graphics state operations
|
|
827
|
+
* Color operations
|
|
828
|
+
* Transformations
|
|
829
|
+
* Basic control flow
|
|
830
|
+
* Dictionary operations
|
|
831
|
+
|
|
832
|
+
**Not Supported:**
|
|
833
|
+
|
|
834
|
+
* File I/O operations
|
|
835
|
+
* Font rendering (partial)
|
|
836
|
+
* Image operators
|
|
837
|
+
* Advanced Level 3 features
|
|
838
|
+
* Binary data
|
|
839
|
+
* Some device-specific operators
|
|
840
|
+
|
|
841
|
+
See the link:../cli-reference/check-command.adoc[Check Command] for validating PostScript compatibility.
|
|
842
|
+
|
|
843
|
+
== Next Steps
|
|
844
|
+
|
|
845
|
+
* Review link:conversion-pipeline.adoc[Conversion Pipeline] to see how PostScript is processed
|
|
846
|
+
* Explore link:path-operations.adoc[Path Operations] for graphics details
|
|
847
|
+
* See link:graphics-state.adoc[Graphics State] for state management
|
|
848
|
+
* Check link:../api-reference.adoc[API Reference] for implementation
|
|
849
|
+
* Read link:../architecture.adoc[Architecture] for system design
|
|
850
|
+
|
|
851
|
+
== Bibliography
|
|
852
|
+
|
|
853
|
+
* link:conversion-pipeline.adoc[Conversion Pipeline]
|
|
854
|
+
* link:path-operations.adoc[Path Operations]
|
|
855
|
+
* link:graphics-state.adoc[Graphics State Management]
|
|
856
|
+
* link:../architecture/interpreter-stage.adoc[Interpreter Architecture]
|
|
857
|
+
* link:https://www.adobe.com/jp/print/postscript/pdfs/PLRM.pdf[PostScript Language Reference Manual]
|
|
858
|
+
* link:https://www-cdf.fnal.gov/offline/PostScript/BLUEBOOK.PDF[PostScript Language Tutorial and Cookbook]
|
|
859
|
+
* link:https://en.wikipedia.org/wiki/PostScript[PostScript Wikipedia Article]
|