This plugin replaces the current dokuwiki handlers for <code> </code> & <file> </file> markup. It adds ability to recognise and render a title above the code box.
This plugin was inspired by 477 and my own curiousity to see if it was possible to override Dokuwiki's native syntax handling.
<code lang |title> some code </code>
<file |title> some text </file>
If the no title is given the plugin will render the <code> or <file> markup identically to the native dokuwiki handler.
See the page in action here
Plugin sources: zip format (4k), tar.gz format (2k) | darcs (requires darcs plugin)
Download the source to your plugin folder, lib/plugins and extract its contents. That will create a new plugin folder, lib/plugins/code, and install the plugin.
The folder will contain:
style.css styles for the new boxes and titles syntax/ syntax plugin folder syntax/code.php plugin script for <code> syntax/file.php plugin script for <file>
The plugin is now installed.
The plugin consists of three files, two (almost identical) syntax plugins files, syntax/code.php & syntax/file.php and some CSS styles, style.css.
To install, put the following PHP file in lib/plugins/code/syntax/.
lib/plugins/code/syntax/code.php
<?php /** * Code Plugin: replaces Dokuwiki's own code syntax * * Syntax: <code lang |title> * lang (optional) programming language name, is passed to geshi for code highlighting * if not provided, the plugin will attempt to derive a value from the file name * (refer $extensions in render() method) * title (optional) all text after '|' will be rendered above the main code text with a * different style. * * if no title is provided will render as native dokuwiki code syntax mode, e.g. * <pre class='code {lang}'> ... </pre> * * if title is provide will render as follows * <div class='source'> * <p>{title}</p> * <pre class='code {lang}'> ... </pre> * </div> * * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * @author Christopher Smith <chris@jalakai.co.uk> */ 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'); /** * All DokuWiki plugins to extend the parser/rendering mechanism * need to inherit from this class */ class syntax_plugin_code_code extends DokuWiki_Syntax_Plugin { var $syntax = ""; /** * return some info */ function getInfo(){ return array( 'author' => 'Christopher Smith', 'email' => 'chris@jalakai.co.uk', 'date' => '2005-08-18', 'name' => 'Code Replacement Plugin', 'desc' => 'Replacement for Dokuwiki\'s own <code> handler, adds a title to the box. Syntax: <code lang|title>, lang and title are optional. title does not support any dokuwiki markup.', 'url' => 'http://wiki.splitbrain.org/plugin:code', ); } function getType(){ return 'protected';} function getPType(){ return 'block';} // must return a number lower than returned by native 'code' mode (200) function getSort(){ return 195; } /** * Connect pattern to lexer */ function connectTo($mode) { $this->Lexer->addEntryPattern('<code(?=[^\r\n]*?\x3E.*?\x3C/code\x3E)',$mode,'plugin_code_code'); } function postConnect() { $this->Lexer->addExitPattern('\x3C/code\x3E', 'plugin_code_code'); } /** * Handle the match */ function handle($match, $state, $pos, &$handler){ switch ($state) { case DOKU_LEXER_ENTER: $this->syntax = substr($match, 1); return false; case DOKU_LEXER_UNMATCHED: // will include everything from <code ... to ... </code > // e.g. ... [lang] [|title] > [content] list($attr, $content) = preg_split('/>/u',$match,2); list($lang, $title) = preg_split('/\|/u',$attr,2); if ($this->syntax == 'code') { $lang = trim($lang); if ($lang == 'html') $lang = 'html4strict'; if (!$lang) $lang = NULL; } else { $lang = NULL; } return array($this->syntax, $lang, trim($title), $content); } return false; } /** * Create output */ function render($mode, &$renderer, $data) { if($mode == 'xhtml'){ if (count($data) == 4) { list($syntax, $lang, $title, $content) = $data; if ($title) $renderer->doc .= "<div class='$syntax'><p>".$renderer->_xmlEntities($title)."</p>"; if ($syntax == 'code') $renderer->code($content, $lang); else $renderer->file($content); if ($title) $renderer->doc .= "</div>"; } return true; } return false; } } //Setup VIM: ex: et ts=4 enc=utf-8 :
lib/plugins/code/syntax/file.php
<?php /** * File Plugin: replaces Dokuwiki's own file syntax * * Syntax: <file |title> * title (optional) all text after '|' will be rendered above the main code text with a * different style. * * if no title is provided will render as native dokuwiki code syntax mode, e.g. * <pre class='file'> ... </pre> * * if title is provide will render as follows * <div class='file'> * <p>{title}</p> * <pre class='file'> ... </pre> * </div> * * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * @author Christopher Smith <chris@jalakai.co.uk> */ 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'); /** * All DokuWiki plugins to extend the parser/rendering mechanism * need to inherit from this class */ class syntax_plugin_code_file extends DokuWiki_Syntax_Plugin { var $syntax = ""; /** * return some info */ function getInfo(){ return array( 'author' => 'Christopher Smith', 'email' => 'chris@jalakai.co.uk', 'date' => '2005-08-18', 'name' => '<file> replacement plugin', 'desc' => 'Replacement for Dokuwiki\'s own <file> handler, adds a title to the box. Syntax: <file|title>, title is optional and does not support any dokuwiki markup.', 'url' => 'http://wiki.splitbrain.org/plugin:code', ); } function getType(){ return 'protected';} function getPType(){ return 'block'; } // must return a number lower than returned by native 'file' mode (210) function getSort(){ return 194; } /** * Connect pattern to lexer */ function connectTo($mode) { $this->Lexer->addEntryPattern('<file(?=[^\r\n]*?\x3E.*?\x3C/file\x3E)',$mode,'plugin_code_file'); } function postConnect() { $this->Lexer->addExitPattern('\x3C/file\x3E', 'plugin_code_file'); } /** * Handle the match */ function handle($match, $state, $pos, &$handler){ switch ($state) { case DOKU_LEXER_ENTER: $this->syntax = substr($match, 1); return false; case DOKU_LEXER_UNMATCHED: // will include everything from <file ... to ... </file > // e.g. ... [lang] [|title] > [content] list($attr, $content) = preg_split('/>/u',$match,2); list($lang, $title) = preg_split('/\|/u',$attr,2); if ($this->syntax == 'code') { $lang = trim($lang); if ($lang == 'html') $lang = 'html4strict'; if (!$lang) $lang = NULL; } else { $lang = NULL; } return array($this->syntax, $lang, trim($title), $content); } return false; } /** * Create output */ function render($mode, &$renderer, $data) { if($mode == 'xhtml'){ if (count($data) == 4) { list($syntax, $lang, $title, $content) = $data; if ($title) $renderer->doc .= "<div class='$syntax'><p>".$renderer->_xmlEntities($title)."</p>"; if ($syntax == 'code') $renderer->code($content, $lang); else $renderer->file($content); if ($title) $renderer->doc .= "</div>"; } return true; } return false; } } //Setup VIM: ex: et ts=4 enc=utf-8 :
These may be modified to suit your own requirements.
style.css
/* * code plugin extension - style additions * * @author Christopher Smith chris@jalakai.co.uk * @link http://wiki.jalakai.co.uk/dokuwiki/doku.php/tutorials/codeplugin */ /* layout */ div.code, div.file { width: 92%; margin: 1em auto; border: 1px solid; padding: 4px; } div.code p, div.file p { font-size: 90%; margin: 0; padding: 2px; } div.code pre.code, div.file pre.file { margin: 4px 0 0 0; } /* colours */ div.code { border-color: #bbd; background: #e4ecf8; } div.code p { background: #cad0ee; } div.file { border-color: #dbb; background: #f8ece4; } div.file p { background: #eed0ca; } div.file pre.file { background: #fdf4ec; border-color: #dbb; } /* end code plugin style additions */
< & ><code> within <file> and vice versa. Downloadable plugin package released.<file>" syntax.
</file> nested within <code> ... </code> and </code> nested within <file> ... </file>
— FIXED
What would be nice is if it automatically generates a title based on the language attribute set if no title is explicitly set. — ta' lajzar 2005-07-30 05:06
Your example syntax to make it work is not entirely the same as the syntax that does make it work. - Monjo
Square brackets ("[]") removed from syntax. — Christopher Smith 2005/08/19 22:30