postscript 0.1.0 → 0.2.1
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/.rubocop.yml +19 -0
- data/.rubocop_todo.yml +323 -0
- data/CHANGELOG.md +71 -0
- data/LICENSE +24 -0
- data/exe/postscript +7 -0
- data/lib/postscript/cli.rb +83 -0
- data/lib/postscript/color.rb +6 -4
- data/lib/postscript/format_number.rb +4 -1
- data/lib/postscript/model/operator.rb +1 -1
- data/lib/postscript/model/operators/arithmetic.rb +30 -0
- data/lib/postscript/model/operators/boolean.rb +23 -11
- data/lib/postscript/model/operators/color.rb +16 -0
- data/lib/postscript/model/operators/container.rb +24 -0
- data/lib/postscript/model/operators/control_flow.rb +16 -1
- data/lib/postscript/model/operators/dictionary.rb +8 -0
- data/lib/postscript/model/operators/font.rb +14 -0
- data/lib/postscript/model/operators/graphics_state.rb +14 -0
- data/lib/postscript/model/operators/path.rb +44 -0
- data/lib/postscript/model/operators/stack.rb +4 -0
- data/lib/postscript/model/operators/transformations.rb +23 -1
- data/lib/postscript/model/program.rb +2 -2
- data/lib/postscript/serializer.rb +32 -212
- data/lib/postscript/source/ast_builder.rb +30 -22
- data/lib/postscript/source/lexer.rb +18 -21
- data/lib/postscript/version.rb +1 -1
- data/lib/postscript.rb +30 -0
- metadata +29 -6
- data/postscript.gemspec +0 -37
|
@@ -31,11 +31,13 @@ module Postscript
|
|
|
31
31
|
class Def < Operator
|
|
32
32
|
register_as "def", consumes: 2, produces: 0
|
|
33
33
|
attr_reader :key, :value
|
|
34
|
+
|
|
34
35
|
def initialize(key:, value:)
|
|
35
36
|
@key = key
|
|
36
37
|
@value = value
|
|
37
38
|
freeze
|
|
38
39
|
end
|
|
40
|
+
|
|
39
41
|
def self.from_operands(stack)
|
|
40
42
|
value = stack.pop
|
|
41
43
|
key = stack.pop
|
|
@@ -46,10 +48,12 @@ module Postscript
|
|
|
46
48
|
class Load < Operator
|
|
47
49
|
register_as "load", consumes: 1, produces: 1
|
|
48
50
|
attr_reader :key
|
|
51
|
+
|
|
49
52
|
def initialize(key:)
|
|
50
53
|
@key = key
|
|
51
54
|
freeze
|
|
52
55
|
end
|
|
56
|
+
|
|
53
57
|
def self.from_operands(stack)
|
|
54
58
|
new(key: stack.pop)
|
|
55
59
|
end
|
|
@@ -58,11 +62,13 @@ module Postscript
|
|
|
58
62
|
class Store < Operator
|
|
59
63
|
register_as "store", consumes: 2, produces: 0
|
|
60
64
|
attr_reader :key, :value
|
|
65
|
+
|
|
61
66
|
def initialize(key:, value:)
|
|
62
67
|
@key = key
|
|
63
68
|
@value = value
|
|
64
69
|
freeze
|
|
65
70
|
end
|
|
71
|
+
|
|
66
72
|
def self.from_operands(stack)
|
|
67
73
|
value = stack.pop
|
|
68
74
|
key = stack.pop
|
|
@@ -78,6 +84,7 @@ module Postscript
|
|
|
78
84
|
new(key: key, dict: dict)
|
|
79
85
|
end
|
|
80
86
|
attr_reader :key, :dict
|
|
87
|
+
|
|
81
88
|
def initialize(key:, dict:)
|
|
82
89
|
@key = key
|
|
83
90
|
@dict = dict
|
|
@@ -107,6 +114,7 @@ module Postscript
|
|
|
107
114
|
new(operand: stack.pop)
|
|
108
115
|
end
|
|
109
116
|
attr_reader :operand
|
|
117
|
+
|
|
110
118
|
def initialize(operand:)
|
|
111
119
|
@operand = operand
|
|
112
120
|
freeze
|
|
@@ -14,10 +14,12 @@ module Postscript
|
|
|
14
14
|
class Findfont < Operator
|
|
15
15
|
register_as "findfont", consumes: 1, produces: 1
|
|
16
16
|
attr_reader :name
|
|
17
|
+
|
|
17
18
|
def initialize(name:)
|
|
18
19
|
@name = name
|
|
19
20
|
freeze
|
|
20
21
|
end
|
|
22
|
+
|
|
21
23
|
def self.from_operands(stack)
|
|
22
24
|
new(name: stack.pop)
|
|
23
25
|
end
|
|
@@ -27,11 +29,13 @@ module Postscript
|
|
|
27
29
|
class Scalefont < Operator
|
|
28
30
|
register_as "scalefont", consumes: 2, produces: 1
|
|
29
31
|
attr_reader :font, :size
|
|
32
|
+
|
|
30
33
|
def initialize(font:, size:)
|
|
31
34
|
@font = font
|
|
32
35
|
@size = size
|
|
33
36
|
freeze
|
|
34
37
|
end
|
|
38
|
+
|
|
35
39
|
def self.from_operands(stack)
|
|
36
40
|
size = stack.pop_number
|
|
37
41
|
font = stack.pop
|
|
@@ -43,10 +47,12 @@ module Postscript
|
|
|
43
47
|
class Setfont < Operator
|
|
44
48
|
register_as "setfont", consumes: 1, produces: 0
|
|
45
49
|
attr_reader :font
|
|
50
|
+
|
|
46
51
|
def initialize(font:)
|
|
47
52
|
@font = font
|
|
48
53
|
freeze
|
|
49
54
|
end
|
|
55
|
+
|
|
50
56
|
def self.from_operands(stack)
|
|
51
57
|
new(font: stack.pop)
|
|
52
58
|
end
|
|
@@ -56,10 +62,12 @@ module Postscript
|
|
|
56
62
|
class Show < Operator
|
|
57
63
|
register_as "show", consumes: 1, produces: 0
|
|
58
64
|
attr_reader :text
|
|
65
|
+
|
|
59
66
|
def initialize(text:)
|
|
60
67
|
@text = text
|
|
61
68
|
freeze
|
|
62
69
|
end
|
|
70
|
+
|
|
63
71
|
def self.from_operands(stack)
|
|
64
72
|
new(text: stack.pop)
|
|
65
73
|
end
|
|
@@ -70,12 +78,14 @@ module Postscript
|
|
|
70
78
|
class Xyshow < Operator
|
|
71
79
|
register_as "xyshow"
|
|
72
80
|
attr_reader :text, :dx, :dy
|
|
81
|
+
|
|
73
82
|
def initialize(text:, dx:, dy:)
|
|
74
83
|
@text = text
|
|
75
84
|
@dx = dx
|
|
76
85
|
@dy = dy
|
|
77
86
|
freeze
|
|
78
87
|
end
|
|
88
|
+
|
|
79
89
|
def self.from_operands(stack)
|
|
80
90
|
dy = stack.pop
|
|
81
91
|
dx = stack.pop
|
|
@@ -90,10 +100,12 @@ module Postscript
|
|
|
90
100
|
class Stringwidth < Operator
|
|
91
101
|
register_as "stringwidth"
|
|
92
102
|
attr_reader :text
|
|
103
|
+
|
|
93
104
|
def initialize(text:)
|
|
94
105
|
@text = text
|
|
95
106
|
freeze
|
|
96
107
|
end
|
|
108
|
+
|
|
97
109
|
def self.from_operands(stack)
|
|
98
110
|
new(text: stack.pop)
|
|
99
111
|
end
|
|
@@ -104,11 +116,13 @@ module Postscript
|
|
|
104
116
|
class Charpath < Operator
|
|
105
117
|
register_as "charpath"
|
|
106
118
|
attr_reader :text, :stroke
|
|
119
|
+
|
|
107
120
|
def initialize(text:, stroke:)
|
|
108
121
|
@text = text
|
|
109
122
|
@stroke = stroke
|
|
110
123
|
freeze
|
|
111
124
|
end
|
|
125
|
+
|
|
112
126
|
def self.from_operands(stack)
|
|
113
127
|
stroke = stack.pop
|
|
114
128
|
text = stack.pop
|
|
@@ -19,10 +19,16 @@ module Postscript
|
|
|
19
19
|
class Setlinewidth < Operator
|
|
20
20
|
register_as "setlinewidth"
|
|
21
21
|
attr_reader :width
|
|
22
|
+
|
|
22
23
|
def initialize(width:)
|
|
23
24
|
@width = width
|
|
24
25
|
freeze
|
|
25
26
|
end
|
|
27
|
+
|
|
28
|
+
def operand_values
|
|
29
|
+
[width]
|
|
30
|
+
end
|
|
31
|
+
|
|
26
32
|
def self.from_operands(stack)
|
|
27
33
|
new(width: stack.pop_number)
|
|
28
34
|
end
|
|
@@ -31,10 +37,12 @@ module Postscript
|
|
|
31
37
|
class Setlinecap < Operator
|
|
32
38
|
register_as "setlinecap"
|
|
33
39
|
attr_reader :cap_code
|
|
40
|
+
|
|
34
41
|
def initialize(cap_code:)
|
|
35
42
|
@cap_code = cap_code.to_i
|
|
36
43
|
freeze
|
|
37
44
|
end
|
|
45
|
+
|
|
38
46
|
def self.from_operands(stack)
|
|
39
47
|
new(cap_code: stack.pop_number.to_i)
|
|
40
48
|
end
|
|
@@ -43,10 +51,12 @@ module Postscript
|
|
|
43
51
|
class Setlinejoin < Operator
|
|
44
52
|
register_as "setlinejoin"
|
|
45
53
|
attr_reader :join_code
|
|
54
|
+
|
|
46
55
|
def initialize(join_code:)
|
|
47
56
|
@join_code = join_code.to_i
|
|
48
57
|
freeze
|
|
49
58
|
end
|
|
59
|
+
|
|
50
60
|
def self.from_operands(stack)
|
|
51
61
|
new(join_code: stack.pop_number.to_i)
|
|
52
62
|
end
|
|
@@ -55,10 +65,12 @@ module Postscript
|
|
|
55
65
|
class Setmiterlimit < Operator
|
|
56
66
|
register_as "setmiterlimit"
|
|
57
67
|
attr_reader :limit
|
|
68
|
+
|
|
58
69
|
def initialize(limit:)
|
|
59
70
|
@limit = limit
|
|
60
71
|
freeze
|
|
61
72
|
end
|
|
73
|
+
|
|
62
74
|
def self.from_operands(stack)
|
|
63
75
|
new(limit: stack.pop_number)
|
|
64
76
|
end
|
|
@@ -67,11 +79,13 @@ module Postscript
|
|
|
67
79
|
class Setdash < Operator
|
|
68
80
|
register_as "setdash"
|
|
69
81
|
attr_reader :pattern, :offset
|
|
82
|
+
|
|
70
83
|
def initialize(pattern:, offset:)
|
|
71
84
|
@pattern = pattern
|
|
72
85
|
@offset = offset
|
|
73
86
|
freeze
|
|
74
87
|
end
|
|
88
|
+
|
|
75
89
|
def self.from_operands(stack)
|
|
76
90
|
offset = stack.pop_number
|
|
77
91
|
pattern = stack.pop
|
|
@@ -11,11 +11,17 @@ module Postscript
|
|
|
11
11
|
class Moveto < Operator
|
|
12
12
|
register_as "moveto"
|
|
13
13
|
attr_reader :x, :y
|
|
14
|
+
|
|
14
15
|
def initialize(x:, y:)
|
|
15
16
|
@x = x
|
|
16
17
|
@y = y
|
|
17
18
|
freeze
|
|
18
19
|
end
|
|
20
|
+
|
|
21
|
+
def operand_values
|
|
22
|
+
[x, y]
|
|
23
|
+
end
|
|
24
|
+
|
|
19
25
|
def self.from_operands(stack)
|
|
20
26
|
y = stack.pop_number
|
|
21
27
|
x = stack.pop_number
|
|
@@ -26,11 +32,13 @@ module Postscript
|
|
|
26
32
|
class Rmoveto < Operator
|
|
27
33
|
register_as "rmoveto"
|
|
28
34
|
attr_reader :dx, :dy
|
|
35
|
+
|
|
29
36
|
def initialize(dx:, dy:)
|
|
30
37
|
@dx = dx
|
|
31
38
|
@dy = dy
|
|
32
39
|
freeze
|
|
33
40
|
end
|
|
41
|
+
|
|
34
42
|
def self.from_operands(stack)
|
|
35
43
|
dy = stack.pop_number
|
|
36
44
|
dx = stack.pop_number
|
|
@@ -41,11 +49,17 @@ module Postscript
|
|
|
41
49
|
class Lineto < Operator
|
|
42
50
|
register_as "lineto"
|
|
43
51
|
attr_reader :x, :y
|
|
52
|
+
|
|
44
53
|
def initialize(x:, y:)
|
|
45
54
|
@x = x
|
|
46
55
|
@y = y
|
|
47
56
|
freeze
|
|
48
57
|
end
|
|
58
|
+
|
|
59
|
+
def operand_values
|
|
60
|
+
[x, y]
|
|
61
|
+
end
|
|
62
|
+
|
|
49
63
|
def self.from_operands(stack)
|
|
50
64
|
y = stack.pop_number
|
|
51
65
|
x = stack.pop_number
|
|
@@ -56,11 +70,17 @@ module Postscript
|
|
|
56
70
|
class Rlineto < Operator
|
|
57
71
|
register_as "rlineto"
|
|
58
72
|
attr_reader :dx, :dy
|
|
73
|
+
|
|
59
74
|
def initialize(dx:, dy:)
|
|
60
75
|
@dx = dx
|
|
61
76
|
@dy = dy
|
|
62
77
|
freeze
|
|
63
78
|
end
|
|
79
|
+
|
|
80
|
+
def operand_values
|
|
81
|
+
[dx, dy]
|
|
82
|
+
end
|
|
83
|
+
|
|
64
84
|
def self.from_operands(stack)
|
|
65
85
|
dy = stack.pop_number
|
|
66
86
|
dx = stack.pop_number
|
|
@@ -71,6 +91,7 @@ module Postscript
|
|
|
71
91
|
class Curveto < Operator
|
|
72
92
|
register_as "curveto"
|
|
73
93
|
attr_reader :x1, :y1, :x2, :y2, :x3, :y3
|
|
94
|
+
|
|
74
95
|
def initialize(x1:, y1:, x2:, y2:, x3:, y3:)
|
|
75
96
|
@x1 = x1
|
|
76
97
|
@y1 = y1
|
|
@@ -80,6 +101,11 @@ module Postscript
|
|
|
80
101
|
@y3 = y3
|
|
81
102
|
freeze
|
|
82
103
|
end
|
|
104
|
+
|
|
105
|
+
def operand_values
|
|
106
|
+
[x1, y1, x2, y2, x3, y3]
|
|
107
|
+
end
|
|
108
|
+
|
|
83
109
|
def self.from_operands(stack)
|
|
84
110
|
y3 = stack.pop_number
|
|
85
111
|
x3 = stack.pop_number
|
|
@@ -94,6 +120,7 @@ module Postscript
|
|
|
94
120
|
class Rcurveto < Operator
|
|
95
121
|
register_as "rcurveto"
|
|
96
122
|
attr_reader :dx1, :dy1, :dx2, :dy2, :dx3, :dy3
|
|
123
|
+
|
|
97
124
|
def initialize(dx1:, dy1:, dx2:, dy2:, dx3:, dy3:)
|
|
98
125
|
@dx1 = dx1
|
|
99
126
|
@dy1 = dy1
|
|
@@ -103,6 +130,11 @@ module Postscript
|
|
|
103
130
|
@dy3 = dy3
|
|
104
131
|
freeze
|
|
105
132
|
end
|
|
133
|
+
|
|
134
|
+
def operand_values
|
|
135
|
+
[dx1, dy1, dx2, dy2, dx3, dy3]
|
|
136
|
+
end
|
|
137
|
+
|
|
106
138
|
def self.from_operands(stack)
|
|
107
139
|
dy3 = stack.pop_number
|
|
108
140
|
dx3 = stack.pop_number
|
|
@@ -117,6 +149,7 @@ module Postscript
|
|
|
117
149
|
class Arc < Operator
|
|
118
150
|
register_as "arc"
|
|
119
151
|
attr_reader :x, :y, :radius, :angle1, :angle2
|
|
152
|
+
|
|
120
153
|
def initialize(x:, y:, radius:, angle1:, angle2:)
|
|
121
154
|
@x = x
|
|
122
155
|
@y = y
|
|
@@ -125,6 +158,11 @@ module Postscript
|
|
|
125
158
|
@angle2 = angle2
|
|
126
159
|
freeze
|
|
127
160
|
end
|
|
161
|
+
|
|
162
|
+
def operand_values
|
|
163
|
+
[x, y, radius, angle1, angle2]
|
|
164
|
+
end
|
|
165
|
+
|
|
128
166
|
def self.from_operands(stack)
|
|
129
167
|
angle2 = stack.pop_number
|
|
130
168
|
angle1 = stack.pop_number
|
|
@@ -138,6 +176,7 @@ module Postscript
|
|
|
138
176
|
class Arcn < Operator
|
|
139
177
|
register_as "arcn"
|
|
140
178
|
attr_reader :x, :y, :radius, :angle1, :angle2
|
|
179
|
+
|
|
141
180
|
def initialize(x:, y:, radius:, angle1:, angle2:)
|
|
142
181
|
@x = x
|
|
143
182
|
@y = y
|
|
@@ -146,6 +185,11 @@ module Postscript
|
|
|
146
185
|
@angle2 = angle2
|
|
147
186
|
freeze
|
|
148
187
|
end
|
|
188
|
+
|
|
189
|
+
def operand_values
|
|
190
|
+
[x, y, radius, angle1, angle2]
|
|
191
|
+
end
|
|
192
|
+
|
|
149
193
|
def self.from_operands(stack)
|
|
150
194
|
angle2 = stack.pop_number
|
|
151
195
|
angle1 = stack.pop_number
|
|
@@ -35,10 +35,12 @@ module Postscript
|
|
|
35
35
|
class Index < Operator
|
|
36
36
|
register_as "index", consumes: 1, produces: 1
|
|
37
37
|
attr_reader :index
|
|
38
|
+
|
|
38
39
|
def initialize(index:)
|
|
39
40
|
@index = index
|
|
40
41
|
freeze
|
|
41
42
|
end
|
|
43
|
+
|
|
42
44
|
def self.from_operands(stack)
|
|
43
45
|
new(index: stack.pop_number.to_i)
|
|
44
46
|
end
|
|
@@ -47,11 +49,13 @@ module Postscript
|
|
|
47
49
|
class Roll < Operator
|
|
48
50
|
register_as "roll", consumes: 2, produces: 0
|
|
49
51
|
attr_reader :count, :positions
|
|
52
|
+
|
|
50
53
|
def initialize(count:, positions:)
|
|
51
54
|
@count = count
|
|
52
55
|
@positions = positions
|
|
53
56
|
freeze
|
|
54
57
|
end
|
|
58
|
+
|
|
55
59
|
def self.from_operands(stack)
|
|
56
60
|
positions = stack.pop_number.to_i
|
|
57
61
|
count = stack.pop_number.to_i
|
|
@@ -7,11 +7,17 @@ module Postscript
|
|
|
7
7
|
class Translate < Operator
|
|
8
8
|
register_as "translate"
|
|
9
9
|
attr_reader :tx, :ty
|
|
10
|
+
|
|
10
11
|
def initialize(tx:, ty:)
|
|
11
12
|
@tx = tx
|
|
12
13
|
@ty = ty
|
|
13
14
|
freeze
|
|
14
15
|
end
|
|
16
|
+
|
|
17
|
+
def operand_values
|
|
18
|
+
[tx, ty]
|
|
19
|
+
end
|
|
20
|
+
|
|
15
21
|
def self.from_operands(stack)
|
|
16
22
|
ty = stack.pop_number
|
|
17
23
|
tx = stack.pop_number
|
|
@@ -22,11 +28,17 @@ module Postscript
|
|
|
22
28
|
class Scale < Operator
|
|
23
29
|
register_as "scale"
|
|
24
30
|
attr_reader :sx, :sy
|
|
31
|
+
|
|
25
32
|
def initialize(sx:, sy:)
|
|
26
33
|
@sx = sx
|
|
27
34
|
@sy = sy
|
|
28
35
|
freeze
|
|
29
36
|
end
|
|
37
|
+
|
|
38
|
+
def operand_values
|
|
39
|
+
[sx, sy]
|
|
40
|
+
end
|
|
41
|
+
|
|
30
42
|
def self.from_operands(stack)
|
|
31
43
|
sy = stack.pop_number
|
|
32
44
|
sx = stack.pop_number
|
|
@@ -37,10 +49,12 @@ module Postscript
|
|
|
37
49
|
class Rotate < Operator
|
|
38
50
|
register_as "rotate"
|
|
39
51
|
attr_reader :angle
|
|
52
|
+
|
|
40
53
|
def initialize(angle:)
|
|
41
54
|
@angle = angle
|
|
42
55
|
freeze
|
|
43
56
|
end
|
|
57
|
+
|
|
44
58
|
def self.from_operands(stack)
|
|
45
59
|
new(angle: stack.pop_number)
|
|
46
60
|
end
|
|
@@ -49,17 +63,23 @@ module Postscript
|
|
|
49
63
|
class Concat < Operator
|
|
50
64
|
register_as "concat"
|
|
51
65
|
attr_reader :matrix
|
|
66
|
+
|
|
52
67
|
def initialize(matrix:)
|
|
53
68
|
@matrix = matrix
|
|
54
69
|
freeze
|
|
55
70
|
end
|
|
71
|
+
|
|
72
|
+
def operand_values
|
|
73
|
+
@matrix.dup
|
|
74
|
+
end
|
|
75
|
+
|
|
56
76
|
def self.from_operands(stack)
|
|
57
77
|
new(matrix: stack.pop)
|
|
58
78
|
end
|
|
59
79
|
end
|
|
60
80
|
|
|
61
81
|
class Matrix < Operator
|
|
62
|
-
register_as "matrix"
|
|
82
|
+
register_as "matrix", consumes: 0, produces: 1
|
|
63
83
|
end
|
|
64
84
|
|
|
65
85
|
class Currentmatrix < Operator
|
|
@@ -69,10 +89,12 @@ module Postscript
|
|
|
69
89
|
class Setmatrix < Operator
|
|
70
90
|
register_as "setmatrix"
|
|
71
91
|
attr_reader :matrix
|
|
92
|
+
|
|
72
93
|
def initialize(matrix:)
|
|
73
94
|
@matrix = matrix
|
|
74
95
|
freeze
|
|
75
96
|
end
|
|
97
|
+
|
|
76
98
|
def self.from_operands(stack)
|
|
77
99
|
new(matrix: stack.pop)
|
|
78
100
|
end
|
|
@@ -51,7 +51,7 @@ module Postscript
|
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
def with(**overrides)
|
|
54
|
-
Header.new(**to_h
|
|
54
|
+
Header.new(**to_h, **overrides)
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
def to_h
|
|
@@ -59,7 +59,7 @@ module Postscript
|
|
|
59
59
|
bounding_box: bounding_box, hires_bounding_box: hires_bounding_box,
|
|
60
60
|
title: title, creator: creator, creation_date: creation_date,
|
|
61
61
|
pages: pages, page_count: page_count, epsf: epsf,
|
|
62
|
-
language_level: language_level, custom: custom
|
|
62
|
+
language_level: language_level, custom: custom
|
|
63
63
|
}
|
|
64
64
|
end
|
|
65
65
|
end
|