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.
Files changed (201) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +105 -0
  3. data/CLAUDE.md +173 -0
  4. data/Gemfile +2 -3
  5. data/README.adoc +456 -179
  6. data/Rakefile +100 -0
  7. data/TODO.roadmap/00-architecture.md +139 -0
  8. data/TODO.roadmap/01-autoload-migration.md +39 -0
  9. data/TODO.roadmap/02-isolate-dormant-code.md +51 -0
  10. data/TODO.roadmap/03-domain-model.md +66 -0
  11. data/TODO.roadmap/04-lexer.md +40 -0
  12. data/TODO.roadmap/05-parser.md +43 -0
  13. data/TODO.roadmap/06-graphics-state.md +45 -0
  14. data/TODO.roadmap/07-matrix-and-color.md +37 -0
  15. data/TODO.roadmap/08-svg-builder.md +51 -0
  16. data/TODO.roadmap/09-renderer.md +52 -0
  17. data/TODO.roadmap/10-visitor.md +58 -0
  18. data/TODO.roadmap/11-operator-coverage.md +103 -0
  19. data/TODO.roadmap/12-svg-domain.md +62 -0
  20. data/TODO.roadmap/13-translation-handlers.md +69 -0
  21. data/TODO.roadmap/14-ps-serializer.md +49 -0
  22. data/TODO.roadmap/15-cli-and-public-api.md +47 -0
  23. data/TODO.roadmap/16-specs.md +84 -0
  24. data/TODO.roadmap/17-docs-sync.md +47 -0
  25. data/TODO.roadmap/18-performance-and-determinism.md +47 -0
  26. data/TODO.roadmap/19-error-model.md +45 -0
  27. data/TODO.roadmap/20-font-and-text.md +46 -0
  28. data/TODO.roadmap/21-images.md +45 -0
  29. data/TODO.roadmap/22-forms-and-resources.md +25 -0
  30. data/TODO.roadmap/23-level2-level3.md +52 -0
  31. data/TODO.roadmap/24-ci-and-release.md +42 -0
  32. data/TODO.roadmap/README.md +77 -0
  33. data/docs/.gitignore +29 -0
  34. data/docs/CHANGELOG.md +114 -0
  35. data/docs/COMPLETE_DOCUMENTATION_STATUS.md +376 -0
  36. data/docs/DEPLOYMENT.md +456 -0
  37. data/docs/DEPLOYMENT_INSTRUCTIONS.md +229 -0
  38. data/docs/DOCUMENTATION_PLAN.md +425 -0
  39. data/docs/FINAL_SUMMARY.md +657 -0
  40. data/docs/Gemfile +15 -0
  41. data/docs/README.md +327 -0
  42. data/docs/_config.yml +99 -0
  43. data/docs/advanced-topics.adoc +370 -0
  44. data/docs/api-reference/colors.adoc +705 -0
  45. data/docs/api-reference/converter.adoc +699 -0
  46. data/docs/api-reference/execution-context.adoc +1210 -0
  47. data/docs/api-reference/graphics-state.adoc +1070 -0
  48. data/docs/api-reference/interpreter.adoc +810 -0
  49. data/docs/api-reference/matrix.adoc +1179 -0
  50. data/docs/api-reference/path-builder.adoc +1284 -0
  51. data/docs/api-reference/postsvg-module.adoc +388 -0
  52. data/docs/api-reference/svg-generator.adoc +891 -0
  53. data/docs/api-reference/tokenizer.adoc +925 -0
  54. data/docs/api-reference.adoc +221 -0
  55. data/docs/architecture/command-registry.adoc +1191 -0
  56. data/docs/architecture/conversion-pipeline.adoc +746 -0
  57. data/docs/architecture/design-decisions.adoc +999 -0
  58. data/docs/architecture/generator-stage.adoc +1115 -0
  59. data/docs/architecture/graphics-state-model.adoc +1089 -0
  60. data/docs/architecture/interpreter-stage.adoc +1125 -0
  61. data/docs/architecture/parser-stage.adoc +1051 -0
  62. data/docs/architecture.adoc +354 -0
  63. data/docs/cli-reference/batch-command.adoc +616 -0
  64. data/docs/cli-reference/check-command.adoc +677 -0
  65. data/docs/cli-reference/cli-options.adoc +802 -0
  66. data/docs/cli-reference/convert-command.adoc +462 -0
  67. data/docs/cli-reference/version-command.adoc +296 -0
  68. data/docs/cli-reference.adoc +317 -0
  69. data/docs/concepts/conversion-pipeline.adoc +903 -0
  70. data/docs/concepts/coordinate-systems.adoc +836 -0
  71. data/docs/concepts/graphics-state.adoc +861 -0
  72. data/docs/concepts/path-operations.adoc +1076 -0
  73. data/docs/concepts/postscript-language.adoc +859 -0
  74. data/docs/concepts/svg-generation.adoc +937 -0
  75. data/docs/concepts.adoc +198 -0
  76. data/docs/contributing.adoc +443 -0
  77. data/docs/development.adoc +420 -0
  78. data/docs/faq.adoc +493 -0
  79. data/docs/getting-started/basic-usage.adoc +538 -0
  80. data/docs/getting-started/common-workflows.adoc +577 -0
  81. data/docs/getting-started/first-conversion.adoc +492 -0
  82. data/docs/getting-started/installation.adoc +534 -0
  83. data/docs/getting-started.adoc +94 -0
  84. data/docs/index.adoc +248 -0
  85. data/docs/optimization.adoc +196 -0
  86. data/docs/ps2svg_compatibility.adoc +149 -0
  87. data/docs/quick-reference.adoc +453 -0
  88. data/docs/sitemap.adoc +337 -0
  89. data/docs/troubleshooting.adoc +486 -0
  90. data/docs/validation.adoc +772 -0
  91. data/exe/postsvg +1 -0
  92. data/lib/postsvg/cli.rb +104 -57
  93. data/lib/postsvg/color.rb +132 -0
  94. data/lib/postsvg/errors.rb +68 -3
  95. data/lib/postsvg/format_number.rb +22 -0
  96. data/lib/postsvg/graphics_context.rb +80 -0
  97. data/lib/postsvg/graphics_stack.rb +43 -0
  98. data/lib/postsvg/model/literals/array.rb +41 -0
  99. data/lib/postsvg/model/literals/dictionary.rb +34 -0
  100. data/lib/postsvg/model/literals/hex.rb +37 -0
  101. data/lib/postsvg/model/literals/name.rb +40 -0
  102. data/lib/postsvg/model/literals/number.rb +36 -0
  103. data/lib/postsvg/model/literals/procedure.rb +41 -0
  104. data/lib/postsvg/model/literals/string.rb +30 -0
  105. data/lib/postsvg/model/literals.rb +19 -0
  106. data/lib/postsvg/model/operator.rb +58 -0
  107. data/lib/postsvg/model/operators/arithmetic.rb +264 -0
  108. data/lib/postsvg/model/operators/boolean.rb +182 -0
  109. data/lib/postsvg/model/operators/color.rb +74 -0
  110. data/lib/postsvg/model/operators/container.rb +186 -0
  111. data/lib/postsvg/model/operators/control_flow.rb +119 -0
  112. data/lib/postsvg/model/operators/device.rb +21 -0
  113. data/lib/postsvg/model/operators/dictionary.rb +118 -0
  114. data/lib/postsvg/model/operators/font.rb +121 -0
  115. data/lib/postsvg/model/operators/graphics_state.rb +84 -0
  116. data/lib/postsvg/model/operators/painting.rb +29 -0
  117. data/lib/postsvg/model/operators/path.rb +169 -0
  118. data/lib/postsvg/model/operators/stack.rb +72 -0
  119. data/lib/postsvg/model/operators/transformations.rb +103 -0
  120. data/lib/postsvg/model/operators.rb +89 -0
  121. data/lib/postsvg/model/program.rb +68 -0
  122. data/lib/postsvg/model/token.rb +43 -0
  123. data/lib/postsvg/model.rb +17 -0
  124. data/lib/postsvg/options.rb +29 -0
  125. data/lib/postsvg/renderer.rb +85 -0
  126. data/lib/postsvg/serializer.rb +325 -0
  127. data/lib/postsvg/source/ast_builder.rb +308 -0
  128. data/lib/postsvg/source/lexer.rb +322 -0
  129. data/lib/postsvg/source/operand_stack.rb +55 -0
  130. data/lib/postsvg/source.rb +21 -0
  131. data/lib/postsvg/svg/attribute_parser.rb +45 -0
  132. data/lib/postsvg/svg/clip_path_registry.rb +44 -0
  133. data/lib/postsvg/svg/document.rb +22 -0
  134. data/lib/postsvg/svg/element.rb +84 -0
  135. data/lib/postsvg/svg/elements/circle.rb +36 -0
  136. data/lib/postsvg/svg/elements/clip_path.rb +26 -0
  137. data/lib/postsvg/svg/elements/defs.rb +24 -0
  138. data/lib/postsvg/svg/elements/ellipse.rb +38 -0
  139. data/lib/postsvg/svg/elements/group.rb +37 -0
  140. data/lib/postsvg/svg/elements/image.rb +35 -0
  141. data/lib/postsvg/svg/elements/line.rb +36 -0
  142. data/lib/postsvg/svg/elements/path.rb +32 -0
  143. data/lib/postsvg/svg/elements/polygon.rb +12 -0
  144. data/lib/postsvg/svg/elements/polyline.rb +32 -0
  145. data/lib/postsvg/svg/elements/rect.rb +44 -0
  146. data/lib/postsvg/svg/elements/svg.rb +39 -0
  147. data/lib/postsvg/svg/elements/text.rb +42 -0
  148. data/lib/postsvg/svg/elements.rb +31 -0
  149. data/lib/postsvg/svg/paint.rb +34 -0
  150. data/lib/postsvg/svg/parser.rb +39 -0
  151. data/lib/postsvg/svg/path_data/command.rb +27 -0
  152. data/lib/postsvg/svg/path_data/parser.rb +82 -0
  153. data/lib/postsvg/svg/path_data.rb +17 -0
  154. data/lib/postsvg/svg/stroke.rb +31 -0
  155. data/lib/postsvg/svg/transform_list.rb +59 -0
  156. data/lib/postsvg/svg.rb +22 -0
  157. data/lib/postsvg/svg_builder.rb +249 -0
  158. data/lib/postsvg/translation/arc_converter.rb +86 -0
  159. data/lib/postsvg/translation/bounding_box.rb +59 -0
  160. data/lib/postsvg/translation/context.rb +34 -0
  161. data/lib/postsvg/translation/handler_registry.rb +38 -0
  162. data/lib/postsvg/translation/handlers/circle_handler.rb +28 -0
  163. data/lib/postsvg/translation/handlers/clip_path_handler.rb +13 -0
  164. data/lib/postsvg/translation/handlers/defs_handler.rb +15 -0
  165. data/lib/postsvg/translation/handlers/ellipse_handler.rb +31 -0
  166. data/lib/postsvg/translation/handlers/group_handler.rb +21 -0
  167. data/lib/postsvg/translation/handlers/image_handler.rb +20 -0
  168. data/lib/postsvg/translation/handlers/line_handler.rb +23 -0
  169. data/lib/postsvg/translation/handlers/open_handler.rb +18 -0
  170. data/lib/postsvg/translation/handlers/path_handler.rb +356 -0
  171. data/lib/postsvg/translation/handlers/polygon_handler.rb +33 -0
  172. data/lib/postsvg/translation/handlers/polyline_handler.rb +31 -0
  173. data/lib/postsvg/translation/handlers/rect_handler.rb +27 -0
  174. data/lib/postsvg/translation/handlers/shared.rb +110 -0
  175. data/lib/postsvg/translation/handlers/svg_handler.rb +25 -0
  176. data/lib/postsvg/translation/handlers/text_handler.rb +56 -0
  177. data/lib/postsvg/translation/handlers.rb +25 -0
  178. data/lib/postsvg/translation/ps_renderer.rb +105 -0
  179. data/lib/postsvg/translation/record_emitter.rb +35 -0
  180. data/lib/postsvg/translation.rb +17 -0
  181. data/lib/postsvg/version.rb +1 -1
  182. data/lib/postsvg/visitors/ps_visitor/arithmetic.rb +125 -0
  183. data/lib/postsvg/visitors/ps_visitor/boolean.rb +105 -0
  184. data/lib/postsvg/visitors/ps_visitor/color.rb +53 -0
  185. data/lib/postsvg/visitors/ps_visitor/common.rb +66 -0
  186. data/lib/postsvg/visitors/ps_visitor/container.rb +164 -0
  187. data/lib/postsvg/visitors/ps_visitor/control_flow.rb +110 -0
  188. data/lib/postsvg/visitors/ps_visitor/device.rb +20 -0
  189. data/lib/postsvg/visitors/ps_visitor/dictionary.rb +89 -0
  190. data/lib/postsvg/visitors/ps_visitor/font.rb +93 -0
  191. data/lib/postsvg/visitors/ps_visitor/graphics_state.rb +55 -0
  192. data/lib/postsvg/visitors/ps_visitor/painting.rb +90 -0
  193. data/lib/postsvg/visitors/ps_visitor/path.rb +112 -0
  194. data/lib/postsvg/visitors/ps_visitor/stack.rb +47 -0
  195. data/lib/postsvg/visitors/ps_visitor/transformations.rb +101 -0
  196. data/lib/postsvg/visitors/ps_visitor.rb +208 -0
  197. data/lib/postsvg/visitors.rb +9 -0
  198. data/lib/postsvg.rb +93 -59
  199. data/lychee.toml +86 -0
  200. metadata +216 -11
  201. data/postsvg.gemspec +0 -38
