# 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.

## 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>
#
#
# 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