postsvg 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rubocop.yml +19 -0
- data/.rubocop_todo.yml +141 -0
- data/Gemfile +15 -0
- data/LICENSE +25 -0
- data/README.adoc +473 -0
- data/Rakefile +10 -0
- data/docs/POSTSCRIPT.adoc +13 -0
- data/docs/postscript/fundamentals.adoc +356 -0
- data/docs/postscript/graphics-model.adoc +406 -0
- data/docs/postscript/implementation-notes.adoc +314 -0
- data/docs/postscript/index.adoc +153 -0
- data/docs/postscript/operators/arithmetic.adoc +461 -0
- data/docs/postscript/operators/control-flow.adoc +230 -0
- data/docs/postscript/operators/dictionary.adoc +191 -0
- data/docs/postscript/operators/graphics-state.adoc +528 -0
- data/docs/postscript/operators/index.adoc +288 -0
- data/docs/postscript/operators/painting.adoc +475 -0
- data/docs/postscript/operators/path-construction.adoc +553 -0
- data/docs/postscript/operators/stack-manipulation.adoc +374 -0
- data/docs/postscript/operators/transformations.adoc +479 -0
- data/docs/postscript/svg-mapping.adoc +369 -0
- data/exe/postsvg +6 -0
- data/lib/postsvg/cli.rb +103 -0
- data/lib/postsvg/colors.rb +33 -0
- data/lib/postsvg/converter.rb +214 -0
- data/lib/postsvg/errors.rb +11 -0
- data/lib/postsvg/graphics_state.rb +158 -0
- data/lib/postsvg/interpreter.rb +891 -0
- data/lib/postsvg/matrix.rb +106 -0
- data/lib/postsvg/parser/postscript_parser.rb +87 -0
- data/lib/postsvg/parser/transform.rb +21 -0
- data/lib/postsvg/parser.rb +18 -0
- data/lib/postsvg/path_builder.rb +101 -0
- data/lib/postsvg/svg_generator.rb +78 -0
- data/lib/postsvg/tokenizer.rb +161 -0
- data/lib/postsvg/version.rb +5 -0
- data/lib/postsvg.rb +78 -0
- data/postsvg.gemspec +38 -0
- data/scripts/regenerate_fixtures.rb +28 -0
- metadata +118 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 0a2ecbfa1ecb4e8bc18ce43304e7ea828054d255bb2183e9356cf08742e91483
|
|
4
|
+
data.tar.gz: c7520e5a867bd4992d169ffa496cfc70eb36dba2bddfc78a1c472b3b21009020
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 212ad8d736573633ab5d335908e1305f89e621e7389740420858fbaacf6c982165af4b69a0c154e21ff0ea456e3e0343c88b9d06c43a2c1b47202dc31078511e
|
|
7
|
+
data.tar.gz: 91f449c7d4a7a09560215bae0f83b58410ca64a472c43c97af9322198e1d2c249442263cdfe5aa41163735bdcd5728211169b30f67feeeaefb14a66e096b5f8f
|
data/.rubocop.yml
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Auto-generated by Cimas: Do not edit it manually!
|
|
2
|
+
# See https://github.com/metanorma/cimas
|
|
3
|
+
inherit_from:
|
|
4
|
+
- https://raw.githubusercontent.com/riboseinc/oss-guides/main/ci/rubocop.yml
|
|
5
|
+
- .rubocop_todo.yml
|
|
6
|
+
|
|
7
|
+
inherit_mode:
|
|
8
|
+
merge:
|
|
9
|
+
- Exclude
|
|
10
|
+
|
|
11
|
+
# local repo-specific modifications
|
|
12
|
+
# ...
|
|
13
|
+
plugins:
|
|
14
|
+
- rubocop-rspec
|
|
15
|
+
- rubocop-performance
|
|
16
|
+
- rubocop-rake
|
|
17
|
+
|
|
18
|
+
AllCops:
|
|
19
|
+
TargetRubyVersion: 3.0
|
data/.rubocop_todo.yml
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# This configuration was generated by
|
|
2
|
+
# `rubocop --auto-gen-config`
|
|
3
|
+
# on 2025-10-19 09:58:29 UTC using RuboCop version 1.81.1.
|
|
4
|
+
# The point is for the user to remove these configuration records
|
|
5
|
+
# one by one as the offenses are removed from the code base.
|
|
6
|
+
# Note that changes in the inspected code, or installation of new
|
|
7
|
+
# versions of RuboCop, may require this file to be generated again.
|
|
8
|
+
|
|
9
|
+
# Offense count: 36
|
|
10
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
11
|
+
# Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, IgnoreCopDirectives, AllowedPatterns, SplitStrings.
|
|
12
|
+
# URISchemes: http, https
|
|
13
|
+
Layout/LineLength:
|
|
14
|
+
Exclude:
|
|
15
|
+
- 'lib/postsvg.rb'
|
|
16
|
+
- 'lib/postsvg/converter.rb'
|
|
17
|
+
- 'lib/postsvg/graphics_state.rb'
|
|
18
|
+
- 'lib/postsvg/interpreter.rb'
|
|
19
|
+
- 'lib/postsvg/parser/postscript_parser.rb'
|
|
20
|
+
- 'lib/postsvg/tokenizer.rb'
|
|
21
|
+
- 'postsvg.gemspec'
|
|
22
|
+
- 'scripts/regenerate_fixtures.rb'
|
|
23
|
+
|
|
24
|
+
# Offense count: 5
|
|
25
|
+
# Configuration parameters: IgnoreLiteralBranches, IgnoreConstantBranches, IgnoreDuplicateElseBranch.
|
|
26
|
+
Lint/DuplicateBranch:
|
|
27
|
+
Exclude:
|
|
28
|
+
- 'lib/postsvg/converter.rb'
|
|
29
|
+
- 'lib/postsvg/interpreter.rb'
|
|
30
|
+
|
|
31
|
+
# Offense count: 1
|
|
32
|
+
Lint/DuplicateCaseCondition:
|
|
33
|
+
Exclude:
|
|
34
|
+
- 'lib/postsvg/converter.rb'
|
|
35
|
+
|
|
36
|
+
# Offense count: 29
|
|
37
|
+
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
|
|
38
|
+
Metrics/AbcSize:
|
|
39
|
+
Exclude:
|
|
40
|
+
- 'lib/postsvg.rb'
|
|
41
|
+
- 'lib/postsvg/cli.rb'
|
|
42
|
+
- 'lib/postsvg/colors.rb'
|
|
43
|
+
- 'lib/postsvg/converter.rb'
|
|
44
|
+
- 'lib/postsvg/graphics_state.rb'
|
|
45
|
+
- 'lib/postsvg/interpreter.rb'
|
|
46
|
+
- 'lib/postsvg/matrix.rb'
|
|
47
|
+
- 'lib/postsvg/path_builder.rb'
|
|
48
|
+
- 'lib/postsvg/svg_generator.rb'
|
|
49
|
+
- 'lib/postsvg/tokenizer.rb'
|
|
50
|
+
|
|
51
|
+
# Offense count: 1
|
|
52
|
+
# Configuration parameters: CountBlocks, CountModifierForms.
|
|
53
|
+
Metrics/BlockNesting:
|
|
54
|
+
Max: 6
|
|
55
|
+
|
|
56
|
+
# Offense count: 14
|
|
57
|
+
# Configuration parameters: AllowedMethods, AllowedPatterns, Max.
|
|
58
|
+
Metrics/CyclomaticComplexity:
|
|
59
|
+
Exclude:
|
|
60
|
+
- 'lib/postsvg/cli.rb'
|
|
61
|
+
- 'lib/postsvg/converter.rb'
|
|
62
|
+
- 'lib/postsvg/interpreter.rb'
|
|
63
|
+
- 'lib/postsvg/tokenizer.rb'
|
|
64
|
+
|
|
65
|
+
# Offense count: 30
|
|
66
|
+
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
|
|
67
|
+
Metrics/MethodLength:
|
|
68
|
+
Max: 111
|
|
69
|
+
|
|
70
|
+
# Offense count: 5
|
|
71
|
+
# Configuration parameters: CountKeywordArgs, MaxOptionalParameters.
|
|
72
|
+
Metrics/ParameterLists:
|
|
73
|
+
Max: 7
|
|
74
|
+
|
|
75
|
+
# Offense count: 13
|
|
76
|
+
# Configuration parameters: AllowedMethods, AllowedPatterns, Max.
|
|
77
|
+
Metrics/PerceivedComplexity:
|
|
78
|
+
Exclude:
|
|
79
|
+
- 'lib/postsvg/cli.rb'
|
|
80
|
+
- 'lib/postsvg/converter.rb'
|
|
81
|
+
- 'lib/postsvg/interpreter.rb'
|
|
82
|
+
- 'lib/postsvg/tokenizer.rb'
|
|
83
|
+
|
|
84
|
+
# Offense count: 67
|
|
85
|
+
# Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames.
|
|
86
|
+
# AllowedNames: as, at, by, cc, db, id, if, in, io, ip, of, on, os, pp, to
|
|
87
|
+
Naming/MethodParameterName:
|
|
88
|
+
Exclude:
|
|
89
|
+
- 'lib/postsvg.rb'
|
|
90
|
+
- 'lib/postsvg/converter.rb'
|
|
91
|
+
- 'lib/postsvg/graphics_state.rb'
|
|
92
|
+
- 'lib/postsvg/interpreter.rb'
|
|
93
|
+
- 'lib/postsvg/matrix.rb'
|
|
94
|
+
- 'lib/postsvg/path_builder.rb'
|
|
95
|
+
- 'lib/postsvg/tokenizer.rb'
|
|
96
|
+
|
|
97
|
+
# Offense count: 1
|
|
98
|
+
# Configuration parameters: NamePrefix, ForbiddenPrefixes, AllowedMethods, MethodDefinitionMacros, UseSorbetSigs.
|
|
99
|
+
# NamePrefix: is_, has_, have_, does_
|
|
100
|
+
# ForbiddenPrefixes: is_, has_, have_, does_
|
|
101
|
+
# AllowedMethods: is_a?
|
|
102
|
+
# MethodDefinitionMacros: define_method, define_singleton_method
|
|
103
|
+
Naming/PredicatePrefix:
|
|
104
|
+
Exclude:
|
|
105
|
+
- 'lib/postsvg/interpreter.rb'
|
|
106
|
+
|
|
107
|
+
# Offense count: 3
|
|
108
|
+
# Configuration parameters: MinSize.
|
|
109
|
+
Performance/CollectionLiteralInLoop:
|
|
110
|
+
Exclude:
|
|
111
|
+
- 'lib/postsvg/interpreter.rb'
|
|
112
|
+
|
|
113
|
+
# Offense count: 1
|
|
114
|
+
# Configuration parameters: IgnoredMetadata.
|
|
115
|
+
RSpec/DescribeClass:
|
|
116
|
+
Exclude:
|
|
117
|
+
- 'spec/postsvg/integration_spec.rb'
|
|
118
|
+
|
|
119
|
+
# Offense count: 7
|
|
120
|
+
# Configuration parameters: CountAsOne.
|
|
121
|
+
RSpec/ExampleLength:
|
|
122
|
+
Max: 16
|
|
123
|
+
|
|
124
|
+
# Offense count: 3
|
|
125
|
+
RSpec/MultipleExpectations:
|
|
126
|
+
Max: 4
|
|
127
|
+
|
|
128
|
+
# Offense count: 1
|
|
129
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
130
|
+
# Configuration parameters: EnforcedStyle, AllowComments.
|
|
131
|
+
# SupportedStyles: empty, nil, both
|
|
132
|
+
Style/EmptyElse:
|
|
133
|
+
Exclude:
|
|
134
|
+
- 'lib/postsvg/converter.rb'
|
|
135
|
+
|
|
136
|
+
# Offense count: 12
|
|
137
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
138
|
+
# Configuration parameters: MaxUnannotatedPlaceholdersAllowed, Mode, AllowedMethods, AllowedPatterns.
|
|
139
|
+
# SupportedStyles: annotated, template, unannotated
|
|
140
|
+
Style/FormatStringToken:
|
|
141
|
+
EnforcedStyle: unannotated
|
data/Gemfile
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
source "https://rubygems.org"
|
|
4
|
+
|
|
5
|
+
# Specify your gem's dependencies in xml-c14n.gemspec
|
|
6
|
+
gemspec
|
|
7
|
+
|
|
8
|
+
gem "canon", github: "lutaml/canon",
|
|
9
|
+
branch: "rt-update-behavior-prevent-data-loss"
|
|
10
|
+
gem "rake"
|
|
11
|
+
gem "rspec"
|
|
12
|
+
gem "rubocop"
|
|
13
|
+
gem "rubocop-performance"
|
|
14
|
+
gem "rubocop-rake"
|
|
15
|
+
gem "rubocop-rspec"
|
data/LICENSE
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
BSD 2-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025, Ribose Inc.
|
|
4
|
+
All rights reserved.
|
|
5
|
+
|
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
|
7
|
+
modification, are permitted provided that the following conditions are met:
|
|
8
|
+
|
|
9
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
10
|
+
list of conditions and the following disclaimer.
|
|
11
|
+
|
|
12
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
13
|
+
this list of conditions and the following disclaimer in the documentation
|
|
14
|
+
and/or other materials provided with the distribution.
|
|
15
|
+
|
|
16
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
17
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
18
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
19
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
20
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
21
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
22
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
23
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
24
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
25
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.adoc
ADDED
|
@@ -0,0 +1,473 @@
|
|
|
1
|
+
= Postsvg
|
|
2
|
+
|
|
3
|
+
image:https://img.shields.io/gem/v/postsvg.svg[Gem Version,
|
|
4
|
+
link=https://rubygems.org/gems/postsvg]
|
|
5
|
+
image:https://github.com/metanorma/postsvg/actions/workflows/test.yml/badge.svg[Build Status,
|
|
6
|
+
link=https://github.com/metanorma/postsvg/actions/workflows/test.yml]
|
|
7
|
+
image:https://img.shields.io/github/license/metanorma/postsvg.svg[License]
|
|
8
|
+
|
|
9
|
+
== Purpose
|
|
10
|
+
|
|
11
|
+
Postsvg is a pure Ruby library for converting PostScript (PS) and
|
|
12
|
+
Encapsulated PostScript (EPS) files to Scalable Vector Graphics (SVG)
|
|
13
|
+
format.
|
|
14
|
+
|
|
15
|
+
Unlike traditional approaches that rely on external tools like
|
|
16
|
+
Ghostscript or Inkscape, Postsvg provides a native Ruby implementation
|
|
17
|
+
using Parslet for parsing PostScript commands and generating clean,
|
|
18
|
+
standards-compliant SVG output.
|
|
19
|
+
|
|
20
|
+
This library is particularly useful for applications that need to:
|
|
21
|
+
|
|
22
|
+
* Convert legacy PostScript graphics to modern SVG format
|
|
23
|
+
* Process vector graphics without external dependencies
|
|
24
|
+
* Generate SVG from PostScript programmatically
|
|
25
|
+
* Work with EPS files in pure Ruby environments
|
|
26
|
+
|
|
27
|
+
== Features
|
|
28
|
+
|
|
29
|
+
* <<basic-conversion,Basic PostScript to SVG conversion>> - Ruby API
|
|
30
|
+
for converting PS/EPS content to SVG
|
|
31
|
+
* <<cli,Command-line interface>> - Thor-based CLI for file and batch
|
|
32
|
+
conversions
|
|
33
|
+
* <<postscript-language,PostScript language support>> - Comprehensive
|
|
34
|
+
documentation and implementation
|
|
35
|
+
* <<architecture,Pure Ruby architecture>> - No external dependencies,
|
|
36
|
+
Parslet-based parser
|
|
37
|
+
|
|
38
|
+
== Architecture
|
|
39
|
+
|
|
40
|
+
[[architecture]]
|
|
41
|
+
|
|
42
|
+
=== General
|
|
43
|
+
|
|
44
|
+
Postsvg uses a three-stage architecture for converting PostScript to
|
|
45
|
+
SVG. This design follows separation of concerns principles, with each
|
|
46
|
+
component handling a specific responsibility in the conversion process.
|
|
47
|
+
|
|
48
|
+
.PostScript to SVG conversion pipeline
|
|
49
|
+
[source]
|
|
50
|
+
----
|
|
51
|
+
┌─────────────┐ ┌───────────┐ ┌──────────────┐
|
|
52
|
+
│ PostScript │──> │ Parser │──> │ Converter │
|
|
53
|
+
│ Input │ │ (Parslet) │ │ (Interpreter)│
|
|
54
|
+
└─────────────┘ └───────────┘ └───────┬──────┘
|
|
55
|
+
│
|
|
56
|
+
▼
|
|
57
|
+
┌─────────────────┐
|
|
58
|
+
│ SVG Generator │
|
|
59
|
+
└────────┬────────┘
|
|
60
|
+
│
|
|
61
|
+
▼
|
|
62
|
+
┌─────────────────┐
|
|
63
|
+
│ SVG Output │
|
|
64
|
+
└─────────────────┘
|
|
65
|
+
----
|
|
66
|
+
|
|
67
|
+
=== Parser stage
|
|
68
|
+
|
|
69
|
+
The parser uses Parslet to tokenize and parse PostScript commands into
|
|
70
|
+
an abstract syntax tree (AST). The parser handles PostScript syntax
|
|
71
|
+
including numbers, operators, names, strings, arrays, and procedures.
|
|
72
|
+
|
|
73
|
+
* `Postsvg::Parser::PostscriptParser` - Parslet grammar for PostScript
|
|
74
|
+
syntax
|
|
75
|
+
* `Postsvg::Parser::Transform` - Transforms AST into Ruby data
|
|
76
|
+
structures
|
|
77
|
+
|
|
78
|
+
=== Converter stage
|
|
79
|
+
|
|
80
|
+
The converter interprets PostScript commands using a stack-based
|
|
81
|
+
execution model. It maintains an operand stack, dictionary, and graphics
|
|
82
|
+
state while executing PostScript operators.
|
|
83
|
+
|
|
84
|
+
* `Postsvg::Converter` - Main orchestrator that executes PostScript
|
|
85
|
+
commands
|
|
86
|
+
* `Postsvg::GraphicsState` - Manages current path, colors,
|
|
87
|
+
transformations, and graphics state stack
|
|
88
|
+
|
|
89
|
+
=== Generator stage
|
|
90
|
+
|
|
91
|
+
The generator creates SVG output from the interpreted graphics
|
|
92
|
+
operations, handling coordinate system transformations and generating
|
|
93
|
+
standards-compliant SVG markup.
|
|
94
|
+
|
|
95
|
+
* `Postsvg::SvgGenerator` - Builds SVG document with proper structure
|
|
96
|
+
and viewBox
|
|
97
|
+
|
|
98
|
+
== Installation
|
|
99
|
+
|
|
100
|
+
Add this line to your application's Gemfile:
|
|
101
|
+
|
|
102
|
+
[source,ruby]
|
|
103
|
+
----
|
|
104
|
+
gem "postsvg"
|
|
105
|
+
----
|
|
106
|
+
|
|
107
|
+
And then execute:
|
|
108
|
+
|
|
109
|
+
[source,sh]
|
|
110
|
+
----
|
|
111
|
+
bundle install
|
|
112
|
+
----
|
|
113
|
+
|
|
114
|
+
Or install it yourself as:
|
|
115
|
+
|
|
116
|
+
[source,sh]
|
|
117
|
+
----
|
|
118
|
+
gem install postsvg
|
|
119
|
+
----
|
|
120
|
+
|
|
121
|
+
== Basic PostScript to SVG conversion
|
|
122
|
+
|
|
123
|
+
[[basic-conversion]]
|
|
124
|
+
|
|
125
|
+
=== General
|
|
126
|
+
|
|
127
|
+
The Postsvg library provides a simple Ruby API for converting PostScript
|
|
128
|
+
content to SVG format. The conversion can be performed on in-memory
|
|
129
|
+
content or directly on files.
|
|
130
|
+
|
|
131
|
+
The library automatically handles BoundingBox extraction, coordinate
|
|
132
|
+
system transformations, and SVG generation while preserving the visual
|
|
133
|
+
appearance of the original PostScript graphics.
|
|
134
|
+
|
|
135
|
+
=== Converting PostScript content
|
|
136
|
+
|
|
137
|
+
Syntax:
|
|
138
|
+
|
|
139
|
+
[source,ruby]
|
|
140
|
+
----
|
|
141
|
+
svg_output = Postsvg.convert(ps_content) <1>
|
|
142
|
+
----
|
|
143
|
+
<1> Convert PostScript string to SVG string
|
|
144
|
+
|
|
145
|
+
Where,
|
|
146
|
+
|
|
147
|
+
`ps_content`:: PostScript or EPS content as a string. Should include
|
|
148
|
+
proper PostScript header and BoundingBox comment for best results.
|
|
149
|
+
|
|
150
|
+
Returns:: SVG markup as a string
|
|
151
|
+
|
|
152
|
+
.Converting PostScript content to SVG
|
|
153
|
+
[example]
|
|
154
|
+
====
|
|
155
|
+
[source,ruby]
|
|
156
|
+
----
|
|
157
|
+
require "postsvg"
|
|
158
|
+
|
|
159
|
+
ps_content = <<~PS
|
|
160
|
+
%!PS-Adobe-3.0 EPSF-3.0
|
|
161
|
+
%%BoundingBox: 0 0 100 100
|
|
162
|
+
newpath
|
|
163
|
+
10 10 moveto
|
|
164
|
+
90 10 lineto
|
|
165
|
+
90 90 lineto
|
|
166
|
+
10 90 lineto
|
|
167
|
+
closepath
|
|
168
|
+
0.5 0.5 0.5 setrgbcolor
|
|
169
|
+
fill
|
|
170
|
+
PS
|
|
171
|
+
|
|
172
|
+
svg = Postsvg.convert(ps_content)
|
|
173
|
+
File.write("output.svg", svg)
|
|
174
|
+
----
|
|
175
|
+
|
|
176
|
+
This converts a PostScript square with gray fill to SVG format and saves
|
|
177
|
+
it to a file.
|
|
178
|
+
====
|
|
179
|
+
|
|
180
|
+
=== Converting PostScript files
|
|
181
|
+
|
|
182
|
+
Syntax:
|
|
183
|
+
|
|
184
|
+
[source,ruby]
|
|
185
|
+
----
|
|
186
|
+
Postsvg.convert_file(input_path, output_path) <1>
|
|
187
|
+
svg_content = Postsvg.convert_file(input_path) <2>
|
|
188
|
+
----
|
|
189
|
+
<1> Convert file and save to output path
|
|
190
|
+
<2> Convert file and return SVG content without saving
|
|
191
|
+
|
|
192
|
+
Where,
|
|
193
|
+
|
|
194
|
+
`input_path`:: Path to input PostScript (.ps) or EPS (.eps) file
|
|
195
|
+
`output_path`:: (Optional) Path where SVG file should be saved. If
|
|
196
|
+
omitted, SVG content is returned without saving.
|
|
197
|
+
|
|
198
|
+
Returns:: When `output_path` is omitted, returns SVG markup as a string.
|
|
199
|
+
When `output_path` is provided, returns the output path.
|
|
200
|
+
|
|
201
|
+
.Converting a PostScript file to SVG
|
|
202
|
+
[example]
|
|
203
|
+
====
|
|
204
|
+
[source,ruby]
|
|
205
|
+
----
|
|
206
|
+
require "postsvg"
|
|
207
|
+
|
|
208
|
+
# Convert and save in one step
|
|
209
|
+
Postsvg.convert_file("input.eps", "output.svg")
|
|
210
|
+
|
|
211
|
+
# Or get SVG content without saving
|
|
212
|
+
svg_content = Postsvg.convert_file("input.ps")
|
|
213
|
+
puts svg_content
|
|
214
|
+
----
|
|
215
|
+
|
|
216
|
+
The first example converts an EPS file and saves the result as SVG. The
|
|
217
|
+
second example reads a PostScript file and returns the SVG content for
|
|
218
|
+
further processing.
|
|
219
|
+
====
|
|
220
|
+
|
|
221
|
+
== Command-line interface
|
|
222
|
+
|
|
223
|
+
[[cli]]
|
|
224
|
+
|
|
225
|
+
=== General
|
|
226
|
+
|
|
227
|
+
Postsvg provides a Thor-based command-line interface for converting
|
|
228
|
+
PostScript and EPS files to SVG format. The CLI supports single file
|
|
229
|
+
conversion, batch processing, and version information.
|
|
230
|
+
|
|
231
|
+
The CLI is available through the `postsvg` executable installed with the
|
|
232
|
+
gem.
|
|
233
|
+
|
|
234
|
+
=== Converting single files
|
|
235
|
+
|
|
236
|
+
Syntax:
|
|
237
|
+
|
|
238
|
+
[source,sh]
|
|
239
|
+
----
|
|
240
|
+
postsvg convert INPUT_FILE [OUTPUT_FILE] <1>
|
|
241
|
+
----
|
|
242
|
+
<1> Convert INPUT_FILE to SVG, optionally saving to OUTPUT_FILE
|
|
243
|
+
|
|
244
|
+
Where,
|
|
245
|
+
|
|
246
|
+
`INPUT_FILE`:: Path to input PostScript (.ps) or EPS (.eps) file
|
|
247
|
+
`OUTPUT_FILE`:: (Optional) Path where SVG file should be saved. If
|
|
248
|
+
omitted, SVG is written to stdout.
|
|
249
|
+
|
|
250
|
+
.Converting a single PostScript file
|
|
251
|
+
[example]
|
|
252
|
+
====
|
|
253
|
+
[source,sh]
|
|
254
|
+
----
|
|
255
|
+
# Convert to stdout
|
|
256
|
+
postsvg convert input.ps
|
|
257
|
+
|
|
258
|
+
# Convert and save to file
|
|
259
|
+
postsvg convert input.eps output.svg
|
|
260
|
+
|
|
261
|
+
# Redirect stdout to file
|
|
262
|
+
postsvg convert input.ps > output.svg
|
|
263
|
+
----
|
|
264
|
+
|
|
265
|
+
The first command prints SVG to stdout. The second saves directly to
|
|
266
|
+
output.svg. The third uses shell redirection to save the output.
|
|
267
|
+
====
|
|
268
|
+
|
|
269
|
+
=== Batch conversion
|
|
270
|
+
|
|
271
|
+
Syntax:
|
|
272
|
+
|
|
273
|
+
[source,sh]
|
|
274
|
+
----
|
|
275
|
+
postsvg batch INPUT_DIR [OUTPUT_DIR] <1>
|
|
276
|
+
----
|
|
277
|
+
<1> Convert all PS/EPS files in INPUT_DIR, optionally saving to
|
|
278
|
+
OUTPUT_DIR
|
|
279
|
+
|
|
280
|
+
Where,
|
|
281
|
+
|
|
282
|
+
`INPUT_DIR`:: Directory containing PostScript (.ps) and/or EPS (.eps)
|
|
283
|
+
files to convert
|
|
284
|
+
`OUTPUT_DIR`:: (Optional) Directory where SVG files should be saved. If
|
|
285
|
+
omitted, SVG files are saved in the same directory as input files with
|
|
286
|
+
.svg extension.
|
|
287
|
+
|
|
288
|
+
.Batch converting PostScript files
|
|
289
|
+
[example]
|
|
290
|
+
====
|
|
291
|
+
[source,sh]
|
|
292
|
+
----
|
|
293
|
+
# Convert all PS/EPS files in a directory
|
|
294
|
+
postsvg batch ps_files/
|
|
295
|
+
|
|
296
|
+
# Convert to a different directory
|
|
297
|
+
postsvg batch ps_files/ svg_files/
|
|
298
|
+
----
|
|
299
|
+
|
|
300
|
+
The first example converts all PS and EPS files in the `ps_files/`
|
|
301
|
+
directory, saving the SVG files in the same directory. The second
|
|
302
|
+
example saves the converted files to the `svg_files/` directory.
|
|
303
|
+
====
|
|
304
|
+
|
|
305
|
+
=== Displaying version information
|
|
306
|
+
|
|
307
|
+
Syntax:
|
|
308
|
+
|
|
309
|
+
[source,sh]
|
|
310
|
+
----
|
|
311
|
+
postsvg version <1>
|
|
312
|
+
----
|
|
313
|
+
<1> Display the Postsvg version number
|
|
314
|
+
|
|
315
|
+
.Getting version information
|
|
316
|
+
[example]
|
|
317
|
+
====
|
|
318
|
+
[source,sh]
|
|
319
|
+
----
|
|
320
|
+
postsvg version
|
|
321
|
+
----
|
|
322
|
+
|
|
323
|
+
Output:
|
|
324
|
+
----
|
|
325
|
+
postsvg version 0.1.0
|
|
326
|
+
----
|
|
327
|
+
====
|
|
328
|
+
|
|
329
|
+
== PostScript language support
|
|
330
|
+
|
|
331
|
+
[[postscript-language]]
|
|
332
|
+
|
|
333
|
+
=== General
|
|
334
|
+
|
|
335
|
+
Postsvg provides comprehensive PostScript language support with detailed
|
|
336
|
+
documentation covering fundamentals, operators, and conversion
|
|
337
|
+
strategies.
|
|
338
|
+
|
|
339
|
+
The implementation supports common PostScript operations including path
|
|
340
|
+
construction, painting, color management, graphics state, and coordinate
|
|
341
|
+
transformations.
|
|
342
|
+
|
|
343
|
+
=== PostScript documentation
|
|
344
|
+
|
|
345
|
+
Complete PostScript language documentation is available at
|
|
346
|
+
link:docs/POSTSCRIPT.adoc[docs/POSTSCRIPT.adoc], organized into the
|
|
347
|
+
following topics:
|
|
348
|
+
|
|
349
|
+
* link:docs/postscript/fundamentals.adoc[Fundamentals] - PostScript
|
|
350
|
+
language basics, syntax, and data types
|
|
351
|
+
* link:docs/postscript/graphics-model.adoc[Graphics model] - Coordinate
|
|
352
|
+
systems, paths, and painting model
|
|
353
|
+
* link:docs/postscript/operators/index.adoc[Operators reference] -
|
|
354
|
+
Detailed documentation for all supported operators:
|
|
355
|
+
** link:docs/postscript/operators/path-construction.adoc[Path
|
|
356
|
+
construction] - moveto, lineto, curveto, closepath, newpath
|
|
357
|
+
** link:docs/postscript/operators/painting.adoc[Painting] - stroke,
|
|
358
|
+
fill
|
|
359
|
+
** link:docs/postscript/operators/graphics-state.adoc[Graphics state] -
|
|
360
|
+
gsave, grestore, setlinewidth
|
|
361
|
+
** link:docs/postscript/operators/transformations.adoc[Transformations]
|
|
362
|
+
- translate, scale, rotate
|
|
363
|
+
** link:docs/postscript/operators/stack-manipulation.adoc[Stack
|
|
364
|
+
manipulation] - dup, pop, exch, roll
|
|
365
|
+
** link:docs/postscript/operators/arithmetic.adoc[Arithmetic] - add,
|
|
366
|
+
sub, mul, div
|
|
367
|
+
** link:docs/postscript/operators/control-flow.adoc[Control flow] - if,
|
|
368
|
+
ifelse, for, repeat
|
|
369
|
+
** link:docs/postscript/operators/dictionary.adoc[Dictionary] - def,
|
|
370
|
+
dict, begin, end
|
|
371
|
+
* link:docs/postscript/svg-mapping.adoc[SVG mapping guide] - How
|
|
372
|
+
PostScript operations map to SVG
|
|
373
|
+
* link:docs/postscript/implementation-notes.adoc[Implementation notes] -
|
|
374
|
+
Postsvg-specific details and design decisions
|
|
375
|
+
|
|
376
|
+
=== Supported PostScript operations
|
|
377
|
+
|
|
378
|
+
==== Path construction
|
|
379
|
+
|
|
380
|
+
* `moveto` - Begin new subpath at coordinates
|
|
381
|
+
* `lineto` - Append straight line segment
|
|
382
|
+
* `rlineto` - Append relative line segment
|
|
383
|
+
* `curveto` - Append cubic Bézier curve
|
|
384
|
+
* `closepath` - Close current subpath
|
|
385
|
+
* `newpath` - Initialize new path
|
|
386
|
+
|
|
387
|
+
==== Painting
|
|
388
|
+
|
|
389
|
+
* `stroke` - Stroke current path with current color and line width
|
|
390
|
+
* `fill` - Fill current path with current color
|
|
391
|
+
|
|
392
|
+
==== Color
|
|
393
|
+
|
|
394
|
+
* `setrgbcolor` - Set RGB color (0-1 range for each component)
|
|
395
|
+
* `setgray` - Set grayscale color (0-1 range)
|
|
396
|
+
|
|
397
|
+
==== Graphics state
|
|
398
|
+
|
|
399
|
+
* `gsave` - Save current graphics state to stack
|
|
400
|
+
* `grestore` - Restore graphics state from stack
|
|
401
|
+
* `setlinewidth` - Set line width for stroke operations
|
|
402
|
+
|
|
403
|
+
==== Transformations
|
|
404
|
+
|
|
405
|
+
* `translate` - Translate coordinate system
|
|
406
|
+
* `scale` - Scale coordinate system
|
|
407
|
+
* `rotate` - Rotate coordinate system (angle in degrees)
|
|
408
|
+
|
|
409
|
+
== Limitations
|
|
410
|
+
|
|
411
|
+
Current version has the following limitations:
|
|
412
|
+
|
|
413
|
+
* Text rendering: Text operations (show, findfont, setfont, etc.) are
|
|
414
|
+
not yet supported. Convert text to outlines before processing.
|
|
415
|
+
* Complex clipping: Clipping paths (clip, eoclip) are not fully
|
|
416
|
+
implemented
|
|
417
|
+
* Gradients and patterns: Pattern fills and gradient operations are not
|
|
418
|
+
yet supported
|
|
419
|
+
* CMYK colors: Only RGB and grayscale colors are supported. CMYK color
|
|
420
|
+
operations will need conversion.
|
|
421
|
+
* Image embedding: Raster images within PostScript (image, imagemask)
|
|
422
|
+
are not supported
|
|
423
|
+
* Advanced operators: Some PostScript Level 2 and 3 operators are not
|
|
424
|
+
yet implemented
|
|
425
|
+
|
|
426
|
+
For files with these features, consider preprocessing with external
|
|
427
|
+
tools or contributing implementations of these features.
|
|
428
|
+
|
|
429
|
+
== Acknowledgments
|
|
430
|
+
|
|
431
|
+
This project uses test fixtures from
|
|
432
|
+
https://github.com/elalish/ps2svg[ps2svg] by Emmett Lalish, licensed
|
|
433
|
+
under the MIT License. These test files help ensure the correctness of
|
|
434
|
+
our SVG generation against a reference implementation. We are grateful
|
|
435
|
+
for this valuable resource that helps validate PostScript to SVG
|
|
436
|
+
conversion.
|
|
437
|
+
|
|
438
|
+
== Development
|
|
439
|
+
|
|
440
|
+
=== Running tests
|
|
441
|
+
|
|
442
|
+
[source,sh]
|
|
443
|
+
----
|
|
444
|
+
bundle exec rspec
|
|
445
|
+
----
|
|
446
|
+
|
|
447
|
+
=== Code style
|
|
448
|
+
|
|
449
|
+
[source,sh]
|
|
450
|
+
----
|
|
451
|
+
bundle exec rubocop
|
|
452
|
+
----
|
|
453
|
+
|
|
454
|
+
=== Running all checks
|
|
455
|
+
|
|
456
|
+
[source,sh]
|
|
457
|
+
----
|
|
458
|
+
bundle exec rake
|
|
459
|
+
----
|
|
460
|
+
|
|
461
|
+
== Contributing
|
|
462
|
+
|
|
463
|
+
Bug reports and pull requests are welcome on GitHub at
|
|
464
|
+
https://github.com/metanorma/postsvg.
|
|
465
|
+
|
|
466
|
+
== Copyright
|
|
467
|
+
|
|
468
|
+
Copyright Ribose.
|
|
469
|
+
|
|
470
|
+
== License
|
|
471
|
+
|
|
472
|
+
The gem is available as open source under the terms of the
|
|
473
|
+
https://opensource.org/licenses/BSD-2-Clause[BSD 2-Clause License].
|
data/Rakefile
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
= PostScript Language Reference
|
|
2
|
+
|
|
3
|
+
For comprehensive PostScript documentation for the Postsvg library, see:
|
|
4
|
+
|
|
5
|
+
* link:postscript/index.adoc[PostScript Quick Reference Guide]
|
|
6
|
+
|
|
7
|
+
== Quick Links
|
|
8
|
+
|
|
9
|
+
* link:postscript/fundamentals.adoc[Language Fundamentals]
|
|
10
|
+
* link:postscript/graphics-model.adoc[Graphics Model]
|
|
11
|
+
* link:postscript/operators/index.adoc[Operator Reference]
|
|
12
|
+
* link:postscript/svg-mapping.adoc[PostScript to SVG Mapping]
|
|
13
|
+
* link:postscript/implementation-notes.adoc[Postsvg Implementation Notes]
|