data/lib/postsvg.rb CHANGED
@@ -1,78 +1,112 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "postsvg/version"
4
- require_relative "postsvg/errors"
5
- require_relative "postsvg/tokenizer"
6
- require_relative "postsvg/interpreter"
3
+ require "parslet"
4
+ require "thor"
5
+ require "nokogiri"
7
6
 
8
7
  module Postsvg
9
- class << self
10
- # Convert PostScript content to SVG
11
- def convert(ps_content)
12
- bbox = extract_bounding_box(ps_content)
13
- tokens = Tokenizer.tokenize(ps_content)
8
+ autoload :VERSION, "postsvg/version"
14
9
 
15
- interpreter = Interpreter.new
16
- svg_out = interpreter.interpret(tokens, bbox)
10
+ # Errors
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"
20
+ autoload :TranslationError, "postsvg/errors"
21
+ autoload :UnsupportedElementError, "postsvg/errors"
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"
17
28
 
18
- generate_svg(svg_out, bbox)
19
- end
29
+ # Foundational value types
30
+ autoload :FormatNumber, "postsvg/format_number"
31
+ autoload :Matrix, "postsvg/matrix"
32
+ autoload :Color, "postsvg/color"
20
33
 
21
- # Convert PostScript file to SVG
22
- def convert_file(input_path, output_path = nil)
23
- ps_content = File.read(input_path)
24
- svg_content = convert(ps_content)
34
+ # Source-reading layer (PS source -> Model::Program)
35
+ autoload :Source, "postsvg/source"
25
36
 
