LaTeX Equations and Graphics in PHP
Listing 1. render_example.php
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html>
<head>
<title>LaTeX Equations and Graphics in PHP</title>
</head>
<body>
<!-- form to enter LaTeX code -->
<form action="render_example.php" method="post">
<textarea rows="20"
cols="60"
name="render_text"></textarea><br />
<input name="submit"
type="submit"
value="Render" />
</form>
<?php
if (isset($_POST['submit'])) {
echo '<h1>Result</h1>';
require('render.class.php');
$text = $_POST['render_text'];
if (get_magic_quotes_gpc())
$text = stripslashes($text);
$render = new render();
echo $render->transform($text);
}
?>
</body>
</html>
This PHP page provides a form for entering LaTeX code and then replaces the thunks with URLs to rendered PNG images through the transform method. Everything else is done behind the scenes in the render class.
Listing 2. render.php
class render {
var $LATEX_PATH = "/usr/local/bin/latex";
var $DVIPS_PATH = "/usr/local/bin/dvips";
var $CONVERT_PATH = "/usr/local/bin/convert";
var $TMP_DIR =
"/usr/home/barik/public_html/gehennom/lj/tmp";
var $CACHE_DIR =
"/usr/home/barik/public_html/gehennom/lj/cache";
var $URL_PATH = "http://www.barik.net/lj/cache";
function wrap($text) { ... }
function transform($text) { ... }
function render_latex($text) { ... }
}
You need to let PHP know where your tools are located and provide a directory where PHP can write temporary files and store its cache. For convenience, a URL_PATH also is needed. This URL_PATH is used when generating the image tags in HTML.
Don't be fooled by the simplicity. A vast array of options is available that you can pass to LaTeX and ImageMagick to modify the output PNG image, and you should explore them all. Here, I've merely provided the framework.
The wrap method takes your LaTeX thunk and surrounds it with a prologue and epilogue to create a valid LaTeX source file. You can consider this to be the equivalent of adding additional includes to a C file or importing packages in Java to extend the functionality of the language (Listing 3).
Listing 3. wrap.php7870l3.qrk
function wrap($thunk) {
return <<<EOS
\documentclass[10pt]{article}
% add additional packages here
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{pst-plot}
\usepackage{color}
\pagestyle{empty}
\begin{document}
$thunk
\end{document}
EOS;
}
As you can see, I include the packages I routinely need in the LaTeX wrapper. Consequently, I've included the American Mathematical Society (AMS) package, which provides additional mathematical constructs, as well as the PSTricks package to render vector graphics. The pagestyle is set to empty so that page numbers do not appear on images. Also, the thunk is inserted between the document blocks.
Not all of these packages may be available on your system. If necessary, you can download additional packages from the Comprehensive TeX Archive Network (CTAN) Web site (see the on-line Resources) to extend the functionality of your base LaTeX system. For example, packages for bar charts, UML notation and even Karnaugh maps can be downloaded. Whatever your needs, the repository is worth a look.
The render_latex method (Listing 4) extracts all thunks and processes them individually until the thunk pool is exhausted.
Listing 4. render_latex.php
function render_latex($thunk, $hash) {
$thunk = $this->wrap($thunk);
$current_dir = getcwd();
chdir($this->TMP_DIR);
// create temporary LaTeX file
$fp = fopen($this->TMP_DIR . "/$hash.tex", "w+");
fputs($fp, $thunk);
fclose($fp);
// run LaTeX to create temporary DVI file
$command = $this->LATEX_PATH .
" --interaction=nonstopmode " .
$hash . ".tex";
exec($command);
// run dvips to create temporary PS file
$command = $this->DVIPS_PATH .
" -E $hash" .
".dvi -o " . "$hash.ps";
exec($command);
// run PS file through ImageMagick to
// create PNG file
$command = $this->CONVERT_PATH .
" -density 120 $hash.ps $hash.png";
exec($command);
// copy the file to the cache directory
copy("$hash.png", $this->CACHE_DIR .
"/$hash.png");
chdir($current_dir);
}
The thunk parameter is obvious: it's the block of LaTeX code we're currently examining. The hash parameter is a unified version of the thunk, essentially, an md5 of the filename base.
I change to the temporary directory and write the thunk to a temporary LaTeX file. LaTeX then creates a DVI file. The command-line parameter tells LaTeX to run non-interactively. The resulting DVI file is converted to PostScript with the use of dvips, and the -E option specifies a bounding box. I then run the resulting PostScript file through convert—that's the program name—to convert the file to a PNG image. The convert tool has a slew of options, and the settings that will work best for you depend on your site.
Finally, be aware that the exec command returns a failure status code. For brevity, I've left out the error checking and always assume that all steps succeed. LaTeX also has a few dangerous commands that could be an issue for multiuser Web sites. It therefore might be prudent to return an error if certain keywords are found in the thunk.
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Sponsored by AMD
If you already use virtualized infrastructure, you are well on your way to leveraging the power of the cloud. Virtualization offers the promise of limitless resources, but how do you manage that scalability when your DevOps team doesn’t scale? In today’s hypercompetitive markets, fast results can make a difference between leading the pack vs. obsolescence. Organizations need more benefits from cloud computing than just raw resources. They need agility, flexibility, convenience, ROI, and control.
Stackato private Platform-as-a-Service technology from ActiveState extends your private cloud infrastructure by creating a private PaaS to provide on-demand availability, flexibility, control, and ultimately, faster time-to-market for your enterprise.
Sponsored by ActiveState
| Speed Up Your Web Site with Varnish | Jun 19, 2013 |
| Non-Linux FOSS: libnotify, OS X Style | Jun 18, 2013 |
| Containers—Not Virtual Machines—Are the Future Cloud | Jun 17, 2013 |
| Lock-Free Multi-Producer Multi-Consumer Queue on Ring Buffer | Jun 12, 2013 |
| Weechat, Irssi's Little Brother | Jun 11, 2013 |
| One Tail Just Isn't Enough | Jun 07, 2013 |
- Speed Up Your Web Site with Varnish
- Containers—Not Virtual Machines—Are the Future Cloud
- Linux Systems Administrator
- Lock-Free Multi-Producer Multi-Consumer Queue on Ring Buffer
- RSS Feeds
- Senior Perl Developer
- Technical Support Rep
- Non-Linux FOSS: libnotify, OS X Style
- UX Designer
- Web & UI Developer (JavaScript & j Query)
- So when they found it hard to
1 min 51 sec ago - yea
24 min 2 sec ago - Reply to comment | Linux Journal
46 min 21 sec ago - Android has been dominating
50 min 53 sec ago - It is quiet helping
3 hours 36 min ago - Technology
3 hours 53 min ago - Reachli - Amplifying your
5 hours 10 min ago - excellent
5 hours 58 min ago - good point!
6 hours 1 min ago - Varnish works!
6 hours 10 min ago
Featured Jobs
| Linux Systems Administrator | Houston and Austin, Texas | Host Gator |
| Senior Perl Developer | Austin, Texas | Host Gator |
| Technical Support Rep | Houston and Austin, Texas | Host Gator |
| UX Designer | Austin, Texas | Host Gator |
| Web & UI Developer (JavaScript & j Query) | Austin, Texas | Host Gator |
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?




Comments
Another aproach to LaTeX equations with PHP
Some time ago I had faced the same problem, but I didn't use the same rendering steps. Instead of rendering to PS and then converting to PNG, I had used dvipng to convert the DVI directly to PNG.
The code is at my personal blog.
Hope it also helps somebody.
Regards,
Filipi Vianna
A bit of trouble
I have been looking for something like this off and on for months but I am a programming newb with most experience in python; this article has me crash-coursing php.
I think I am having problems naming the .php files, placing them in the right place and/or setting the correct permissions. I know exactly where convert, latex and dvips are, that is not the problem. I have put everything in the document root in separate files, each listing.
wrap.php7870l3.qrk I have just named wrap.php, I can't find any logic for the '7870l3.qrk' part.
If I name the second listing/file 'render.php' I get the follwing error:
Warning: require(render.class.php) [function.require]: failed to open stream: No such file or directory in /var/www/render_example.php on line 26
Fatal error: require() [function.require]: Failed opening required 'render.class.php' (include_path='.:/usr/share/php:/usr/share/pear') in /var/www/render_example.php on line 26
If I name the second listing 'render.class.php' I get a different error:
class render { var $LATEX_PATH = "/usr/bin/latex"; var $DVIPS_PATH = "/usr/bin/dvips"; var $CONVERT_PATH = "/usr/bin/convert"; var $TMP_DIR = "/usr/home/biouser/texwebtmp"; var $CACHE_DIR = "/usr/home/biouser/texwebtmp/cache"; var $URL_PATH = "http://127.0.1.1/lj/cache"; function wrap($text) { ... } function transform($text) { ... } function render_latex($text) { ... } }
Fatal error: Class 'render' not found in /var/www/render_example.php on line 33
Something is going on here... I would b so excited and grateful if i could get this to work!!!
uninformed question
This looks exactly like what I need. I am trying to set up a simple wiki to collaborate with co-writers, and am trying to find how to embed latex capabilities. I am a rookie in programming though, and cannot figure out some things. Specifically, "You need to let PHP know where your tools are located and provide a directory where PHP can write temporary files and store its cache."==> What tools? I see I need latex and dvips etc., but what exactly are these as tools? I use latex, but don't know exactly what I need to upload to the server.
Thanks!
matt
Awesome!
Hi!
I'm starting to implement this into a math worksheet website I'm (slowly) building. It's superior to html formatting because it doesn't vary from browser to browser. I had to alter it a bit because I'm making worksheets for print and the images weren't printing well. I changed the density to 300. Then, I get the image height using "identity" and reduce it by 40% using the height attribute in the image tag.
The images on screen are a bit choppy but the prints look great. My students are sure to appreciate it!
Would you like me to post a link or give you other credit?
Thanks a bunch!
Dynamic Base URL
It may be a good idea to add a function to get the base URL instead of hard writing it on the source code.
it may be something like:
$base_url = 'http' . (isset($_SERVER['HTTPS']) ? $_SERVER['HTTPS'] == 'on' ? 's' : '' : '');
$base_url .= '://' .$_SERVER['HTTP_HOST'];
if ($dir = trim(dirname($_SERVER['SCRIPT_NAME']), '\,/')) {
$base_url .= "/$dir";
}
$URL_PATH= $base_url . "/cache"
Carlos
Web CAS, another LaTeX+PHP on Apache
Although I has not read the interesting article, a project of SourceForge, WMI (Web Mathematic Interactive, http://wmi.sf.net), may be the subject that readers are interested. WMI integrates almost the powerful CAS in Linux world, e.g. Maxima, Octave, Gnuplot and Maple etc. within LAMP envirnment. Don't forget to visit the official site.
Curious
How did you know that the article was interesting if you hadn't read it? I did read it and it was great help!