Maths Publisher Plugin

experimental

This plugin makes use of phpmathpublisher by Pascal Brachet to allow inclusion of properly rendered mathematical formulae in Dokuwiki pages.

This is a completely self-contained php solution. It requires no third party packages. It makes use of php's GD library & freely available fonts1) to create an images for each formula. The plugin script, phpmathpublisher and the required fonts are all included in the download package.

PHP Installation Requirements

To run this plugin your PHP installation needs to have:

  • gd library
  • png capabilities, ie. libpng, which also requires the zlib library
  • freetype font library

For full details refer to the php documentation.

Syntax

Dokuwiki Syntax:

<m size>...mathematical formulae...</m>

size (optional) the base glyph size in pixels - default value: 12.

alignment can be controlled in the same way as dokuwiki images, one space to the left to right align, one to the right to left align, one on each side to centre.

Formulae syntax

Example:

<m>S(f)(t)=a_{0}+sum{n=1}{+infty}{a_{n} cos(n omega t)+b_{n} sin(n omega t)}</m>
<m 8>delim{lbrace}{matrix{3}{1}{{3x-5y+z=0} {sqrt{2}x-7y+8z=0} {x-8y+9z=0}}}{ }</m>
<m 32>delim{|}{{1/N} sum{n=1}{N}{gamma(u_n)} - 1/{2 pi} int{0}{2 pi}{gamma(t) dt}}{|} <= epsilon/3</m>

Result:


You can see the plugin in action here.

Installation

Plugin sources: zip format (460k), tar.gz format (454k), rar format (424k) | darcs repository

The zip & tar.gz format packages maybe installed using the plugin manager. The darcs repository can be used with the darcs plugin.

To install manually, download the source to your plugin folder, lib/plugins and extract its contents. That will create a new plugin folder, lib/plugins/math, and install the plugin.

The folder will contain:

syntax.php                                   the plugin script
phpmathpublisher/                            phpmathpublisher folder
phpmathpublisher/mathpublisher.php           the main phpmathpublisher script
phpmathpublisher/COPYING                     GPL2 licence
phpmathpublisher/CHANGELOG                   phpmathpublisher changelog
phpmathpublisher/fonts/                      font folder
phpmathpublisher/fonts/COPYING               font copyright information
phpmathpublisher/fonts/FreeSerif.ttf         truetype font
phpmathpublisher/fonts/FreeSerifItalic.ttf   truetype font
phpmathpublisher/fonts/cmex10.ttf            truetype font
phpmathpublisher/fonts/cmmi10.ttf            truetype font
phpmathpublisher/fonts/cmr10.ttf             truetype font
phpmathpublisher/fonts/msam10.ttf            truetype font

The plugin is now installed.

Details

Configuration

The plugin will work successfully with no changes to its configuration. However there are three settings you may alter:

  • $mathplugin_size — the size value to be used if none is provided.
  • $dirimg — the folder to be used as an image cache
  • $mathplugin_urlimg — the url required to access images stored in the image cache.

The full details of these settings are given in the plugin source code.

Plugin Source

<?php
/**
 * Math Plugin: incorporate mathematical formulae using MathPublisher into Dokuwiki
 *
 * Syntax:     <m size>...mathematical formula..</m>
 *   size      (optional) base glyph size in pixels, 
 *             if not present will use the value of $mathplugin_size global, the value
 *             of which can be set below (default: 12)
 *   
 * Formulae syntax:  refer http://www.xm1math.net/phpmathpublisher/doc/help.html
 * 
 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
 * @author     Christopher Smith <chris@jalakai.co.uk>
 * @date       2005-12-17
 *
 * phpmathpublisher
 * @link       http://www.xm1math.net/phpmathpublisher/
 * @author     Pascal Brachet
 */
 
if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
require_once(DOKU_PLUGIN.'syntax.php');
require_once(DOKU_INC.'inc/io.php');
 
global $conf;
 
// -----------------------[ math plugin globals ]---------------------------------------
global $mathplugin_size, $mathplugin_urlimg;
 
  // default base size (pixels) of glyphs in the forumlae
  $mathplugin_size = 12;
 
  // base url to access images, should correspond to $dirimg below.
  // if left at default, it will be modified to add a subfolder to avoid filling
  // the root media folder with clutter, refer _cacheExists()
  $mathplugin_urlimg = DOKU_URL.'lib/exe/fetch.php?w=&amp;h=&amp;cache=cache&amp;media=';
 