26
- File.write(output_path, svg_content) if output_path
37
+ # PS domain model
38
+ autoload :Model, "postsvg/model"
27
39
 
28
- svg_content
29
- end
40
+ # Graphics state
41
+ autoload :GraphicsContext, "postsvg/graphics_context"
42
+ autoload :GraphicsStack, "postsvg/graphics_stack"
43
+ autoload :PathBuilder, "postsvg/path_builder"
44
+
45
+ # SVG emission (forward direction)
46
+ autoload :SvgBuilder, "postsvg/svg_builder"
47
+
48
+ # Forward direction (PS -> SVG)
49
+ autoload :Options, "postsvg/options"
50
+ autoload :Renderer, "postsvg/renderer"
51
+ autoload :Visitors, "postsvg/visitors"
52
+
53
+ # SVG domain model (reverse direction input)
54
+ autoload :Svg, "postsvg/svg"
55
+
56
+ # Reverse direction (SVG -> PS)
57
+ autoload :Translation, "postsvg/translation"
58
+ autoload :Serializer, "postsvg/serializer"
30
59
 
31
- private
60
+ # CLI
61
+ autoload :CLI, "postsvg/cli"
32
62
 
33
- def extract_bounding_box(ps_content)
34
- match = ps_content.match(/%%BoundingBox:\s*([-+0-9.eE]+)\s+([-+0-9.eE]+)\s+([-+0-9.eE]+)\s+([-+0-9.eE]+)/)
35
- return nil unless match
63
+ # Legacy implementations retained on disk for reference. Not on the
64
+ # public autoload path; require explicitly if needed:
65
+ # require "postsvg/tokenizer"
66
+ # require "postsvg/interpreter"
67
+ # require "postsvg/parser"
68
+ # require "postsvg/converter"
69
+ # require "postsvg/svg_generator"
70
+ # require "postsvg/graphics_state"
71
+ # require "postsvg/colors"
36
72
 
37
- {
38
- llx: match[1].to_f,
39
- lly: match[2].to_f,
40
- urx: match[3].to_f,
41
- ury: match[4].to_f,
42
- }
73
+ class << self
74
+ # PS/EPS source -> SVG string.
75
+ def to_svg(source, **options)
76
+ program = Source.parse(source)
77
+ Renderer.call(program, Options.new(**options))
78
+ end
79
+
80
+ # PS/EPS file -> SVG string. Writes to +output_path+ if given;
81
+ # returns the SVG string either way.
82
+ def to_svg_file(input_path, output_path = nil, **options)
83
+ svg = to_svg(File.read(input_path), **options)
84
+ File.write(output_path, svg) if output_path
85
+ svg
43
86
  end
44
87
 
45
- def generate_svg(svg_out, bbox)
46
- if bbox
47
- width = bbox[:urx] - bbox[:llx]
48
- height = bbox[:ury] - bbox[:lly]
49
- view_box = "viewBox=\"#{num_fmt(bbox[:llx])} #{num_fmt(bbox[:lly])} #{num_fmt(width)} #{num_fmt(height)}\" " \
50
- "width=\"#{num_fmt(width)}\" height=\"#{num_fmt(height)}\""
51
- else
52
- width = 1920
53
- height = 1080
54
- view_box = "viewBox=\"0 0 #{width} #{height}\" width=\"#{width}\" height=\"#{height}\""
55
- end
56
-
57
- defs = svg_out[:defs].empty? ? "" : "<defs>\n#{svg_out[:defs].join("\n")}\n</defs>"
58
- shapes = svg_out[:element_shapes].join("\n")
59
- texts = svg_out[:element_texts].join("\n")
60
- body = "<g transform=\"translate(0 #{height}) scale(1 -1)\">\n#{shapes}\n#{texts}</g>"
61
-
62
- "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" \
63
- "<svg xmlns=\"http://www.w3.org/2000/svg\" #{view_box}>\n" \
64
- "#{defs}\n" \
65
- "#{body}\n" \
66
- "</svg>"
88
+ # SVG string -> PS source. Pass +eps: true+ for EPS output.
89
+ def to_ps(svg_string, eps: false, **options)
90
+ document = Svg::Parser.call(svg_string)
91
+ program = Translation::PsRenderer.call(document, eps: eps)
92
+ Serializer.call(program, eps: eps, **options)
67
93
  end
68
94
 
69
- def num_fmt(n)
70
- # Format number, removing unnecessary decimals
71
- if n == n.to_i
72
- n.to_i.to_s
73
- else
74
- format("%.3f", n).sub(/\.?0+$/, "")
75
- end
95
+ # SVG string -> EPS source.
96
+ def to_eps(svg_string, **options)
97
+ to_ps(svg_string, eps: true, **options)
76
98
  end
99
+
100
+ # SVG file -> PS source. Writes to +output_path+ if given.
101
+ def to_ps_file(input_path, output_path = nil, eps: false, **options)
102
+ ps = to_ps(File.read(input_path), eps: eps, **options)
103
+ File.write(output_path, ps) if output_path
104
+ ps
105
+ end
106
+
107
+ # Backwards-compatible aliases. Pre-0.2 the only direction was
108
+ # PS -> SVG; existing callers used +convert+ / +convert_file+.
109
+ alias convert to_svg
110
+ alias convert_file to_svg_file
77
111
  end
78
112
  end
data/lychee.toml ADDED
@@ -0,0 +1,86 @@
1
+ # Lychee link checker configuration for Postsvg documentation
2
+ # https://lychee.cli.rs/
3
+ #
4
+ # This configuration is optimized for checking internal documentation links.
5
+ # External URLs are excluded by default to avoid false positives from
6
+ # anti-bot measures and rate limiting.
7
+
8
+ # Base configuration
9
+ max_redirects = 10
10
+ max_retries = 3
11
+ timeout = 20
12
+
13
+ # Check files matching these patterns
14
+ include = [
15
+ "docs/**/*.adoc",
16
+ "README.adoc"
17
+ ]
18
+
19
+ # Exclude certain patterns from checking (regex patterns)
20
+ exclude = [
21
+ # Exclude generated/temporary files
22
+ "docs/docs/.*",
23
+ ".*/node_modules/.*",
24
+ ".*/.git/.*"
25
+ ]
26
+
27
+ # Exclude certain link patterns
28
+ exclude_link_local = false
29
+ exclude_all_private = false
30
+ exclude_mail = false
31
+
32
+ # Accept status codes as valid
33
+ accept = [
34
+ 200, 201, 202, 203, 204, 205, 206, # 2xx success
35
+ 300, 301, 302, 303, 307, 308, # 3xx redirects
36
+ 429 # Rate limit - acceptable for external links
37
+ ]
38
+
39
+ # Include fragments in link validation (e.g., #section-name)
40
+ include_fragments = true
41
+
42
+ # Follow HTTP redirects
43
+ follow_redirects = true
44
+
45
+ # Check for broken fragments (anchor links)
46
+ check_fragments = true
47
+
48
+ # Retry broken links before reporting
49
+ retry_broken = true
50
+
51
+ # Cache successful link checks to speed up repeated runs
52
+ cache = true
53
+
54
+ # User agent string for HTTP requests
55
+ user_agent = "lychee/postsvg-docs"
56
+
57
+ # HTTP method for checking links
58
+ method = "get"
59
+
60
+ # Headers to send with requests
61
+ headers = [
62
+ "accept=text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
63
+ ]
64
+
65
+ # Base URL for relative links (when checking outside of workspace context)
66
+ # base = "https://metanorma.github.io/postsvg/"
67
+
68
+ # Skip checking SSL certificates (not recommended for production)
69
+ insecure = false
70
+
71
+ # Maximum number of concurrent network requests
72
+ max_concurrency = 8
73
+
74
+ # Remap URLs (useful for local development or changed URLs)
75
+ # remap = ["https://old-url.com https://new-url.com"]
76
+
77
+ # Custom glob patterns for AsciiDoc links
78
+ # AsciiDoc uses link:path[text] syntax
79
+ # Lychee should automatically detect these, but we ensure all .adoc files are checked
80
+
81
+ # Output format (compact, detailed, json, markdown)
82
+ # This can be overridden via CLI
83
+ format = "detailed"
84
+
85
+ # Exclude specific domains that may have anti-bot measures
86
+ # exclude_path can be used for this purpose if needed
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: postsvg
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
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: 2025-10-19 00:00:00.000000000 Z
11
+ date: 2026-07-27 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: nokogiri
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: parslet
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -39,9 +53,10 @@ dependencies:
39
53
  - !ruby/object:Gem::Version
40
54
  version: '0'
41
55
  description: |
42
- Postsvg provides a pure Ruby library for converting PostScript (PS) and
43
- Encapsulated PostScript (EPS) files to clean,
44
- standards-compliant Scalable Vector Graphics (SVG) format output.
56
+ Postsvg is a pure-Ruby transformer between PostScript (PS) /
57
+ Encapsulated PostScript (EPS) and Scalable Vector Graphics (SVG).
58
+ Both directions are implemented: PS/EPS -> SVG and SVG -> PS/EPS.
59
+ No external tools (Ghostscript, Inkscape) are required.
45
60
  email:
46
61
  - open.source@ribose.com
47
62
  executables:
@@ -51,11 +66,92 @@ extra_rdoc_files: []
51
66
  files:
52
67
  - ".rubocop.yml"
53
68
  - ".rubocop_todo.yml"
69
+ - CHANGELOG.md
70
+ - CLAUDE.md
54
71
  - Gemfile
55
72
  - LICENSE
56
73
  - README.adoc
57
74
  - Rakefile
75
+ - TODO.roadmap/00-architecture.md
76
+ - TODO.roadmap/01-autoload-migration.md
77
+ - TODO.roadmap/02-isolate-dormant-code.md
78
+ - TODO.roadmap/03-domain-model.md
79
+ - TODO.roadmap/04-lexer.md
80
+ - TODO.roadmap/05-parser.md
81
+ - TODO.roadmap/06-graphics-state.md
82
+ - TODO.roadmap/07-matrix-and-color.md
83
+ - TODO.roadmap/08-svg-builder.md
84
+ - TODO.roadmap/09-renderer.md
85
+ - TODO.roadmap/10-visitor.md
86
+ - TODO.roadmap/11-operator-coverage.md
87
+ - TODO.roadmap/12-svg-domain.md
88
+ - TODO.roadmap/13-translation-handlers.md
89
+ - TODO.roadmap/14-ps-serializer.md
90
+ - TODO.roadmap/15-cli-and-public-api.md
91
+ - TODO.roadmap/16-specs.md
92
+ - TODO.roadmap/17-docs-sync.md
93
+ - TODO.roadmap/18-performance-and-determinism.md
94
+ - TODO.roadmap/19-error-model.md
95
+ - TODO.roadmap/20-font-and-text.md
96
+ - TODO.roadmap/21-images.md
97
+ - TODO.roadmap/22-forms-and-resources.md
98
+ - TODO.roadmap/23-level2-level3.md
99
+ - TODO.roadmap/24-ci-and-release.md
100
+ - TODO.roadmap/README.md
101
+ - docs/.gitignore
102
+ - docs/CHANGELOG.md
103
+ - docs/COMPLETE_DOCUMENTATION_STATUS.md
104
+ - docs/DEPLOYMENT.md
105
+ - docs/DEPLOYMENT_INSTRUCTIONS.md
106
+ - docs/DOCUMENTATION_PLAN.md
107
+ - docs/FINAL_SUMMARY.md
108
+ - docs/Gemfile
58
109
  - docs/POSTSCRIPT.adoc
110
+ - docs/README.md
111
+ - docs/_config.yml
112
+ - docs/advanced-topics.adoc
113
+ - docs/api-reference.adoc
114
+ - docs/api-reference/colors.adoc
115
+ - docs/api-reference/converter.adoc
116
+ - docs/api-reference/execution-context.adoc
117
+ - docs/api-reference/graphics-state.adoc
118
+ - docs/api-reference/interpreter.adoc
119
+ - docs/api-reference/matrix.adoc
120
+ - docs/api-reference/path-builder.adoc
121
+ - docs/api-reference/postsvg-module.adoc
122
+ - docs/api-reference/svg-generator.adoc
123
+ - docs/api-reference/tokenizer.adoc
124
+ - docs/architecture.adoc
125
+ - docs/architecture/command-registry.adoc
126
+ - docs/architecture/conversion-pipeline.adoc
127
+ - docs/architecture/design-decisions.adoc
128
+ - docs/architecture/generator-stage.adoc
129
+ - docs/architecture/graphics-state-model.adoc
130
+ - docs/architecture/interpreter-stage.adoc
131
+ - docs/architecture/parser-stage.adoc
132
+ - docs/cli-reference.adoc
133
+ - docs/cli-reference/batch-command.adoc
134
+ - docs/cli-reference/check-command.adoc
135
+ - docs/cli-reference/cli-options.adoc
136
+ - docs/cli-reference/convert-command.adoc
137
+ - docs/cli-reference/version-command.adoc
138
+ - docs/concepts.adoc
139
+ - docs/concepts/conversion-pipeline.adoc
140
+ - docs/concepts/coordinate-systems.adoc
141
+ - docs/concepts/graphics-state.adoc
142
+ - docs/concepts/path-operations.adoc
143
+ - docs/concepts/postscript-language.adoc
144
+ - docs/concepts/svg-generation.adoc
145
+ - docs/contributing.adoc
146
+ - docs/development.adoc
147
+ - docs/faq.adoc
148
+ - docs/getting-started.adoc
149
+ - docs/getting-started/basic-usage.adoc
150
+ - docs/getting-started/common-workflows.adoc
151
+ - docs/getting-started/first-conversion.adoc
152
+ - docs/getting-started/installation.adoc
153
+ - docs/index.adoc
154
+ - docs/optimization.adoc
59
155
  - docs/postscript/fundamentals.adoc
60
156
  - docs/postscript/graphics-model.adoc
61
157
  - docs/postscript/implementation-notes.adoc
@@ -70,31 +166,140 @@ files:
70
166
  - docs/postscript/operators/stack-manipulation.adoc
71
167
  - docs/postscript/operators/transformations.adoc
72
168
  - docs/postscript/svg-mapping.adoc
169
+ - docs/ps2svg_compatibility.adoc
170
+ - docs/quick-reference.adoc
171
+ - docs/sitemap.adoc
172
+ - docs/troubleshooting.adoc
173
+ - docs/validation.adoc
73
174
  - exe/postsvg
74
175
  - lib/postsvg.rb
75
176
  - lib/postsvg/cli.rb
177
+ - lib/postsvg/color.rb
76
178
  - lib/postsvg/colors.rb
77
179
  - lib/postsvg/converter.rb
78
180
  - lib/postsvg/errors.rb
181
+ - lib/postsvg/format_number.rb
182
+ - lib/postsvg/graphics_context.rb
183
+ - lib/postsvg/graphics_stack.rb
79
184
  - lib/postsvg/graphics_state.rb
80
185
  - lib/postsvg/interpreter.rb
81
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
213
+ - lib/postsvg/options.rb
82
214
  - lib/postsvg/parser.rb
83
215
  - lib/postsvg/parser/postscript_parser.rb
84
216
  - lib/postsvg/parser/transform.rb
85
217
  - lib/postsvg/path_builder.rb
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
224
+ - lib/postsvg/svg.rb
225
+ - lib/postsvg/svg/attribute_parser.rb
226
+ - lib/postsvg/svg/clip_path_registry.rb
227
+ - lib/postsvg/svg/document.rb
228
+ - lib/postsvg/svg/element.rb
229
+ - lib/postsvg/svg/elements.rb
230
+ - lib/postsvg/svg/elements/circle.rb
231
+ - lib/postsvg/svg/elements/clip_path.rb
232
+ - lib/postsvg/svg/elements/defs.rb
233
+ - lib/postsvg/svg/elements/ellipse.rb
234
+ - lib/postsvg/svg/elements/group.rb
235
+ - lib/postsvg/svg/elements/image.rb
236
+ - lib/postsvg/svg/elements/line.rb
237
+ - lib/postsvg/svg/elements/path.rb
238
+ - lib/postsvg/svg/elements/polygon.rb
239
+ - lib/postsvg/svg/elements/polyline.rb
240
+ - lib/postsvg/svg/elements/rect.rb
241
+ - lib/postsvg/svg/elements/svg.rb
242
+ - lib/postsvg/svg/elements/text.rb
243
+ - lib/postsvg/svg/paint.rb
244
+ - lib/postsvg/svg/parser.rb
245
+ - lib/postsvg/svg/path_data.rb
246
+ - lib/postsvg/svg/path_data/command.rb
247
+ - lib/postsvg/svg/path_data/parser.rb
248
+ - lib/postsvg/svg/stroke.rb
249
+ - lib/postsvg/svg/transform_list.rb
250
+ - lib/postsvg/svg_builder.rb
86
251
  - lib/postsvg/svg_generator.rb
87
252
  - lib/postsvg/tokenizer.rb
253
+ - lib/postsvg/translation.rb
254
+ - lib/postsvg/translation/arc_converter.rb
255
+ - lib/postsvg/translation/bounding_box.rb
256
+ - lib/postsvg/translation/context.rb
257
+ - lib/postsvg/translation/handler_registry.rb
258
+ - lib/postsvg/translation/handlers.rb
259
+ - lib/postsvg/translation/handlers/circle_handler.rb
260
+ - lib/postsvg/translation/handlers/clip_path_handler.rb
261
+ - lib/postsvg/translation/handlers/defs_handler.rb
262
+ - lib/postsvg/translation/handlers/ellipse_handler.rb
263
+ - lib/postsvg/translation/handlers/group_handler.rb
264
+ - lib/postsvg/translation/handlers/image_handler.rb
265
+ - lib/postsvg/translation/handlers/line_handler.rb
266
+ - lib/postsvg/translation/handlers/open_handler.rb
267
+ - lib/postsvg/translation/handlers/path_handler.rb
268
+ - lib/postsvg/translation/handlers/polygon_handler.rb
269
+ - lib/postsvg/translation/handlers/polyline_handler.rb
270
+ - lib/postsvg/translation/handlers/rect_handler.rb
271
+ - lib/postsvg/translation/handlers/shared.rb
272
+ - lib/postsvg/translation/handlers/svg_handler.rb
273
+ - lib/postsvg/translation/handlers/text_handler.rb
274
+ - lib/postsvg/translation/ps_renderer.rb
275
+ - lib/postsvg/translation/record_emitter.rb
88
276
  - lib/postsvg/version.rb
