My solution to this is ugly, and I will get to it below, but first it is important to understand why this is happening.
Why is this happening
The intermediate .tex
file that is generated indirectly calls for the Latin Modern fonts. Latin Modern is a fine choice for math fonts, but it is sucky for monospaced. The Latin Modern mono font does not include Greek.
Latin Modern is set by the unicode-math LaTeX package, which is loaded in the generated LaTeX around line 43.
\ifPDFTeX
\usepackage[T1]{fontenc}
\IfFileExists{alphabeta.sty}{
\usepackage{alphabeta}
}{
\usepackage[mathletters]{ucs}
\usepackage[utf8x]{inputenc}
}
\else
\usepackage{fontspec}
\usepackage{unicode-math}
\fi
So the unicode-math
package will be loaded if you are using XeLaTeX (which is a good default) or LuaTeX or any other LaTeX engine for which fontspec
is available.
The unicode-math package very reasonably uses Latin Modern for math, but if nothing is set otherwise, it will also use Latin Modern for monospaced fonts. From the documentation
Once the package is loaded, traditional TFM-based maths fonts are no longer supported; you can only switch to a different OpenType maths font using the \setmathfont command. If you do not load an OpenType maths font before \begin{document}, Latin Modern Math will be loaded automatically.
The creators of unicode-math
assume that you will set your non-math fonts up after you have loaded the unicode-math
, but that isn't done with the .tex
generated by jupyter nbconvert
. (I don't know if this is a jupyter thing or a Pandoc thing, but either way we end up with a document that is used Latin Modern for more than just math.)
So one solution is to set some other mono font after unicode-math is loaded and before \begin{Document}
.
My solution
My solution is tuned for what I already had set up. It may not be the right approach for you, and it certainly will need some adjusting.
My Makefile used to have a simple juypter nbconvert --to=pdf
in it. But now I need to edit the intermediate .tex
file. So I have this for a notebook named computation-examples
. You will need to use your own file name or do some Make rule magic.
# sed on macOS is just weird. Resorting to perl
computation-examples.tex: computation-examples.ipynb
jupyter nbconvert --to=latex $<
perl -pi -e '/^([ \t]*)\\usepackage{unicode-math}/ and $$_.="$$1\\usepackage[default]{fontsetup}\n"' $@
The perl adds the line \usepackage[default]{fontsetup}
immediately after the line with\usepackage{unicode-math}
. There are probably nicer ways to do that. I started with sed, but gave up. So the .tex
file that is then processed to PDF by XeLaTeX has this.
\else
\usepackage{fontspec}
\usepackage{unicode-math}
\usepackage[default]{fontsetup}
\fi
The fontsetup
package preserves all of the goodness of unicode-math
while setting up the non-math founts. The default is to use the OpenType (.otf
) Computer Modern Unicode fonts that will be a part of any TeX distribution that has xelatex on it.
Another approach
Probably a cleaner approach, but one I haven't experimented with, would be to create a fontspec.cfg file which lies about (overrides) what font files to load for what we are calling Latin Modern Mono. I would need to reread the fontspec documentation for the hundredths time to do that.
Make magic
Since writing the above, I have set up a more general Makefile rule,
%.tex: %.ipynb
jupyter nbconvert --to=latex $<
perl -pi -e '/^([ \t]*)\\usepackage{unicode-math}/ and $$_.="$$1\\usepackage[default]{fontsetup}\n"' $@
which sits along rules to make a PDF from a .tex
file.
But if you aren't using make and Makefiles, then you can wrap up that perl monstrosity into a script of your choosing.