DokuWiki

It's better when it's simple

User Tools

Site Tools


plugin:highlight

Highlight Plugin

Compatible with DokuWiki

  • 2013-12-08 "Binky" yes
  • 2013-05-10 "Weatherwax" yes
  • 2012-10-13 "Adora Belle" unknown
  • 2012-01-25 "Angua" unknown

plugin Enables a simple mark-up syntax for highlighting text in various colors.

Last updated on
2013-10-24
Provides
Syntax

Similar to changemarks, emphasis, fontcolor, wrap

Tagged with highlight, marking

Recent changes

I've made security fix in function _isValid to prevent XSS vulnerability. All unrecognized as color input now is ignored. If you want to fix your installation, just apply the patch.— Alexander Sorkin aka Kibi 2009/01/22 13:01

    // old code
    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 true;
 
        return false;
    }
 
    // new code
   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";
 
        return (preg_match($pattern, $c));
 
    }

Background

Although Esther Brunner already created a highlight plugin, I felt it was limiting since it didn't allow the user to define the color of the highlighting. This plugin addresses that shortcoming and adds a nice toolbar menu to choose from various predefined colors. You can also customize the toolbar to add additional colors if you wish.

You can try out this plugin on Neal's wiki at http://www.staddle.net/wiki/plugins/highlight. He has also packaged a version for installation via the plugin manager. FIXED :-P Version for download includes all the corrections on this page - Neal 2009-11-30

Installation

  1. Install via Plugin Manager
    1. Visit Neal's site for the Plugin Manager packaged version
      FIXME This link doesn't work.
  2. Manual Installation
    1. Create a directory lib/plugins/highlight
    2. Place the PHP code below in a file called syntax.php in that directory
    3. Place the JavaScript code below in a file called script.js in that directory
    4. Create a file called toolbar_icon.png size 16×16. You can use this image (not found April 2008) – make sure to save it as toolbar_icon.png
  3. Optional Add additional colors to your conf/userscript.js file (see below for more details)
  4. Enjoy! :-)

Syntax

