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