DokuWiki

It's better when it's simple

User Tools

Site Tools


tips:tex_howto

TeX

This patch (to 2005-05-07 version) add AMSLaTeX mathematical expresion support to Dokuwiki.

http://smp.if.uj.edu.pl/wiki/tex.diff

diff -ruN ./wiki.org/inc/mediawiki/Math.php ./wiki/inc/mediawiki/Math.php
--- ./wiki.org/inc/mediawiki/Math.php1970-01-01 01:00:00.000000000 +0100
+++ ./wiki/inc/mediawiki/Math.php2005-05-13 08:55:34.000000000 +0200
@@ -0,0 +1,230 @@
+<?php
+$wgMathDirectory = "/var/lib/wiki/mathimg/";
+$wgTmpDirectory = "/var/lib/wiki/mathtmp/";
+$wgInputEncoding = "ISO-8859-2";
+$wgTexvc = "/usr/local/bin/texvc";
+$wgMathPath = "/wiki/mathimg";
+
+$texvc = "/usr/local/bin/texvc";
+$tempdir = "/var/lib/wiki/mathtmp/";
+$imgdir = "/var/lib/wiki/mathimg/";
+$imgpath = "/wiki/mathimg/";
+
+/**
+ * Contain everything related to <math> </math> parsing
+ * @package MediaWiki
+ */
+
+/**
+ * Takes LaTeX fragments, sends them to a helper program (texvc) for rendering
+ * to rasterized PNG and HTML and MathML approximations. An appropriate
+ * rendering form is picked and returned.
+ * 
+ * by Tomasz Wegrzanowski, with additions by Brion Vibber (2003, 2004)
+ *
+ * @package MediaWiki
+ */
+class MathRenderer {
+var $mode = MW_MATH_MODERN;
+var $tex = '';
+var $inputhash = '';
+var $hash = '';
+var $html = '';
+var $mathml = '';
+var $conservativeness = 0;
+
+function MathRenderer( $tex ) {
+$this->tex = $tex;
+ }
+
+function setOutputMode( $mode ) {
+$this->mode = $mode;
+}
+
+function render() {
+global $wgMathDirectory, $wgTmpDirectory, $wgInputEncoding;
+global $wgTexvc;
+$fname = 'MathRenderer::render';
+
+if( $this->mode == MW_MATH_SOURCE ) {
+# No need to render or parse anything more!
+return ('$ '.htmlspecialchars( $this->tex ).' $');
+}
+
+if( !$this->_recall() ) {
+# Ensure that the temp and output directories are available before continuing...
+if( !file_exists( $wgMathDirectory ) ) {
+if( !@mkdir( $wgMathDirectory ) ) {
+return $this->_error( 'math_bad_output' );
+}
+} elseif( !is_dir( $wgMathDirectory ) || !is_writable( $wgMathDirectory ) ) {
+return $this->_error( 'math_bad_output' );
+}
+if( !file_exists( $wgTmpDirectory ) ) {
+if( !@mkdir( $wgTmpDirectory ) ) {
+return $this->_error( 'math_bad_tmpdir' );
+}
+} elseif( !is_dir( $wgTmpDirectory ) || !is_writable( $wgTmpDirectory ) ) {
+return $this->_error( 'math_bad_tmpdir' );
+}
+
+if( !is_executable( $wgTexvc ) ) {
+return $this->_error( 'math_notexvc' );
+}
+$cmd = $wgTexvc.' '.
+escapeshellarg($wgTmpDirectory).' '.
+escapeshellarg($wgMathDirectory).' '.
+escapeshellarg($this->tex).' '.
+escapeshellarg($wgInputEncoding);
+//wfDebug( 'TeX: '.$cmd );
+$contents = `$cmd`;
+
+if (strlen($contents) == 0) {
+return $this->_error( 'math_unknown_error' );
+}
+
+$retval = substr ($contents, 0, 1);
+if (($retval == 'C') || ($retval == 'M') || ($retval == 'L')) {
+if ($retval == 'C')
+$this->conservativeness = 2;
+else if ($retval == 'M')
+$this->conservativeness = 1;
+else
+$this->conservativeness = 0;
+$outdata = substr ($contents, 33);
+
+$i = strpos($outdata, "\000");
+
+$this->html = substr($outdata, 0, $i);
+$this->mathml = substr($outdata, $i+1);
+} else if (($retval == 'c') || ($retval == 'm') || ($retval == 'l'))  {
+$this->html = substr ($contents, 33);
+if ($retval == 'c')
+$this->conservativeness = 2;
+else if ($retval == 'm')
+$this->conservativeness = 1;
+else
+$this->conservativeness = 0;
+$this->mathml = NULL;
+} else if ($retval == 'X') {
+$this->html = NULL;
+$this->mathml = substr ($contents, 33);
+$this->conservativeness = 0;
+} else if ($retval == '+') {
+$this->html = NULL;
+$this->mathml = NULL;
+$this->conservativeness = 0;
+} else {
+$errbit = htmlspecialchars( substr($contents, 1) );
+switch( $retval ) {
+case 'E': return $this->_error( 'math_lexing_error', $errbit );
+case 'S': return $this->_error( 'math_syntax_error', $errbit );
+case 'F': return $this->_error( 'math_unknown_function', $errbit );
+default:  return $this->_error( 'math_unknown_error', $errbit );
+}
+}
+
+$this->hash = substr ($contents, 1, 32);
+if (!preg_match("/^[a-f0-9]{32}$/", $this->hash)) {
+return $this->_error( 'math_unknown_error' );
+}
+
+if( !file_exists( "$wgMathDirectory/{$this->hash}.png" ) ) {
+return $this->_error( 'math_image_error' );
+}
+/*
+# Now save it back to the DB:
+if ( !wfReadOnly() ) {
+$outmd5_sql = pack('H32', $this->hash);
+
+$md5_sql = pack('H32', $this->md5); # Binary packed, not hex
+
+$dbw =& wfGetDB( DB_MASTER );
+$dbw->replace( 'math', array( 'math_inputhash' ),
+  array( 
+'math_inputhash' => $md5_sql, 
+'math_outputhash' => $outmd5_sql,
+'math_html_conservativeness' => $this->conservativeness,
+'math_html' => $this->html,
+'math_mathml' => $this->mathml,
+  ), $fname, array( 'IGNORE' ) 
+);
+}
+*/
+}
+
+return $this->_doRender();
+}
+
+function _error( $msg, $append = '' ) {
+$mf   = htmlspecialchars( 'math_failure' );
+$munk = htmlspecialchars( 'math_unknown_error' );
+$errmsg = htmlspecialchars( $msg );
+$source = htmlspecialchars($this->tex);
+return "<strong class='error'>$mf ($errmsg$append): $source</strong>\n";
+}
+
+function _recall() {
+global $wgMathDirectory;
+$fname = 'MathRenderer::_recall';
+
+$this->md5 = md5( $this->tex );
+/*$dbr =& wfGetDB( DB_SLAVE );
+$rpage = $dbr->selectRow( 'math', 
+array( 'math_outputhash','math_html_conservativeness','math_html','math_mathml' ),
+array( 'math_inputhash' => pack("H32", $this->md5)), # Binary packed, not hex
+$fname
+);
+*/
+
+if( $rpage !== false ) {
+# Tailing 0x20s can get dropped by the database, add it back on if necessary:
+$xhash = unpack( 'H32md5', $rpage->math_outputhash . "                " );
+$this->hash = $xhash ['md5'];
+
+$this->conservativeness = $rpage->math_html_conservativeness;
+$this->html = $rpage->math_html;
+$this->mathml = $rpage->math_mathml;
+
+if( file_exists( "$wgMathDirectory/{$this->hash}.png" ) ) {
+return true;
+}
+}
+
+# Missing from the database and/or the render cache
+return false;
+}
+
+/**
+ * Select among PNG, HTML, or MathML output depending on
+ */
+function _doRender() {
+if( $this->mode == MW_MATH_MATHML && $this->mathml != '' ) {
+return "<math xmlns='http://www.w3.org/1998/Math/MathML'>{$this->mathml}</math>";
+}
+if (($this->mode == MW_MATH_PNG) || ($this->html == '') ||
+   (($this->mode == MW_MATH_SIMPLE) && ($this->conservativeness != 2)) ||
+   (($this->mode == MW_MATH_MODERN || $this->mode == MW_MATH_MATHML) && ($this->conservativeness == 0))) {
+return $this->_linkToMathImage();
+} else {
+return '<span class="texhtml">'.$this->html.'</span>';
+};echo "aaa";
+}
+
+function _linkToMathImage() {
+global $wgMathPath;
+$url = htmlspecialchars( "$wgMathPath/{$this->hash}.png" );
+$alt = trim(str_replace("\n", ' ', htmlspecialchars( $this->tex )));
+return "<img class='tex' src=\"$url\" alt=\"$alt\" />";
+}
+}
+
+function renderMath( $tex ) {
+//global $wgUser;
+$math = new MathRenderer( $tex );
+//$math->setOutputMode( $wgUser->getOption('math'));
+$math->setOutputMode( MW_MATH_PNG );
+return $math->render();
+}
+
+?>
diff -ruN ./wiki.org/inc/parser/handler.php ./wiki/inc/parser/handler.php
--- ./wiki.org/inc/parser/handler.php2005-05-07 11:22:56.000000000 +0200
+++ ./wiki/inc/parser/handler.php2005-05-15 06:55:00.000000000 +0200
@@ -510,6 +510,17 @@
         }
         return TRUE;
     }
