8000 Closes #15796 (building PDF docs of matplotlib via LaTeX) by jfbu · Pull Request #15797 · matplotlib/matplotlib · GitHub
[go: up one dir, main page]

Skip to content

Closes #15796 (building PDF docs of matplotlib via LaTeX) #15797

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from

Conversation

jfbu
Copy link
Contributor
@jfbu jfbu commented Nov 30, 2019

PR Summary

Make build of matplotlib documentation to PDF possible.

The #15796 issue is caused by the fact that latex_elements dict got redefined near end of conf.py hence the part about using LaTeX package enumitem and its \setlistdepth got lost. But anyway since Sphinx 1.5 there is 'maxlistdepth' key, so use that.

Another problem arose related to expdlist very old LaTeX package. I realized it broke the build with recent LaTeX (when a description environment was found in a longtable cell).

edited: this also breaks with LaTeX as old as 2012. Because I did not recall having seen the issue in 2018 when trying out building scipy's PDF documentation (but perhaps I had already patched expdlist), and as my laptop only has TeXLive 2018 and 2019 I erroneously thought the issue arose from LaTeX upstream change of array package. But I see now expdlist (not updated since 1999...) breaks LaTeX (even from 2012) when a description list ends up in a table cell. It is not recent issue.

The cause is probably the upstream LaTeX changes in array package which last year invalidated tabu package.

For time being I simply commented out usage of expdlist. Turns out that a patch of mine which got merged into scipy (also for matters of building PDF) in April 2018 fixes the more recent breakage caused by expdlist. As experimenting with builds of matplotlib (close to 3000 pages) is time costly, I did not much investigate if it would be worthwile using expdlist as patched in my scipy PR. (see commit message).

Finally, matplotlib documentation of "Mathtext" uses tons of Unicode math-like characters in plain text, and DejaVu Serif was lacking 134 of them. I thus configure the build to use XITS and it turns out it provided all glyphs. It comes with TeXLive TeX distributions of recent years. I used syntax which should work whether compiling on Mac OS or Linux and probably Windows.

As latex engine is xelatex, it is not easy without additional mark-up to use both OpenType fonts and traditional TeX fonts, so I removed the \usepackage{txfonts} and used FreeSans and FreeMono for the sans and mono famillies. This means though that the math symbols will be the Knuth Computer Modern ones. I left commented out two lines loading unicode-math and the OpenType Math font XITS Math which would fix that aspect. Perhaps they should be activated ?

PR Checklist

almost None of this applies because it is simply a modification of doc/conf.py...

Arrgh

$ flake8 conf.py
conf.py:4:80: E501 line too long (80 > 79 characters)
conf.py:7:80: E501 line too long (82 > 79 characters)
conf.py:93:1: E402 module level import not at top of file
conf.py:95:1: E402 module level import not at top of file
conf.py:180:80: E501 line too long (83 > 79 characters)
conf.py:297:80: E501 line too long (81 > 79 characters)

but... none of this comes from my patch as it is all after line number 300 :-)

  • Has Pytest style unit tests
  • Code is Flake 8 compliant
  • New features are documented, with examples if plot related
  • Documentation is sphinx and numpydoc compliant
  • Added an entry to doc/users/next_whats_new/ if major new feature (follow instructions in README.rst there)
  • Documented in doc/api/api_changes.rst if API changed in a backward-incompatible way

Tested the PDF build with Sphinx 1.8.5 and 2.2.1 and Python 3.7.5 and matplotlib at 3d1a1bc

@jfbu
Copy link
Contributor Author
jfbu commented Dec 2, 2019

