1<?php
2/**
3 * jsMath Plugin - see http://www.math.union.edu/~dpvc/jsmath/
4 *
5 * Syntax:    <jsm> ...latex... </jsm>
6 *         <jsmath> ...latex... </jsmath>
7 * (optional)     $ ...latex... $
8 * (optional)    \[ ...latex... \]
9 * (optional)    \( ...latex... \)
10 *
11 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
12 * @author     Holger <yllohy@gmail.com>
13 * @author     Stephen Gould <sgould@cs.stanford.edu>
14 **/
15
16if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
17if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
18require_once(DOKU_PLUGIN.'syntax.php');
19
20/**
21 * All DokuWiki plugins to extend the parser/rendering mechanism
22 * need to inherit from this class
23 **/
24class syntax_plugin_jsmath extends DokuWiki_Syntax_Plugin {
25
26  /**
27   * Get an associative array with plugin info.
28   **/
29  function getInfo(){
30    return array(
31      'author' => 'Holger',
32      'email'  => 'yllohy@gmail.com',
33      'date'   => @file_get_contents(DOKU_PLUGIN.'jsmath/VERSION'),
34      'name'   => 'jsMath Plugin',
35      'desc'   => 'Plugin for displaying latex equations using MathJax or jsMath
36      See http://www.mathjax.org
37      See http://www.math.union.edu/~dpvc/jsmath/
38      Syntax: <jsm(ath)?>math formulae</jsm(ath)?>',
39        'url'    => 'http://www.dokuwiki.org/plugin:jsmath',
40      );
41  }
42
43  function getType(){ return 'protected'; }
44  function getAllowedTypes() {
45    return array('disabled');
46  }
47  function getPType(){ return 'normal'; }
48  function getSort(){ return 222; }
49
50  /**
51   * Connect pattern to lexer
52   **/
53  function connectTo($mode) {
54    $this->Lexer->addEntryPattern('<jsm>(?=.*?</jsm>)',$mode,'plugin_jsmath');
55    $this->Lexer->addEntryPattern('<jsmath>(?=.*?</jsmath>)',$mode,'plugin_jsmath');
56    if($this->getConf('use_dollar'))
57    {
58      $this->Lexer->addEntryPattern('\$(?=.*?\$)',$mode,'plugin_jsmath');
59    }
60    if($this->getConf('use_rounded'))
61    {
62      $this->Lexer->addEntryPattern('\\\\\((?=.*?\\\\\))',$mode,'plugin_jsmath');
63    }
64    if($this->getConf('use_square'))
65    {
66      $this->Lexer->addEntryPattern('\\\\\[(?=.*?\\])',$mode,'plugin_jsmath');
67    }
68  }
69
70  function postConnect() {
71    $this->Lexer->addExitPattern('</jsm>','plugin_jsmath');
72    $this->Lexer->addExitPattern('</jsmath>','plugin_jsmath');
73    if($this->getConf('use_dollar'))
74    {
75      $this->Lexer->addExitPattern('\$','plugin_jsmath');
76    }
77    if($this->getConf('use_rounded'))
78    {
79      $this->Lexer->addExitPattern('\\\)','plugin_jsmath');
80    }
81    if($this->getConf('use_square'))
82    {
83      $this->Lexer->addExitPattern('\\\]','plugin_jsmath');
84    }
85  }
86
87  /**
88   *      * Handler to prepare matched data for the rendering process.
89   *           */
90  function handle($match, $state, $pos, &$handler){
91    switch ($state) {
92    case DOKU_LEXER_ENTER :
93      if(preg_match("/^(\\\\\()$/", $match) > 0
94       ||preg_match("/^(\\\$)$/", $match) > 0
95       ||preg_match("/^(<jsm>)$/", $match) > 0)
96      {
97        return array($state, 'inline');
98      }
99      else
100      {
101        return array($state, 'block');
102      }
103      break;
104    case DOKU_LEXER_MATCHED :
105      break;
106    case DOKU_LEXER_UNMATCHED :
107      return array($state, $match);
108      break;
109    case DOKU_LEXER_EXIT :
110      if(preg_match("/^(\\\\\))$/", $match) > 0
111       ||preg_match("/^(\\\$)$/", $match) > 0
112       ||preg_match("/^(<\/jsm>)$/", $match) > 0)
113      {
114        return array($state, 'inline');
115      }
116      else
117      {
118        return array($state, 'block');
119      }
120      break;
121    case DOKU_LEXER_SPECIAL :
122      break;
123    }
124    return array($state, '');
125  }
126
127  /**
128   * Handle the actual output creation.
129   **/
130  function render($mode, &$renderer, $data) {
131    $backend_is_jsmath = ($this->getConf('backend') != 'MathJax');
132    if($mode == 'xhtml') {
133      list($state, $match) = $data;
134      switch ($state) {
135      case DOKU_LEXER_ENTER :
136        if ($match=='inline') {
137          if($backend_is_jsmath)
138          {
139            $renderer->doc .= '<span class="math">';
140          }
141          else
142          {
143            $renderer->doc .= '<span dir="ltr"><script type="math/tex">';
144          }
145        } else {
146          if($backend_is_jsmath)
147          {
148            $renderer->doc .= '<div class="math">';
149          }
150          else
151          {
152            $renderer->doc .= '<span dir="ltr"><script type="math/tex; mode=display">';
153          }
154        }
155        break;
156      case DOKU_LEXER_MATCHED :
157        break;
158      case DOKU_LEXER_UNMATCHED :
159        if($backend_is_jsmath)
160        {// jsMath needs < to be replaced with &lt; and so on.
161          $renderer->doc .= $renderer->_xmlEntities($match);
162        }
163        else
164        {
165          $renderer->doc .= $match;
166        }
167        break;
168      case DOKU_LEXER_EXIT :
169        if ($match=='inline') {
170          if($backend_is_jsmath)
171          {
172            $renderer->doc .= '</span>';
173          }
174          else
175          {
176            $renderer->doc .= '</script></span>';
177          }
178        } else {
179          if($backend_is_jsmath)
180          {
181            $renderer->doc .= '</div>';
182          }
183          else
184          {
185            $renderer->doc .= '</script></span>';
186          }
187        }
188        break;
189      case DOKU_LEXER_SPECIAL :
190        break;
191      }
192      return true;
193    }
194    return false;
195  }
196}
197
198//Setup VIM: ex: et ts=4 enc=utf-8 :
199