Sphinx LaTeX markup limitations

2019-02-09 15:11发布

I'm trying to do three really basic things inside of a multi-line math mode in Sphinx (version 1.1.2-1).

  1. Write underscores as part of my variable names even in math mode;
  2. Use the \big, \biggl, etc., delimiters to make large brackets and parentheses;
  3. and include regular text as part of equations.

Note the following two things. (1) I am using a raw string in my Python code for the Sphinx-markup documentation, so extra backslashes are not needed for escape characters, and (2) I am not doing inline math mode, which is delimited like this in Sphinx:

:math:`Some math stuff goes here` regular text could go here...

Instead, I am doing multi-line stuff, often like eqnarray in LaTeX:

.. math::
    DividendYield &=& \frac{DVT(t)}{CurrentMarketCap} \\
    Avg_Assets &=& \biggl( A/B \biggr) \textrm { when B is not zero...}

Currently, I get Sphinx errors (and the generated doc pages look like gibberish), that say things like:

Unknown LaTeX command: textrm

The same happens for \biggl. For the underscore, it just always interprets it as if I am denoting a subscript, but if I use \textunderscore or other tricks then it throws the same sorts of errors as above.

Underscores within math mode, the textrm command, and big delimiters are extremely basic parts of every native TeX package I've ever used. So why are they inaccessible through Sphinx?

Update

One particular Python file that I am working on calculates Book Equity data for me. So below, when you see the stuff about BookEquity, that's the reference. I can't run our build-docs process except through a version control system, so making a reproducible error was easiest if I just modified an existing file.

However, all I did was to add the following class function in my code, with a simple docstring.

def foo(self):
    r"""
    Sample docstring

    .. math::
        Ax &=& b \\
        Cx &=& \biggl(\frac{x/y}\biggr) \textrm{ if y is not zero.}
    """
    pass

And then the image below is the output coming from building the docs with Sphinx 1.1.2-1.

Snippet of the generated doc page showing the error exactly as it appears from Sphinx.

If you right-click and select 'view image' you can see a better version.

3条回答
孤傲高冷的网名
2楼-- · 2019-02-09 15:32

You have to edit the standard configuration file that sphinx-quickstart creates, otherwise sphinx will barf at math blocks. In the file conf.py, I changed

extensions = []

to

extensions = ['sphinx.ext.pngmath']

After that the following rst file more-or-less worked;

.. foo documentation master file, created by
   sphinx-quickstart on Thu Oct 25 11:04:31 2012.
   You can adapt this file completely to your liking, but it should at least
   contain the root `toctree` directive.

Welcome to foo's documentation!
===============================

Contents:

.. toctree::
   :maxdepth: 2

This is the first chapter
=========================

Instead, I am doing multi-line stuff, often like eqnarray in LaTeX:

.. math::
    DividendYield &=& \frac{DVT(t)}{CurrentMarketCap} \\
    Avg_Assets &=& \biggl( A/B \biggr) \textrm { when B is not zero...}

It produced the following LaTeX code for the math fragment:

\chapter{This is the first chapter}
\label{index:welcome-to-foo-s-documentation}\label{index:this-is-the-first-chapter}
Instead, I am doing multi-line stuff, often like eqnarray in LaTeX:
\begin{gather}
\begin{split}DividendYield &=& \frac{DVT(t)}{CurrentMarketCap} \\
Avg_Assets &=& \biggl( A/B \biggr) \textrm { when B is not zero...}\end{split}\notag\\\begin{split}\end{split}\notag
\end{gather}

The choice of using the combination of split and gather seems a bit weird to me, and obviously doesn't work well with the code you wrote for eqnarray, but this is hardcoded in Sphinx.

Running pdflatex did stop at \end{gather}, with the error Extra alignment tab has been changed to \cr. but I was able to proceed past that by entering nonstopmode. This give me the following result:

test image

While there is still something wrong with the alignment (because of the differences between the split and eqnarray environments), the textrm and biggl seem to work fine. (Note that you'll still have to escape the underscore in Average_Assets, but that is par for the course, AFAICT).

You might get away with postprocessing the generated LaTeX code, e.g. by replacing \begin{gather}\begin{split} and \end{split}\notag\\\begin{split}\end{split}\notag\end{gather} by the math environment of your choice.

Update:

The screenshot from the update seems to be from a webpage, not a LaTeX document! So it looks to me that what is producing the error is the handler that converts the LaTeX math notation so something a browser can show. That will be probably be either MathJax or jsMath. From looking at the code, pngmath would produce other error messages. According to this page, your code snippet should work in mathjax. From the jsMath symbols page, it doesn't look like jsmath supports \Biggl. So my best guess is that SPhinx is configured to use jsMath. A peek at the source of the generated web page should tell you what is used to render the math. If my guess is correct, switching the configuration to use mathjax and slightly adapting your equation might fix the problem.

Update2: I can definitely confirm that it works fine with MathJax (see below). I don't have jsMath installed, though.

with mathjax

查看更多
劳资没心,怎么记你
3楼-- · 2019-02-09 15:32

Now (2016) Sphinx math directive has option :nowrap: returning full control to the user, so doing just

.. math::
   :nowrap:

   \begin{eqnarray}
      y    & = & ax^2 + bx + c \\
      f(x) & = & x^2 + 2xy + y^2
   \end{eqnarray}

renders fine in both html and latexpdf.

查看更多
Rolldiameter
4楼-- · 2019-02-09 15:50

Update

As mentioned, sphinx uses gather and split for math mode. According to the AMS math guide split takes a single $ sign. So

.. math::
    DividendYield &= \frac{DVT(t)}{CurrentMarketCap} \\
    Avg_Assets &= \biggl( A/B \biggr) \textrm { when B is not zero...} \\
    Avg \_ Assets &= \biggl(\frac{A}{B}\biggr) \textrm{ when B is not zero...}

.. autofunction:: mymodule.foo

with foo defined as

def foo(self):
    r"""Sample docstring

    .. math::
        Ax &= b \\
        Cx &= \biggl( \frac{x}{y} \biggr) \textrm{ if y is not zero.}
    """
    pass

renders fine with latexpdf and to html with the MathJax extension.

sphinx-math

Note that I used \_ for the underscore in math mode , which worked, but \textunderscore didn't work (You have to load additional packages I think, see this question on tex.stackexchange.com). So as it comes out, I think your question is clearly a Tex question.

I don't remove my previous answer, however it is only applicable for the latex builder, not for the html builder.

Original answer

Sphinx produces "unusual" latex code. It uses gather and split for equations (have a look at the latex source it generates).

The problem is, that there is no simple way to modify the latex source it produces. You have to post-process the latex source to get "scientific" grade latex code.

Sphinx is designed for html docs (and by web developers I think), latex (and scientific "problems" like numbered figures, tables and equations) doesn't seem to be the main focus of the project. By the way, your code renders fine to html with the mathjax extension.

I think I remember some criticism by the docutils developers on this topic too: docutils has a latex builder (which seems to be "better"), but this builder is not used by sphinx.

There was once an announcement of a project called relatex (link) on the mailing list to post-process the latex code created by sphinx. But I'm not sure about the development status. I used my own code, which I made available here (unfortunately it is a mixture of German an English). I don't think that it is very useful, because I decided that it is to complicated to post-process sphinx latex and I switched to pure latex. So I didn't developed it further. However the basic steps are

  • create your own latex style and template
  • let sphinx create it's latex code
  • post-process the latex code and paste it into your template
  • use a building system for LaTeX to generate the pdf from your code

I adapted the sphinx Makefile to do this in a single step. As the building system I used rubber (nowadays I would use latexmk).

查看更多
登录 后发表回答