Forced pushed to reword a commit message. I had forgotten that in scipy/scipy@c881fde (from scipy/scipy#8657) I had already found out that expdlist broke description lists ending up in table cells. Turns out that matplotlib docs do have such an instance (with master at 3d1a1bc). As I indicated in my original post, the scipy patch could also be used here, but I simply commented out usage of expdlist not having examined closely the difference in PDF output between doing this or incorporating same LaTeX fix as in my scipy commit.

edit: turns out that the breakage caused by old buggy expdlist package was masked (in some past state of matplotlib, when latex_elements['preamble'] did not have 2 definitions in conf.py) by using package enumitem. The latter modifies in its way the latex list environments and by some luck this was hiding the expdlist breakage (there is nothing in enumitem source code comments relative to expdlist and it is only a lucky thing). As this PR uses Sphinx 1.5 'maxlistdepth' it has no need for enumitem, hence I tested without it and hit againts the expdlist causing a crash. Thus I commented out its usage, and as pointed above there is also a fix known and applied in a scipy commit.

I try hard to be very focused and to not dwell on long LaTeX inherent complications and explanations about bad or badly interacting packages but I always end up piling up paragraphs...

@jfbu
Copy link
Contributor Author
jfbu commented Dec 3, 2019

on further thought and having experimented with building numpy's docs to PDF, and now remembering better my similar experience with building scipy's PDF docs, I think it would be better for coherence with these two other projects (who probably have many shared users with matplotlib project) to not comment out usage of expdlist LaTeX package (as I did in this PR) but rather to fix it the same as I did in scipy/scipy@c881fde and copied over to numpy/numpy#15028. It is only a matter of how parameter descriptions look like in PDF, i.e. here is a piece of matplotlib doc with this PR
Capture d’écran 2019-12-03 à 23 14 36
compared to how numpy's docs look like (with usage of expdlist):
Capture d’écran 2019-12-03 à 23 14 52
Personally I would rather prefer yet another style, with the type description being on same line of label and description on new line....

(highlighting of Parameters in above screenshot is accidental, my PDF viewer was used to search for that string)

@jfbu
Copy link
Contributor Author
jfbu commented Dec 4, 2019

I have pushed some more commits. Sorry about mishap with latex_elements['pointsize'] which I moved to a place where latex_elements dict had not been initialized, then reverted.

Before:
Capture d’écran 2019-12-04 à 22 10 26

After:
Capture d’écran 2019-12-04 à 22 13 20

  • use XITS Math and unicode-math to get blackboard alphabet \mathbb accept b, c, d letters.

Before:
Capture d’écran 2019-12-04 à 22 16 19

After:
Capture d’écran 2019-12-04 à 22 18 07

LaTeX installation must have xelatex installed: on Ubuntu xenial, I think this means texlive-xetex, and xindy are needed. Also latexmk is needed for make latexpdf.

And https://github.com/alif-type/xits fonts are needed. Ubuntu's texlive-fonts-extra provided it at xenial already. And texlive-fonts-extra is on Ubuntu xenial a requirement of Sphinx LaTeX.

nota bene: while working on this I have noticed a problem with 'xelatex' (in smartquotes = False) context with the " character. Unfortunately 'xelatex' converts "versions" in latex file (as smart quotes are turned off, "versions" in reST sources makes it unmodified to LaTeX file) into ”versions” in PDF output by default with fonts such as XITS or also GNU FreeFont which is the default font used by Sphinx 2.x with xelatex.

See sphinx-doc/sphinx#6886. It is possible the issue does not show with old LaTeX, because fontspec package according to its docs in some (unspecified) past state did not activate so-called TeX ligatures by default. But now (since when?) it does it by default.

By the way I do not understand why the mapping " to ” can be called a "TeX ligature" because TeX ligatures dealt only with mapping `` to and '' (this is two straight single quotes not a ") to . And the handling of ` and ' were not by ligatures but simply having curly glyphs at certain font slots. But LaTeX life is desperately complicated and counter-intuitive in so many cases.

@tacaswell
Copy link
Member

Thank you for your work on this @jfbu !

How does this overlap with #15799 ?

Don't worry about force-pushing to your branch or making mistakes that you fix.

But LaTeX life is desperately complicated and counter-intuitive in so many cases.

too true....

@jfbu
Copy link
Contributor Author
jfbu commented Dec 5, 2019

How does this overlap with #15799 ?

Ah sorry when I updated this one I had forgotten about #15799... and I incorporated here in my last update half of it, i.e. usage of \and mark-up (which fixes overflowing but will still have until Sphinx 2.3.0 the sphinx-doc/sphinx/issues/6876 problem).

Better to keep the two separated, but when I will update #15799 to only contain the fix of author display on title page, part of your reviewing work over there will be marked "outdated"... because it was on commits which will be only in this one soon. (my rationale into incorporating into #15799 the commits present here was to allow testing the PDF build, but if you trust the picture I posted over there it is not really needed....)

Don't worry about force-pushing to your branch or making mistakes that you fix.

Ok, I will clean up a bit this branch. And add a commit backporting the method sphinx-doc/sphinx/pull/6888 fix of the double quote issue when using xelatex under smartquotes = False regime. This will need no change with future Sphinx incorporating that fix, except that it will simply become superfluous.

But LaTeX life is desperately complicated and counter-intuitive in so many cases.

too true....

@jfbu
Copy link
Contributor Author
jfbu commented Dec 5, 2019

I have force pushed to reorganize the commit history and messages into logically consecutive steps.

@QuLogic
Copy link
Member
QuLogic commented Mar 7, 2020

e01fe33 seems to have the wrong commit message (and could be merged with the following commit.) Otherwise, I think this looks reasonable, though I have yet to test it.

@QuLogic
Copy link
Member
QuLogic commented Mar 9, 2020

I tried this out, but even after installing the texlive-xits, it fails to find the font:

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! fontspec error: "font-not-found"
! 
! The font "XITS-Regular" cannot be found.
! 
! See the fontspec documentation for further information.
! 
! For immediate help type H <return>.
!...............................................  

The file name is xits-regular.otf, and the font name is XITS Regular, so why is it looking for XITS-Regular?

@QuLogic
Copy link
Member
QuLogic commented Mar 9, 2020

Ah, I see we have this in our pgf documentation; xelatex can't find fonts installed in texlive directories instead of globally. I worked around this by giving it the file name xits-regular.

However, it also failed to find FreeSans.otf. In Fedora, it's a ttf (probably will be otf in 32), but even changing Extension = .ttf, didn't work. Since FreeSans is also the name of the font, dropping the Extension line entirely seems to have fixed that.

@jfbu
Copy link
Contributor Author
jfbu commented Mar 9, 2020

Ah, I see we have this in our pgf documentation; xelatex can't find fonts installed in texlive directories instead of globally. I worked around this by giving it the file name xits-regular.

The situation is a wee'bit complicated with xelatex+fontspec for fonts, things have changed overtime. On my mac os x, I have a special set-up with symlinks in $HOME/Library/Fonts to point to the TrueType and OpenType repertories in the TeXLive tree. However I often forget I had long time ago set-up these symlinks and this may lead me to have a smoother ride than some users (on mac os). As per Linux I can test on Ubuntu but I have no Fedora handy.

On TeXLIve based distribution, if xelatex does not find the font in system/user locations it will then, it can still find it indeed by filename via the services of kpsewhich which comes with these distributions.

e01fe33 seems to have the wrong commit message (and could be merged with the following commit.) Otherwise, I think this looks reasonable, though I have yet to test it.

should I add another setting (using filename for XITS Math) and then squash commits?

@QuLogic
Copy link
Member
QuLogic commented Mar 13, 2020

It should definitely work with a default setup, not sure if an option would be needed.

jfbu added 2 commits March 22, 2020 09:01
- remove loading of amsmath, amssymb, amsfonts (already done by
  sphinx.sty)
- remove loading of txfonts (not compatible with xetex/fontspec)
- patch old obsolete expdlist.sty
- resolve "Too deeply nested" error without using enumitem package.
  This Imports the fix already applied to NumPy and SciPy

    numpy/numpy#15028
    scipy/scipy@c881fde

- use XITS and XITS Math for wide enough Unicode coverage. As XITS has
  all the Unicode mathematical symbols needed for the section of the
  documentation related to Mathtext.
  (DejaVu Serif was missing 134 of them, and GNU FreeFont 19 of them)

  The Ubuntu package texlive-fonts-extra provides these latex dependencies.

- better looking general index in PDF documentation
- backport sphinx-doc/sphinx/pull/6888 to fix double quote issue
@jfbu
Copy link
Contributor Author
jfbu commented Mar 22, 2020

Squashed and rebased to get a clear commit message.

I don't know what to do for XITS loading. Here is my local set-up:

$ ls /usr/local/texlive/2020/texmf-dist/fonts/opentype/public/xits
XITS-Bold.otf        XITS-Italic.otf      XITSMath-Bold.otf
XITS-BoldItalic.otf  XITS-Regular.otf     XITSMath-Regular.otf

On my mac os x, filenames ignore case. So I could use xits-regular.otf . I have no .ttf for XITS on my system. How do filenames look on Fedora systems ?

@QuLogic
Copy link
Member
QuLogic commented Mar 24, 2020

The file names for XITS on Fedora are like /usr/share/texlive/texmf-dist/fonts/opentype/public/xits/xits-regular.otf.

@QuLogic
Copy link
Member
QuLogic commented Jun 23, 2020

Any progress here? What needs to be done?

@jkseppan
Copy link
Member
jkseppan commented Aug 4, 2020

I installed a clean mactex (mactex-20200407.pkg) from homebrew on Catalina and upgraded all packages with sudo tlmgr update --all. The build fails with

kpathsea: Running mktextfm XITS-Regular
/usr/local/texlive/2020/texmf-dist/web2c/mktexnam: Could not map source abbreviation X for XITS-Regular.
/usr/local/texlive/2020/texmf-dist/web2c/mktexnam: Need to update /usr/local/texlive/2020/texmf-dist/fonts/map/fontname/special.map?
mktextfm: Running mf-nowin -progname=mf \mode:=ljfour; mag:=1; ; nonstopmode; input XITS-Regular
This is METAFONT, Version 2.7182818 (TeX Live 2020) (preloaded base=mf)


kpathsea: Running mktexmf XITS-Regular
! I can't find file `XITS-Regular'.
<*> ...; mag:=1; ; nonstopmode; input XITS-Regular

Please type another input file name
! Emergency stop.
<*> ...; mag:=1; ; nonstopmode; input XITS-Regular

Transcript written on mfput.log.
grep: XITS-Regular.log: No such file or directory
mktextfm: `mf-nowin -progname=mf \mode:=ljfour; mag:=1; ; nonstopmode; input XITS-Regular' failed to make XITS-Regular.tfm.
kpathsea: Appending font creation commands to missfont.log.


! Package fontspec Error: The font "XITS-Regular" cannot be found.

I think xetex shouldn't need TeX font metrics, so it shouldn't be calling mktextfm.

@jkseppan
Copy link
Member ED48
jkseppan commented Aug 4, 2020

Editing the file like so allows the build to continue:

\setmainfont{XITS}[
Extension = .otf,
  UprightFont    = *-Regular,
  ItalicFont     = *-Italic,
  BoldFont       = *-Bold,
  BoldItalicFont = *-BoldItalic,
]
\setsansfont{FreeSans}[
Extension = .otf,
  UprightFont    = *,
  ItalicFont     = *Oblique,
  BoldFont       = *Bold,
  BoldItalicFont = *BoldOblique,
]
\setmonofont{FreeMono}[
Extension = .otf,
  UprightFont    = *,
  ItalicFont     = *Oblique,
  BoldFont       = *Bold,
  BoldItalicFont = *BoldOblique,
]
% needed for \mathbb (blackboard alphabet) to actually work
\usepackage{unicode-math}
\setmathfont{XITSMath-Regular}[
Extension = .otf
]

Would this work on Linux?

@jkseppan
Copy link
Member
jkseppan commented Aug 4, 2020

Here's a Dockerfile for testing on Fedora:

FROM fedora:latest
RUN dnf install -y texlive-xetex texlive-xits latexmk \
        'tex(cmap.sty)'     \
        'tex(FreeSans.otf)' \
        'tex(fncychap.sty)' \
        'tex(fancyhdr.sty)' \
        'tex(titlesec.sty)' \
        'tex(tabulary.sty)' \
        'tex(longtable.sty)'\
        'tex(varwidth.sty)' \
        'tex(makeidx.sty)'  \
        'tex(framed.sty)'   \
        'tex(xcolor.sty)'   \
        'tex(fancyvrb.sty)' \
        'tex(float.sty)'    \
        'tex(wrapfig.sty)'  \
        'tex(parskip.sty)'  \
        'tex(alltt.sty)'    \
        'tex(upquote.sty)'  \
        'tex(capt-of.sty)'  \
        'tex(needspace.sty)'\
        'tex(remreset.sty)' \
        'tex(atbegshi.sty)' \
        'tex(kvoptions.sty)'\
        'tex(expdlist.sty)'

COPY . $HOME
RUN latexmk -pdf -dvi- -ps- Matplotlib.tex

Calling docker build . in the build/latex directory after the Matplotlib.tex file has been generated installs the dependencies and runs the build. It fails in makeindex, but that is after the first call to xelatex, so the altered font commands seem to be working fine.

Copy link
Member
@jkseppan jkseppan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

# the Unicode codepoints needed for the section about Mathtext
# "Writing mathematical expressions"
latex_elements['fontpkg'] = r"""
\setmainfont{XITS}[
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
\setmainfont{XITS}[
\setmainfont{XITS}[
Extension = .otf,

BoldFont = *-Bold,
BoldItalicFont = *-BoldItalic,
]
\setsansfont{FreeSans}[
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
\setsansfont{FreeSans}[
\setsansfont{FreeSans}[
Extension = .otf,

BoldFont = *Bold,
BoldItalicFont = *BoldOblique,
]
\setmonofont{FreeMono}[
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
\setmonofont{FreeMono}[
\setmonofont{FreeMono}[
Extension = .otf,

]
% needed for \mathbb (blackboard alphabet) to actually work
\usepackage{unicode-math}
\setmathfont{XITS Math}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
\setmathfont{XITS Math}
\setmathfont{XITSMath-Regular}[
Extension = .otf
]

@QuLogic
Copy link
Member
QuLogic commented Aug 4, 2020

It fails in makeindex

You need to install texlive-xindy for that, I believe.

@QuLogic
Copy link
Member
QuLogic commented Nov 14, 2020

That won't work for Fedora, because it has FreeSans.ttf, not .otf.

@QuLogic QuLogic mentioned this pull request Nov 14, 2020
3 tasks
@QuLogic
Copy link
Member
QuLogic commented Nov 14, 2020

I rebased this and added additional fixes for new bugs in the above-linked PR.

@QuLogic QuLogic closed this Nov 14, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants
0