function texify($string, $dpi = '90', $r = 0.0, $g = 0.0, $b = 0.0, $br = 1.0, $bg = 1.0, $bb = 1.0, $extraprelude = "", $sharpen = FALSE) { global $imgfmt; if ($dpi > 300) { $dpi = 300; } $back = phplatex_colorhex($br, $bg, $bb); $fore = phplatex_colorhex($r, $g, $b); # Figure out TeX, either to get the right cache entry or to, you know, compile # Semi-common (ams) symbol packages are included. $totex = "\\documentclass[14pt,landscape]{extarticle}\n" . "\\usepackage{color}\n" . "\\usepackage{amsmath}\n\\usepackage{amsfonts}\n\\usepackage{amssymb}\n" . $extraprelude . "\n" . "\\pagestyle{empty}\n" . "\\begin{document}\n" . "\\color[rgb]{" . $r . "," . $g . "," . $b . "}\n" . "\\pagecolor[rgb]{" . $br . "," . $bg . "," . $bb . "}\n" . $string . "\n" . "\\end{document}\n"; $strhash = sha1($totex) . '.' . $dpi; #file cache entry string: 40-char hash string plus size $stralt = str_replace("&", "&", preg_replace("/[\"\n]/", "", $string)); #stuck in the alt and title attributes #May need some extra safety. $heredir = dirname(__FILE__); #Experiment: Tries to guess vertical positioning fix that will look short rendered works look natural inside HTML text. #Only descenders are really a problem since HTML's leeway is upwards. #TODO: avoid using letters that are part of TeX commands. # the slash varies per font. In the default CM it is, in Times and others it isn't. $ascenders = "/(b|d|f|h|i|j|k|l|t|A|B|C|D|E|F|G|H|I|J|L|K|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|\\[|\\]|\\{|\\}|\\(|\\)|\\/|0|1|2|3|4|5|6|7|8|9|\\#|\\*|\\?|'|\\\\'|\\\\`|\\\\v)/"; $monoliners = "/(a|c|e|m|n|o|r|s|u|v|w|x|z|-|=|\\+|:|.)/"; $descenders = "/(g|j|p|\\/|q|y|Q|,|;|\\[|\\]|\\{|\\}|\\(|\\)|\\#|\\\\LaTeX|\\\\TeX|\\\\c\\{)/"; $deepdescenders = "/(\\[|\\]|\\{|\\}|\\(|\\)|\\int)/"; $ba = preg_match_all($ascenders, $string, $m); $bm = preg_match_all($monoliners, $string, $m); $bd = preg_match_all($descenders, $string, $m); $dd = preg_match_all($deepdescenders, $string, $m); if ($dd > 0) { $verticalalign = "vertical-align: -27%"; } else { if ($bd > 0 && $ba == 0) { $verticalalign = "vertical-align: -20%"; } else { if ($bd == 0 && $ba > 0) { $verticalalign = "vertical-align: -1%"; } else { if ($bd == 0 && $ba == 0) { $verticalalign = "vertical-align: -2%"; } else { $verticalalign = "vertical-align: -19%"; } } } } # both ascender and regular descender #check image cache, return link if exists #the vertical-align is to fix text baseline/descender(/tail) details in and on-average sort of way if (file_exists($heredir . '/texImages/' . $strhash . '.' . $imgfmt)) { return '<img style="' . $verticalalign . '" title="' . $stralt . '" alt="LaTeX formula: ' . $stralt . '" src="texImages/' . $strhash . '.' . $imgfmt . '">'; } #chdir to have superfluous file be created in tmp. if (chdir("/tmp") === FALSE) { return false; } #I should chech whether file creation is allowed to give a nice error for that problem case $tfn = tempnam("/tmp", 'PTX'); #file in tmp dir #write temporary .tex file if (($tex = fopen($tfn . '.tex', "w")) == FALSE) { return false; } fwrite($tex, $totex); fclose($tex); #Run latex to create a .dvi. Try to fix minor errors instead of breaking/pausing on them. exec('latex --interaction=nonstopmode ' . $tfn . '.tex'); if (!file_exists($tfn . ".dvi")) { phplatex_cleantmp($tfn, $heredir); return false; } exec('dvipng -bg Transparent -q -T tight ' . $tfn . ' -o ' . $tfn . '.' . $imgfmt); if (!file_exists($tfn . '.' . $imgfmt)) { phplatex_cleantmp($tfn, $heredir); return false; } #Copy result image to chache. copy($tfn . '.' . $imgfmt, $heredir . '/texImages/' . $strhash . '.' . $imgfmt); #Clean up temporary files, and return link to just-created image phplatex_cleantmp($tfn, $heredir); return '<img style="' . $verticalalign . '" title="' . $stralt . '" alt="LaTeX formula: ' . $stralt . '" src="texImages/' . $strhash . '.' . $imgfmt . '">'; }
function texify($string, $dpi = '90', $r = 0.0, $g = 0.0, $b = 0.0, $br = 1.0, $bg = 1.0, $bb = 1.0, $extraprelude = "", $sharpen = FALSE) { //global $imgfmt,$path_to_latex,$path_to_dvips,$path_to_convert; // For some reason the globals don't work $path_to_latex = '/usr/bin/latex'; $path_to_dvips = '/usr/bin/dvips'; $path_to_convert = '/usr/bin/convert'; $imgfmt = "png"; #literally used in extensions, and in parameters to convert. Should be either png or gif. if ($dpi > 300) { $dpi = 300; } $back = phplatex_colorhex($br, $bg, $bb); $fore = phplatex_colorhex($r, $g, $b); # Figure out TeX, either to get the right cache entry or to, you know, compile # Semi-common (ams) symbol packages are included. $totex = "\\documentclass[14pt,landscape]{extarticle}\n" . "\\usepackage{color}\n" . "\\usepackage{amsmath}\n\\usepackage{amsfonts}\n\\usepackage{amssymb}\n" . $extraprelude . "\n" . "\\pagestyle{empty}\n" . "\\begin{document}\n" . "\\color[rgb]{" . $r . "," . $g . "," . $b . "}\n" . "\\pagecolor[rgb]{" . $br . "," . $bg . "," . $bb . "}\n" . $string . "\n" . "\\end{document}\n"; $strhash = sha1($totex) . '.' . $dpi; #file cache entry string: 40-char hash string plus size $stralt = str_replace("&", "&", preg_replace("/[\"\n]/", "", $string)); #stuck in the alt and title attributes #May need some extra safety. $heredir = getcwd(); #Experiment: Tries to adjust vertical positioning, so that rendered TeX text looks natural enough inline with HTML text #Only descenders are really a problem since HTML's leeway is upwards. #TODO: This can always use more work. # Avoid using characters that are part of TeX commands. # Some things vary per font, e.g. the slash. In the default CM it is a descender, in Times and others it isn't. $ascenders = "/(b|d|f|h|i|j|k|l|t|A|B|C|D|E|F|G|H|I|J|L|K|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|\\[|\\]|\\{|\\}|\\(|\\)|\\/|0|1|2|3|4|5|6|7|8|9|\\#|\\*|\\?|'|\\\\'|\\\\`|\\\\v)/"; $monoliners = "/(a|c|e|m|n|o|r|s|u|v|w|x|z|-|=|\\+|:|.)/"; $descenders = "/(g|j|p|\\/|q|y|Q|,|;|\\[|\\]|\\{|\\}|\\(|\\)|\\#|\\\\LaTeX|\\\\TeX|\\\\c\\{)/"; $deepdescenders = "/(\\[|\\]|\\{|\\}|\\(|\\)|\\int)/"; $ba = preg_match_all($ascenders, $string, $m); $bm = preg_match_all($monoliners, $string, $m); $bd = preg_match_all($descenders, $string, $m); $dd = preg_match_all($deepdescenders, $string, $m); if ($dd > 0) { $verticalalign = "vertical-align: -25%"; } else { if ($bd > 0 && $ba == 0) { $verticalalign = "vertical-align: -15%"; } else { if ($bd == 0 && $ba > 0) { $verticalalign = "vertical-align: 0%"; } else { if ($bd == 0 && $ba == 0) { $verticalalign = "vertical-align: 0%"; } else { $verticalalign = "vertical-align: -15%"; } } } } # both ascender and regular descender #check image cache, return link if exists #the vertical-align is to fix text baseline/descender(/tail) details in and on-average sort of way if (file_exists($heredir . '/images/' . $strhash . '.' . $imgfmt)) { return '<img style="' . $verticalalign . '" title="' . $stralt . '" alt="' . $stralt . '" src="images/' . $strhash . '.' . $imgfmt . '">'; } #chdir to have superfluous files be created in tmp. (you stiill have to empty this yourself) error_reporting(0); # not checking existence myself, that would be double. if (chdir("tmp") === FALSE) { return '[directory access error, fix permissions]'; } #I should chech whether file creation is allowed to give a nice error for that problem case error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE); # TODO: set old value $tfn = tempnam(getcwd(), 'PTX'); #file in tmp dir #write temporary .tex file if (($tex = fopen($tfn . '.tex', "w")) == FALSE) { return '[file access error] ' . phplatex_cleantmp($tfn, $heredir); } fwrite($tex, $totex); fclose($tex); #Run latex to create a .dvi. Have it try to fix minor errors instead of breaking/pausing on them. exec($path_to_latex . ' --interaction=nonstopmode ' . $tfn . '.tex'); if (!file_exists($tfn . ".dvi")) { $log = file_get_contents($tfn . '.log'); #The log always exists, but now it's actually interesting since it'll contain an error return '[latex error, code follows]<pre>' . $totex . '</pre><p><b>Log file:</b><pre>' . $log . '</pre></p> ' . phplatex_cleantmp($tfn, $heredir); } #DVI -> PostScript. Since dvips uses lpr, which may be configured to actually print by default, force writing to a file with -o exec($path_to_dvips . ' ' . $tfn . '.dvi -o ' . $tfn . '.ps'); if (!file_exists($tfn . '.ps')) { return '[dvi2ps error] ' . phplatex_cleantmp($tfn, $heredir); } #PostScript -> image. Trim based on corner pixel, and set transparent color. exec($path_to_convert . ' -transparent-color "#' . $back . '" -colorspace RGB -density ' . $dpi . ' -trim +page ' . $tfn . '.ps -transparent "#' . $back . '" ' . $tfn . '.' . $imgfmt); #Note: +page OR -page +0+0 OR +repage moves the image to the cropped area (kills offset) #Older code tried: exec('/usr/bin/mogrify -density 90 -trim +page -format $imgfmt '.$tfn.'.ps'); # It seems some versions of convert may not have -trim. Old versions? if (!file_exists($tfn . '.' . $imgfmt)) { return '[image convert error] ' . phplatex_cleantmp($tfn, $heredir); } #Copy result image to chache. copy($tfn . '.' . $imgfmt, $heredir . '/images/' . $strhash . '.' . $imgfmt); #Clean up temporary files, and return link to just-created image return phplatex_cleantmp($tfn, $heredir) . '<img style="' . $verticalalign . '" title="' . $stralt . '" alt="LaTeX formula: ' . $stralt . '" src="images/' . $strhash . '.' . $imgfmt . '">'; }