*/ if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); require_once(DOKU_INC.'inc/parserutils.php'); require_once(DOKU_PLUGIN.'syntax.php'); /** * All DokuWiki plugins to extend the parser/rendering mechanism * need to inherit from this class */ class syntax_plugin_hidden extends DokuWiki_Syntax_Plugin { function getType(){ return 'container'; } function getPType(){ return 'stack'; } function getAllowedTypes() { return array('container', 'baseonly', 'substition','protected','disabled','formatting','paragraphs'); } function getSort(){ //make sure it's greater than hiddenSwitch plugin's one in order to avoid a confusion between "Lexer->addEntryPattern('(?=.*?)', $mode,'plugin_hidden'); $this->Lexer->addSpecialPattern(']*>', $mode,'plugin_hidden'); } function postConnect() { $this->Lexer->addExitPattern('','plugin_hidden'); } function handle($match, $state, $pos, Doku_Handler $handler) { switch ($state) { case DOKU_LEXER_SPECIAL: //hiddenSwitch $return = array('text' => $this->getLang('switch.default'), 'type' => 'switch'); $match = trim(utf8_substr($match, 14, -1)); //14 = strlen(" 'true', 'element'=>Array(), 'onHidden'=>'', 'onVisible'=>'', 'initialState'=>'hidden', 'state'=>$state, 'printHead' => true, 'bytepos_start' => $pos, 'edit' => false, 'editText' => $this->getLang('edit'), 'onExportPdf' => '' ); $match = substr($match, 7, -1); //7 = strlen(" 1 ){ $return['editText'] = end($found); } $return['edit'] = true; $match = str_replace($found[0], '', $match); } //Looking if this block is active preg_match("/active *= *\"([^\"]*)\" ?/i", $match, $active); if( count($active) != 0 ){ $match = str_replace($active[0], '', $match); $active = strtolower(trim($active[1])); if($active=='false' || $active=='f' || $active=='0' || $active=='n'){ $return['active'] = false; } } //Looking for the element(s) of the block (ie: which switches may activate this element) preg_match("/element *= *\"([^\"]*)\" ?/i", $match, $element); if( count($element) != 0 ){ $match = str_replace($element[0], '', $match); $element[1] = htmlspecialchars($element[1]); $return['element'] = explode(' ', $element[1]); } //Looking for the texts to display $this->_grepOption($return, 'onHidden', $match); $this->_grepOption($return, 'onVisible', $match); $this->_grepOption($return, 'onExportPdf', $match); //If there were neither onHidden nor onVisible, take what's left if( $return['onHidden']=='' && $return['onVisible']=='' ){ $text = trim($match); if($text != ''){ $return['onHidden'] = $text; $return['onVisible'] = $text; } else { //if there's nothing left, take the default texts $return['onHidden'] = $this->getConf('default_text_when_hidden'); $return['onVisible'] = $this->getConf('default_text_when_displayed'); } } else { //if one string is specified but not the other, take the defaul text $return['onHidden'] = ($return['onHidden']!='') ? $return['onHidden'] : $this->getConf('default_text_when_hidden'); $return['onVisible'] = ($return['onVisible']!='') ? $return['onVisible'] : $this->getConf('default_text_when_displayed'); } //If we don't have an exportPdf text, take the onVisible one, since the block will be exported unfolded if ( $return['onExportPdf'] == '' ){ $return['onExportPdf'] = $return['onVisible']; } //for security $return['onHidden'] = htmlspecialchars($return['onHidden']); $return['onVisible'] = htmlspecialchars($return['onVisible']); $return['onExportPdf'] = htmlspecialchars($return['onExportPdf']); //FIXME: is it always the kind of escpaing we want? return $return; case DOKU_LEXER_UNMATCHED : return array('state'=>$state, 'text'=>$match); default: return array('state'=>$state, 'bytepos_end' => $pos + strlen($match)); } } // handle() private function _grepOption(&$options, $tag, &$match){ preg_match("/$tag *= *\"([^\"]*)\" ?/i", $match, $text); if ( count($text) != 0 ){ $match = str_replace($text[0], '', $match); $options[$tag] = $text[1]; } } function render($mode, Doku_Renderer $renderer, $data) { if ( $this->_exportingPDF() ){ $data['onVisible'] = $data['onExportPdf']; } if($mode == 'xhtml' && $data['type'] == 'switch') { $renderer->doc .= ''; return true; } if($mode == 'xhtml'){ switch ($data['state']) { case DOKU_LEXER_ENTER : $this->editableBlocks[] = $data['edit']; $classEdit = ($data['edit'] ? $renderer->startSectionEdit($data['bytepos_start'], 'section', $data['editText']) : ''); $tab = array(); $onVisible = p_render('xhtml', p_get_instructions($data['onVisible']), $tab); $onHidden = p_render('xhtml', p_get_instructions($data['onHidden']), $tab); // "\n" are inside tags to avoid whitespaces in the DOM with FF $renderer->doc .= '
'; $renderer->doc .= '
'; foreach($data['element'] as $element){ $renderer->doc .= ' '.$element; } $renderer->doc .= "
"; $renderer->doc .= '
'; $renderer->doc .= '
'.$onHidden."
"; //text displayed when hidden $renderer->doc .= '
'.$onVisible."
"; //text displayed when expanded $renderer->doc .= '
'; $renderer->doc .= '
'; break; case DOKU_LEXER_UNMATCHED : $text = $renderer->_xmlEntities($data['text']); if ( preg_match("/^[ \t]*={2,}[^\n]+={2,}[ \t]*$/", $text, $match) ){ $title = trim($match[0]); $level = 7 - strspn($title,'='); if($level < 1) $level = 1; $title = trim($title,'='); $title = trim($title); $renderer->header($title, $level, 0); } else { $renderer->doc .= $text; } break; case DOKU_LEXER_EXIT : $renderer->doc .= "
"; //close hiddenBody and hiddenGlobal if ( array_pop($this->editableBlocks) ){ $renderer->finishSectionEdit($data['bytepos_end']); } break; } return true; } if ($mode == 'odt') { if ($data['state'] == DOKU_LEXER_UNMATCHED && $data['type'] != 'switch') { $renderer->doc .= $renderer->_xmlEntities($data['text']); } return true; } return false; } // render() private function _exportingPDF(){ global $ACT; return ($ACT == 'export_pdf' || $ACT == 'export_pdfbook' || $ACT == 'export_odt'); } var $editableBlocks = array(); } // class syntax_plugin_nspages