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

use preview.sty for mathimages #1863

Open
wants to merge 15 commits into
base: master
Choose a base branch
from

Conversation

xworld21
Copy link
Contributor

@xworld21 xworld21 commented May 22, 2022

Early attempt at using preview.sty to generate properly sized and aligned SVGs via dvisvgm. The advantage is that preview.sty embeds bounding box and depth information in the DVI output, which then is parsed by dvisvgm and dvipng, producing more accurate results. It seems to fix #1841, #1842.

Edit: the PR now does much more. It uses preview.sty to direct dvipng, dvisvgm, and ghostscript to crop each image to the correct bounding box (including padding). This means that (1) framing & cropping can be avoided, and (2) when using dvips, ghostscript can emit PNGs directly, making the process roughly as fast as dvipng. Moreover it does fix #1841 and #1842. The price to pay is that hyperref must be excluded because it seems to break preview.sty.

@xworld21
Copy link
Contributor Author

Making progress: I have implemented pixel-perfect sizing and alignment when using dvipng!

The same for dvisvgm is just as easy, but it requires either (1) a schema change to allow fractional dimensions, for use in the @style attribute, or (2) modifying the SVG bounding box to have integer pixel size and baseline aligned to a pixel.

@xworld21 xworld21 marked this pull request as ready for review August 14, 2022 18:29
@xworld21 xworld21 force-pushed the mathimages-preview-sty branch 2 times, most recently from cbd4b8f to 09805db Compare August 20, 2022 12:15
@brucemiller
Copy link
Owner

Seeing that you're still working on this... I hate to be discouraging of interesting explorations and useful patches, but also hate to see you wasting time on what may be a deadend.

It's getting complicated and probably not so much in a direction I'm likely to want to go. I'd prefer working on a direct XMath to SVG conversion where we can directly produce the SVG we want rather than having to trick dvisvgm, and we'd still have a reasonable chance of adding accessibility information. And also having mixed feelings about investing too much in math to svg when MathML is finally getting a shot at the big time.

@xworld21
Copy link
Contributor Author

rather than having to trick dvisvgm

This was more meant as a general fix for the current LaTeXImages pipeline, as there is a lot of work (framing, padding, "clippingfudge" etc.) which can be avoided by using the native preview.sty support in dvipng and dvisvgm, as it guarantees that the output will be cropped and sized correctly. I'd argue that my code is simpler than the previous one, in fact. I could push it further to fix the dvips pipeline as well, and get rid of the framing code completely.

mixed feelings about investing too much in math to svg when MathML is finally getting a shot at the big time

I wouldn't use it for browsers thanks to MathJax and the new MathML support coming, rather I am trying to produce good EPUBs, for which MathML support is abysmal. Ideally, I'd like to create EPUBs with --pmml --mathsvg --mathimages, possibly with some interactive element to switch between the three, but right now the output images are quite poor.

PS: the PR is basically done, it needs some testing to make sure that all code paths behave correctly (there were some embarrassing typos yesterday).

@brucemiller
Copy link
Owner

If you're close, then I might as well let you finish and test things out. Maybe I'll like it after all :>

@xworld21
Copy link
Contributor Author

If you're close, then I might as well let you finish and test things out. Maybe I'll like it after all :>

Thanks! Let's see if I can make it convincing. I'll remove the WIP tag once I am satisfied with my own tests (in a few days), and I'll add a few comments to clarify what preview.sty is doing.

I might slip in an extra commit for dvips, but I suspect it will remain as fragile as the current code, for reasons I'll explain in the comments (but the code itself should become simpler).

@xworld21 xworld21 force-pushed the mathimages-preview-sty branch 3 times, most recently from 44185f9 to 26063a0 Compare August 22, 2022 19:41
@xworld21
Copy link
Contributor Author

It turns out that preview.sty breaks the original dvips conversion because ImageMagick does not understand the bounding box correctly.

So I went all in: I replaced dvips -E with dvips && gs -sDEVICE=pngalpha (sort of) and got rid of the clipping code entirely, which makes everything a lot simpler. Among other things, this is supposed to make the dvips pipeline just as fast as dvipng, without the shortcomings of dvipng.

Still WIP because this was more work than I expected. I need to do more tests and cleanups.

@xworld21 xworld21 force-pushed the mathimages-preview-sty branch 2 times, most recently from ee533f9 to 04e8b0f Compare August 23, 2022 19:06
@xworld21 xworld21 changed the title [WIP] use preview.sty for mathimages use preview.sty for mathimages Aug 23, 2022
@xworld21 xworld21 force-pushed the mathimages-preview-sty branch 2 times, most recently from 743c44c to 67c1e54 Compare August 24, 2022 12:14
@xworld21
Copy link
Contributor Author

@brucemiller the PR is now complete. I am afraid this is much more substantial than my original idea, but I also fixed a few other bugs along the way (e.g. hyperref breaking LaTeXImages, fragile exclusion of packages, error reporting, performance). It behaves properly whether you are using dvisvgm, dvipng, or dvips, and dvips+gs is now roughly as fast as dvipng.

I like to think this is quite robust now.

$$self{background} = $options{background} || "#FFFFFF";
$$self{imagetype} = $options{imagetype} || 'png';

# Parameters for separating the clipping box from the
# desired padding between image edge and "ink"
$$self{padding} = $options{padding} || 2; # pixels
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 may as well do

Suggested change
$$self{padding} = $options{padding} || 2; # pixels
$$self{padding} = $options{padding} || 0; # pixels

since there is no risk of interference with framing. Or maybe one pixel to ensure antialiasing is preserved. Two pixels starts to be visible with inline formulas.

return; }
else {
# find ghostscript executable
my @gscmd = grep { which $_ } ($^O eq 'MSWin32' ? ('gswin64c', 'gswin64', 'gswin32c', 'gswin32', 'mgs') : ('gs'));
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Does anybody know what we should do with cygwin?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

SVG images are not sized properly (--mathsvg + dvisvgm)
2 participants