Open certik opened 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.
@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.
I think it uses STIX. Apparently you can change it https://docs.mathjax.org/en/latest/font-support.html
Is there anything to do from Sphinx side? If nothing, I'd like to close this issue.
@tk0miya what Sphinx should do is to make the SVG equations by default look like the MathJax ones.
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.
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
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
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:
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).
@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.
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.
@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).
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.
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.
@jfbu thanks for fixing it!
Would you mind posting screenshots how the SVG looks with the surrounding text in your branch?
@certik
With MathJaX:
With #6310 and fouriernc (serif mathematics):
With #6310 and newtxsf for sans serif math:
In the above examples:
without #6310 all math snippets using parentheses would be shifted upwards compared to baseline,
the pgcd
uses \mathrm{pgcd}
and maybe one would need to check more closely which fonts are used depending on the used latex preambles. (and try to control better their sizes).
the svg math snippets look a bit smaller than the MathJaX ones. From a typographical point of view they are better fitted to baseline separation, but still they look a bit small particularly for letters such as x
and y
. They are produced with 12pt option but I did not look in detail the exact intermediate TeX files. (it is possible the LaTeX preamble are lacking a \DeclareMathSizes
I did not concentrate on the pure LaTeX aspects; it is very time costly to test fonts...)
The Sphinx project uses agogo HTML theme.
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.
@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.
@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.
The default SVG output looks like this:
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:
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: