Repository: numpy/numpy

Issue:
[DOC] doc/source/conf.py contains usage of latex_preamble which was removed at Sphinx 1.6.1
I wanted to build the PDF documentation (using Sphinx 2.2.1 and current versions of scipy, matplotlib, etc from `pip install` and using numpy from git at b83f10ef7e) and was disconcerted that it actually succeeded :wink:

Turns out after checking that https://github.com/numpy/numpy/blob/master/doc/source/conf.py uses removed `latex_preamble` variable (it was removed at Sphinx 1.6.1). Correct syntax is now with `latex_elements['preamble']`. I did that, and obtained the failure on building `numpy-ref.pdf` that I was expecting:
```
! Extra }, or forgotten \endgroup.
\@endpbox ...\@arstrutbox \color@endgroup \egroup 
                                                  \the \LT@p@ftn \global \LT...
l.131934 \item[{Parameters}]
                             \leavevmode
```
This is caused by these lines 

https://github.com/numpy/numpy/blob/b83f10ef7ee766bf30ccfa563b6cc8f7fd38a4c8/doc/source/conf.py#L187-L189

I know two fixes:
- add `\usepackage{enumitem}`. I don't recommend that because the fact that it fixes the `expdlist` breakage appears unintentional, it is sheer luck (and I tested it on only one small example, not the full `numpy-ref.tex`). In the past Sphinx users used `enumitem` to avoid `Too deeply nested` error, but since Sphinx 1.5, there is `latex_elements['maxlistdepth']` to fix that LaTeX limitation:
```
latex_elements['maxlistdepth'] = '10'  # should be enough, increase at will (don't use '2048' as this would create needlessly thousands of TeX macros)
```
- the second fix is to be found  in a https://github.com/scipy/scipy/commit/c881fdea7a7ef7c518b7898cfd53b2880af06778 and I copy it here. It would thus be like this:
```latex
% In the parameters section, place a newline after the Parameters
% header
\usepackage{expdlist}
\let\latexdescription=\description
\def\description{\latexdescription{}{} \breaklabel}

% Remove extra space
\usepackage{etoolbox}
\makeatletter
\patchcmd\@item{{\@breaklabel} }{{\@breaklabel}}{}{}
\makeatother

% Fix bug in expdlist's way of breaking the line after long item label
\makeatletter
\def\breaklabel{%
    \def\@breaklabel{%
        \leavevmode\par
        % now a hack because Sphinx inserts \leavevmode after term node
        \def\leavevmode{\def\leavevmode{\unhbox\voidb@x}}%
    }%
}
\makeatother
```

Side remark about
https://github.com/numpy/numpy/blob/b83f10ef7ee766bf30ccfa563b6cc8f7fd38a4c8/doc/source/conf.py#L182-L183

It is unneeded because already done by Sphinx

As for the remainder of the LaTeX code in this former `latex_preamble` it may need some check that it still gives a desired effect in the PDF.

By the way I would recommend using `--halt-on-error` for `pdflatex` builds. In case of an error, the `make` exits with error code but the LaTeX console output is gigantic and the log file too and one loses time searching for first TeX error, whereas with `--halt-on-error` this is more efficient.

The
https://github.com/numpy/numpy/blob/b83f10ef7ee766bf30ccfa563b6cc8f7fd38a4c8/doc/Makefile#L220
does nothing actually with current Sphinx produced Makefile in latex build directory. You can use the method from https://www.sphinx-doc.org/en/master/usage/builders/index.html#sphinx.builders.latex.LaTeXBuilder
```
To pass options directly to the (pdf|xe|lua)latex binary, use variable LATEXOPTS, for example:

make latexpdf LATEXOPTS="--halt-on-error"

```

and
```
Since 1.6, make latexpdf uses latexmk (not on Windows). This makes sure the needed number of runs is automatically executed to get the cross-references, bookmarks, indices, and tables of contents right.

One can pass to latexmk options via the LATEXMKOPTS Makefile variable. For example:

make latexpdf LATEXMKOPTS="-silent"

```
(this is with standard Sphinx distributed Makefile, in your case replace `latexpdf` by  `-C build/latex all-pdf`) and the two can be combined but then (with patches of `expdlist` above commented out) the LaTeX error does not make it to the console output only to the end of the log file:

```
$ make numpy-ref.pdf LATEXOPTS="--halt-on-error" LATEXMKOPTS="--silent"
latexmk -pdf -dvi- -ps- --silent 'numpy-ref.tex'
Latexmk: Run number 1 of rule 'makeindex numpy-ref.idx'
Latexmk: Run number 1 of rule 'pdflatex'
This is pdfTeX, Version 3.14159265-2.6-1.40.20 (TeX Live 2019) (preloaded format=pdflatex)
 restricted \write18 enabled.
entering extended mode
Latexmk: Summary of warnings from last run of (pdf)latex:
  Latex found 4 multiply defined reference(s)
  Latex failed to resolve 388 citation(s)
Collected error summary (may duplicate other messages):
  pdflatex: Command for 'pdflatex' gave return code 1
      Refer to 'numpy-ref.log' for details
Latexmk: Use the -f option to force complete processing,
 unless error was exceeding maximum runs, or warnings treated as errors.
make: *** [Makefile:33: numpy-ref.pdf] Error 12
```
One has to go in `numpy-ref.log` find the LaTeX error causing abort:
```
! Extra }, or forgotten \endgroup.
\@endpbox ...\@arstrutbox \color@endgroup \egroup 
                                                  \the \LT@p@ftn \global \LT...
l.131952 \item[{Parameters}]
                             \leavevmode 
Here is how much of TeX's memory you used:
 26928 strings out of 493377
 686470 string characters out of 6157389
 755139 words of memory out of 5000000
 26189 multiletter control sequences out of 15000+600000
 84239 words of font info for 133 fonts, out of 8000000 for 9000
 500 hyphenation exceptions out of 8191
 51i,26n,49p,1225b,732s stack positions out of 5000i,500n,10000p,200000b,80000s

!  ==> Fatal error occurred, no output PDF file produced!
```

To recap, `numpy-ref.pdf` builds currently because `latex_preamble` from doc/source/conf.py is ignored! If this LaTeX configuration was not ignored, the build would fail due to usage of very old (1999) LaTeX package `expdlist` which causes usage of description lists in table cells break LaTeX (and there is one such usage subsection ``distutils.misc`` from section ``Modules in numpy.distuils`` part of ``numpy-ref``). A fix is known from an April 2018 scipy commit scipy/scipy@c881fde.


Discussion:

Resolving patch:
diff --git a/doc/source/conf.py b/doc/source/conf.py
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -178,15 +178,28 @@ def setup(app):
 }
 
 # Additional stuff for the LaTeX preamble.
-latex_preamble = r'''
-\usepackage{amsmath}
-\DeclareUnicodeCharacter{00A0}{\nobreakspace}
-
+latex_elements['preamble'] = r'''
 % In the parameters section, place a newline after the Parameters
 % header
 \usepackage{expdlist}
 \let\latexdescription=\description
 \def\description{\latexdescription{}{} \breaklabel}
+% but expdlist old LaTeX package requires fixes:
+% 1) remove extra space
+\usepackage{etoolbox}
+\makeatletter
+\patchcmd\@item{{\@breaklabel} }{{\@breaklabel}}{}{}
+\makeatother
+% 2) fix bug in expdlist's way of breaking the line after long item label
+\makeatletter
+\def\breaklabel{%
+    \def\@breaklabel{%
+        \leavevmode\par
+        % now a hack because Sphinx inserts \leavevmode after term node
+        \def\leavevmode{\def\leavevmode{\unhbox\voidb@x}}%
+    }%
+}
+\makeatother
 
 % Make Examples/etc section headers smaller and more compact
 \makeatletter


Test patch: