Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sage
Path: blob/develop/src/doc/en/tutorial/latex.rst
4111 views
***********************
Sage, LaTeX and Friends
***********************

Sage and the LaTeX dialect of TeX have an intensely synergistic relationship.
This section aims to introduce the variety of interactions, beginning with the
most basic and proceeding to the more unusual.

Basic Use
=========

Every "object" in Sage is required to have a LaTeX representation.  You can
access this representation by executing ``latex(foo)`` where ``foo`` is some
object in Sage.  The output is a string that should render a reasonably
accurate representation of ``foo`` when used in TeX's math-mode (for example,
when enclosed between a pair of single dollar signs). Some examples of this
follow below. ::

    sage: var('z')
    z
    sage: latex(z^12)
    z^{12}
    sage: latex(sqrt(z^2 + 1/2))
    \sqrt{z^{2} + \frac{1}{2}}
    sage: latex('a string')
    \text{\texttt{a{ }string}}
    sage: latex(QQ)
    \Bold{Q}
    sage: latex(ZZ['x'])
    \Bold{Z}[x]
    sage: latex(matrix(QQ, 2, 3, [[2,4,6],[-1,-1,-1]]))
    \left(\begin{array}{rrr}
    2 & 4 & 6 \\
    -1 & -1 & -1
    \end{array}\right)

In this way, Sage can be used effectively for constructing portions of
a LaTeX document: create or compute an object in Sage, do ``latex(foo)``
of the object ``foo`` and cut/paste the LaTeX string into your document.

The command ``view(foo)`` will show the rendered LaTeX
representation of ``foo``. In the background, the command runs ``latex(foo)``
and incorporates the LaTeX string into a simple LaTeX document, processes that
document with the system-wide TeX installation, and finally an appropriate
viewer will be called to display the output.

In the Jupyter notebook, you can see the rendered LaTeX representation of the
output of the entered commands automatically. You can start this
automatic rendering by executing ``%display latex`` (and stop by executing
``%display plain``).

.. ONLY:: html

    Thus, in the Jupyter notebook, you get

    .. JUPYTER-EXECUTE::

        %display latex
        var('z')
        z^12

    .. JUPYTER-EXECUTE::

        sqrt(z^2 + 1/2)

    .. JUPYTER-EXECUTE::

        'a string'

    .. JUPYTER-EXECUTE::

        QQ

    .. JUPYTER-EXECUTE::

        ZZ['x']

    .. JUPYTER-EXECUTE::

        matrix(QQ, 2, 3, [[2,4,6],[-1,-1,-1]])

    .. JUPYTER-EXECUTE::

        %display plain

The Jupyter notebook uses `MathJax <http://www.mathjax.org>`_ to render
mathematics cleanly in a web browser. MathJax is an open source JavaScript
display engine for mathematics that works in all modern browsers.  It is able
to render a large, but not totally complete, subset of LaTeX.  It has no
support for things like complicated tables, sectioning or document management,
as it is oriented towards accurately rendering math snippets of LaTeX.

