>>
* width width of the box, must include unit (one of "%", "px", "em" or "ex")
* styles one or more classes used to style the box, several predefined styles included in style.css
* title (optional) all text between '|' and ':::' will be rendered above the main code text with a
* different style.
* caption (optional) all text between ':::' and '>>>' will be rendered above the main code text with a
* different style.
*
* NB: To omit the title, drop it and it's preceding '|'
* To omit the caption, drop it and it's preceding ':::'
* To omit styles, drop the first ':::' and all preceding it
* You can have an empty style section and title: <<< | title ::: content >>>
* EG1: <<< contents >>>
* EG2: <<< round red ::: contents >>>
* EG3: <<< {media_link} ::: From left to right: Person 1, Person 2, Person 3 >>>
*
* Acknowledgments:
* Rounded corners based on snazzy borders by Stu Nicholls (http://www.cssplay.co.uk/boxes/snazzy)
* which is in turn based on nifty corners by Alessandro Fulciniti (http://pro.html.it/esempio/nifty/)
*
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
* @author Christopher Smith
* @modified Robert Meerman
*/
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_box extends DokuWiki_Syntax_Plugin {
var $title_mode = false;
var $caption_mode = false;
/**
* return some info
*/
function getInfo(){
return array(
'author' => 'Christopher Smith',
'email' => 'chris@jalakai.co.uk',
'date' => '2005-10-25',
'name' => 'Box Plugin',
'desc' => 'Boxes with titles, colour and rounded corners.
Syntax:
<<< ... >>>
or <<< style1..styleN ::: ... >>>
or <<< style1..styleN | title ::: ... >>>
or <<< ... ::: caption >>>
or combination of above.
Styles to try: round, square, orange, green, blue and red.',
'url' => 'http://www.dokuwiki.org/plugin:boxes_mod',
);
}
function getType(){ return 'container';}
function getAllowedTypes() { return array('container','substition','protected','disabled','formatting','paragraphs'); }
function getPType(){ return 'normal';}
// must return a number lower than returned by native 'code' mode (200)
function getSort(){ return 195; }
/**
* Connect pattern to lexer
*
* Avoid matching the title (if present) so its markup can be parsed normally
*/
function connectTo($mode) {
$this->Lexer->addEntryPattern('<<<[^:\|\r\n]*?\|(?=.*?>>>)',$mode,'plugin_box'); // Styled & Titled
$this->Lexer->addEntryPattern('<<<[^:\|\r\n]*?:::(?=.*?>>>)',$mode,'plugin_box'); // Styled only
$this->Lexer->addEntryPattern('<<<(?=.*?>>>)',$mode,'plugin_box'); // Plain (default)
}
function postConnect() {
$this->Lexer->addPattern(':::', 'plugin_box'); // Begin caption (a title/style ":::" is consumed by addEntryPattern)
$this->Lexer->addExitPattern(':::[^\r\n]*?>>>', 'plugin_box'); // Captioned
$this->Lexer->addExitPattern('>>>', 'plugin_box'); // Plain
}
/**
* Handle the match
*/
function handle($match, $state, $pos, &$handler){
switch ($state) {
// addEntryPattern matched
case DOKU_LEXER_ENTER:
// Expect either plain "<<<" or "<<< style1 ... styleN |"
$data = $this->_boxstyle(trim(substr($match, 3, -1)));
if (substr($match, -1) == '|') {
$this->title_mode = true;
return array('title_open',$data);
} else {
return array('box_open',$data);
}
// addPattern matched
case DOKU_LEXER_MATCHED:
if ($this->title_mode) {
// End title mode and open content box
$this->title_mode = false;
return array('box_open','');
} else {
// begin caption mode and open caption
$this->caption_mode = true;
return array('caption_open', '');
}
case DOKU_LEXER_UNMATCHED:
return array('data', $match);
// addExitPattern matched
case DOKU_LEXER_EXIT:
return array('box_close', $match);
}
return false;
}
/**
* Create output
*/
function render($mode, &$renderer, $indata) {
list($instr, $data) = $indata;
if($mode == 'xhtml'){
switch ($instr) {
case 'title_open' :
$this->title_mode = true;
$renderer->doc .= "
\n".$this->_xhtml_boxopen($data)."";
break;
case 'box_open' :
if ($this->title_mode) {
$this->title_mode = false;
$renderer->doc .= "
\n";
} else {
$renderer->doc .= "
\n".$this->_xhtml_boxopen($data)."
";
}
break;
case 'data' :
$renderer->doc .= $renderer->_xmlEntities($data);
break;
case 'caption_open' :
$this->caption_mode = true;
$renderer->doc .= "
\n"; // First close content div
$renderer->doc .= "
"; // Then open caption
break;
case 'box_close' :
if($this->caption_mode){
// Close caption div
$renderer->doc .= "
\n";
} else {
// Close content div
$renderer->doc .= "
\n";
}
$renderer->doc .= $this->_xhtml_boxclose()."";
break;
}
return true;
}
return false;
}
function _boxstyle($str) {
if (!strlen($str)) return array();
$styles = array();
$tokens = preg_split('/\s+/', $str, 9); // limit is defensive
foreach ($tokens as $token) {
if (preg_match('/^\d+(%|px|em|ex)$/', $token)) {
$styles['width'] = $token;
continue;
}
$styles['class'] = (isset($styles['class']) ? $styles['class'].' ' : '').$token;
}
return $styles;
}
function _xhtml_boxopen($style) {
$class = "class='box" . (isset($style['class']) ? ' '.$style['class'] : '') . "'";
$style = isset($style['width']) ? " style='width: {$style['width']};'" : '';
$html = "
\n";
$html .="
\n";
$html .="
\n";
return $html;
}
function _xhtml_boxclose() {
$html = "
\n";
$html .= "
\n";
$html .= "
\n";
return $html;
}
}
//Setup VIM: ex: et ts=4 enc=utf-8 :