====== color plugin ======
---- plugin ----
description: Opportunity to write colored text in Dokuwiki.
author : Christopher Smith
email : chris@jalakai.co.uk
type : Syntax
lastupdate : 2008-02-06
compatible :
depends :
conflicts :
similar :
tags : Colors
----
===== Straightforward Instructions =====
STEP ONE - upload your plugin
1. in your plugins directory, create a new plugin folder titled "color"
2. copy the PHP CODE below and name it syntax.php
3. place the syntax.php in your plugin folder titled "color"
4. upload the color/syntax.php into your plugins directory
STEP TWO - use this example
place this code sample in your playground
text
[[devel:Syntax Plugins#sample_plugin_2_-_color|Source of below syntax.php -Sample Plugin Tutorial]]
PHP CODE **syntax.php**
*/
// 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_color extends DokuWiki_Syntax_Plugin {
/**
* return some info
*/
function getInfo(){
return array(
'author' => 'Christopher Smith',
'email' => 'chris@jalakai.co.uk',
'date' => '2008-02-06',
'name' => 'Color Plugin',
'desc' => 'Changes text colour and background',
'url' => 'http://www.dokuwiki.org/plugin:tutorial',
);
}
function getType(){ return 'formatting'; }
function getAllowedTypes() { return array('formatting', 'substition', 'disabled'); }
function getSort(){ return 158; }
function connectTo($mode) { $this->Lexer->addEntryPattern('(?=.*?)',$mode,'plugin_color'); }
function postConnect() { $this->Lexer->addExitPattern('','plugin_color'); }
/**
* Handle the match
*/
function handle($match, $state, $pos, &$handler){
switch ($state) {
case DOKU_LEXER_ENTER :
list($color, $background) = preg_split("/\//u", substr($match, 6, -1), 2);
if ($color = $this->_isValid($color)) $color = "color:$color;";
if ($background = $this->_isValid($background)) $background = "background-color:$background;";
return array($state, array($color, $background));
case DOKU_LEXER_UNMATCHED : return array($state, $match);
case DOKU_LEXER_EXIT : return array($state, '');
}
return array();
}
/**
* Create output
*/
function render($mode, &$renderer, $data) {
if($mode == 'xhtml'){
list($state, $match) = $data;
switch ($state) {
case DOKU_LEXER_ENTER :
list($color, $background) = $match;
$renderer->doc .= "";
break;
case DOKU_LEXER_UNMATCHED : $renderer->doc .= $renderer->_xmlEntities($match); break;
case DOKU_LEXER_EXIT : $renderer->doc .= ""; break;
}
return true;
}
return false;
}
// validate color value $c
// this is cut price validation - only to ensure the basic format is correct and there is nothing harmful
// three basic formats "colorname", "#fff[fff]", "rgb(255[%],255[%],255[%])"
function _isValid($c) {
$c = trim($c);
$pattern = "/^\s*(
([a-zA-z]+)| #colorname - not verified
(\#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}))| #colorvalue
(rgb\(([0-9]{1,3}%?,){2}[0-9]{1,3}%?\)) #rgb triplet
)\s*$/x";
if (preg_match($pattern, $c)) return trim($c);
return "";
}
}
?>
===== Demos =====
http://dokuwiki.fr/doku.php?id=test_plugin:color
===== Discussion =====
This source for this plugin is shown in the [[devel:Syntax Plugins#sample_plugin_2_-_color|Sample Plugin Tutorial]].
===== Update History =====
* 2008-02-06 --- Fixed a security vulnerability in the colour pattern. Any users of this plugin should apply this update. --- //[[chris@jalakai.co.uk|Christopher Smith]] 2008-02-06 17:20//
===== Version with ODT renderer support =====
This modified version is no more suitable for a simple tutorial example. But I needed the ODT renderer support ;-)
--- //[[birke@d-scribe.de|Gabriel Birke]] 2008/05/09 11:46//
**''syntax.php''**
*/
// must be run within Dokuwiki
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_color extends DokuWiki_Syntax_Plugin {
var $odt_styles = array();
/**
* return some info
*/
function getInfo(){
return array(
'author' => 'Christopher Smith',
'email' => 'chris@jalakai.co.uk',
'date' => '2005-07-31',
'name' => 'Color Plugin',
'desc' => 'Changes text colour and background',
'url' => 'http://www.dokuwiki.org/plugin:tutorial',
);
}
function getType(){ return 'formatting'; }
function getAllowedTypes() { return array('formatting', 'substition', 'disabled'); }
function getSort(){ return 158; }
function connectTo($mode) { $this->Lexer->addEntryPattern('(?=.*?)',$mode,'plugin_color'); }
function postConnect() { $this->Lexer->addExitPattern('','plugin_color'); }
/**
* Handle the match
*/
function handle($match, $state, $pos, &$handler){
switch ($state) {
case DOKU_LEXER_ENTER :
list($color, $background) = preg_split("/\//u", substr($match, 6, -1), 2);
$color = $this->_isValid($color);
$background = $this->_isValid($background);
return array($state, array($color, $background));
case DOKU_LEXER_UNMATCHED : return array($state, $match);
case DOKU_LEXER_EXIT : return array($state, '');
}
return array();
}
/**
* Create output
*/
function render($mode, &$renderer, $data) {
if($mode == 'xhtml'){
list($state, $match) = $data;
switch ($state) {
case DOKU_LEXER_ENTER :
list($color, $background) = $match;
$color = $color?"color:$color;":"";
$background = $background?"background-color:$background;":"";
$renderer->doc .= "";
break;
case DOKU_LEXER_UNMATCHED : $renderer->doc .= $renderer->_xmlEntities($match); break;
case DOKU_LEXER_EXIT : $renderer->doc .= ""; break;
}
return true;
}
if($mode == 'odt'){
list($state, $match) = $data;
switch ($state) {
case DOKU_LEXER_ENTER :
list($color, $background) = $match;
$style_index = $color.'/'.$background;
if(empty($this->odt_styles[$style_index]))
{
$stylename = "ColorizedText".count($this->odt_styles);
$this->odt_styles[$style_index] = $stylename;
$color = $color?'fo:color="'.$this->_color2hex($color).'" ':'';
$background = $background?'fo:background="'.$this->_color2hex($background).'" ':'';
$renderer->autostyles[$stylename] = '
';
}
$renderer->doc .= '';
break;
case DOKU_LEXER_UNMATCHED : $renderer->doc .= $renderer->_xmlEntities($match); break;
case DOKU_LEXER_EXIT : $renderer->doc .= ""; break;
}
return true;
}
return false;
}
// validate color value $c
// this is cut price validation - only to ensure the basic format is correct and there is nothing harmful
// three basic formats "colorname", "#fff[fff]", "rgb(255[%],255[%],255[%])"
function _isValid($c) {
$c = trim($c);
$pattern = "/
([a-zA-z]+)| #colorname - not verified
(\#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}))| #colorvalue
(rgb\(([0-9]{1,3}%?,){2}[0-9]{1,3}%?\)) #rgb triplet
/x";
if (preg_match($pattern, $c)) return $c;
return "";
}
/**
* Translate color names and RGB to hex values
*/
function _color2hex($name)
{
static $colornames = null;
if(is_null($colornames))
{
include dirname(__FILE__).'/colornames.php';
}
if(!preg_match('/^(#|rgb)/', $name) && array_key_exists($name, $colornames))
return $colornames[$name];
elseif(preg_match('/rgb\(([0-9]{1,3}%?),([0-9]{1,3}%?),([0-9]{1,3}%?)\)/', $name, $matches))
{
$colors = array();
for($i=1;$i<4;$i++)
{
$percent = substr($matches[$i], -1, 1) == '%';
$colors[$i] = $percent?(substr($matches[$i],0,-1)/100)*256:$matches[$i];
}
return sprintf('#%02X%02X%02X', $colors[1], $colors[2], $colors[3]);
}
else
return $name;
}
}
//Setup VIM: ex: et ts=4 enc=utf-8 :
**''colornames.php''**
'#000000',
'navy' => '#000080',
'blue' => '#0000FF',
'green' => '#008000',
'teal' => '#008080',
'lime' => '#00FF00',
'aqua' => '#00FFFF',
'maroon' => '#800000',
'purple' => '#800080',
'olive' => '#808000',
'gray' => '#808080',
'silver' => '#C0C0C0',
'red' => '#FF0000',
'fuchsia' => '#FF00FF',
'yellow' => '#FFFF00',
'white' => '#FFFFFF',
'orange' => '#FFA500' // From CSS 2.1 spec
);