* Content of 'comma' including [[:syntax|wiki syntax]] * Content of 'separated' and here **is** //some// ''formatting'' * Content of 'list' * * * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) */ 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_simpletabs extends DokuWiki_Syntax_Plugin { var $current_tab; var $tab_area_counter; var $tab_counter; var $tabs; function __construct() { global $PARSER_MODES; $this->allowedModes = array_merge($PARSER_MODES['container'], $PARSER_MODES['formatting'], $PARSER_MODES['substition'], $PARSER_MODES['protected'], $PARSER_MODES['disabled'], $PARSER_MODES['paragraphs']); $this->tab_area_counter = 0; $this->tab_counter = 0; $this->tabs = array(); } /** * Get the type of syntax this plugin defines. */ function getType() { return 'container'; } /** * What kind of syntax do we allow (optional) */ function getAllowedTypes() { return array('container', 'formatting', 'substition', 'protected', 'disabled', 'paragraphs'); } /** getAllowedTypes() **/ /** * Define how this plugin is handled regarding paragraphs. * *

* This method is important for correct XHTML nesting. It returns * one of the following values: *

*
*
normal
The plugin can be used inside paragraphs.
*
block
Open paragraphs need to be closed before * plugin output.
*
stack
Special case: Plugin wraps other paragraphs.
*
*/ // function getPType() // { // return 'normal'; // } /** * Where to sort in? */ function getSort() { return 45; } /** * Connect lookup pattern to lexer. */ function connectTo($mode) { $this->Lexer->addEntryPattern('(?=.*?)$',$mode,'plugin_simpletabs'); $this->Lexer->addPattern('', 'plugin_simpletabs'); $this->Lexer->addPattern('', 'plugin_simpletabs'); } function postConnect() { $this->Lexer->addExitPattern('','plugin_simpletabs'); } /** * Handler to prepare matched data for the rendering process. * *

* The $aState parameter gives the type of pattern * which triggered the call to this method: *

*
*
DOKU_LEXER_ENTER
*
a pattern set by addEntryPattern()
*
DOKU_LEXER_MATCHED
*
a pattern set by addPattern()
*
DOKU_LEXER_EXIT
*
a pattern set by addExitPattern()
*
DOKU_LEXER_SPECIAL
*
a pattern set by addSpecialPattern()
*
DOKU_LEXER_UNMATCHED
*
ordinary text encountered within the plugin's syntax mode * which doesn't match any pattern.
*
* @param $aMatch String The text matched by the patterns. * @param $aState Integer The lexer state for the match. * @param $aPos Integer The character position of the matched text. * @param $aHandler Object Reference to the Doku_Handler object. * @return Integer The current lexer state for the match. * @public * @see render() * @static */ function handle($match, $state, $pos, &$handler) { switch ($state) { case DOKU_LEXER_ENTER: $this->tab_area_counter++; //cho "[DEBUG] Encountered tabbed area: " . $this->tab_area_counter . "
"; $this->current_tab = ''; $this->tab_count = 0; $this->tab_names = array(); if (preg_match('/tabs="(.+)"/', $match, $matches)) { $this->tab_names = explode(',', $matches[1]); } return array($state, array($this->tab_area_counter, $this->tab_names, $this->getConf('defaulttab'))); break; case DOKU_LEXER_MATCHED: $params = $match; if ($match == '') { $this->current_tab = ''; // close any section edit block $handler->_addCall('finishSectionEdit', array($pos - 1), $pos); // render end of tabbed area $params = array(true, $this->tab_area_counter, '', 0, false); } else { // Do we have a tab open? $close_first = false; if (!empty($this->current_tab)) { // close any section edit block $handler->_addCall('finishSectionEdit', array($pos - 1), $pos); $close_first = true; } $this->current_tab = $this->tab_names[$this->tab_count]; $this->tab_count++; $active = false; if ($this->current_tab == $this->getConf('defaulttab')) { $active = true; } // start section edit // - note the +5 is to account for the section starting "" $handler->_addCall('startSectionEdit', array(($pos + 5), 'section', $this->current_tab), $pos); $params = array($close_first, $this->tab_area_counter, $this->current_tab, $this->tab_count, $active); } return array($state, $params); break; case DOKU_LEXER_UNMATCHED: if (!empty($this->current_tab)) { // SPECIAL CASE: We have to handle headers ourselves (apparently - // having looked in several other plugins similar to this) $headerMatch = preg_grep('/([ \t]*={2,}[^\n]+={2,}[ \t]*(?=))/msSi', array($match)); // - not a header, just pass it through if (empty($headerMatch)) { //$handler->_addCall('cdata', array($match), $pos); return array($state, $match); } else { // if it's a == header ==, use the core header() renderer // (copied from core header() in inc/parser/handler.php) $title = trim($match); $level = 7 - strspn($title,'='); if ($level < 1) { $level = 1; } $title = trim($title,'='); $title = trim($title); $handler->_addCall('header',array($title,$level,$pos), $pos); // close the section edit the header could open /* if ($title && $level <= $conf['maxseclevel']) { $handler->addPluginCall('wrap_closesection', array(), DOKU_LEXER_SPECIAL, $pos, ''); } */ } return false; } break; case DOKU_LEXER_EXIT: $close_first = false; if (!empty($this->current_tab)) { // close any pending section edit block $handler->_addCall('finishSectionEdit', array($pos - 1), $pos); $close_first = true; } // generate dummy heading at top level to ensure that no following headers are nested under titles in the tabbed area $handler->_addCall('header', array('#',1,$pos), $pos); return array($state, $close_first); break; case DOKU_LEXER_SPECIAL: break; } return array(); } /** * Handle the actual output creation. * *

* The method checks for the given $aFormat and returns * FALSE when a format isn't supported. $aRenderer * contains a reference to the renderer object which is currently * handling the rendering. The contents of $aData is the * return value of the handle() method. *

* @see handle() */ function render($mode, &$renderer, $data) { if($mode == 'xhtml') { list($state, $params) = $data; switch ($state) { case DOKU_LEXER_ENTER: list($tab_area_id, $tab_names, $active_tab) = $params; //cho "[DEBUG] Generating tabbed area: " . $tab_area_id . "
"; $renderer->doc .= '
'; break; case DOKU_LEXER_MATCHED: list($close_tab, $tab_area_counter, $tab_name, $tab_content_count, $active) = $params; if ($close_tab) { $renderer->doc .= '
'; } if (!empty($tab_name)) { $this->tab_content_counter++; $renderer->doc .= '
doc .= ' style="display:none;"'; } $renderer->doc .= '>'; } break; case DOKU_LEXER_UNMATCHED: $renderer->doc .= $params; break; case DOKU_LEXER_EXIT: $renderer->doc .= '
'; break; } return true; } return false; } } //Setup VIM: ex: et ts=4 enc=utf-8 : ?>