[Tex/LaTex] eqnarray math to svg

equationslatex2htmlsvg

I want to write a perl processor that filters equations out of html images and creates svg replacements for it so that my equations show up nicely in epub and in major browsers. (I understand that text browsers and email clients will be spott.)

think

<html>
<body>
   <h1>Visible</h1>
   <p>I can see this and change its size in my browser and in epub.
   <pre class="math">
      y &=& \frac{\sqrt{x}}{z} \\
         &&+\frac{\sqrt{z}}{\mathtt{myvar}} \nonumber
   </pre>
</body>
</html>

it's easy for me to parse out the pre contents. I can then stick them into a latex file.

\documentclass[12pt]{article}

\RequirePackage{charter} 
\RequirePackage[mdbch,ttscaled=true]{mathdesign} 
\usepackage{microtype}
\usepackage[english]{babel}

\begin{document}
\begin{eqnarray}
    y &=& \frac{\sqrt{x}}{z} \\
       && + \frac{\sqrt{z}}{\mathtt{myvar}}
\end{eqnarray}

\end{document}

presumably, I then run

 pdflatex -output dvi file.tex ; dvisvgm file.dvi .

the reason I use dvisvgm is that texlive does not include a pdfsvgm and pdf2svg scares me because it refers to poppler and cairo (and I want my equations to remain fully rendered/scaleable). but, I do need my resulting document that is run through

1. how do I ask latex to create a page that is just the bounding box of the equation?

2. are there any recommended other arguments that I should hand to dvisvgm for my purpose? (e.g., exact?).

thereafter, I want to encode this back into my html source. presumably, now I would want to do something like

<html>
<body>
   <h1>Visible</h1>
   <p>I can see this and change its size in my browser and in epub.
   <svg>
      ... (whatever I see in file.svg)
   </svg>
</body>
</html>

3. Is this the right approach to the problem? or am I making a mistake here?

help appreciated.

regards,

/iaw

PS: if anyone reads this, the links at http://www.latex2html.org/node2.html seem to be broken. the dates here are from 2001.

Best Answer

eqnarray does not seem to be easily possible, but normal equations may be and the array environment makes it possible to include multi-line equations. here is an example. start with

\documentclass[border={5pt 5pt 5pt 5pt}]{standalone}
  % left bottom right top .  warning: does not understand ex or em

\RequirePackage[T1]{fontenc}
\RequirePackage{textcomp}
\RequirePackage{charter}
\RequirePackage[mdbch,ttscaled=true]{mathdesign}
\usepackage{microtype}

\usepackage[english]{babel}

\pagestyle{empty}

\begin{document}

  \LARGE

  $ \begin{array}{cccc}
     y &=& \frac{\sqrt{x}}{z}\\
       && + \frac{\sqrt{z}}{x} \end{array} $

\end{document}

then

$ latex test.tex
$ dvisvgm -n test.dvi

will create an svg file. without the -n, the quality is lousy. with it, it is pretty good. (thx, martin). the array is a math-mode eqnarray substitute that is quite workable--and can align more than just two.

the example does not have the equation line numbering. presumably, one could easily do this with a float:right on a numbering.

this example produces an svg file of about 4KB. even with 100 equations, we are still looking at an html file that is an order of magnitude smaller than one with mathjax included. it should also work in epub, although I have not tested it yet. mathjax is advantageous if it has already been loaded and cached by the browser.

I am enclosing a basic perl hack that translates an html file with dependency on mathjax into one without it. it has baseline problems and probably a couple of other bugs. but it is a starting point.

#!/usr/bin/perl -w
use 5.010;
use strict;
use warnings FATAL => qw{ uninitialized };

=pod

=head1 Title

  htmltexmath2svg.pl --- replaces mathjax-style eqns in html files with inline svg images
    (to remove dependency on mathjax)

=head1 Requirements

  texlive or equivalent (with latex and dvisvgm)

  Perl6::slurp

  Unix type OS (OSX or linux)


=head1 Output

  the output will be a file with -svg before the file extension,
  where all mathjax equations have been replaced with svg.

  you should define a span class of mathsvg and mathsvgblock for \(..\) and \[..\]

  the basic creation file is attached in the __DATA__ section and can be fixed up.