The automatic LaTeX rendering in the Jupyter notebook (with ``%display latex``
on) is internally done via the :class:`sage.misc.html.MathJax` class. The
object of this class converts a Sage object through ``latex()`` to a form of
HTML palatable to MathJax and then wraps it in HTML.  ::

    sage: from sage.misc.html import MathJax
    sage: mj = MathJax()
    sage: var('z')
    z
    sage: mj(z^12)
    <html>\[z^{12}\]</html>
    sage: mj(sqrt(z^2 + 1/2))
    <html>\[\sqrt{z^{2} + \frac{1}{2}}\]</html>
    sage: mj('a string')
    <html>\[\verb|a|\verb| |\verb|string|\]</html>
    sage: mj(QQ)
    <html>\[\newcommand{\Bold}[1]{\mathbf{#1}}\Bold{Q}\]</html>
    sage: mj(ZZ['x'])
    <html>\[\newcommand{\Bold}[1]{\mathbf{#1}}\Bold{Z}[x]\]</html>
    sage: mj(matrix(QQ, 2, 3, [[2,4,6],[-1,-1,-1]]))
    <html>\[\left(\begin{array}{rrr}
    2 & 4 & 6 \\
    -1 & -1 & -1
    \end{array}\right)\]</html>

This is useful to know if you need to understand the LaTeX rendering of a Sage object.


.. _sec-custom-generation:

Customizing LaTeX Generation
============================

There are several ways to customize the actual LaTeX code generated by the
``latex()`` command. There is a pre-defined object named ``latex`` which has
several methods, which you can list by typing ``latex.``, followed by the
:kbd:`Tab` key (note the period).

A good example is the ``latex.matrix_delimiters`` method.  It can be
used to change the notation surrounding a matrix -- large parentheses,
brackets, braces, vertical bars.  No notion of style is enforced,
you can mix and match as you please.  Notice how the backslashes
needed in LaTeX require an extra slash so they are escaped
properly within the Python string.  ::

    sage: A = matrix(ZZ, 2, 2, range(4))
    sage: latex(A)
    \left(\begin{array}{rr}
    0 & 1 \\
    2 & 3
    \end{array}\right)
    sage: latex.matrix_delimiters(left='[', right=']')
    sage: latex(A)
    \left[\begin{array}{rr}
    0 & 1 \\
    2 & 3
    \end{array}\right]
    sage: latex.matrix_delimiters(left='\\{', right='\\}')
    sage: latex(A)
    \left\{\begin{array}{rr}
    0 & 1 \\
    2 & 3
    \end{array}\right\}

The ``latex.vector_delimiters`` method works similarly.

The way common rings and fields (integers, rational, reals, etc.)
are typeset can be controlled by the ``latex.blackboard_bold``
method.  These sets are by default typeset in bold, but may
optionally be written in a double-struck fashion as sometimes
done in written work.  This is accomplished by redefining the
``\Bold{}`` macro which is built-in to Sage. ::

    sage: latex(QQ)
    \Bold{Q}
    sage: from sage.misc.html import MathJax
    sage: mj = MathJax()
    sage: mj(QQ)
    <html>\[\newcommand{\Bold}[1]{\mathbf{#1}}\Bold{Q}\]</html>
    sage: latex.blackboard_bold(True)
    sage: mj(QQ)
    <html>\[\newcommand{\Bold}[1]{\mathbb{#1}}\Bold{Q}\]</html>
    sage: latex.blackboard_bold(False)

.. ONLY:: html

    In the Jupyter notebook,

    .. JUPYTER-EXECUTE::

        %display latex
        QQ

    .. JUPYTER-EXECUTE::

        latex.blackboard_bold(True)
        QQ

    .. JUPYTER-EXECUTE::

        latex.blackboard_bold(False)
        %display plain

It is possible to take advantage of the extensible nature of LaTeX by adding in
new macros. Individual macros can be added so that they are used when MathJax
interprets a LaTeX snippet. ::

    sage: latex.add_macro(r"\newcommand{\sqrt}[1]{(#1)^\frac{1}{2}}")
    sage: latex.extra_macros()
    '\\newcommand{\\sqrt}[1]{(#1)^\\frac{1}{2}}'
    sage: var('x y')
    (x, y)
    sage: latex(sqrt(x+y))
    \sqrt{x + y}
    sage: from sage.misc.html import MathJax
    sage: mj = MathJax()
    sage: mj(sqrt(x + y))
    <html>\[\newcommand{\sqrt}[1]{(#1)^\frac{1}{2}}\sqrt{x + y}\]</html>
    sage: latex.extra_macros('')

.. ONLY:: html

    In the Jupyter notebook,

    .. JUPYTER-EXECUTE::

        %display latex
        var('x y')
        sqrt(x + y)

    .. JUPYTER-EXECUTE::

        latex.add_macro(r"\newcommand{\sqrt}[1]{(#1)^\frac{1}{2}}")
        sqrt(x + y)

    .. JUPYTER-EXECUTE::

        latex.extra_macros('')
        %display plain


.. _sec-custom-processing:

Customizing LaTeX Processing
============================

The system-wide TeX is called to process a complete LaTeX document, such as
when you ``view(foo)``, where ``foo`` is a complicated Sage object, too
complicated for ``MathJax`` to handle.  The command ``latex_extra_preamble`` is
used to build the preamble of the complete LaTeX document, so the following
illustrates how this is accomplished. As usual note the need for the
double-backslashes in the Python strings.  ::

    sage: latex.extra_macros('')
    sage: latex.extra_preamble('')
    sage: from sage.misc.latex import latex_extra_preamble
    sage: print(latex_extra_preamble())
    \newcommand{\ZZ}{\Bold{Z}}
    ...
    \newcommand{\Bold}[1]{\mathbf{#1}}
    sage: latex.add_macro("\\newcommand{\\foo}{bar}")
    sage: print(latex_extra_preamble())
    \newcommand{\ZZ}{\Bold{Z}}
    ...
    \newcommand{\Bold}[1]{\mathbf{#1}}
    \newcommand{\foo}{bar}

Again, for larger or more complicated LaTeX expressions, it is possible to add
packages (or anything else) to the preamble of the LaTeX file.  Anything may be
incorporated into the preamble with the ``latex.add_to_preamble`` command, and
the specialized command ``latex.add_package_to_preamble_if_available`` will
first check if a certain package is actually available before trying to add it
to the preamble.

Here we add the geometry package to the preamble and use it to set the size of
the region on the page that TeX will use (effectively setting the margins).  As
usual, note the need for the double-backslashes in the Python strings.  ::

    sage: from sage.misc.latex import latex_extra_preamble
    sage: latex.extra_macros('')
    sage: latex.extra_preamble('')
    sage: latex.add_to_preamble('\\usepackage{geometry}')
    sage: latex.add_to_preamble('\\geometry{letterpaper,total={8in,10in}}')
    sage: latex.extra_preamble()
    '\\usepackage{geometry}\\geometry{letterpaper,total={8in,10in}}'
    sage: print(latex_extra_preamble())
    \usepackage{geometry}\geometry{letterpaper,total={8in,10in}}
    \newcommand{\ZZ}{\Bold{Z}}
    ...
    \newcommand{\Bold}[1]{\mathbf{#1}}

A particular package may be added along with a check on its existence, as
follows.  As an example, we just illustrate an attempt to add to the preamble a
package that presumably does not exist. ::

    sage: latex.extra_preamble('')
    sage: latex.extra_preamble()
    ''
    sage: latex.add_to_preamble('\\usepackage{foo-bar-unchecked}')
    sage: latex.extra_preamble()
    '\\usepackage{foo-bar-unchecked}'
    sage: latex.add_package_to_preamble_if_available('foo-bar-checked')
    sage: latex.extra_preamble()
    '\\usepackage{foo-bar-unchecked}'

Which dialect of TeX is used, and therefore the nature of the output and
associated viewer, can also be customized.

.. NOTE::

    Sage includes almost everything you need to build and use Sage, but a
    significant exception is TeX itself. So in the following situations you
    need to have a full TeX system installed, along with some associated
    conversion utilities. Many versions of Linux have packages based on
    TeXLive, for macOS there is MacTeX and for Windows there is MiKTeX.

The ``latex.engine()`` command can be used to control if the system-wide
executables ``latex``, ``pdflatex`` or ``xelatex`` are employed. When
``view()`` is called and the engine is set to ``latex``, a dvi file is produced
and Sage will use a dvi viewer (like xdvi) to display the result.  In contrast,
using ``view()`` when the engine is set to ``pdflatex`` will produce a PDF as
the result and Sage will call your system's utility for displaying PDF files
(acrobat, okular, evince, etc.).

For your exercises with these facilities, there are some pre-packaged examples.
To use these, it is necessary to import the ``sage.misc.latex.latex_examples``
object, which is an instance of the :class:`sage.misc.latex.LatexExamples`
class, as illustrated below.  This class currently has examples of commutative
diagrams, combinatorial graphs, knot theory and pstricks, which respectively
exercise the following packages: xy, tkz-graph, xypic, pstricks.  After the
import, use tab-completion on ``latex_examples`` to see the pre-packaged
examples.  Calling each example will give you back some explanation about what
is required to make the example render properly.  To actually see the examples,
it is necessary to use ``view(foo)`` (once the preamble, engine, etc are all set
properly).  ::

    sage: from sage.misc.latex import latex_examples
    sage: foo = latex_examples.diagram()
    sage: foo
    LaTeX example for testing display of a commutative diagram produced
    by xypic.
    <BLANKLINE>
    To use, try to view this object -- it will not work.  Now try
    'latex.add_to_preamble("\\usepackage[matrix,arrow,curve,cmtip]{xy}")',
    and try viewing again. You should get a picture (a part of the diagram arising
    from a filtered chain complex).

For an example of how complicated LaTeX expressions can be processed, let us see the
example of combinatorial graphs, that use ``tkz-graph`` LaTeX package.

.. NOTE::

    ``tkz-graph`` LaTeX package is built on top of the ``tikz`` front-end to
    the ``pgf`` library.  Rendering combinatorial graphs requires the ``pgf``
    library, and the files ``tkz-graph.sty`` and ``tkz-berge.sty``. It is
    highly likely that they are already part of your system-wide TeX
    installation. Even if not, it should be easy to find instructions to
    install them.

First, we ensure that the relevant packages are included by adding them to the
preamble of the LaTeX document. ::

    sage: latex.extra_preamble('\\usepackage{tikz}\n\\usepackage{tkz-graph}\n'
    ....:                      '\\usepackage{tkz-berge}\n\\usetikzlibrary{arrows,shapes}')

The images of graphs do not form properly when a dvi file is used as an
intermediate format, so it is best to set the latex engine to the ``pdflatex``
executable::

    sage: latex.engine('pdflatex')

At this point a command like ``view(graphs.CompleteGraph(4))`` should produce a
PDF with an appropriate image of the complete graph `K_4`.

Actually the preliminary steps could be omitted as the preamble is
automatically set up properly for graphs and ``pdflatex`` is the default LaTeX
engine in Sage. Try the command again after restarting Sage.

Note that there is a variety of options to affect how a graph is rendered in
LaTeX via ``tkz-graph``, which is outside the scope of this section. See the
section :ref:`sage.graphs.graph_latex` of the Reference Manual for instructions
and details.


SageTeX
=======

SageTeX is a program available to further integrate TeX and Sage. It is a
collection of TeX macros that allow a LaTeX document to include instructions to
have Sage compute various objects and format objects using the ``latex()``.
See :ref:`sec-sagetex` for more information.