89
- - postsvg.gemspec
277
+ - lib/postsvg/visitors.rb
278
+ - lib/postsvg/visitors/ps_visitor.rb
279
+ - lib/postsvg/visitors/ps_visitor/arithmetic.rb
280
+ - lib/postsvg/visitors/ps_visitor/boolean.rb
281
+ - lib/postsvg/visitors/ps_visitor/color.rb
282
+ - lib/postsvg/visitors/ps_visitor/common.rb
283
+ - lib/postsvg/visitors/ps_visitor/container.rb
284
+ - lib/postsvg/visitors/ps_visitor/control_flow.rb
285
+ - lib/postsvg/visitors/ps_visitor/device.rb
286
+ - lib/postsvg/visitors/ps_visitor/dictionary.rb
287
+ - lib/postsvg/visitors/ps_visitor/font.rb
288
+ - lib/postsvg/visitors/ps_visitor/graphics_state.rb
289
+ - lib/postsvg/visitors/ps_visitor/painting.rb
290
+ - lib/postsvg/visitors/ps_visitor/path.rb
291
+ - lib/postsvg/visitors/ps_visitor/stack.rb
292
+ - lib/postsvg/visitors/ps_visitor/transformations.rb
293
+ - lychee.toml
90
294
  - scripts/regenerate_fixtures.rb
91
- homepage: https://github.com/metanorma/postsvg
295
+ homepage: https://github.com/claricle/postsvg
92
296
  licenses:
93
297
  - BSD-2-Clause
94
298
  metadata:
95
- homepage_uri: https://github.com/metanorma/postsvg
96
- source_code_uri: https://github.com/metanorma/postsvg
97
- changelog_uri: https://github.com/metanorma/postsvg
299
+ homepage_uri: https://github.com/claricle/postsvg
300
+ source_code_uri: https://github.com/claricle/postsvg
301
+ changelog_uri: https://github.com/claricle/postsvg/blob/main/CHANGELOG.md
302
+ bug_tracker_uri: https://github.com/claricle/postsvg/issues
98
303
  rubygems_mfa_required: 'true'
99
304
  post_install_message:
100
305
  rdoc_options: []
@@ -114,5 +319,5 @@ requirements: []
114
319
  rubygems_version: 3.5.22
115
320
  signing_key:
116
321
  specification_version: 4
117
- summary: Pure Ruby PostScript/EPS to SVG converter
322
+ summary: Pure Ruby bidirectional PS/EPS <-> SVG converter
118
323
  test_files: []
data/postsvg.gemspec DELETED
@@ -1,38 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "lib/postsvg/version"
4
-
5
- Gem::Specification.new do |spec|
6
- spec.name = "postsvg"
7
- spec.version = Postsvg::VERSION
8
- spec.authors = ["Ribose Inc."]
9
- spec.email = ["open.source@ribose.com"]
10
-
11
- spec.summary = "Pure Ruby PostScript/EPS to SVG converter"
12
- spec.description = <<~HEREDOC
13
- Postsvg provides a pure Ruby library for converting PostScript (PS) and
14
- Encapsulated PostScript (EPS) files to clean,
15
- standards-compliant Scalable Vector Graphics (SVG) format output.
16
- HEREDOC
17
-
18
- spec.homepage = "https://github.com/metanorma/postsvg"
19
- spec.license = "BSD-2-Clause"
20
- spec.required_ruby_version = ">= 3.0.0"
21
-
22
- spec.metadata["homepage_uri"] = spec.homepage
23
- spec.metadata["source_code_uri"] = "https://github.com/metanorma/postsvg"
24
- spec.metadata["changelog_uri"] = "https://github.com/metanorma/postsvg"
25
- spec.metadata["rubygems_mfa_required"] = "true"
26
-
27
- spec.files = Dir.chdir(__dir__) do
28
- `git ls-files -z`.split("\x0").reject do |f|
29
- (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
30
- end
31
- end
32
- spec.bindir = "exe"
33
- spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
34
- spec.require_paths = ["lib"]
35
-
36
- spec.add_dependency "parslet"
37
- spec.add_dependency "thor"
38
- end