* @author Chris Smith
* @author Danny Lin
*/
// must be run within Dokuwiki
if(!defined('DOKU_INC')) die();
/**
* All DokuWiki plugins to extend the parser/rendering mechanism
* need to inherit from this class
*/
class syntax_plugin_header3 extends DokuWiki_Syntax_Plugin {
function getType() { return 'baseonly';}
function getPType() { return 'block';}
function getAllowedTypes() { return array('formatting', 'substition', 'disabled'); }
function getSort() { return 49; }
/**
* Connect pattern to lexer
*/
function connectTo($mode) {
$this->Lexer->addEntryPattern("[ \t]*={2,}(?=[^\n]+={2,}[ \t]*\n)", $mode, 'plugin_header3');
}
function postConnect() {
$this->Lexer->addExitPattern('={2,}[ \t]*(?=\n)', 'plugin_header3');
}
/**
* Handle the match
*/
function handle($match, $state, $pos, Doku_Handler $handler){
switch ($state) {
case DOKU_LEXER_ENTER :
$this->h_level = 7 - strspn($match,"=");
$this->h_pos = $pos;
if ($handler->status['section']) $handler->_addCall('section_close',array(),$pos);
$handler->addPluginCall('header3',array($state),$state,$pos,$match);
$handler->CallWriter = & new Doku_Handler_Nest($handler->CallWriter,'nest_close');
return false;
case DOKU_LEXER_UNMATCHED :
$handler->_addCall('cdata', array($match), $pos);
return false;
case DOKU_LEXER_EXIT :
$handler->_addCall('nest_close', array(), $pos);
$handler->CallWriter->process();
$handler->CallWriter = & $handler->CallWriter->CallWriter;
$handler->addPluginCall('header3',array($state,$this->h_level,$this->h_pos),$state,$pos,$match);
$handler->_addCall('section_open',array($this->h_level),$pos);
$handler->status['section'] = true;
return false;
}
return false;
}
/**
* Create output
*/
function render($format, Doku_Renderer $renderer, $data) {
list($state,$level,$pos) = $data;
switch ($state) {
case DOKU_LEXER_ENTER :
// store current parsed content
$this->store = $renderer->doc;
$renderer->doc = '';
// metadata renderer should always parse content in the header
if ($format=='metadata') {
$this->capture = $renderer->capture;
$renderer->capture = true;
}
break;
case DOKU_LEXER_EXIT :
// retrieve content parsed by nest parser (i.e. in the header)
$title = trim($renderer->doc);
$renderer->doc = $this->store;
$this->store = '';
// restore variable
if ($format=='metadata') {
$renderer->capture = $this->capture;
}
// create header
if($level < 1) $level = 1;
$method = '_' . $format . '_header';
if (method_exists($this,$method)) {
// we have special procedure for the renderer
$this->$method($title, $level, $pos, $renderer);
} else {
// fall back to default renderer behavior
$renderer->header($title,$level,$pos);
}
break;
}
return true;
}
// simple function to strip all html tags
function _remove_html_tags($text) {
return preg_replace( "#<[^>]*?>#", "" , $text);
}
/**
* Revised procedures for renderers
*
* Basically adds &$renderer argument and replaces $this to $renderer,
* and our procedures of course.
*/
function _xhtml_header($text, $level, $pos, &$renderer) {
global $conf;
$displaytext = $text; // <= added
$text = htmlspecialchars_decode($this->_remove_html_tags($text),ENT_QUOTES); // <= added
if(!$text) return; //skip empty headlines
$hid = $renderer->_headerToLink($text,true);
//only add items within configured levels
$renderer->toc_additem($hid, $text, $level);
// adjust $node to reflect hierarchy of levels
$renderer->node[$level-1]++;
if ($level < $renderer->lastlevel) {
for ($i = 0; $i < $renderer->lastlevel-$level; $i++) {
$renderer->node[$renderer->lastlevel-$i-1] = 0;
}
}
$renderer->lastlevel = $level;
if ($level <= $conf['maxseclevel'] &&
count($renderer->sectionedits) > 0 &&
$renderer->sectionedits[count($renderer->sectionedits) - 1][2] === 'section') {
$renderer->finishSectionEdit($pos - 1);
}
// write the header
$renderer->doc .= DOKU_LF.'doc .= ' class="' . $renderer->startSectionEdit($pos, 'section', $text) . '"';
}
$renderer->doc .= '>';
$renderer->doc .= $displaytext; // <= revised
$renderer->doc .= "".DOKU_LF;
}
function _odt_header($text, $level, $pos, &$renderer){
$displaytext = $text; // <= added
$text = $this->_remove_html_tags($text); // <= added
$hid = $renderer->_headerToLink($text,true);
$renderer->doc .= '';
$renderer->doc .= '';
$renderer->doc .= $displaytext; // <= revised
$renderer->doc .= '';
$renderer->doc .= '';
}
function _xml_header($text, $level, $pos, &$renderer){
if (!$text) return; //skip empty headlines
$renderer->nextHeader = ''.
$renderer->nextHeader .= $text; // <= revised
$renderer->nextHeader .= ''.DOKU_LF;
}
}