4

I'm using Julia in a jupyter notebook.

I want to generate a pdf for the results of my work. However, when generating the pdf, the λ of the mathematical expression λ=3 is lost so that the output in the pdf is =3.

Here is the jupyter notebook code

In[1]: λ=3 
Out[1]: 3

Here is the pdf generated with the jupyter notebook

In[1]: =3 
Out[1]: 3

This is not the case in with the pdf generated with nteract where the expression λ=3 is fully printed out. However the overall appearance of the pdf generated with nteract is not as nice as the pdf generated with jupyter notebook.

Here is printed pdf generated with nteract (looks exactly the same as the code itself):

In[1]: λ=3
Out[1]: 3

Can somebody know how to print such character with jupyter notebook?

Many thanks in advance

hckr
  • 5,456
  • 1
  • 20
  • 31
ecjb
  • 5,169
  • 12
  • 43
  • 79
  • Some minimal code to reproduce would help. – Jongware Mar 30 '18 at 21:34
  • I tried the accepted answer, unfortunately it didn't work for me. Then I found a way to kind of skip this issue by using `$\lambda$` this kind of notation, luckily it did work for me. So, in short, don't use unicode letters, but reply on latex syntax to generate Greek letters. – Timeless Oct 21 '20 at 05:19

2 Answers2

5

The issue is related to how Jupyter itself generates and compiles the latex file. Jupyter, by default, compiles the file with xelatex to support Unicode. My guess is, however, xelatex requires some configurations in the files and Jupyter does not generate the file that works out of the box with plain xelatex command.

You can change the configuration of Jupyter to compile latex file generated with pdflatex or latex command.

Solution: Find your Jupyter configuration directory(i.e. output of jupyter --config-dir, on Linux usually ~/.jupyter. To find out which jupyter IJulia uses run using IJulia; IJulia.jupyter then find out the config directory of that jupyter)

Create the file jupyter_notebook_config.py in this directory if there is not one, already.

Put the following line of code at the end of this file and save it:

c.PDFExporter.latex_command = ['pdflatex', '{filename}']

Then you can export the PDF file using the notebook, as usual. The characters should appear, just right. This should work provided that pdflatex command is found in your shell.

If you do not have pdflatex but have latex you can also use the following line instead of the code above:

c.PDFExporter.latex_command = ['latex', '--output-format=pdf', '{filename}']

If you are not able to change the configuration of Jupyter, download the latex file and compile it with the command latex --output-format=pdf filename.tex.

Hope it works!

hckr
  • 5,456
  • 1
  • 20
  • 31
  • Sadly this didn't work for me, I get errors like "! Package ucs Error: Unknown Unicode character 12479 = U+30BF," – minexew Jul 25 '18 at 20:11
  • ['pdflatex', '{filename}'] – minexew Jul 30 '18 at 08:02
  • The problem might be related with your Latex distribution. Could you try `pdflatex` with the Latex copy of your notebook (Download as *.tex)? – hckr Jul 30 '18 at 17:18
0

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.

Jeffrey Goldberg
  • 390
  • 4
  • 10