Skip to content
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

Make imgmath_use_preview work also for svg output #6310

Merged
merged 3 commits into from
Apr 25, 2019

Conversation

jfbu
Copy link
Contributor

@jfbu jfbu commented Apr 16, 2019

Currently, inline mathematics in svg format is not well aligned with surrounding text.

This PR improves the situation.

Relates: #5301

@jfbu jfbu added the type:enhancement enhance or introduce a new feature label Apr 16, 2019
@jfbu jfbu added this to the 2.1.0 milestone Apr 16, 2019
Copy link
Contributor Author

@jfbu jfbu left a comment

Choose a reason for hiding this comment

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

This gives somewhat satisfactory result in my testing of inline math with depth (for example anything using (, ) or letters p, q,...). But it is frustrating to lose the precision of the dvisvgm depth indication.

Consider this a bit of WIP. Suggestions welcome on how to improve this.

@@ -76,7 +76,7 @@ class InvokeError(SphinxError):
'''

DOC_BODY_PREVIEW = r'''
\usepackage[active]{preview}
\usepackage[active,tightpage]{preview}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is needed for dvisvgm to gather "depth" information. I hope it does not affect dvipng usage (with its -Ttight option).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In fact adding this option did change the dvipng console output and thus broke imgmath for it because the regex did not find matches anymore. Fixed in second commit.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We probably don't need to use -T tight option of dvipng anymore.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The tightpage option does not play well with dvipng. In my latest commit I am thus using it only for dvisvgm. As per my previous comment, the -T tight option of dvipng remains required.

@@ -85,7 +85,7 @@ class InvokeError(SphinxError):
'''

depth_re = re.compile(br'\[\d+ depth=(-?\d+)\]')

depthsvg_re = re.compile(br'.*, depth=(.*)pt')
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here is some example output from dvisvgm when the dvi was produced with tightpage option of preview.

$ dvisvgm --no-fonts testsvg
pre-processing DVI file (format version 2)
processing page 1
  computing extents based on data set by preview package (version 11.91)
  width=103.354867pt, height=9.225002pt, depth=3.075001pt
  graphic size: 103.354867pt x 12.300003pt (36.325081mm x 4.322957mm)
  output written to testsvg.svg
1 of 1 page converted in 0.253939 seconds

Perhaps the regex can be made better?

for line in stderr.splitlines(): # not stdout !
matched = depthsvg_re.match(line)
if matched:
depth = round(float(matched.group(1)) * 100 / 72.27) # assume 100ppi
Copy link
Contributor Author

Choose a reason for hiding this comment

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

as shown above the depth may have fractional digit. The unit is the TeX point (72.27pt=1in). We could convert it to HTML "pt" unit (72pt=1in) but due to shared code with "png" format, we have to return an integral number of pixels. Thus I round it to an integer here and assume 100ppi.

Clearly any advice welcome on how to better handle this. Probably I have to change more of imgmath to handle a non integer depth. Should we pass it over to html output using pt unit or if we use px how to best convert? The dvipng returns an integral number of px but I don't know how it does the conversion internally from TeX dimensions to px unit.

Copy link
Member

Choose a reason for hiding this comment

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

+1: enough to me.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think in future more separate handling of dvipng and dvisvgm could be considered. Because here I coerce to an int mainly due to shared code between the two.

Also, dvisvgm can generate its own hashing for naming svg files.


depth = None
if builder.config.imgmath_use_preview:
for line in stderr.splitlines(): # not stdout !
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The dvisvgm output (as shown above) goes to stderr... whereas the dvipng used stdout...

@codecov
Copy link

codecov bot commented Apr 16, 2019

Codecov Report

Merging #6310 into master will decrease coverage by 0.04%.
The diff coverage is 20.68%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #6310      +/-   ##
==========================================
- Coverage   84.18%   84.14%   -0.05%     
==========================================
  Files         274      274              
  Lines       39289    39313      +24     
  Branches     5831     5838       +7     
==========================================
+ Hits        33074    33078       +4     
- Misses       4900     4920      +20     
  Partials     1315     1315
Impacted Files Coverage Δ
sphinx/ext/imgmath.py 48.21% <20.68%> (-3.79%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 2757458...48ad83d. Read the comment docs.

@jfbu
Copy link
Contributor Author

jfbu commented Apr 16, 2019

I think the usage of preview package to get the needed depth info should not be optional (whether for PNG or SVG). The preview package is old package, we can assume it to be available in Sphinx user LaTeX installation (I will check on Ubuntu xenial). And inline math without this depth correction basically looks very bad (be it with PNG or SVG).

@jfbu jfbu force-pushed the imgmath_correct_svg_baselines branch from 878d3eb to 28ee88e Compare April 16, 2019 15:09
Copy link
Contributor Author

@jfbu jfbu left a comment

Choose a reason for hiding this comment

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

I forgot to comment on lines 238-240. For png it seems Sphinx hardcodes the depth inside the png file (for reuse). Probably this must be extended to SVG case. As I did not see immediately how to handle this (and wondering if the whole thing might become obsolete once we let dvipng or dvisvgm handle many equations at once instead of one per one) I put together this PR in this WIP state, sorry.

@jfbu
Copy link
Contributor Author

jfbu commented Apr 16, 2019

On xenial I got this:


/usr/share/texmf/tex/latex/preview/preview.sty | preview-latex-style
-- | --
/usr/share/xemacs21/xemacs-packages/etc/auctex/latex/preview.sty | xemacs21-basesupport

I propose we add preview-latex-style as dependency at some later Sphinx release so that imgmath_use_preview defaults to True. Display mathematics does not need it but inline math snippets is basically broken without it for PNG and SVG.

@jfbu
Copy link
Contributor Author

jfbu commented Apr 16, 2019

Unfortunately the tightpage option of preview package breaks PNG rendering of display math: equations get shifted to the right. This might be caused by whitespace in LaTeX source which we did not see because of dvipng -Ttight but under the tightpage option of preview package, dvipng acts differently.

@jfbu
Copy link
Contributor Author

jfbu commented Apr 16, 2019

I will update this PR. The dvipng and dvisvgm must be separated more one reason being that there is bad interaction of tightpage option of preview package with dvipng in case of display math: the display gets shifted to the right whether or not we use the -Ttight option of dvipng. Thus, we must separate more the code branches for PNG and SVG cases.

edit I have done that now.

@jfbu
Copy link
Contributor Author

jfbu commented Apr 16, 2019

I forgot to comment on lines 238-240. For png it seems Sphinx hardcodes the depth inside the png file (for reuse). Probably this must be extended to SVG case.

Done now.

@jfbu jfbu force-pushed the imgmath_correct_svg_baselines branch from 2d2101b to 3edcff7 Compare April 23, 2019 13:29
@jfbu
Copy link
Contributor Author

jfbu commented Apr 23, 2019

Squashed and rebased on master tip after merge of #6308

Copy link
Member

@tk0miya tk0miya left a comment

Choose a reason for hiding this comment

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

Sorry for late. LGTM with nits.

with open(filename, 'r') as f:
for line in f:
pass
return int(line[11:-4])
Copy link
Member

Choose a reason for hiding this comment

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

I feel this is a bit fragile. Could you replace this by regexp?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think you mean to use a regex for the parsing of very last line (cf write_svg_depth()), and we can pass over silently other lines?

for line in stderr.splitlines(): # not stdout !
matched = depthsvg_re.match(line)
if matched:
depth = round(float(matched.group(1)) * 100 / 72.27) # assume 100ppi
Copy link
Member

Choose a reason for hiding this comment

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

+1: enough to me.

@@ -105,8 +105,9 @@ built:
Unfortunately, this only works when the `preview-latex package`_ is
installed. Therefore, the default for this option is ``False``.

Currently this option is only used when ``imgmath_image_format`` is
``'png'``.
.. versionchanged:: 2.1.0
Copy link
Member

Choose a reason for hiding this comment

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

I've written versionchnaged:: 2.1 (not 2.1.0) in another PR. I don't know what is best.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I will use 2.1 too. I still need to adjust a bit to our new branch/release model.

Copy link
Contributor Author

@jfbu jfbu left a comment

Choose a reason for hiding this comment

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

I will update, thanks for reviewing.

@@ -105,8 +105,9 @@ built:
Unfortunately, this only works when the `preview-latex package`_ is
installed. Therefore, the default for this option is ``False``.

Currently this option is only used when ``imgmath_image_format`` is
``'png'``.
.. versionchanged:: 2.1.0
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I will use 2.1 too. I still need to adjust a bit to our new branch/release model.

with open(filename, 'r') as f:
for line in f:
pass
return int(line[11:-4])
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think you mean to use a regex for the parsing of very last line (cf write_svg_depth()), and we can pass over silently other lines?

for line in stderr.splitlines(): # not stdout !
matched = depthsvg_re.match(line)
if matched:
depth = round(float(matched.group(1)) * 100 / 72.27) # assume 100ppi
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think in future more separate handling of dvipng and dvisvgm could be considered. Because here I coerce to an int mainly due to shared code between the two.

Also, dvisvgm can generate its own hashing for naming svg files.

@jfbu jfbu force-pushed the imgmath_correct_svg_baselines branch from 5ac9715 to ea28bd9 Compare April 24, 2019 09:56
Copy link
Member

@tk0miya tk0miya left a comment

Choose a reason for hiding this comment

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

Great work! LGTM :-)

@jfbu
Copy link
Contributor Author

jfbu commented Apr 25, 2019

Thanks for reviewing :-) merging...

@jfbu jfbu merged commit dd9598f into sphinx-doc:master Apr 25, 2019
@jfbu jfbu deleted the imgmath_correct_svg_baselines branch April 25, 2019 21:31
jfbu added a commit that referenced this pull request Apr 25, 2019
jfbu added a commit that referenced this pull request Jul 30, 2019
@jfbu jfbu restored the imgmath_correct_svg_baselines branch August 1, 2019 15:26
jfbu added a commit that referenced this pull request Aug 1, 2019
jfbu added a commit that referenced this pull request Aug 1, 2019
jfbu added a commit that referenced this pull request Aug 1, 2019
jfbu added a commit that referenced this pull request Aug 1, 2019
@jfbu jfbu deleted the imgmath_correct_svg_baselines branch August 1, 2019 16:18
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 10, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
type:enhancement enhance or introduce a new feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants