Code Replacement Plugin

code plugin by Christopher Smith
Enhancements for the normal <code> syntax

Last updated on 2005-08-18. Provides Syntax.
No compatibility info given!

Similar to cli, code2, code3, xterm.

Tagged with code, highlighting, syntax.

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.

There is another Code Plugin which adds line numbers and can highlight diff output.

Syntax

<code lang |title> some code </code>
<file |title> some text </file>

If 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

Installation

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.

Details

The plugin consists of three files, two (almost identical) syntax plugins files, syntax/code.php & syntax/file.php and some CSS styles, style.css.

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 provided will render as follows
 *   <div class='code'>
 *     <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]*?>.*?</co'.'de>)',$mode,'plugin_code_code');
    }
 
    function postConnect() {
      $this->Lexer->addExitPattern('</co'.'de>', '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 :

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]*?>.*?</file>)',$mode,'plugin_code_file');
    }
 
    function postConnect() {
      $this->Lexer->addExitPattern('</file>', '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 :

style.css

These may be modified to suit your own requirements.

/*
 * 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 */

Revision History

  • 2006-12-17 — Sync below darcs update into main package.
  • 2006-01-24 — Minor update, darcs only (package release held until after next Dokuwiki update)
    • replace hex entities in patterns with < & >
  • 2005-08-19 — Updated, split into two plugin scripts to allow nesting of <code> within <file> and vice versa. Downloadable plugin package released.
  • 2005-08-01 — Updated, adds titles to the ”<file>” syntax.
  • 2005-07-30 — Released.

To Do

Bugs

</file> nested within <code> ... </code> and </code> nested within <file> ... </file> — FIXED

Discussion

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

Modify handle() …
                if (!$lang) $lang = NULL;
// add one line
                if (!trim($title) && $lang) $title = "Language: $lang";
// end addition
            } else {

ChrisS 2005-07-31 (updated 2005-08-01)

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

Not works

Installed, but it don't works :(

Can give a little more information, a link to a page, an explanation of what you are seeing (nothing, same as ordinary <code> and <file>). Did you install from the download, from the source above? Do you have an up-to-date version of Dokuwiki. This plugin makes use of the recent addition of subfolders for syntax plugins. I am not sure that feature is included in the current production release - you need the development release. — Christopher Smith 2005-08-30 19:58


Just installed onto dokuwiki-2005-12-13. Doesn't work. :( The plugins are detected and included in the plugin list, but code nor file actually work when testing the title feature. — Skit 2005-12-16 02:49

Can you include a link to your wiki? — Christopher Smith 2005-12-17 07:44

Can you make the class search for java code search java 1.5 (or let me config what i want as 1.6 is around the corner)?

DokuWiki uses the GeSHi syntax highlighter to provide the highlighting. Refer to DokuWiki's syntax page and to GeSHi for details. — Christopher Smith 2006-10-20 12:32

Can you put a download link for every <code> or <file> ? praveen


Cool plug-in, but would be even better with line numbering.

See the other Code plugin which provides just that.
That would be great if I wanted only line numbering ;-) What I need is a 2in1 thing.
What do you mean by “2in1 thing”?
Matthias Watermann 2007-01-30 13:03
On one side I can have line numbering, and on the other one I can have titles for my code blocks, but I want both.
Am I missing something ?
For now, I stick with titles since my current code blocks are quite short and line numbers are not mandatory, but this will evolve.
The socalled “title” is just a simple paragraph (see the source above) so it's easy to write any text you wish in front of your code block – or am I missing something?
Matthias Watermann 2007-01-31 08:51
Of course, one can add a <p> block, but having the title “inside” the code block ensures it will move with the block in case of page refactoring, and there's no formatting to do…
I see – and hope you'll find the new header/footer option of the Code plugin usefull.
Matthias Watermann 2007-01-31 21:59
Maybe the discussion should take place on your plugin's page now :-) ; I'll take a look and try try it right now

I love this plugin, but I often find myself documenting console instructions, is it possible to add a <console> version of the file/code but with the <console> its black background with white writing similar to a console I guess :) just and idea or perhaps someone has all ready done this.

How about the cli plugin? cli? Just change the style sheet for the colours you want.
You might want to install the other Code Plugin which provides a console mode.
Matthias Watermann 2008/04/05 19:35

Code Plugin and ODT plugin. How can it work together? I patched my code plugin to display the code in OpenOffice. May be this is helpful for you. In the syntax.php replace the render method with this version:

 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;
      } else {
            list($syntax, $lang, $title, $content) = $data;
            $renderer->code($content, $lang);
            return true;
      }
 
      return false;
    }
Good idea. I've updated the darcs version and will release an updated package shortly. — Christopher Smith 2008/04/07 13:22
 
plugin/code.txt · Last modified: 2008/04/07 13:23 by ChrisS
 
Imprint Recent changes RSS feed Creative Commons License Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki
WikiForumIRCBugsTranslate