Text¶
Overview and Quick Start¶
The text module provides PyX’s text typesetting facilities. Depending on
your needs and environment, PyX offers two complementary text rendering engines:
TeX and LaTeX engines (
TexEngineandLatexEngine): The default typesetting backend. PyX runs Donald E. Knuth’s TeX [1] or LaTeX as a background process, giving you full access to TeX’s mathematical typesetting, macro expansion, kerning, ligatures, and LaTeX packages.Direct Unicode font engine (
UnicodeEngine): A lightweight, pure-Python text engine that renders Unicode strings directly using Type 1 or OpenType/TrueType (.otf/.ttf) fonts without invoking an external TeX process.
Basic Usage¶
In most scripts, you do not create a text engine directly. Instead, you call
canvas.canvas.text() (which delegates to the module-level default engine)
and configure the global engine via text.set() and text.preamble():
from pyx import *
# Switch the default engine from plain TeX to LaTeX and load packages
text.set(cls=text.LatexEngine)
text.preamble(r"\usepackage{amsmath}")
c = canvas.canvas()
c.text(0, 0, r"$\int_{-\infty}^{\infty} e^{-x^2}\,dx = \sqrt{\pi}$",
[text.halign.center, text.vshift.mathaxis, text.size.Large])
c.writePDFfile("gauss")
Calling text.text() (or canvas.canvas.text()) returns a
textextbox_pt (or textbox) instance—a canvas-like object that
knows its exact typographic width, height, and depth, and can be aligned,
transformed, or queried for its bounding box before or after insertion into a
canvas.
Architecture of the TeX Interface¶
Understanding how PyX communicates with TeX/LaTeX is helpful when customizing preambles, handling TeX warnings, or optimizing scripts that typeset many text fragments.
Direct TeX execution: PyX does not parse or restrict TeX syntax itself; instead, it passes your text directly to an external
texorlatexprocess wrapped in a thin TeX macro for box measurement and shipout. Because arbitrary TeX primitives can read files on disk, untrusted user input should only be typeset inside a restricted environment (see Typesetting Untrusted Text).Persistent background process: As soon as the first preamble command or
text()call is issued, PyX launches the TeX interpreter as a child process bound to aSingleEngineinstance. This single process stays alive across subsequenttext()calls so that TeX only initializes once and macro definitions persist.Immediate box metrics and output parsing: For each text fragment, PyX places the typeset material into a TeX box, instructs TeX to print the box’s exact
width,height, anddepthtostdoutfollowed by a unique end-of-command marker, and ships the box out to its own page in the DVI [2] file. PyX immediately parsesstdoutusing a chain oftexmessageparsers:Expected status messages are stripped silently.
Overfull/underfull box notices and font warnings are logged via the
"pyx"logger atWARNINGlevel.Any unrecognized output left over after all
texmessageparsers have run raises aTexResultErrorwith a detailed diagnostic report.
Because TeX reports box dimensions immediately on
stdout, PyX knows the exact dimensions of every text box (width, height, depth) right away—even before reading the DVI file.DVI reading and font embedding: When final output (EPS, PS, PDF, or SVG) is written—or when a coordinate marker inside the text box is queried via
textextbox_pt.marker()—PyX reads the corresponding page from the DVI file, resolves virtual fonts (.vf), TeX font metrics (.tfm), and font map files (psfonts.map/pdftex.map), and embeds the required Type 1 font outlines directly into the output document.
TeX and LaTeX Engines¶
PyX separates the low-level management of a single TeX process
(SingleEngine) from the high-level engine interface
(MultiEngine) that automatically restarts TeX if needed (for instance,
when the DVI file must be flushed and read mid-script without TeX IPC Mode).
Single-Process Engines¶
- class text.SingleEngine(cmd, texenc='ascii', usefiles=[], texipc=config.getboolean('text', 'texipc', 0), copyinput=None, dvitype=False, errordetail=errordetail.default, texmessages_start=[], texmessages_end=[], texmessages_preamble=[], texmessages_run=[])¶
Base class for the TeX interface.
Note
This class cannot be used directly. It is the base class for all tex engines and provides most of the implementation. Still, to the end user the parameters except for cmd are important, as they are preserved in derived classes usually.
- Parameters:
cmd (list of str) – command and arguments to start the TeX interpreter
texenc (str) – encoding to use in the communication with the TeX interpreter
usefiles (list of str) – list of supplementary files to be copied to and from the temporary working directory (see Debugging TeX Typesetting Issues for usage details)
texipc (bool) – TeX IPC Mode flag.
copyinput (None or str or file) – filename or file to be used to store a copy of all the input passed to the TeX interpreter
dvitype (bool) – flag to turn on dvitype-like output
errordetail (
errordetail) – verbosity of theTexResultErrortexmessages_start (list of
texmessageparsers) – additional message parsers at interpreter startuptexmessages_end (list of
texmessageparsers) – additional message parsers at interpreter shutdowntexmessages_preamble (list of
texmessageparsers) – additional message parsers for preamble outputtexmessages_run (list of
texmessageparsers) – additional message parsers for typset output
- texmessages_start_default = [<function texmessage.start>]¶
default
texmessageparsers at interpreter startup
- texmessages_end_default = [<function texmessage.end>, <function texmessage.font_warning>, <function texmessage.rerun_warning>, <function texmessage.nobbl_warning>]¶
default
texmessageparsers at interpreter shutdown
- texmessages_preamble_default = [<function texmessage.load>]¶
default
texmessageparsers for preamble output
- texmessages_run_default = [<function texmessage.font_warning>, <function texmessage.box_warning>, <function texmessage.package_warning>, <function texmessage.load_def>, <function texmessage.load_graphics>]¶
default
texmessageparsers for typeset output
- preamble(expr, texmessages=[])¶
Execute a preamble.
- Parameters:
expr (str) – expression to be executed
texmessages (list of
texmessageparsers) – additional message parsers
Preambles must not generate output, but are used to load files, perform settings, define macros, etc. In LaTeX mode, preambles are executed before
\begin{document}. The method can be called multiple times, but only prior toSingleEngine.text()andSingleEngine.text_pt().
- text_pt(x_pt, y_pt, expr, textattrs=[], texmessages=[], fontmap=None, singlecharmode=False)¶
Typeset text.
- Parameters:
x_pt (float) – x position in pts
y_pt (float) – y position in pts
expr (str or
MultiEngineText) – text to be typesettextattrs (list of
textattr, :class:`trafo.trafo_pt, andstyle.fillstyle) – styles and attributes to be applied to the texttexmessages (list of
texmessageparsers) – additional message parsersfontmap (None or fontmap) – force a fontmap to be used (instead of the default depending on the output format)
singlecharmode (bool) – position each character separately
- Returns:
text output insertable into a canvas.
- Return type:
- Raises:
TexDoneError: when the TeX interpreter has been terminated already.
- class text.SingleTexEngine(cmd=config.getlist('text', 'tex', ['tex']), lfs='10pt', **kwargs)¶
Plain TeX interface.
This class adjusts the
SingleEngineto use plain TeX.- Parameters:
cmd (list of str) – command and arguments to start the TeX interpreter
lfs (str or None) – resemble LaTeX font settings within plain TeX by loading a lfs-file
kwargs – additional arguments passed to
SingleEngine
An lfs-file is a file defining a set of font commands like
\normalsizeby font selection commands in plain TeX. Several of those files resembling standard settings of LaTeX are distributed along with PyX in thepyx/data/lfsdirectory. This directory also contains a LaTeX file to create lfs files for different settings (LaTeX class, class options, and style files).
- class text.SingleLatexEngine(cmd=config.getlist('text', 'latex', ['latex']), docclass='article', docopt=None, pyxgraphics=True, texmessages_docclass=[], texmessages_begindoc=[], **kwargs)¶
LaTeX interface.
This class adjusts the
SingleEngineto use LaTeX.- Parameters:
cmd (list of str) – command and arguments to start the TeX interpreter in LaTeX mode
docclass (str) – document class
docopt (str or None) – document loading options
pyxgraphics (bool) – activate graphics bundle support, see Using the LaTeX graphics Bundle with PyX
texmessages_docclass (list of
texmessageparsers) – additional message parsers at LaTeX class loadingtexmessages_begindoc (list of
texmessageparsers) – additional message parsers at\begin{document}kwargs – additional arguments passed to
SingleEngine
- texmessages_docclass_default = [<function texmessage.load>]¶
default
texmessageparsers at LaTeX class loading
- texmessages_begindoc_default = [<function texmessage.load>, <function texmessage.no_aux>]¶
default
texmessageparsers at\begin{document}
Multi-Run Wrapper Engines¶
MultiEngine and its subclasses (TexEngine and
LatexEngine) wrap one or more SingleEngine instances. They
provide the same public methods (preamble(),
text(), and text_pt()), while
automatically starting a fresh SingleEngine (and replaying all
accumulated preamble commands) whenever the previous process had to be closed to
read its DVI file.
- class text.MultiEngine(cls, *args, **kwargs)¶
A restartable
SingleEngineclass- Parameters:
cls (
SingleEngineclass) – the class being wrappedargs (list) – args at class instantiation
kwargs (dict) – keyword args at at class instantiation
- preamble(expr, texmessages=[])¶
resembles
SingleEngine.preamble()
- text_pt(*args, **kwargs)¶
resembles
SingleEngine.text_pt()
- text(*args, **kwargs)¶
resembles
SingleEngine.text()
- reset(reinit=False)¶
Start a new
SingleEngineinstance- Parameters:
reinit (bool) – replay
preamble()calls on the new instance
After executing this function further preamble calls are allowed, whereas once a text output has been created,
preamble()calls are forbidden.
- class text.TexEngine(*args, **kwargs)¶
A restartable
SingleTexEngineclass- Parameters:
args (list) – args at class instantiation
kwargs (dict) – keyword args at at class instantiation
- class text.LatexEngine(*args, **kwargs)¶
A restartable
SingleLatexEngineclass- Parameters:
args (list) – args at class instantiation
kwargs (dict) – keyword args at at class instantiation
Text Boxes and Coordinate Markers¶
Every call to text() or text_pt() on a TeX/LaTeX engine returns a
textextbox_pt instance:
- class text.textextbox_pt(x_pt, y_pt, left_pt, right_pt, height_pt, depth_pt, do_finish, fontmap, singlecharmode, fillstyles)¶
Text output.
An instance of this class contains the text output generated by PyX. It is a
baseclasses.canvasitemand thus can be inserted into a canvas.- left¶
left extent of the text (PyX length)
- right¶
right extent of the text (PyX length)
- width¶
width of the text (PyX length)
- height¶
height of the text (PyX length)
- depth¶
height of the text (PyX length)
- marker(name)¶
Return the position of a marker.
- Parameters:
name (str) – name of the marker
- Returns:
position of the marker
- Return type:
tuple of two PyX lengths
This method returns the position of the marker of the given name within, previously defined by the
\PyXMarker{name}macro in the typeset text. Please do not use the@character within your name to prevent name clashes with PyX internal uses (although we don’t the marker feature internally right now).Similar to generating actual output, the marker function accesses the DVI output, stopping. The TeX IPC Mode feature will allow for this access without stopping the TeX interpreter.
Tip
Using PyX Markers inside TeX:
You can record the exact position of any point inside a TeX expression by
inserting \PyXMarker{id} in your TeX string and later calling
tb.marker("id") on the returned text box to obtain its (x, y)
coordinates on the canvas:
tb = c.text(0, 0, r"$y = \PyXMarker{rhs}\underbrace{a x^2 + b x + c}$")
mx, my = tb.marker("rhs")
Module-Level Functions¶
For convenience, the text module maintains a default module-level text
engine (defaulttextengine, which defaults to a TexEngine
instance) and exposes its methods as module-level functions. Calling
text.set() replaces defaulttextengine with a newly configured
engine.
- text.defaulttextengine¶
the current
MultiEngineinstance for the module level functions
- text.preamble¶
defaulttextengine.preamble (bound method)
- text.text_pt¶
defaulttextengine.text_pt (bound method)
- text.text¶
defaulttextengine.text (bound method)
- text.reset¶
defaulttextengine.reset (bound method)
- text.set(engine=None, cls=None, mode=None, *args, **kwargs)¶
Setup a new module level
MultiEngine- Parameters:
engine – the module level engine object to be used, i.e.
TexEngine,LatexEngine, orUnicodeEnginecls (Engine object, not instance) –
identical to engine
- deprecated:
use the engine argument instead
mode (str or None) –
"tex"forTexEngineor"latex"forLatexEnginewith arbitrary capitalization- deprecated:
use the engine argument instead
args (list) – args at class instantiation
kwargs (dict) – keyword args at at class instantiation
- text.escapestring(s, replace={" ": "~", "$": '\\$', "&": '\\&', " "_": '\\_', "%": '\\%', "^": '\\string^', "~": '\\string~', "<": '{$<$}', ">": '{$>$}', "{": '{$\\{$}', "}": '{$\\}$}', "\\": '{$\\setminus$}', "|": r"{$\mid$}"})¶
Escapes ASCII characters such that they can be typeset by TeX/LaTeX
TeX Output Parsers and Error Handling¶
When TeX or LaTeX runs, it writes status banners, file load notices, box
warnings, and error messages to stdout. After stripping its own internal page
and extent markers, PyX passes the remaining output string through a sequence of
texmessage parser callables. Each parser inspects the output string and
performs one of four actions:
Unrelated output: Return the string unchanged so subsequent parsers can inspect it.
Expected/harmless message: Strip the recognized message and return the remaining string.
Warning: Log a warning via the
"pyx"logger (printed tostderrby default, e.g. for overfull/underfull boxes or font substitutions), strip the message, and return the remaining string.Error: Raise
TexResultError(or leave the error text in the returned string—any non-empty text remaining after all parsers have run automatically triggers aTexResultError).
The amount of context included in a TexResultError exception is
controlled by errordetail:
- class text.errordetail¶
Constants defining the verbosity of the
TexResultError.- none = 0¶
Without any input and output.
- default = 1¶
Input and parsed output shortend to 5 lines.
- full = 2¶
Full input and unparsed as well as parsed output.
- exception text.TexResultError¶
Error raised by
texmessageparsers.
To accept unknown TeX output without raising an error, you can append
texmessage.warn or texmessage.ignore to the texmessages_*
lists. The built-in message parsers are:
- class text.texmessage¶
Collection of TeX output parsers.
This class is not meant to be instanciated. Instead, it serves as a namespace for TeX output parsers, which are functions receiving a TeX output and returning parsed output.
In addition, this class also contains some generator functions (namely
texmessage.no_fileandtexmessage.pattern), which return a function according to the given parameters. They are used to generate some of the parsers in this class and can be used to create others as well.- static start(msg)¶
Validate TeX/LaTeX startup message including scrollmode test.
- Example:
>>> texmessage.start(r''' ... This is e-TeX (version) ... *! Undefined control sequence. ... <*> \raiseerror ... % ... ''') ''
- static no_file(fileending, qualname=None)¶
Generator function to ignore the missing file message for fileending.
- static no_aux(msg)¶
Ignore the missing aux file message.
Ignore the missing nav file message.
- static end(msg)¶
Validate TeX shutdown message.
- static load(msg)¶
Ignore file loading messages.
Removes text starting with a round bracket followed by a filename ignoring all further text until the corresponding closing bracket. Quotes and/or line breaks in the filename are handled as needed for TeX output.
Without quoting the filename, the necessary removal of line breaks is not well defined and the different possibilities are tested to check whether one solution is ok. The last of the examples below checks this behavior.
- Examples:
>>> texmessage.load(r'''other (text.py) things''') 'other things' >>> texmessage.load(r'''other ("text.py") things''') 'other things' >>> texmessage.load(r'''other ("tex ... t.py" further (ignored) ... text) things''') 'other things' >>> texmessage.load(r'''other (t ... ext ... .py ... fur ... ther (ignored) text) things''') 'other things'
- static load_def(msg)¶
Ignore font definition (
*.fdand*.def) loading messages.
- static load_graphics(msg)¶
Ignore graphics file (
*.eps) loading messages.
- static ignore(msg)¶
Ignore all messages.
Should be used as a last resort only. You should write a proper TeX output parser function for the output you observe.
- static warn(msg)¶
Warn about all messages.
Similar to
ignore, but writing a warning to the logger about the TeX output. This is considered to be better when you need to get it working quickly as you will still be prompted about the unresolved output, while the processing continues.
- static pattern(p, warning, qualname=None)¶
Warn by regular expression pattern matching.
- static box_warning(msg)¶
Warn about overfull/underfull box.
- static font_warning(msg)¶
Warn about font substitutions of NFSS.
- static package_warning(msg)¶
Warn about generic package messages.
- static rerun_warning(msg)¶
Warn about rerun required message.
- static nobbl_warning(msg)¶
Warn about no-bbl message.
Text Attributes (Alignment, Parboxes, Math Mode, Font Size)¶
Text attributes are passed in a list to text.text() or
canvas.canvas.text() alongside transformations (trafo.trafo),
colors (color.color), and decorators. They generate appropriate
TeX/LaTeX wrapper fragments or geometric alignments and automatically resolve
ordering dependencies.
Horizontal Alignment (halign)¶
- class text.halign(boxhalign, flushhalign)¶
Controls both the horizontal alignment of the text box relative to its reference point
(x, y)(boxhalign) and the horizontal alignment of text lines inside a multi-lineparbox(flushhalign). Standard values are0(left),0.5(center), and1(right), though arbitrary floating point numbers are permitted.The separate helper classes
boxhalignandflushhalignallow setting box placement and line flushing independently. Predefined instances are provided as class attributes onhalign:- boxleft¶
Left-aligns the text box at the reference point (
boxhalign=0, leaves flushhalign unchanged).
- boxcenter¶
Horizontally centers the text box at the reference point (
boxhalign=0.5, leaves flushhalign unchanged).
- boxright¶
Right-aligns the text box at the reference point (
boxhalign=1, leaves flushhalign unchanged).
- flushleft¶
- raggedright¶
Left-aligns (ragged-right) lines inside a
parbox(flushhalign=0, leaves boxhalign unchanged).
- flushcenter¶
- flushright¶
- raggedleft¶
Right-aligns (ragged-left) lines inside a
parbox(flushhalign=1, leaves boxhalign unchanged).
- center¶
Combines
boxcenterandflushcenter(halign(0.5, 0.5)).
- right¶
Combines
boxrightandflushright(halign(1, 1)).
Vertical Alignment (valign) and Multi-Line Boxes (parbox)¶
Vertical alignment of single-line text boxes using valign (left) and
baseline selection in multi-line parbox boxes (right).¶
- class text.valign(valign)¶
Sets the vertical alignment of the text box relative to its overall bounding height (from bottom of depth to top of height):
0aligns at the top,0.5at the vertical center, and1at the bottom. See the left side of figure Vertical alignment of single-line text boxes using valign (left) and baseline selection in multi-line parbox boxes (right)..- top¶
Aligns the top of the text box with the reference point (
valign(0)).
- middle¶
Vertically centers the text box at the reference point (
valign(0.5)).
- bottom¶
Aligns the bottom of the text box with the reference point (
valign(1)).
- baseline¶
Clears any box-based vertical alignment (identical to
valign.clear) so that the text box is aligned along its typographic baseline (the default).
- class text.parbox(width, baseline=top)¶
Typesets text in a vertical paragraph box of fixed width (a PyX length or number in user units), enabling automatic line wrapping and explicit line breaks (
\\). By default, TeX typesets in LR (left-to-right) mode on a single line unless aparboxattribute is provided.Because a multi-line paragraph has multiple baselines, baseline selects which baseline serves as the reference baseline of the box:
parbox.top(default): the baseline of the first line.parbox.middle: the vertical center of the paragraph box.parbox.bottom: the baseline of the last line.
See the right side of figure Vertical alignment of single-line text boxes using valign (left) and baseline selection in multi-line parbox boxes (right)..
Vertical Shifts (vshift)¶
- class text.vshift(lowerratio, heightstr='0')¶
Lowers the text box relative to its baseline by lowerratio times the height of the character(s) in heightstr (default
"0"). Multiplevshiftattributes accumulate; usevshift.clearto remove all vertical shifts.- bottomzero¶
vshift(0)— no vertical shift (aligns at the baseline of"0").
- middlezero¶
vshift(0.5)— lowers the text by half the height of"0".
- topzero¶
vshift(1)— lowers the text by the full height of"0".
- mathaxis¶
Lowers the text by the height of TeX’s mathematical axis (the vertical center of math operators such as minus signs and fraction bars). This is used by default for graph axis labels and titles.
Math Mode, Font Sizes, and Phantom Text¶
- text.mathmode¶
Typesets the text in TeX display math mode (
$\displaystyle ...$). Useclearmathmodeto clear this attribute.
- class text.size(sizeindex=None, sizename=None, sizelist=defaultsizelist)¶
Applies a TeX/LaTeX font size command from sizelist (default
["normalsize", "large", "Large", "LARGE", "huge", "Huge", None, "tiny", "scriptsize", "footnotesize", "small"]). You can specify either an integer sizeindex into sizelist or a command name sizename.Predefined instances corresponding to standard LaTeX font sizes are available as class attributes:
- tiny¶
size(-4)
- scriptsize¶
size(-3)
- footnotesize¶
size(-2)
- small¶
size(-1)
- normalsize¶
size(0)
- large¶
size(1)
- Large¶
size(2)
- LARGE¶
size(3)
- huge¶
size(4)
- Huge¶
size(5)
- text.phantom¶
Typesets an invisible box that occupies the exact width, height, and depth of the given text without drawing any glyphs (equivalent to TeX’s
\phantom). Useclearphantomto clear this attribute.
UnicodeEngine: Direct Font Rendering without TeX¶
When you only need simple labels or want to use system OpenType/TrueType
(.otf/.ttf) or Type 1 fonts without invoking an external TeX process,
you can use UnicodeEngine.
from pyx import *
text.set(text.UnicodeEngine, size=12)
c = canvas.canvas()
c.text(0, 0, "Direct Unicode text rendering", [color.rgb.blue])
- class text.UnicodeEngine(font=_marker, size=10)¶
A pure-Python text engine that renders Unicode strings directly using Type 1 (
font.T1font) or OpenType/TrueType (font.OTFfont) fonts.font: Font instance (defaults to
T1font.from_fontname("cmr10")). Other options would beT1font.from_fontfile(filename),OTFfont.from_fontname(fontname), andOTFfont.from_fontfile(filename).size: Base font size in PostScript points (default
10).
- text_pt(x_pt, y_pt, text, textattrs=[], texmessages=[], fontmap=None, singlecharmode=False)¶
- text(x, y, text, textattrs=[], **kwargs)¶
Typesets text (which may be a string,
Text,StackedText,MultiEngineText, or a list thereof) at(x, y)and returns aunicodetextbox_ptinstance. Supportsmathmode,trafo.trafo_pt, andstyle.fillstyle(such ascolor.color) attributes in textattrs.
- class text.Text(text, scale=1, shift=0)¶
Wraps a string text for
UnicodeEnginewith a relative font scale factor and a vertical baseline shift (in units of the unscaled text size). This is useful for superscripts and subscripts when usingUnicodeEngine, for example["10", text.Text("-3", scale=0.7, shift=0.4)].
- class text.StackedText(texts, frac=False, align=0)¶
Stacks a sequence of texts vertically for
UnicodeEnginewith horizontal alignment align (0for left,0.5for center,1for right) and optional fraction bar frac (whenlen(texts) == 2).
- class text.MultiEngineText(tex, unicode)¶
Holds two representations of a text fragment: tex (passed when a TeX/LaTeX engine is active) and unicode (passed when
UnicodeEngineis active). PyX’s axis texters useMultiEngineTextso that exponential tick labels work seamlessly with both TeX engines andUnicodeEngine.
Using the LaTeX graphics Bundle with PyX¶
The packages in the standard LaTeX graphics bundle (color, graphicx,
rotating, etc.) rely on driver-specific \special commands emitted into
the DVI file. PyX ships with its own driver file pyx.def (located in
pyx/data/def/pyx.def) that translates LaTeX color, scaling, rotation, and EPS
inclusion commands into native PyX canvas operations.
By default, SingleLatexEngine enables pyxgraphics=True, which
automatically injects pyx.def so you can write
\usepackage{color,graphicx} in your LaTeX preamble without specifying a
driver option. If you install pyx.def into your local TeX tree and configure
color.cfg / graphics.cfg [3], you can set pyxgraphics=False and load
packages explicitly with \usepackage[pyx]{color,graphicx}.
Supported LaTeX Color Models and Specials¶
When you define or use colors in LaTeX via the gray, cmyk, rgb,
RGB, or hsb models, or via named colors, PyX maps them directly to
the corresponding color classes and predefined named colors (see appendix
Appendix: Named colors). In addition, the pyx color model lets you pass any PyX
color expression directly from LaTeX, such as
\textcolor[pyx]{color.cmyk.PineGreen}{colored text}.
For developer reference, PyX’s DVI reader interprets the following \special
commands generated by pyx.def:
PyX:color_begin (model) (spec)Pushes a color onto the graphics state.
(model)is one ofgray,cmyk,rgb,hsb,texnamed, orpyxcolor, and(spec)contains the model parameters or name.PyX:color_endRestores the previous color state.
PyX:epsinclude file= llx= lly= urx= ury= width= height= clip=0/1Includes an Encapsulated PostScript (
.eps) file scaled, positioned, and optionally clipped according to the specified bounding box coordinates.PyX:scale_begin (x) (y)/PyX:scale_endStarts and ends coordinate scaling relative to the current DVI reference point.
PyX:rotate_begin (angle)/PyX:rotate_endStarts and ends coordinate rotation (in degrees) around the current DVI reference point.
Configuration and Debugging¶
As described in Introduction, PyX reads its system-wide defaults from
pyx/data/pyxrc, followed by user-level settings in ~/.pyxrc (or
%APPDATA%\pyxrc on Windows) and any file referenced by the PYXRC
environment variable. Most options in [general] and [text] configure how
PyX locates TeX files and runs the TeX/LaTeX interpreter.
TeX IPC Mode¶
To read the actual glyph positions or \PyXMarker coordinates of a text box,
PyX must read the DVI page written by TeX. However, standard TeX buffers its DVI
output until the TeX process terminates. When texipc is disabled (the
default), accessing a marker or writing a canvas forces MultiEngine to
close the running TeX process so the DVI file is flushed, and then spawn a new
TeX process if further text is typeset afterward.
Most modern TeX distributions support the --ipc command-line option, which
flushes the DVI file after every \shipout. Enabling texipc = 1 in the
[text] section of your pyxrc allows PyX to read DVI pages on the fly
without terminating TeX, dramatically speeding up scripts that alternate between
typesetting text and querying marker positions.
Debugging TeX Typesetting Issues¶
PyX provides several tools for diagnosing TeX errors and environment problems:
Error verbosity (
errordetail): Passerrordetail=text.errordetail.fulltotext.set()to include the full TeX session transcript and input commands whenever aTexResultErroris raised.Saving the TeX input stream (
copyinput): Pass a filename or writable file object ascopyinput="debug.tex"totext.set()to record the exact TeX code PyX sends to the interpreter so you can runtexorlatexon it manually.Preserving ``.log`` and ``.aux`` files (
usefiles): Each TeX process runs in a temporary working directory that is deleted on exit. Passingusefiles=["myjob.log", "myjob.aux"]totext.set()copies those files into and out of the temporary directory (matching PyX’s internal\jobnamewhile preserving the file extension), allowing you to inspect the full TeX.logfile or share.auxfiles across runs.Enabling ``INFO`` logging (
pyx.pyxinfo()):PyX logs all external command executions and file lookups to the standard Python logger
"pyx"atINFOlevel. Callingpyx.pyxinfo()at the top of your script attaches a stream handler that prints these messages tostderr:- pyx.pyxinfo()¶
Make PyX a little verbose (for information or debugging)
This function enables info level on the
"pyx"logger. It also adds some general information about the Python interpreter, the PyX installation, and the PyX configuration to the logger.
Typesetting Untrusted Text¶
Because TeX has primitives that can read arbitrary files accessible to the user
running the script (and, in misconfigured environments, execute shell commands),
never pass untrusted user input directly to TeX without isolation [4]. If you
use PyX in a web service or multi-user environment, you can run TeX inside a
chroot jail by configuring the chroot option, the TeX executable command,
and the filelocator paths in pyxrc.
Footnotes