You surround the text that you would like to highlight with the tags <hi color> and </hi>. Here color can be any of:

  1. A three or six hexadecimal color value [ e.g. #E8E or #7fffd4 ]
  2. One of the standard color names [ e.g. white, black, aqua ]
  3. An decimal or percentage RGB color [ e.g. rgb(55%, 35%, 25%), rgb(255, 0, 255) ]
  • Note 1: If color is omitted, a default of yellow (#FF0) will be used.
  • Note 2: This follows the W3C CSS standard for colors. See: the CSS2.1 spec for more detail.

Example

<hi cyan>named cyan highlight</hi>
 \\
<hi>default highlight with **some bold** text</hi>
 \\
<hi #e0e>3-hex magenta highlight</hi>
 \\
<hi cyan>cyan with <hi pink>pink in the middle</hi> of the highlight</hi> --- doesn't work :-(
 \\
 \\
you <hi cyan>need to </hi><hi pink>do it</hi><hi cyan> this</hi> way

you <hi cyan>need to </hi><hi pink>do it</hi><hi cyan> this</hi> way

Plugin

PHP

Put this code into lib/plugins/highlight/syntax.php:

syntax.php
<?php
/**
 * Highlight Plugin: Allows user-defined colored highlighting
 *
 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
 * @author     Joseph Nahmias <joe@nahmias.net>
 * @link       http://www.dokuwiki.org/plugin:highlight
 * @version    3.1
 */
 
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_highlight extends DokuWiki_Syntax_Plugin {
 
    function getInfo(){  // return some info
        return array(
            'author' => 'Joseph Nahmias',
            'email'  => 'joe@nahmias.net',
            'date'   => '2006-09-06',
            'name'   => 'Color Highlight Plugin',
            'desc'   => 'Highlight text with a specific color
                         Syntax: <hi color>highlighted content</hi>',
            'url'    => 'http://www.dokuwiki.org/plugin:highlight',
        );
    }
 
     // What kind of syntax are we?
    function getType(){ return 'formatting'; }
 
    // What kind of syntax do we allow (optional)
    function getAllowedTypes() {
        return array('formatting', 'substition', 'disabled');
    }
 
   // What about paragraphs? (optional)
   function getPType(){ return 'normal'; }
 
    // Where to sort in?
    function getSort(){ return 90; }
 
 
    // Connect pattern to lexer
    function connectTo($mode) {
      $this->Lexer->addEntryPattern('(?i)<hi(?: .+?)?>(?=.+</hi>)',$mode,'plugin_highlight');
    }
    function postConnect() {
      $this->Lexer->addExitPattern('(?i)</hi>','plugin_highlight');
    }
 
 
    // Handle the match
    function handle($match, $state, $pos, &$handler){
        switch ($state) {
          case DOKU_LEXER_ENTER :
            preg_match("/(?i)<hi (.+?)>/", $match, $color); // get the color
            if ( $this->_isValid($color[1]) ) return array($state, $color[1]);
            break;
          case DOKU_LEXER_MATCHED :
            break;
          case DOKU_LEXER_UNMATCHED :
            return array($state, $match);
            break;
          case DOKU_LEXER_EXIT :
            break;
          case DOKU_LEXER_SPECIAL :
            break;
        }
        return array($state, "#ff0");
    }
 
    // Create output
    function render($mode, &$renderer, $data) {
        if($mode == 'xhtml'){
          list($state, $color) = $data;
          switch ($state) {
            case DOKU_LEXER_ENTER :
              $renderer->doc .= "<span style=\"background-color: $color\">";
              break;
            case DOKU_LEXER_MATCHED :
              break;
            case DOKU_LEXER_UNMATCHED :
              $renderer->doc .= $renderer->_xmlEntities($color);
              break;
            case DOKU_LEXER_EXIT :
              $renderer->doc .= "</span>";
              break;
            case DOKU_LEXER_SPECIAL :
              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";
 
        return (preg_match($pattern, $c));
 
    }
}
 
//Setup VIM: ex: et ts=4 sw=4 enc=utf-8 :

JavaScript

Put this code into lib/plugins/highlight/script.js:

script.js
/* JavaScript function to create highlight toolbar in DokuwKki */
/* see http://www.dokuwiki.org/plugin:highlight for more info */
 
var plugin_highlight_colors = {
 
  "Yellow":      "#ffff00",
  "Red":         "#ff0000",
  "Orange":      "#ffa500",
  "Salmon":      "#fa8072",
  "Pink":        "#ffc0cb",
  "Plum":        "#dda0dd",
  "Purple":      "#800080",
  "Fuchsia":     "#ff00ff",
  "Silver":      "#c0c0c0",
  "Aqua":        "#00ffff",
  "Teal":        "#008080",
  "Cornflower":  "#6495ed",
  "Sky Blue":    "#87ceeb",
  "Aquamarine":  "#7fffd4",
  "Pale Green":  "#98fb98",
  "Lime":        "#00ff00",
  "Green":       "#008000",
  "Olive":       "#808000"
 
};
 
function plugin_highlight_make_color_button(name, value) {
 
  var btn = document.createElement('button');
 
  btn.className = 'pickerbutton';
  btn.value = ' ';
  btn.title = name;
  btn.style.height = '2em';
  btn.style.padding = '1em';
  btn.style.backgroundColor = value;
 
  var open = "<hi " + value + ">";
  var close ="<\/hi>";
  var sample = name + " Highlighted Text";
  btn.onclick = function(){
    insertTags('wiki__text',open,close,sample);
    return false; };
 
  return(btn);
 
}
 
function plugin_highlight_toolbar_picker() {
 
  var toolbar = document.getElementById('tool__bar');
  if (!toolbar) return;
 
  // Create the picker button
  var p_id = 'picker_plugin_highlight'; // picker id that we're creating
  var p_ico = document.createElement('img');
  p_ico.src = DOKU_BASE + 'lib/plugins/highlight/toolbar_icon.png';
  var p_btn = document.createElement('button');
  p_btn.className = 'toolbutton';
  p_btn.title = 'Highlight Text';
  p_btn.appendChild(p_ico);
  p_btn.onclick = function() {
    showPicker(p_id,this); return false; };
 
  // Create the picker <div>
  var picker = document.createElement('div');
  picker.className = 'picker';
  picker.id = p_id;
  picker.style.position = 'absolute';
  picker.style.display = 'none';
 
  // Add a button to the picker <div> for each of the colors
  for( var color in plugin_highlight_colors ) {
    var btn = plugin_highlight_make_color_button(color,
        plugin_highlight_colors[color]);
    picker.appendChild(btn);
  }
  if (typeof user_highlight_colors != 'undefined') {
    for( var color in user_highlight_colors ) {
      var btn = plugin_highlight_make_color_button(color,
          user_highlight_colors[color]);
      picker.appendChild(btn);
    }
  }
 
  var body = document.getElementsByTagName('body')[0];
  body.appendChild(picker);     // attach the picker <div> to the page body
  toolbar.appendChild(p_btn);   // attach the picker button to the toolbar
}
addInitEvent(plugin_highlight_toolbar_picker);
 
//Setup VIM: ex: et ts=2 sw=2 enc=utf-8 :

Additional Colors

To add more colors to the toolbar picker, add the following code to the conf/userscript.js file (create it if it doesn't exist already):

// Additional user-defined highlighting colors
var user_highlight_colors = {
  "Indian Red":  "#cd5c5c",
  "Khaki":       "#f0e68c",
  "Powder Blue": "#b0e0e6",
  "Sandy Brown": "#f4a460",
  "Steel Blue":  "#4682b4",
  "Thistle":     "#d8bfd8",
  "Yellow Green":"#9acd32",
  "Dark Violet": "#9400d3",
  "Maroon":      "#800000"
};

For additional colors (with names) check out the page at: W3Schools.

Changelog

  • Version 3.1: Fix bug in IE when no user-defined colors exists; thanks Neal! — Joseph Nahmias 2006-09-06 15:39
  • Version 3.0: Added support for user-defined colors — Joseph Nahmias 2006-09-06 00:40
  • Version 2.2: Changed script.js to not use a data: URL (No IE support), added Raw 3
  • Version 2.1: Changed toolbar icon to use a data: URL for ease of installation
  • Version 2.0: Added javascript toolbar picker
  • Version 1.0: Added highlight syntax code

TODO

  • Figure out how users can add colors to the toolbar in conf/userscript.js
  • Done?! :-)

Bugs

  • You can't nest highlights (anyone know how to fix this? — I thought making the second glob greedy would help, but it doesn't :-() FIXME.

Discussion

  • NOTE: Please email me if you change the page; for some reason I can't subscribe to changes…
  • I have modified your plugin to change only the colour of the font (not the background). I didn't want to use inline HTML because it conflicts with many other plugins (notes, styler, draw, etc.).
    • Here's the modified plugins/colour/syntax.php
<?php
/**
 * Highlight Plugin: Allows user-defined colored highlighting
 *
 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
 * @author     Joseph Nahmias <joe@nahmias.net>
 */
 
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_colour extends DokuWiki_Syntax_Plugin {
 
    /**
     * return some info
     */
    function getInfo(){
        return array(
            'author' => 'Joseph Nahmias',
            'email'  => 'joe@nahmias.net',
            'date'   => '2006-07-27',
            'name'   => 'Colour Plugin',
            'desc'   => 'Colour text with a specific color. Modified by alex@seidlitz.ca',
            'url'    => 'http://www.dokuwiki.org/plugin:highlight',
        );
    }
 
    /**
     * What kind of syntax are we?
     */
    function getType(){
        return 'formatting';
    }
 
    /**
     * What kind of syntax do we allow (optional)
     */
    function getAllowedTypes() {
        return array('formatting', 'substition', 'disabled');
    }
 
    /**
     * What about paragraphs? (optional)
     */
   function getPType(){
       return 'normal';
   }
 
    /**
     * Where to sort in?
     */
    function getSort(){
        return 90;
    }
 
 
    /**
     * Connect pattern to lexer
     */
    function connectTo($mode) {
      $this->Lexer->addEntryPattern('(?i)<col(?: .+?)?>(?=.+</col>)',$mode,'plugin_colour');
    }
 
    function postConnect() {
      $this->Lexer->addExitPattern('(?i)</col>','plugin_colour');
    }
 
 
    /**
     * Handle the match
     */
    function handle($match, $state, $pos, &$handler){
        switch ($state) {
          case DOKU_LEXER_ENTER :
            preg_match("/(?i)<col (.+?)>/", $match, $color); // get the color
            if ( $this->_isValid($color[1]) ) return array($state, $color[1]);
            break;
          case DOKU_LEXER_MATCHED :
            break;
          case DOKU_LEXER_UNMATCHED :
            return array($state, $match);
            break;
          case DOKU_LEXER_EXIT :
            break;
          case DOKU_LEXER_SPECIAL :
            break;
        }
        return array($state, "#ff0");
    }
 
    /**
     * Create output
     */
    function render($mode, &$renderer, $data) {
        if($mode == 'xhtml'){
          list($state, $color) = $data;
          switch ($state) {
            case DOKU_LEXER_ENTER :
              $renderer->doc .= "<font color=\"$color\">";
              break;
            case DOKU_LEXER_MATCHED :
              break;
            case DOKU_LEXER_UNMATCHED :
              $renderer->doc .= $renderer->_xmlEntities($color);
              break;
            case DOKU_LEXER_EXIT :
              $renderer->doc .= "</font>";
              break;
            case DOKU_LEXER_SPECIAL :
              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 true;
 
        return false;
    }
}
 
//Setup VIM: ex: et ts=4 enc=utf-8 :

…and I have updated the script.js file to correspond

  • Here's the modified plugins/colour/script.js
/* javascript function to create colour toolbar in dokuwiki */
/* see http://www.dokuwiki.org/plugin:colour for more info */
 
var plugin_colour_colors = {
 
  "Yellow":      "#ffff00",
  "Red":         "#ff0000",
  "Orange":      "#ffa500",
  "Salmon":      "#fa8072",
  "Pink":        "#ffc0cb",
  "Plum":        "#dda0dd",
  "Purple":      "#800080",
  "Fuchsia":     "#ff00ff",
  "Silver":      "#c0c0c0",
  "Aqua":        "#00ffff",
  "Teal":        "#008080",
  "Cornflower":  "#6495ed",
  "Sky Blue":    "#87ceeb",
  "Aquamarine":  "#7fffd4",
  "Pale Green":  "#98fb98",
  "Lime":        "#00ff00",
  "Green":       "#008000",
  "Olive":       "#808000"
 
};
 
function plugin_colour_make_color_button(name, value) {
 
  var btn = document.createElement('button');
 
  btn.className = 'pickerbutton';
  btn.value = ' ';
  btn.title = name;
  btn.style.height = '2em';
  btn.style.padding = '1em';
  btn.style.backgroundColor = value;
 
  var open = "<col " + value + ">";
  var close ="<\/col>";
  var sample = name + " Colour Text";
  btn.onclick = function(){
    insertTags('wiki__text',open,close,sample);
    return false; };
 
  return(btn);
 
}
 
function plugin_colour_toolbar_picker() {
 
  // Check that we are editing the page - is there a better way to do this?
  var edbtn = document.getElementById('edbtn__save');
  if (!edbtn) return;
 
  var toolbar = document.getElementById('tool__bar');
  if (!toolbar) return;
 
  // Create the picker button
  var p_id = 'picker_plugin_colour';    // picker id that we're creating
  var p_ico = document.createElement('img');
  p_ico.src = DOKU_BASE + 'lib/plugins/colour/colour_toolbar_icon.png';
  var p_btn = document.createElement('button');
  p_btn.className = 'toolbutton';
  p_btn.title = 'Colour Text';
  p_btn.appendChild(p_ico);
  p_btn.onclick = function() {
    showPicker(p_id,this); return false; };
 
  // Create the picker <div>
  var picker = document.createElement('div');
  picker.className = 'picker';
  picker.id = p_id;
  picker.style.position = 'absolute';
  picker.style.display = 'none';
 
  // Add a button to the picker <div> for each of the colors
  for( var color in plugin_colour_colors ) {
    var btn = plugin_colour_make_color_button(color,
        plugin_colour_colors[color]);
    picker.appendChild(btn);
  }
  if (typeof user_colour_colors != 'undefined') {
    for( var color in user_colour_colors ) {
      var btn = plugin_colour_make_color_button(color,
          user_colour_colors[color]);
      picker.appendChild(btn);
    }
  }
 
  var body = document.getElementsByTagName('body')[0];
  body.appendChild(picker);     // attach the picker <div> to the page body
  toolbar.appendChild(p_btn);   // attach the picker button to the toolbar
}
addInitEvent(plugin_colour_toolbar_picker);
 
//Setup VIM: ex: et ts=2 sw=2 enc=utf-8 :

…and, finally the colour_toolbar_icon.png : (oops, can't upload the file)

Toolbar button missing

Any tips on making the toolbar button show up? Everything works, except the button isn't there. Thanks. -Richard Jupp, I'm having the same problem here … any help welcome! - Kristine

Changing script.js line 60 from: p_ico.src = DOKU_BASE + 'lib/plugins/highlight/toolbar_icon.png'; to: p_ico.src = DOKU_BASE + 'lib/plugins/highlight/images/toolbar_icon.png';

And placing the image inside the images folder solved the problem.

The icon for highlighting shows in the page source when not logged in to the wiki. ADD
if (!document.getElementById('spell__action')) return;
below function plugin_highlight_toolbar_picker() {

Toolbar button isn't added to the toolbar….

Adding button to toolbar

Does anybody know which changes need to be made in order to have the button displayed in the toolbar?

Adding button to toolbar

button image is accessible but the button is not added at all at the toolbar.

Toolbar button still missing

Bump! Has anybody out there been able to fix the missing toolbar button? Since I've updated to DokuWiki 2009-12-25c the button is gone (the generated HTML isn't even showing the JavaScript to insert the button, so that's not a browser problem).

Bugfix for missing toolbar icon

Yup, after quite a lot of debugging and finally digging into the code, it's obvious that the toolbar has changed quite a bit in recent versions. After rewriting the init function like below, everything works fine in DokuWiki 2010-11-07 (“Anteater”):

(code removed, as it breaks rendering you can find a copy in the page history, if you need a fix now.)

Adding button to toolbar

I've added support for Weatherwax toolbar and made some new icons. The JavaScript code isn't very “DRY”, but works well. Jan

plugin/highlight.txt · Last modified: 2014/02/17 21:39 by hh lohmann