PSTricks Converter

Pstake is a simple tool that turns PSTricks commands into an image file. (PSTricks can draw anything, but needs TeX/LaTeX. The quality of the drawings is unbeatable.) Pstake uses command line as the primary interface, but also works as a Sphinx extension and a SCons tool. It is made as a single-file module.

How It Works

The source PSTricks commands are stored in a .tex file. Pstake will (i) wrap them around a boilerplate, (ii) use LaTeX to generate an EPS file, and (iii) convert the EPS file to the destination format (for now only PNG). The conversion needs external tools (i) ghostscript and (ii) either imagemagick or PIL/Pillow.

Example: Grid of the c-\(\tau\) Scheme of the Space-Time CESE Method

Source code is available at https://bitbucket.org/yungyuc/pstake. The software can be installed with pip install pstake (https://pypi.python.org/pypi/pstake).

Command-Line Examples

Show help:

$ pstake -h
usage: pstake [-h] [-V] [--font {None,cmbright}] [-k] [-t DSTEXT] [-q]
              [--cmdout CMDOUT] [--tempdir TEMPDIR]
              src [dst]

Convert a pstricks LaTeX file (.tex) to an image file.

positional arguments:
  src                   source file name
  dst                   destination file name

optional arguments:
  -h, --help            show this help message and exit
  -V, --version         show program's version number and exit
  --font {None,cmbright}
                        font selection (default = None)
  -k                    keep temporary directory
  -t DSTEXT             destination file type (default = png)
  -q, --quiet           suppress terminal output
  --cmdout CMDOUT       sub-command output file (default = None)
  --tempdir TEMPDIR     DANGEROUS! Be sure to set -k, otherwise the temporary
                        directory you specified will be deleted after the
                        script ends.

Output Type by Command-Line Option

Set file type to PNG:

$ rm -f sample.*
$ if [ ! -a sample.png ]; then echo "Good, no file"; fi
Good, no file
$ pstake ${SRCDIR}/example/sample.tex -t png > /dev/null 2>&1
$ if [ -a sample.png ]; then echo "Good, file created"; fi
Good, file created

Set file type to EPS (the intermediate file format):

$ rm -f sample.*
$ if [ ! -a sample.eps ]; then echo "Good, no file"; fi
Good, no file
$ pstake ${SRCDIR}/example/sample.tex -t eps > /dev/null 2>&1
$ if [ -a sample.eps ]; then echo "Good, file created"; fi
Good, file created

Default file type is PNG:

$ rm -f sample.*
$ if [ ! -a sample.png ]; then echo "Good, no file"; fi
Good, no file
$ pstake ${SRCDIR}/example/sample.tex > /dev/null 2>&1
$ if [ -a sample.png ]; then echo "Good, file created"; fi
Good, file created

Output Type by File Extension Name

Destination file extension name is PNG:

$ rm -f other.*
$ if [ ! -a other.png ]; then echo "Good, no file"; fi
Good, no file
$ pstake ${SRCDIR}/example/sample.tex other.png > /dev/null 2>&1
$ if [ -a other.png ]; then echo "Good, file created"; fi
Good, file created

Destination file extension name is EPS:

$ rm -f other.*
$ if [ ! -a other.eps ]; then echo "Good, no file"; fi
Good, no file
$ pstake ${SRCDIR}/example/sample.tex other.eps > /dev/null 2>&1
$ if [ -a other.eps ]; then echo "Good, file created"; fi
Good, file created

Control Message Output

Suppress all message output:

$ rm -f sample.*
$ if [ ! -a sample.png ]; then echo "Good, no file"; fi
Good, no file
$ pstake ${SRCDIR}/example/sample.tex -t png -q
$ if [ -a sample.png ]; then echo "Good, file created"; fi
Good, file created

Suppress sub-command output:

$ rm -f sample.*
$ if [ ! -a sample.png ]; then echo "Good, no file"; fi
Good, no file
$ pstake ${SRCDIR}/example/sample.tex --cmdout /dev/null -t png
Working in * ... (glob)
latex sample.tex
dvips sample.dvi -q -E -o sample.eps
convert -density 300 -units PixelsPerInch sample.eps */sample.png (glob)
Removing the temporary working directory * ... Done (glob)
$ if [ -a sample.png ]; then echo "Good, file created"; fi
Good, file created

If we specify a temporary directory with --tempdir, the -k option should also be used to prevent the temporary directory from being deleted. It is useful to debugging.

$ rm -rf tempdir/
$ if [ ! -a tempdir ]; then echo "Good, no directory"; fi
Good, no directory
$ mkdir -p tempdir/
$ pstake ${SRCDIR}/example/sample.tex --tempdir mytmp/ -k > /dev/null 2>&1
$ if [ -a tempdir ]; then echo "Good, we still have the directory"; fi
Good, we still have the directory

The -k option itself can work alone:

$ pstake ${SRCDIR}/example/sample.tex -k > /dev/null 2>&1

Sphinx Extension

Pstake supports Sphinx and can act like a Sphinx extension by adding a new directive:

.. pstake:: input_file.tex

This Sphinx directive turns then input file to an image (PNG file), and insert the image directly to the document. Most options of the figure is supported. For example, the file sample.tex:

.. pstake:: sample.tex
  :align: center

  PSTricks Figure From an External File

  We can write a caption here.

will be converted to an image:

PSTricks figure from external file

We can write a caption here.

When a pstake figure has a caption, it can be referred by a reference, like PSTricks figure from external file.

Another use case is to embed PSTricks commands in the directive content, like:

.. pstake::
  :alt: PSTricks for a hexahedron
  :align: center
  :width: 50%
  :scale: 50%

  \begin{pspicture}(-1.5,-0.9)(1.5,1.9)
  \psset{xMin=0,yMin=0,zMin=0,xunit=2.4cm,yunit=1.6cm,Alpha=60,Beta=30}

  \pstThreeDNode(0.6,-0.2,0){0}
  \pstThreeDDot(0.6,-0.2,0)
  \pstThreeDPut(0.6,-0.2,-0.2){0}
  \pstThreeDNode(0.4,0.5,0){1}
  \pstThreeDDot(0.4,0.5,0)
  \pstThreeDPut(0.4,0.6,0){1}
  \pstThreeDNode(-0.5,0.2,0){2}
  \pstThreeDDot(-0.5,0.2,0)
  \pstThreeDPut(-0.5,0.3,0){2}
  \pstThreeDNode(0,-0.3,0){3}
  \pstThreeDDot(0,-0.3,0)
  \pstThreeDPut(0,-0.4,0){3}

  \pstThreeDNode(0.6,-0.2,1){4}
  \pstThreeDDot(0.6,-0.2,1)
  \pstThreeDPut(0.6,-0.2,1.2){4}
  \pstThreeDNode(0.3,0.45,1){5}
  \pstThreeDDot(0.3,0.45,1)
  \pstThreeDPut(0.3,0.45,1.2){5}
  \pstThreeDNode(-0.5,0.2,1){6}
  \pstThreeDDot(-0.5,0.2,1)
  \pstThreeDPut(-0.5,0.3,1){6}
  \pstThreeDNode(0,-0.3,1){7}
  \pstThreeDDot(0,-0.3,1)
  \pstThreeDPut(0,-0.4,1){7}

  \ncline{0}{1}
  \ncline{1}{2}
  \ncline[linestyle=dotted]{2}{3}
  \ncline[linestyle=dotted]{3}{0}

  \ncline{0}{4}
  \ncline{1}{5}
  \ncline{2}{6}
  \ncline[linestyle=dotted]{3}{7}

  \ncline{4}{5}
  \ncline{5}{6}
  \ncline{6}{7}
  \ncline{7}{4}

  \end{pspicture}

The image is produced. No caption can be generated for embedded PSTricks images.

PSTricks for a hexahedron

SCons Tool

Save the following content to site_scons/site_tools/pstricks.py (the file can be downloaded here). Then you can use pstake as a SCons tool (by adding a line env.Tool('pstricks') in your SConstruct file).

# -*- coding: UTF-8 -*-
#
# Copyright (c) 2014, Yung-Yu Chen <yyc@solvcon.net>
#
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# - Redistributions of source code must retain the above copyright notice, this
#   list of conditions and the following disclaimer.
# - Redistributions in binary form must reproduce the above copyright notice,
#   this list of conditions and the following disclaimer in the documentation
#   and/or other materials provided with the distribution.
# - Neither the name of the pstake nor the names of its contributors may be
#   used to endorse or promote products derived from this software without
#   specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

"""
SCons tool for PSTricks.
"""


import os
import glob

from SCons.Builder import Builder

import pstake


# FIXME: this tool is very primitive.


def action(target, source, env):
    pst = pstake.Pstricks()
    assert len(target) == len(source)
    for dst, src in zip(target, source):
        fn = pstake.Filename(str(src), str(dst))
        pst(fn)


def emitter(target, source, env):
    newtarget = list()
    for src in source:
        src = str(src)
        srcmain = os.path.split(src)[-1]
        dst = '/'.join([
            env['OUTDIR'],
            os.path.splitext(srcmain)[0]+'.eps',
        ])
        newtarget.append(dst)
    return newtarget, source


def exists(env):
    return True


def generate(env):
    builder = Builder(emitter=emitter, action=action)
    env.Append(BUILDERS={'Pstricks': builder})
    return env

Indices and tables