=head1 Bugs

  this program still has baseline alignment problems.

  this is a hack.  probably many bugs.  as I use this program, I will
  probably update and fix various issues.  It has worked on some simple
  sample files.  parsing could be more intelligent.

  we overwrite temp.* files every time, and do not clean up after ourselves.

  the program is slow, but one should run it only rarely anyway.

=head1 Versions

  0.0: Sat Jan 18 15:32:02 2014, Ivo Welch.  no copyright claim.  free further distribution.

=cut

################################################################

use Perl6::Slurp;  ## only dependency

################################################################

my $usage= "usage: $0 filename.*ml ... creates filename-svg.*ml";

(@ARGV) or die "$usage\n";
(-e $ARGV[0]) or die "$0: file $_[0] does not exist\n";
($ARGV[0] =~ /ml$/) or die "$0: file $_[0] must end with file extension *ml\n";
($ARGV[0] =~ /-svg\.$/) and die "$0: file $_[0] seems to already contain -svg.\n";
(my $ofname= $ARGV[0]) =~ s/(.*)\.(.*)/$1-svg.$2/;
(defined($ofname)) or die "$0: cannot parse output file anem!\n";

my $textemplate= slurp \*DATA;

my $file_contents = slurp $ARGV[0];

($file_contents =~ /mathjax\.org/) and warn "\n\n$0: your file still contains the string mathjax.org, which should no longer be necessary. consider deleting it.\n\n";

$file_contents =~ s/\<span class=\"math\"(\>.*?)<\/span\>/runme($1)/gmse;  ## good enough parsing

open my $FOUT, ">", $ofname or die "cannot open '$ofname' for write: $!\n";
print $FOUT $file_contents;
close $FOUT;

print "$0: successfully converted $ARGV[0] to $ofname\n";


################################################################
sub runme {
  (my $convert=$_[0]) =~ s/^\>//;  ## we are going to extend the tag with an alt, so we needed to remove it

  $convert=~ s/\&amp;/\&/g;  $convert=~ s/\&lt;/\</g; $convert=~ s/\&gt;/\>/g;  ## undo previous html mangling.  coult be more unmangling;
  $convert =~ s/^\s+//gms; $convert =~ s/\s+$//gms;  ## remove leading and trailing spaces

  print STDERR "[convert '$convert' ";

  my $classname;
  if ($convert =~ s/^\\\(//) {
    $convert =~ s/\\\)$//;
    $classname="mathsvg";
  } elsif ($convert =~ s/^\\\[//) {
    $convert =~ s/\\\]$//;
    $classname="mathsvgblock";
  } else {
    die "$0: I do not understand equation type in '$convert'\n";
  }

  open(my $FOUT, ">", "temp.tex") or die "$0: I cannot open temp.tex for writing: $!\n";

  my $texfile= $textemplate;
  $texfile=~ s/\*\*\*\*MATHJAXHERE\*\*\*\*/$convert/;
  print $FOUT $texfile;
  close($FOUT);

  system("rm -f temp.dvi temp.svg ; latex -halt-on-error temp.tex &> /dev/null ; dvisvgm -n temp.dvi &> /dev/null");

  my $svgcontents= (-e "temp.svg") ? slurp "temp.svg" : "svg conversion failed";
  $svgcontents =~ s/<!DOCTYPE .*?\>//;  ## we are inlining this one, so no doctype
  ($svgcontents =~ /<\/svg>/) or $svgcontents="svg conversion failed (incomplete)";

  print STDERR (($svgcontents =~ /svg conversion failed/) ? "failed" : "ok")."\n";

  return "<span class=\"$classname\" alt=\"$convert\">$svgcontents\<\/span>";
}



__DATA__

\documentclass[border={1pt 1pt 1pt 1pt}]{standalone}
%%%% left bottom right top .  standalone does not understand ex or em!

\RequirePackage[T1]{fontenc}
\RequirePackage{textcomp}
\RequirePackage{charter} 
\RequirePackage[mdbch,ttscaled=true]{mathdesign} 
\usepackage{microtype}

\usepackage[english]{babel}

\pagestyle{empty}

\begin{document}

$****MATHJAXHERE****$

\end{document}
);
Related Question