+
+    function math($match, $state, $pos) {
+        switch ( $state ) {
+            case DOKU_LEXER_UNMATCHED:
+        $this->_addCall('append', array(renderMath($match)), $pos);
+            break;
+        }
+        return TRUE;
+
+        return TRUE;
+    }
 }
 
 //------------------------------------------------------------------------
diff -ruN ./wiki.org/inc/parser/parser.php ./wiki/inc/parser/parser.php
--- ./wiki.org/inc/parser/parser.php2005-05-07 11:22:56.000000000 +0200
+++ ./wiki/inc/parser/parser.php2005-05-15 06:51:10.000000000 +0200
@@ -335,6 +335,7 @@
         $this->allowedModes[] = 'php';
         $this->allowedModes[] = 'code';
         $this->allowedModes[] = 'file';
+        $this->allowedModes[] = 'html';
     }
     
     function connectTo($mode) {
@@ -837,6 +838,7 @@
     $modes = array(
         'preformatted','code','file',
         'php','html','quote',
+'math',
     );
     return $modes;
 }
@@ -849,5 +851,16 @@
     return $modes;
 }
 
+class Doku_Parser_Mode_Math extends Doku_Parser_Mode {
+    
+    function connectTo($mode) {
+        $this->Lexer->addEntryPattern('<math>(?=.*</math>)',$mode,'math');
+    }
+    
+    function postConnect() {
+        $this->Lexer->addExitPattern('</math>','math');
+    }
+}
+
 
 //Setup VIM: ex: et ts=4 enc=utf-8 :
diff -ruN ./wiki.org/inc/parser/xhtml.php ./wiki/inc/parser/xhtml.php
--- ./wiki.org/inc/parser/xhtml.php2005-05-07 11:22:56.000000000 +0200
+++ ./wiki/inc/parser/xhtml.php2005-05-13 08:56:13.000000000 +0200
@@ -724,6 +724,11 @@
         $this->doc .= $this->_formatLink($link);
     }
 
+    function append ($str) {
+        $this->doc .= $str;
+    }
+
+
     /**
      * Renders an RSS feed using Magpie
      * 
diff -ruN ./wiki.org/inc/parserutils.php ./wiki/inc/parserutils.php
--- ./wiki.org/inc/parserutils.php2005-05-07 11:22:56.000000000 +0200
+++ ./wiki/inc/parserutils.php2005-05-13 08:34:57.000000000 +0200
@@ -11,6 +11,8 @@
 
   require_once(DOKU_INC.'inc/confutils.php');
   require_once(DOKU_INC.'inc/pageutils.php');
+  require_once(DOKU_INC.'inc/mediawiki/Math.php');
+
 
 /**
  * Returns the parsed Wikitext in XHTML for the given id and revision.
@@ -210,7 +212,9 @@
   $Parser->addMode('windowssharelink',new Doku_Parser_Mode_WindowsShareLink());
   //$Parser->addMode('filelink',new Doku_Parser_Mode_FileLink()); //FIXME ???
   $Parser->addMode('eol',new Doku_Parser_Mode_Eol());
-  
+
+  $Parser->addMode('math',new Doku_Parser_Mode_Math());
+
   // Do the parsing
   $p    = $Parser->parse($text);
 #  dbg($p);


Apply this patch in main dokuwiki directory with patch -p1 < abovepatch.diff


You will also need latex, tetex, dvipng, imagemagic, ghostscript, ocaml (apt-get install dvipng latex convert gs ocaml on Debian) and texvc. Get texvc (get from Mediawiki main distrbution file or SF project page http://sourceforge.net/project/showfiles.php?group_id=34373&package_id=111620 http://sourceforge.net/project/showfiles.php?group_id=34373).


Install everything, compile texvc and place someware.

Change a very beging of ./wiki/inc/mediawiki/Math.php file.


Mathematical mode is accessible by <math> </math> tag. Only mathematical mode is avaible but it's very fast and cache results.



Example:

<math> \frac{\sum_{n=1}^N x^{\sqrt{n+1}}-x^{x^{2n}}}{(\ln(x)+2x^{4x+1289})^{\frac{1}{2}}} </math>

Result:

You can configure it to produce MathML, PNG, HTML.


15 May 2005, Witold Baryluk <baryluk.smp.if.uj.edu.pl>

tips/tex_howto.txt · Last modified: 2013-03-06 16:13 by Klap-in

Except where otherwise noted, content on this wiki is licensed under the following license: CC Attribution-Share Alike 4.0 International
CC Attribution-Share Alike 4.0 International Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki