sphinx-doc / sphinx

The Sphinx documentation generator
https://www.sphinx-doc.org/
Other
6.39k stars 2.09k forks source link

SVG output is not as nice as MathJax #5301

Open certik opened 6 years ago

certik commented 6 years ago

The default SVG output looks like this:

screenshot_2018-08-14 5 1 maxwell s equations theoretical physics reference 0 5 documentation

As you can see, the math font is much thinner than the surrounding ReST text, so it looks incompatible. Also the equations are quite thin and look gray instead of black.

MathJax, on the other hand, looks like this:

screenshot_2018-08-14 5 1 maxwell s equations theoretical physics reference 0 5 documentation 1

The fonts are very much compatible with the surrounding ReST text, and also the equations are a bit fuller, and so they look good and the color is black.

In general, when mixing ReST and math in one sentence, the MathJax looks natural, while SVG does not.

How can this be fixed? It seems the solution is to do both of these:

asmeurer commented 6 years ago

SVG is just using Computer Modern, so if you want it to look like the surrounding text, you should use the same font. MathJax also uses a different font from the main text (your main text font isn't even serif), but I guess it happens to look closer.

This should all be modifiable by changing the preamble.

certik commented 6 years ago

@asmeurer thanks. I need to figure out what font MathJax uses and then try to use the same font in LaTeX. I'll update the issue here if I figure it out.

asmeurer commented 6 years ago

I think it uses STIX. Apparently you can change it https://docs.mathjax.org/en/latest/font-support.html

tk0miya commented 5 years ago

Is there anything to do from Sphinx side? If nothing, I'd like to close this issue.

certik commented 5 years ago

@tk0miya what Sphinx should do is to make the SVG equations by default look like the MathJax ones.

jfbu commented 5 years ago

Maybe https://github.com/jennigorham/mathjax-fonts-in-latex can help you. Follow installation instructions (for your locale or on the build system you use) and adjust accordingly imgmath_latex_preamble. (untested)

On the other hand you can also instruct the math to svg converter to use STIX fonts and again a priori one only needs to adjust imgmath_latex_preamble (and make sure the LaTeX packages and the fonts are available at place of build). Instructions for a latex build depend whether you use latex or xelatex.

Notice as background info that SVG is produced via dvisvgm on files in DVI format produced by a LaTeX run. You may need or not to configure the options passed by Sphinx to dvisvgm depending on fonts, see the dvisvgm FAQ page.

jfbu commented 5 years ago

I tried to follow my own instructions to use stix2 but this LaTeX package conflicts with the default preamble used by sphinx.ext.imgmath. See #6278

jfbu commented 5 years ago

For "math into SVG" the path is "equation --> latex --> conversion of dvi to svg by dvisvgm".

You can customize the fonts simply via modifying imgmath_latex_preamble which can load some TeX math packages. As reported (#6278) this may not always work depending on math package. (the default preamble used by Sphinx can not be replaced, only extended, this may need to be changed in future).

Two examples :

extensions = [
    'sphinx.ext.imgmath',
]

imgmath_image_format = 'svg'

imgmath_latex_preamble = '\\usepackage{newtxmath}'

gives

Capture d’écran 2019-04-15 à 23 23 33

and if you want sans-serif math you can try for example

extensions = [
    'sphinx.ext.imgmath',
]

imgmath_image_format = 'svg'

imgmath_latex_preamble = '\\usepackage{newtxsf}'

with which I get:

Capture d’écran 2019-04-15 à 23 22 57

It is difficult for Sphinx to make a default choice among TeX math packages and fonts and any help appreciated. There are quite a few math font packages. But all are fonts specific to TeX.

We are investigating at #6279 opening up usage of xelatex to produce SVGs using xelatex which will open access to OpenType Math fonts; there are few of them but their list is growing XITS Math, or Libertinus, or Cambria, etc....

For sans serif DejaVu Sans Math exists (there is support for DejaVu Sans with pdflatex, but I don't think this includes math fonts, last time I checked I did not find it).

certik commented 5 years ago

@jfbu, thanks for investigating this. Indeed, I think the solution is to play with the fonts in pdflatex or xelatex, and find some way that looks acceptable compared to the Sphinx text font.

I typically use Docker to build my website using Sphinx, so I think a reasonable goal to achieve before closing this issue would be to get it working in Docker by installing whatever is necessary for latex. I understand that Sphinx might not do this by default due to the many different latex setups that people have, but I would like to figure out a way to make this work for people that want this, even if it is not the default.

asmeurer commented 5 years ago

Note that unless you specify a web safe font or a web font, the actual font that is used in a Sphinx document will depend on the what fonts are installed on a person's computer and their browser settings. The font-family CSS field usually specifies several fonts for fallback purposes.

jfbu commented 5 years ago

@asmeurer This indeed means it is hard to really match text and math, but for the SVG snippets produced by dvisvgm I don't think CSS or browser settings can influence it as by default Sphinx currently uses --no-fonts so the glyphs are rendered by path elements. But, if using --font-format=woff, then browser settings can indeed more readily modify the math rendering. I tested the latter with imgmath_latex_preamble = '\\usepackage{newtxsf}'; incidentally the glyphs seemed a bit cropped in Firefox and the --exact option of dvisvgm did not change that.

@certik

I understand that Sphinx might not do this by default due to the many different latex setups that people have

This is indeed a problem for us. I like the way the sans serif rendering looks with imgmath_latex_preamble = '\\usepackage{newtxsf}' but if Sphinx does it by default this means I have to check which Ubuntu xenial package provides it which takes time each time such a dependency is added (I should do it now rather than writing this). At any rate it is definitely better than the Computer Modern fonts of Knuth designed 40 years ago for print media (and it is documented that the printing machines did not really render the thinness of the glyphs, so nowadays, they definitely look too thin, even in PDF output produced entirely by LaTeX, although mathematicians and physicists for their most part continue using them without much questioning; the only real change came from the coming to the forefront of beamer presentation class which uses sans serif fonts per default, only reason why the afore mentioned LaTeX users became aware one could change math fonts in LaTeX).

The problem here is that we have to make it extra simple for Sphinx users not suspecting that the rendering of math by SVG actually involves LaTeX, whereas rendering by MathJaX does not... (which is contrary to many people expectations as they think that MathJaX is LaTeX). Handling "too many symbol fonts" error in pdflatex due to too many accumulating math packages is really a pain...

I think getting nice looking SVG is very worthwile goal for Sphinx, as depending on CDNs for the MathJaX can be a maintenance problem. (some old projects like lecture notes for a course should not need a rebuild with a newer Sphinx when things such as MathJaX change; thus once and for all done SVGs are perfect for static sites).

jfbu commented 5 years ago

I obtain very satisfactory result for math in sans serif using

imgmath_image_format = 'svg'
imgmath_latex_preamble = r'''
\usepackage[sfdefault,scaled=.85]{FiraSans}
\usepackage[T1]{fontenc}
\usepackage[cmintegrals]{newtxsf}
'''

and satisfactory result for serif with

imgmath_image_format = 'svg'

imgmath_latex_preamble = '\\usepackage{fouriernc}'

Some further exploration would be needed of (serif) math packages with latex, though.

But there is a problem with inline math: the math "baseline" does not match the text one. This is related to imgmath_use_preview not being implemented for SVG output yet. We will need a patch for that, first.

jfbu commented 5 years ago

But there is a problem with inline math: the math "baseline" does not match the text one. This is related to imgmath_use_preview not being implemented for SVG output yet. We will need a patch for that, first.

Fixed at #6310. In my testing I obtain very good results in output. Production of SVGs is slower than PNGs. But once #6281 is solved, we will have very good alternative to using MathJaX for math rendering in HTML.

certik commented 5 years ago

@jfbu thanks for fixing it!

Would you mind posting screenshots how the SVG looks with the surrounding text in your branch?

jfbu commented 5 years ago

@certik

With MathJaX:

Capture d’écran 2019-04-17 à 08 47 42

With #6310 and fouriernc (serif mathematics):

Capture d’écran 2019-04-17 à 08 48 19

With #6310 and newtxsf for sans serif math:

Capture d’écran 2019-04-17 à 08 47 58

In the above examples:

The Sphinx project uses agogo HTML theme.

jfbu commented 5 years ago

Forgot to say that the fouriernc example was with a project using the default dvisvgm --no-fonts so the glyph are rendered using path elements, and the newtxsf example had been done with dvisvgm --font-format=woff so there the svg uses really embedded fonts. I am using Firefox and paid attention to allow web pages to use their own fonts.

certik commented 5 years ago

@jfbu this is a huge improvement over my screenshot above, thank you!

I can see now that one should probably use sans serif for math if one uses the default sans serif Sphinx fonts. Or one should switch Sphinx fonts to serif, and then use serif math.

jfbu commented 5 years ago

@certik I am not sure there is something such as a default Sphinx font for the text in html (there is one for PDF output). The above screenshots use the agogo theme which contains in its CSS

body {
  font-family: "Verdana", Arial, sans-serif;
  line-height: 1.4em;
  color: black;
  background-color: #eeeeec;
}

And indeed Firefox Inspector tells me the Verdana font (which is available on my Mac OS) is used for text. In _static/basic.css I find a few font-family settings all saying simply font-family: sans-serif;. Thus this is theme dependent.

On the other hand the SVG files are produced by a tool chain which goes via a latex compilation, and it is the customization of this which decides the fonts used for mathematics. By default dvisvgm uses <font> elements but its FAQ says they are rendered by few browsers. By default Sphinx uses --no-fonts option which means dvisvgm will use <path> elements in the SVG. But its dvisvgm FAQ says --font-format=woff should give embedded fonts compatible with most modern browsers and perhaps we should switch to that although this will mean the user browser settings can override the fonts (as far as I understand situation).

Anyway the important thing is that so far, the latex step of SVG production did not customize fonts from the LaTeX default (Computer Modern) beyond using amsfonts. As indicated above the way I modified it is simply via imgmath_latex_preamble.

Additionally the #6310 adds the vertical-align styling to shift the SVG snippets to better position with respect to surrounding text. But even without it, one can already use imgmath_latex_preamble to achieve nice looking fonts for math (be it inline or displayed, but the inline math will often looks badly positioned).

The main problem now (#6281) is that it is very slow to execute again latex+dvisvgm for each math snippet; it is already slow for latex+dvipng which produces png, and if one wanted to use xelatex with unicode-math for an OpenType math font the build time would be too long for any project intensive in math.

The good thing is that dvisvgm is able to handle muti-page latex document which Sphinx could create to contain all math from a project, or at least all math from one (html) page, and produce in one go the multitude of needed small SVG files, the bad thing is that as far as I can tell so far this basically means a complete overhaul of the current core sphinx.ext.imgmath extension (one reason being we can not completely separate straightforwardly html building from SVG file production because we need to know which vertical-align styling to apply).

Side note: in my previous comment I referred to the size of math, I was not aware of imgmath_font_size which perhaps can help control this to some extent. Besides things like \mathrm{pgcd} use a text font, and in the newtxsf example it is scaled down from \usepackage[sfdefault,scaled=.85]{FiraSans}.

It is a bit annoying here that to provide support for HTML+SVG to Sphinx users we have to handle some pure LaTeX font problems, as, regrettably, we can not simply assume the users have the latest full TeXLive or MikTeX installs, being well-known the linux distros are often years behind and with only partial support. For example preview.sty is a very old LaTeX package which we absolutely need to help dvipng or dvisvgm get the depth of the math snippets, but it is not installed by default together with core LaTeX on say Ubuntu xenial. As a result we currently don't use it per default.

But I am of the opinion that we should add it as requirement for the Math as SVG support.