postsvg 0.2.6 → 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 (91) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +49 -533
  3. data/CLAUDE.md +3 -27
  4. data/Gemfile +2 -2
  5. data/README.adoc +4 -62
  6. data/Rakefile +0 -17
  7. data/lib/postsvg/cli.rb +5 -10
  8. data/lib/postsvg/color.rb +132 -0
  9. data/lib/postsvg/format_number.rb +22 -0
  10. data/lib/postsvg/graphics_context.rb +1 -2
  11. data/lib/postsvg/interpreter.rb +2 -1
  12. data/lib/postsvg/matrix.rb +106 -0
  13. data/lib/postsvg/model/literals/array.rb +41 -0
  14. data/lib/postsvg/model/literals/dictionary.rb +34 -0
  15. data/lib/postsvg/model/literals/hex.rb +37 -0
  16. data/lib/postsvg/model/literals/name.rb +40 -0
  17. data/lib/postsvg/model/literals/number.rb +36 -0
  18. data/lib/postsvg/model/literals/procedure.rb +41 -0
  19. data/lib/postsvg/model/literals/string.rb +30 -0
  20. data/lib/postsvg/model/literals.rb +19 -0
  21. data/lib/postsvg/model/operator.rb +58 -0
  22. data/lib/postsvg/model/operators/arithmetic.rb +264 -0
  23. data/lib/postsvg/model/operators/boolean.rb +182 -0
  24. data/lib/postsvg/model/operators/color.rb +74 -0
  25. data/lib/postsvg/model/operators/container.rb +186 -0
  26. data/lib/postsvg/model/operators/control_flow.rb +119 -0
  27. data/lib/postsvg/model/operators/device.rb +21 -0
  28. data/lib/postsvg/model/operators/dictionary.rb +118 -0
  29. data/lib/postsvg/model/operators/font.rb +121 -0
  30. data/lib/postsvg/model/operators/graphics_state.rb +84 -0
  31. data/lib/postsvg/model/operators/painting.rb +29 -0
  32. data/lib/postsvg/model/operators/path.rb +169 -0
  33. data/lib/postsvg/model/operators/stack.rb +72 -0
  34. data/lib/postsvg/model/operators/transformations.rb +103 -0
  35. data/lib/postsvg/model/operators.rb +89 -0
  36. data/lib/postsvg/model/program.rb +68 -0
  37. data/lib/postsvg/model/token.rb +43 -0
  38. data/lib/postsvg/model.rb +17 -0
  39. data/lib/postsvg/options.rb +1 -1
  40. data/lib/postsvg/parser/postscript_parser.rb +7 -7
  41. data/lib/postsvg/renderer.rb +3 -7
  42. data/lib/postsvg/serializer.rb +325 -0
  43. data/lib/postsvg/source/ast_builder.rb +308 -0
  44. data/lib/postsvg/source/lexer.rb +322 -0
  45. data/lib/postsvg/source/operand_stack.rb +55 -0
  46. data/lib/postsvg/source.rb +21 -0
  47. data/lib/postsvg/svg/clip_path_registry.rb +1 -3
  48. data/lib/postsvg/svg/element.rb +2 -4
  49. data/lib/postsvg/svg/elements/ellipse.rb +1 -2
  50. data/lib/postsvg/svg/elements/svg.rb +1 -2
  51. data/lib/postsvg/svg/paint.rb +1 -1
  52. data/lib/postsvg/svg/parser.rb +3 -3
  53. data/lib/postsvg/svg/path_data/parser.rb +6 -10
  54. data/lib/postsvg/svg/stroke.rb +2 -4
  55. data/lib/postsvg/svg/transform_list.rb +1 -1
  56. data/lib/postsvg/svg.rb +1 -1
  57. data/lib/postsvg/svg_builder.rb +11 -15
  58. data/lib/postsvg/translation/arc_converter.rb +14 -23
  59. data/lib/postsvg/translation/bounding_box.rb +4 -7
  60. data/lib/postsvg/translation/handlers/circle_handler.rb +2 -2
  61. data/lib/postsvg/translation/handlers/ellipse_handler.rb +3 -8
  62. data/lib/postsvg/translation/handlers/group_handler.rb +1 -2
  63. data/lib/postsvg/translation/handlers/image_handler.rb +2 -3
  64. data/lib/postsvg/translation/handlers/line_handler.rb +2 -6
  65. data/lib/postsvg/translation/handlers/open_handler.rb +2 -3
  66. data/lib/postsvg/translation/handlers/path_handler.rb +60 -82
  67. data/lib/postsvg/translation/handlers/polygon_handler.rb +2 -4
  68. data/lib/postsvg/translation/handlers/polyline_handler.rb +4 -5
  69. data/lib/postsvg/translation/handlers/rect_handler.rb +5 -10
  70. data/lib/postsvg/translation/handlers/shared.rb +11 -11
  71. data/lib/postsvg/translation/handlers/svg_handler.rb +2 -3
  72. data/lib/postsvg/translation/handlers/text_handler.rb +8 -17
  73. data/lib/postsvg/translation/handlers.rb +1 -2
  74. data/lib/postsvg/translation/ps_renderer.rb +4 -18
  75. data/lib/postsvg/translation/record_emitter.rb +0 -54
  76. data/lib/postsvg/version.rb +1 -1
  77. data/lib/postsvg/visitors/ps_visitor/arithmetic.rb +6 -6
  78. data/lib/postsvg/visitors/ps_visitor/color.rb +5 -8
  79. data/lib/postsvg/visitors/ps_visitor/common.rb +2 -1
  80. data/lib/postsvg/visitors/ps_visitor/container.rb +13 -13
  81. data/lib/postsvg/visitors/ps_visitor/control_flow.rb +3 -3
  82. data/lib/postsvg/visitors/ps_visitor/dictionary.rb +4 -8
  83. data/lib/postsvg/visitors/ps_visitor/font.rb +4 -15
  84. data/lib/postsvg/visitors/ps_visitor/graphics_state.rb +5 -7
  85. data/lib/postsvg/visitors/ps_visitor/painting.rb +3 -3
  86. data/lib/postsvg/visitors/ps_visitor/path.rb +33 -52
  87. data/lib/postsvg/visitors/ps_visitor/transformations.rb +7 -45
  88. data/lib/postsvg/visitors/ps_visitor.rb +2 -18
  89. data/lib/postsvg.rb +38 -43
  90. metadata +39 -20
  91. data/gemfiles/native-parity/Gemfile +0 -8
@@ -36,7 +36,6 @@ module Postsvg
36
36
  @graphics = graphics
37
37
  @stack = [] # operand stack for execution semantics
38
38
  @path = PathState.new
39
- @saved_paths = []
40
39
  @dict_stack = [{}] # runtime dict stack (mirrors PLRM dict stack)
41
40
  @recursion_depth = 0
42
41
  end
@@ -117,7 +116,6 @@ module Postsvg
117
116
  # geometry bookkeeping.
118
117
  class PathState
119
118
  attr_reader :commands, :current_x, :current_y
120
- attr_accessor :matrix
121
119
 
122
120
  def initialize
123
121
  @commands = []
@@ -129,11 +127,6 @@ module Postsvg
129
127
  @commands.empty?
130
128
  end
131
129
 
132
- def initialize_copy(other)
133
- super
134
- @commands = other.commands.map(&:dup)
135
- end
136
-
137
130
  def move_to(x, y)
138
131
  @commands << "M #{fmt(x)} #{fmt(y)}"
139
132
  @current_x = x.to_f
@@ -177,27 +170,18 @@ module Postsvg
177
170
  @current_y = y.to_f
178
171
  end
179
172
 
180
- def append_deferred(command, x, y)
181
- @commands << command
182
- @current_x = x
183
- @current_y = y
184
- end
185
-
186
173
  def close
187
174
  @commands << "Z"
188
175
  end
189
176
 
190
177
  def reset
191
- @matrix = nil
192
178
  @commands = []
193
179
  @current_x = 0.0
194
180
  @current_y = 0.0
195
181
  end
196
182
 
197
- def to_path_d(paint_matrix = @matrix || Matrix.new)
198
- @commands.map do |command|
199
- command.is_a?(Proc) ? command.call(paint_matrix) : command
200
- end.join(" ")
183
+ def to_path_d
184
+ @commands.join(" ")
201
185
  end
202
186
 
203
187
  def fmt(value)
data/lib/postsvg.rb CHANGED
@@ -1,68 +1,63 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "postscript"
4
3
  require "parslet"
5
4
  require "thor"
6
- require "leptris"
5
+ require "nokogiri"
7
6
 
8
7
  module Postsvg
9
8
  autoload :VERSION, "postsvg/version"
10
9
 
11
- # ============================================================
12
- # Posts created and managed by the +postscript+ gem.
13
- # ============================================================
14
- #
15
- # `postscript` owns PS source parsing, the typed PS domain model,
16
- # and the PS source serializer. The `Postscript` namespace is the
17
- # canonical location; the aliases below keep existing user code
18
- # working during the transition (deprecated, will be removed at
19
- # postsvg 1.0).
20
- #
21
- # If you maintain postsvg, prefer `Postscript::*` in new code.
22
-
23
- Source = Postscript::Source
24
- Model = Postscript::Model
25
- Serializer = Postscript::Serializer
26
- Matrix = Postscript::Matrix
27
- Color = Postscript::Color
28
- FormatNumber = Postscript::FormatNumber
29
-
30
- ParseError = Postscript::ParseError
31
- LexError = Postscript::LexError
32
- SyntaxError = Postscript::SyntaxError
33
- StackUnderflowError = Postscript::StackUnderflowError
34
- UndefinedOperatorError = Postscript::UndefinedOperatorError
35
- RecursionLimitError = Postscript::RecursionLimitError
36
- RenderError = Postscript::RenderError
37
- SerializeError = Postscript::SerializeError
38
- ExitSignal = Postscript::ExitSignal
39
- QuitSignal = Postscript::QuitSignal
40
-
41
- # ============================================================
42
- # Errors that originate in the SVG side (kept here, not in postscript).
43
- # ============================================================
10
+ # Errors
44
11
  autoload :Error, "postsvg/errors"
12
+ autoload :ParseError, "postsvg/errors"
13
+ autoload :LexError, "postsvg/errors"
14
+ autoload :SyntaxError, "postsvg/errors"
15
+ autoload :RenderError, "postsvg/errors"
16
+ autoload :StackUnderflowError, "postsvg/errors"
17
+ autoload :UndefinedOperatorError, "postsvg/errors"
18
+ autoload :RecursionLimitError, "postsvg/errors"
19
+ autoload :SizeLimitError, "postsvg/errors"
45
20
  autoload :TranslationError, "postsvg/errors"
46
21
  autoload :UnsupportedElementError, "postsvg/errors"
47
22
  autoload :UnresolvedReferenceError, "postsvg/errors"
23
+ autoload :SerializeError, "postsvg/errors"
24
+ autoload :ConversionError, "postsvg/errors"
25
+ autoload :UnsupportedOperatorError, "postsvg/errors"
26
+ autoload :ExitSignal, "postsvg/errors"
27
+ autoload :QuitSignal, "postsvg/errors"
48
28
 
49
- # Legacy alias for RenderError (postsvg 0.1 API).
50
- ConversionError = RenderError
51
- # Legacy alias for UndefinedOperatorError (postsvg 0.1 API).
52
- UnsupportedOperatorError = UndefinedOperatorError
29
+ # Foundational value types
30
+ autoload :FormatNumber, "postsvg/format_number"
31
+ autoload :Matrix, "postsvg/matrix"
32
+ autoload :Color, "postsvg/color"
53
33
 
54
- # ============================================================
55
- # Rendering / SVG-side types owned by postsvg.
56
- # ============================================================
34
+ # Source-reading layer (PS source -> Model::Program)
35
+ autoload :Source, "postsvg/source"
36
+
37
+ # PS domain model
38
+ autoload :Model, "postsvg/model"
39
+
40
+ # Graphics state
57
41
  autoload :GraphicsContext, "postsvg/graphics_context"
58
42
  autoload :GraphicsStack, "postsvg/graphics_stack"
59
43
  autoload :PathBuilder, "postsvg/path_builder"
44
+
45
+ # SVG emission (forward direction)
60
46
  autoload :SvgBuilder, "postsvg/svg_builder"
47
+
48
+ # Forward direction (PS -> SVG)
61
49
  autoload :Options, "postsvg/options"
62
50
  autoload :Renderer, "postsvg/renderer"
63
51
  autoload :Visitors, "postsvg/visitors"
52
+
53
+ # SVG domain model (reverse direction input)
64
54
  autoload :Svg, "postsvg/svg"
55
+
56
+ # Reverse direction (SVG -> PS)
65
57
  autoload :Translation, "postsvg/translation"
58
+ autoload :Serializer, "postsvg/serializer"
59
+
60
+ # CLI
66
61
  autoload :CLI, "postsvg/cli"
67
62
 
68
63
  # Legacy implementations retained on disk for reference. Not on the
@@ -78,7 +73,7 @@ module Postsvg
78
73
  class << self
79
74
  # PS/EPS source -> SVG string.
80
75
  def to_svg(source, **options)
81
- program = Postscript::Source.parse(source)
76
+ program = Source.parse(source)
82
77
  Renderer.call(program, Options.new(**options))
83
78
  end
84
79
 
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: postsvg
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.6
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-11-02 00:00:00.000000000 Z
11
+ date: 2026-07-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: leptris
14
+ name: nokogiri
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 1.9.399.0
19
+ version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 1.9.399.0
26
+ version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: parslet
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -38,20 +38,6 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
- - !ruby/object:Gem::Dependency
42
- name: postscript
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '0.2'
48
- type: :runtime
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '0.2'
55
41
  - !ruby/object:Gem::Dependency
56
42
  name: thor
57
43
  requirement: !ruby/object:Gem::Requirement
@@ -186,22 +172,55 @@ files:
186
172
  - docs/troubleshooting.adoc
187
173
  - docs/validation.adoc
188
174
  - exe/postsvg
189
- - gemfiles/native-parity/Gemfile
190
175
  - lib/postsvg.rb
191
176
  - lib/postsvg/cli.rb
177
+ - lib/postsvg/color.rb
192
178
  - lib/postsvg/colors.rb
193
179
  - lib/postsvg/converter.rb
194
180
  - lib/postsvg/errors.rb
181
+ - lib/postsvg/format_number.rb
195
182
  - lib/postsvg/graphics_context.rb
196
183
  - lib/postsvg/graphics_stack.rb
197
184
  - lib/postsvg/graphics_state.rb
198
185
  - lib/postsvg/interpreter.rb
186
+ - lib/postsvg/matrix.rb
187
+ - lib/postsvg/model.rb
188
+ - lib/postsvg/model/literals.rb
189
+ - lib/postsvg/model/literals/array.rb
190
+ - lib/postsvg/model/literals/dictionary.rb
191
+ - lib/postsvg/model/literals/hex.rb
192
+ - lib/postsvg/model/literals/name.rb
193
+ - lib/postsvg/model/literals/number.rb
194
+ - lib/postsvg/model/literals/procedure.rb
195
+ - lib/postsvg/model/literals/string.rb
196
+ - lib/postsvg/model/operator.rb
197
+ - lib/postsvg/model/operators.rb
198
+ - lib/postsvg/model/operators/arithmetic.rb
199
+ - lib/postsvg/model/operators/boolean.rb
200
+ - lib/postsvg/model/operators/color.rb
201
+ - lib/postsvg/model/operators/container.rb
202
+ - lib/postsvg/model/operators/control_flow.rb
203
+ - lib/postsvg/model/operators/device.rb
204
+ - lib/postsvg/model/operators/dictionary.rb
205
+ - lib/postsvg/model/operators/font.rb
206
+ - lib/postsvg/model/operators/graphics_state.rb
207
+ - lib/postsvg/model/operators/painting.rb
208
+ - lib/postsvg/model/operators/path.rb
209
+ - lib/postsvg/model/operators/stack.rb
210
+ - lib/postsvg/model/operators/transformations.rb
211
+ - lib/postsvg/model/program.rb
212
+ - lib/postsvg/model/token.rb
199
213
  - lib/postsvg/options.rb
200
214
  - lib/postsvg/parser.rb
201
215
  - lib/postsvg/parser/postscript_parser.rb
202
216
  - lib/postsvg/parser/transform.rb
203
217
  - lib/postsvg/path_builder.rb
204
218
  - lib/postsvg/renderer.rb
219
+ - lib/postsvg/serializer.rb
220
+ - lib/postsvg/source.rb
221
+ - lib/postsvg/source/ast_builder.rb
222
+ - lib/postsvg/source/lexer.rb
223
+ - lib/postsvg/source/operand_stack.rb
205
224
  - lib/postsvg/svg.rb
206
225
  - lib/postsvg/svg/attribute_parser.rb
207
226
  - lib/postsvg/svg/clip_path_registry.rb
@@ -1,8 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- eval_gemfile "../../Gemfile"
4
-
5
- # Drop this CI-only overlay once postscript releases NativeEngine and
6
- # parsanol/parsanol-ruby#354 ships a fix for previously baked grammars.
7
- gem "parsanol", "1.3.109"
8
- gem "postscript", git: "https://github.com/claricle/postscript.git", branch: "main"