Gem Version Build Status License

Purpose

Postsvg is a pure Ruby library for converting PostScript (PS) and Encapsulated PostScript (EPS) files to Scalable Vector Graphics (SVG) format.

Unlike traditional approaches that rely on external tools like Ghostscript or Inkscape, Postsvg provides a native Ruby implementation using Parslet for parsing PostScript commands and generating clean, standards-compliant SVG output.

This library is particularly useful for applications that need to:

  • Convert legacy PostScript graphics to modern SVG format

  • Process vector graphics without external dependencies

  • Generate SVG from PostScript programmatically

  • Work with EPS files in pure Ruby environments

Features

Architecture

General

Postsvg uses a three-stage architecture for converting PostScript to SVG. This design follows separation of concerns principles, with each component handling a specific responsibility in the conversion process.

PostScript to SVG conversion pipeline

Parser stage

The parser uses Parslet to tokenize and parse PostScript commands into an abstract syntax tree (AST). The parser handles PostScript syntax including numbers, operators, names, strings, arrays, and procedures.

  • Postsvg::Parser::PostscriptParser - Parslet grammar for PostScript syntax

  • Postsvg::Parser::Transform - Transforms AST into Ruby data structures

Converter stage

The converter interprets PostScript commands using a stack-based execution model. It maintains an operand stack, dictionary, and graphics state while executing PostScript operators.

  • Postsvg::Converter - Main orchestrator that executes PostScript commands

  • Postsvg::GraphicsState - Manages current path, colors, transformations, and graphics state stack

Generator stage

The generator creates SVG output from the interpreted graphics operations, handling coordinate system transformations and generating standards-compliant SVG markup.

  • Postsvg::SvgGenerator - Builds SVG document with proper structure and viewBox

Installation

Add this line to your application’s Gemfile:

gem "postsvg"

And then execute:

bundle install

Or install it yourself as:

gem install postsvg

Basic PostScript to SVG conversion

General

The Postsvg library provides a simple Ruby API for converting PostScript content to SVG format. The conversion can be performed on in-memory content or directly on files.

The library automatically handles BoundingBox extraction, coordinate system transformations, and SVG generation while preserving the visual appearance of the original PostScript graphics.

Converting PostScript content

Syntax:

svg_output = Postsvg.convert(ps_content) <b class="conum">(1)</b>
  1. Convert PostScript string to SVG string

Where,

ps_content

PostScript or EPS content as a string. Should include proper PostScript header and BoundingBox comment for best results.

Returns

SVG markup as a string

Example 1. Converting PostScript content to SVG
require "postsvg"

ps_content = "%!PS-Adobe-3.0 EPSF-3.0\n%%BoundingBox: 0 0 100 100\nnewpath\n10 10 moveto\n90 10 lineto\n90 90 lineto\n10 90 lineto\nclosepath\n0.5 0.5 0.5 setrgbcolor\nfill\n"

svg = Postsvg.convert(ps_content)
File.write("output.svg", svg)

This converts a PostScript square with gray fill to SVG format and saves it to a file.

Converting PostScript files

Syntax:

Postsvg.convert_file(input_path, output_path) <b class="conum">(1)</b>
svg_content = Postsvg.convert_file(input_path) <b class="conum">(2)</b>
  1. Convert file and save to output path

  2. Convert file and return SVG content without saving

Where,

input_path

Path to input PostScript (.ps) or EPS (.eps) file

output_path

(Optional) Path where SVG file should be saved. If omitted, SVG content is returned without saving.

Returns

When output_path is omitted, returns SVG markup as a string. When output_path is provided, returns the output path.

Example 2. Converting a PostScript file to SVG
require "postsvg"

# Convert and save in one step
Postsvg.convert_file("input.eps", "output.svg")

# Or get SVG content without saving
svg_content = Postsvg.convert_file("input.ps")
puts svg_content

The first example converts an EPS file and saves the result as SVG. The second example reads a PostScript file and returns the SVG content for further processing.

Command-line interface

General

Postsvg provides a Thor-based command-line interface for converting PostScript and EPS files to SVG format. The CLI supports single file conversion, batch processing, and version information.

The CLI is available through the postsvg executable installed with the gem.

Converting single files

Syntax:

postsvg convert INPUT_FILE [OUTPUT_FILE] <b class="conum">(1)</b>
  1. Convert INPUT_FILE to SVG, optionally saving to OUTPUT_FILE

Where,

INPUT_FILE

Path to input PostScript (.ps) or EPS (.eps) file

OUTPUT_FILE

(Optional) Path where SVG file should be saved. If omitted, SVG is written to stdout.

Example 3. Converting a single PostScript file
# Convert to stdout
postsvg convert input.ps

# Convert and save to file
postsvg convert input.eps output.svg

# Redirect stdout to file
postsvg convert input.ps > output.svg

The first command prints SVG to stdout. The second saves directly to output.svg. The third uses shell redirection to save the output.

Batch conversion

Syntax:

postsvg batch INPUT_DIR [OUTPUT_DIR] <b class="conum">(1)</b>
  1. Convert all PS/EPS files in INPUT_DIR, optionally saving to OUTPUT_DIR

Where,

INPUT_DIR

Directory containing PostScript (.ps) and/or EPS (.eps) files to convert

OUTPUT_DIR

(Optional) Directory where SVG files should be saved. If omitted, SVG files are saved in the same directory as input files with .svg extension.

Example 4. Batch converting PostScript files
# Convert all PS/EPS files in a directory
postsvg batch ps_files/

# Convert to a different directory
postsvg batch ps_files/ svg_files/

The first example converts all PS and EPS files in the ps_files/ directory, saving the SVG files in the same directory. The second example saves the converted files to the svg_files/ directory.

Displaying version information

Syntax:

postsvg version <b class="conum">(1)</b>
  1. Display the Postsvg version number

Example 5. Getting version information
postsvg version

Output:

postsvg version 0.1.0

PostScript language support

General

Postsvg provides comprehensive PostScript language support with detailed documentation covering fundamentals, operators, and conversion strategies.

The implementation supports common PostScript operations including path construction, painting, color management, graphics state, and coordinate transformations.

PostScript documentation

Complete PostScript language documentation is available at docs/POSTSCRIPT.adoc, organized into the following topics:

Supported PostScript operations

Path construction

  • moveto - Begin new subpath at coordinates

  • lineto - Append straight line segment

  • rlineto - Append relative line segment

  • curveto - Append cubic Bézier curve

  • closepath - Close current subpath

  • newpath - Initialize new path

Painting

  • stroke - Stroke current path with current color and line width

  • fill - Fill current path with current color

Color

  • setrgbcolor - Set RGB color (0-1 range for each component)

  • setgray - Set grayscale color (0-1 range)

Graphics state

  • gsave - Save current graphics state to stack

  • grestore - Restore graphics state from stack

  • setlinewidth - Set line width for stroke operations

Transformations

  • translate - Translate coordinate system

  • scale - Scale coordinate system

  • rotate - Rotate coordinate system (angle in degrees)

Limitations

Current version has the following limitations:

  • Text rendering: Text operations (show, findfont, setfont, etc.) are not yet supported. Convert text to outlines before processing.

  • Complex clipping: Clipping paths (clip, eoclip) are not fully implemented

  • Gradients and patterns: Pattern fills and gradient operations are not yet supported

  • CMYK colors: Only RGB and grayscale colors are supported. CMYK color operations will need conversion.

  • Image embedding: Raster images within PostScript (image, imagemask) are not supported

  • Advanced operators: Some PostScript Level 2 and 3 operators are not yet implemented

For files with these features, consider preprocessing with external tools or contributing implementations of these features.

Acknowledgments

This project uses test fixtures from ps2svg by Emmett Lalish, licensed under the MIT License. These test files help ensure the correctness of our SVG generation against a reference implementation. We are grateful for this valuable resource that helps validate PostScript to SVG conversion.

Development

Running tests

bundle exec rspec

Code style

bundle exec rubocop

Running all checks

bundle exec rake

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/metanorma/postsvg.

Copyright Ribose.

License

The gem is available as open source under the terms of the BSD 2-Clause License.