WikiTeX
Introduction
This wiki is based on DokuWiki, but modifies the standard syntax in order to permit the same source files to be used by both the wiki and LaTeX. Our configuration is documented below; feedback is welcome.
Getting Started
You will need:
- DokuWiki;
- The monobook template for DokuWiki (probably optional);
- the comment plugin for DokuWiki;
- the include plugin for DokuWiki;
- the imagebox plugin for DokuWiki (optional).
(We have upgraded our mathematics processing from jsMath to MathJax. Unlike jsMath, MathJax requires no local installation, and no fonts, although a local copy may be installed if desired. Our original installation instructions for use with jsMath can be found here.)
Overview
We chopped up our LaTeX files into small pieces, roughly one per section, thus removing most LaTeX formatting commands from these files. We then edited these files to be compatible with both DokuWiki and LaTeX syntax, double-coding where necessary (e.g. figures and some cross-references). Finally, we added separate header files for the wiki (to call MathJax, load macros, etc.) and for LaTeX (to load packages and macros and define some cross-references). As a matter of policy, section headings were put in these header files, not in the actual content files, allowing the same content to be called in multiple ways. The header files then separately call the main content, using the include plugin for the wiki, or the \input command in LaTeX.
For details of the necessary syntax for the content files, look here.
A typical wiki header file looks like this:
{{page>..:macros:header}} ==== Topic ==== {{page>..:mathcontent:topic}}
which first loads the global header file, inserts a section title, then loads the content file. Our global header file looks like this:
<html> <style type="text/css"> OL OL { list-style-type: lower-alpha; } </style> </html> {{page>..:macros:hmacros}} <html> <script type="text/x-mathjax-config"> MathJax.Hub.Config({ jax: ["input/TeX","output/HTML-CSS"], extensions: ["tex2jax.js","MathMenu.js","MathZoom.js"], tex2jax: { inlineMath: [ ['$','$'], ['\\(','\\)'] ], processEscapes: true }, "HTML-CSS": { availableFonts: ["STIX","TeX"], extensions: ["handle-floats.js"], scale: 100 }, menuSettings: { zoom: "Double-Click" }, TeX: { extensions: ["AMSmath.js","AMSsymbols.js","noErrors.js","noUndefined.js"], equationNumbers: { autoNumber: "AMS" } } }); MathJax.Hub.Register.StartupHook("TeX Jax Ready", function () { var ENV = MathJax.InputJax.TeX.Definitions.environment; ENV["eqnarray"] = ["AMSarray",null,true,true,'rcl','thickmathspace']; ENV["eqnarray*"] = ["AMSarray",null,false,true,'rcl','thickmathspace']; }); </script> <script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js"> </script> </html>
Similarly, a typical LaTeX header file might look like:
%% -*- latex -*- \if\Book0 \input macros/header % \usepackage{epsfig} % UNCOMMENT IF USING FIGURES \setcounter{page}{1} % INSERT PAGE NUMBER HERE \setcounter{subsection}{1} % INSERT SECTION NUMBER HERE \addtocounter{subsection}{-1} \begin{document} \fi \section{The Dot Product} \label{dot} \input mathcontent/dot.txt \input macros/footer
where the header file is something like:
%**start of header % Used as input for notes.tex if \Book=1; else set \Book=0. % \expandafter\ifx\csname Book\endcsname\relax\let\Book0\fi % \if\Book0 \documentclass[12pt]{article} % \usepackage{fullpage} \input macros/Macros \renewcommand{\thesubsection}{\arabic{subsection}} \fi %**end of header
and the footer file similarly checks whether a single section or the entire book is being processed, and exits accordingly.
Installation details
The following instructions assume that you have a working DokuWiki installation, with monobook and the above plugins installed, as well as a working LaTeX installation.
Comment syntax
Create new comment sequences starting with % by modifying both the comment plugin and the parser. First, change the connectTo function in …/lib/plugins/comment/syntax.php so that it becomes:
function connectTo($mode) { $this->Lexer->addSpecialPattern("/\*.*?\*/", $mode, 'plugin_comment'); $this->Lexer->addSpecialPattern("%/\*.*?%\*/", $mode, 'plugin_comment'); $this->Lexer->addSpecialPattern("%\*", $mode, 'plugin_comment'); $this->Lexer->addSpecialPattern("//.*?$", $mode, 'plugin_comment'); $this->Lexer->addSpecialPattern("%%.*?$", $mode, 'plugin_comment'); }
(This adds %% as an initial comment character and %/* , %*/ as begin/end comment characters.)
Then make the following changes to …/inc/parser/parser.php:
Replace
$this->Lexer->addSpecialPattern('\x5C{2}(?=\s)',$mode,'linebreak');
with
$this->Lexer->addSpecialPattern('\x5C{4}(?=\s)',$mode,'linebreak');
Replace
$this->Lexer->addSpecialPattern('\n[ \t]*-{4,}[ \t]*(?=\n)',$mode,'hr');
with
$this->Lexer-> addSpecialPattern('\n[ \t]*-{4,}[ \t]*(?=\n)',$mode,'hr'); $this->Lexer-> addSpecialPattern('\n%\*[ \t]*-{4,}[ \t]*(?=\n)',$mode,'hr');
Replace
'entry'=>'\x27\x27(?=.*\x27\x27)', 'exit'=>'\x27\x27',
with
'entry'=>'\x27\x27\x27\x27(?=.*\x27\x27\x27\x27)', 'exit'=>'\x27\x27\x27\x27',
Replace
$this->Lexer->addEntryPattern('\n {2,}[\-\*]',$mode,'listblock'); $this->Lexer->addEntryPattern('\n\t{1,}[\-\*]',$mode,'listblock'); $this->Lexer->addPattern('\n {2,}[\-\*]','listblock'); $this->Lexer->addPattern('\n\t{1,}[\-\*]','listblock');
with
$this->Lexer->addEntryPattern('\n {2,}[\-\*]',$mode,'listblock'); $this->Lexer->addEntryPattern('\n\t{1,}[\-\*]',$mode,'listblock'); $this->Lexer->addEntryPattern('\n%\* {2,}[\-\*]',$mode,'listblock'); $this->Lexer->addEntryPattern('\n%\*\t{1,}[\-\*]',$mode,'listblock'); $this->Lexer->addPattern('\n {2,}[\-\*]','listblock'); $this->Lexer->addPattern('\n\t{1,}[\-\*]','listblock'); $this->Lexer->addPattern('\n%\* {2,}[\-\*]','listblock'); $this->Lexer->addPattern('\n%\*\t{1,}[\-\*]','listblock');
Replace
$this->Lexer->addEntryPattern('%%(?=.*%%)',$mode,'unformattedalt');
with
$this->Lexer->addEntryPattern('%%%%(?=.*%%%%)',$mode,'unformattedalt');
Replace
$this->Lexer->addExitPattern('%%','unformattedalt');
with
$this->Lexer->addExitPattern('%%%%','unformattedalt');
Replace
$this->Lexer->addEntryPattern('\n (?![\*\-])',$mode,'preformatted'); $this->Lexer->addEntryPattern('\n\t(?![\*\-])',$mode,'preformatted');
with
$this->Lexer->addEntryPattern('\n %',$mode,'preformatted'); $this->Lexer-> addEntryPattern('\n (?![&=\$\*\-])',$mode,'preformatted'); $this->Lexer-> addEntryPattern('\n\t(?![&=\$\*\-])',$mode,'preformatted');
and in the next block replace
$this->Lexer->addPattern('\n ','preformatted'); $this->Lexer->addPattern('\n\t','preformatted');
with
$this->Lexer->addPattern('\n %','preformatted'); $this->Lexer->addPattern('\n ','preformatted'); $this->Lexer->addPattern('\n\t','preformatted');
LaTeX syntax
Teach DokuWiki to parse LaTeX character commands by putting them in the file …/conf/entities.local.conf, which you may need to create. Ours currently looks like this:
`` “ '' ” ~ \'e é \`e è \"o ö \begin{itemize}\item <ul><li> \begin{enumerate}\item <ol><li> \end{itemize} </li></ul> \end{enumerate} </li></ol> \item </li><li>
Teach DokuWiki to process font commands such as \textit and \textbf by creating a file …/lib/plugins/latex/syntax.php (you can replace “latex” with any other name), and inserting the following code:
<?php /** * LaTeX Plugin: allows parsing of some LaTeX commands * * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * @author Tevian Dray <tevian@math.oregonstate.edu> */ // must be run within Dokuwiki if(!defined('DOKU_INC')) die(); if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); require_once(DOKU_PLUGIN.'syntax.php'); /** * All DokuWiki plugins to extend the parser/rendering mechanism * need to inherit from this class */ class syntax_plugin_latex extends DokuWiki_Syntax_Plugin { /** * return some info */ function getInfo(){ return array( 'author' => 'Tevian Dray', 'email' => 'tevian@math.oregonstate.edu', 'date' => '2009-09-15', 'name' => 'LaTeX Plugin', 'desc' => 'allows parsing of some LaTeX commands', 'url' => 'none', ); } function getType(){ return 'substition'; } function getSort(){ return 500; } function connectTo($mode) { $this->Lexer->addEntryPattern('\\\\textit{',$mode,'emphasis'); $this->Lexer->addEntryPattern('{\\\\itshape',$mode,'emphasis'); $this->Lexer->addEntryPattern('\\\\textbf{',$mode,'strong'); $this->Lexer->addEntryPattern('{\\\\bfseries',$mode,'strong'); } function postConnect() { $this->Lexer->addExitPattern('}','emphasis'); $this->Lexer->addExitPattern('}','strong'); } function handle($match, $state, $pos, &$handler){ return ''; } function render($mode, &$renderer, $data) { return true; } }
That's it; you're done!
Tevian Dray, 29 September 2009 (revised 18 October 2009; footnote added 14 July 2011)