// -----------------------[ mathpublisher settings ]------------------------------------
global $dirfonts,$dirimg;
 
  // absolute path to the fonts directory (must not have '/' at end)
  $dirfonts=dirname(__FILE__)."/phpmathpublisher/fonts";
 
  // absolute path to the img directory (must not have '/' at end)
  // if left at default, it will be modified to add a subfolder to avoid filling
  // the root media folder with clutter, refer _cacheExists()
  $dirimg=$conf['mediadir'];
 
// ------------------------------------------------------------------------------------
 
/**
 * All DokuWiki plugins to extend the parser/rendering mechanism
 * need to inherit from this class
 */
class syntax_plugin_math extends DokuWiki_Syntax_Plugin {
 
    // FIXME localise
    var $str_nopng = "PHP's gd library is missing or unable to create PNG images";
    var $str_noft = "PHP installation missing access to freetype library";
    var $enable = false;
    var $msg_disable = "math plugin disabled: ";
    var $msg_sent = false;
 
    function syntax_plugin_math() {
        $this->enable = $this->_requirements_ok();    
    }
 
    /**
     * return some info
     */
    function getInfo(){
 
      return array(
        'author' => 'Christopher Smith',
        'email'  => 'chris@jalakai.co.uk',
        'date'   => '2005-12-17',
        'name'   => 'Math Plugin'.(!$this->enable ? ' (disabled)' : ''),
        'desc'   => 'Add mathematical formulae to dokuwiki
                     Syntax: <m size>math formulae</m>
                     For formulae syntax visit http://www.xm1math.net/phpmathpublisher/doc/help.html'.
                     (!$this->enable ? "\n(".$this->msg_disable.")" : ''),
        'url'    => 'http://wiki.splitbrain.org/plugin:math2',
      );
    }
 
    function getType(){ return 'protected'; }
    function getPType(){ return 'normal'; }
    function getSort(){ return 208; }
 
    /**
     * Connect pattern to lexer
     */
    function connectTo($mode) {
      $this->Lexer->addEntryPattern('<m(?=[^\r\n]*?>.*?</m>)',$mode,'plugin_math');
    }
 
    function postConnect() {
      $this->Lexer->addExitPattern('</m>','plugin_math');
    } 
 
    /**
     * Handle the match
     */
    function handle($match, $state, $pos, &$handler){
      global $mathplugin_size;
 
      if ( $state == DOKU_LEXER_UNMATCHED ) {
        list($size, $math) = preg_split('/>/u', $match, 2);   // will split into size & math formulae
        if (!is_numeric($size)) $size = $mathplugin_size;
 
        if (strlen($math) > 1) {
          $c_first = $math{0};
          $c_last = $math{strlen($math)-1};
 
          $align = ($c_first == ' ') ? ($c_last == ' ' ? 'center' : 'right') : ($c_last == ' ' ? 'left' : 'normal');
        } else {
          $align = 'normal';
        }
 
        return (array($size, trim($math), $align));
      }      
      return false;
    }
 
    /**
     * Create output
     */
    function render($mode, &$renderer, $data) {
      global $mathplugin_urlimg;
 
      if (!$data) return;   // skip rendering for the enter and exit patterns
      list($size, $math, $align) = $data;
 
      if($mode == 'xhtml'){
          // phpmathpublisher generates many E_NOTICE errors, ensure error_reporting doesn't include E_NOTICE.
          $error_level = error_reporting();
          error_reporting($error_level & ~E_NOTICE);
 
          // check we have ability to create png images
          if ($this->enable) {
            // check we have somewhere to create our images & make them
            if ($this->_cacheExists()) {    
                require_once(dirname(__FILE__).'/phpmathpublisher/mathpublisher.php');              
                $math_html = mathimage($math, $size, $mathplugin_urlimg);
 
                if ($align != 'normal') {
                    $math_html = preg_replace('/<img /i','\0 class="media'.$align.'" ',$math_html);
                }
 
                $renderer->doc .= $math_html;
            } else {
                $this->_msg("math plugin img folder is not writable", -1);
            }
          } else {
            $this->_msg($this->msg_disable, -1);
          }
 
          // return to previous error reporting level
          error_reporting($error_level);      
          return true;
      }
      return false;
    }
 
    function _cacheExists() {
        global $dirimg, $mathplugin_urlimg, $conf;
 
        // check for default setting
        if (!isset($dirimg) || !$dirimg) { $dirimg = $conf['mediadir']; }
        if ($dirimg == $conf['mediadir']) {
            // we don't want to clutter the root media dir, so create our own subfolder
            $dirimg .= "/cache_mathplugin";
            $mathplugin_urlimg .= "cache_mathplugin%3a";
 
            if (!@is_dir($dirimg)) {
                $this->_mkdir($dirimg);
            }
        }
 
        return @is_writable($dirimg);
    }
 
    // return true if php installation has required libraries/functions for mathpublisher
    function _requirements_ok() {
        if (!function_exists('imagepng')) {
          $this->msg_disable .= $this->str_nopng;
          return false;
        }
 
        if (!function_exists('imagettftext')) {
          $this->msg_disable .= $this->str_noft;
          return false;
        }
 
        return true;    
    }
 
    // used to avoid multiple messages
    function _msg($str, $lvl=0) {
        if ($this->msg_sent) return;
 
        msg($str, $lvl);
        $this->msg_sent = true;
    }
 
    // would like to see this function in io.php :)
    function _mkdir($d) {
        global $conf;
 
        umask($conf['dmask']);
        $ok = io_mkdir_p($d);
        umask($conf['umask']);
        return $ok;
    }    
 
}
 
//Setup VIM: ex: et ts=4 enc=utf-8 :

php math publisher

The plugin uses slightly modified version of the phpmathpublisher version 0.3 script. Only the script and fonts (and appropriate copyright files) are included in the download. The full phpmathpublisher package complete with demonstration pages is available at the phpmathpublisher home page.

Revision History

2005-07-27
Released.
2005-08-19
Updated to phpmathpublisher v0.3, size parameter added, will create and use its own image cache, report error if image cache not writable. Single file download released.
2005-09-05
Updated to correct problem with using “/” in image url (thanks Diego Caro).
2005-11-14
Updated to support dokuwiki style alignment syntax, correction to PType (thanks Matthias Grimm).
2005-11-21
Font files updated for improved support for non-standard characters (thanks again to Matthias).
2005-12-17
Add checking for required php capabilities, gd library, png capability & free type library.

Bugs

  • $conf['mediaweb'] is not defined out of the box.
  • direct access to media-dir is denied out of the box

⇒ replace

$renderer->doc .= mathimage($data[0], 10, $conf['mediaweb']."/"

with something like that

$renderer->doc .= mathimage($data[0], 10, DOKU_URL.'lib/exe/fetch.php?w=&amp;h=&amp;cache=cache&amp;media=');
$conf['mediaweb'] code replaced as indicated. I am not sure about $conf['mediadir'], its a subfolder of data/ and the installation instructions include making that folder and all its subfolders writeable by the webserver. — ChrisS 2005-07-29

images are not displayed

We had a problem. The images were generated but dokuwiki couldn't show them. The problem was with the image url. "cache_mathplugin" must be followed by ":" instead of "/".

./dokuwikitrial/lib/exe/fetch.php?w=&h=&cache=cache&media=cache_mathplugin/math_993.5_40f0daa8d07f168d75df0f5241e9f7e3.png 

We decided to add a line of code in the function "mathimage" in mathpublisher.php. Right after the line

$valign=$v-1000;

we write

$pathtoimg=rtrim($pathtoimg, "/").":";

And now it works fine! — Jesús 2005-08-26

Todo

  • review image caching to better follow Dokuwiki's own methods - DONE
  • review phpmathpublishers decision making to use cached image. It seems to do all but generate the png image in order to access some dimensions. Version 0.3 corrects this problem - DONE.

Discussion

..

your download links dont work!

1) freeserif from the Free Software Foundation and several fonts made freely available by the American Mathematical Association
 
tutorials/maths_plugin.txt · Last modified: 2010/05/31 16:21 (external edit)
 
Recent changes RSS feed Creative Commons License Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki