*/ if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'inc/plugins/'); require_once(DOKU_PLUGIN.'syntax.php'); // -----------------------[ docbook settings ]------------------------------------ global $xsltproc, $docbookXsl; /** * The executable for xsltproc. If a path to the executable is used, it must be absolute. */ $xsltproc = 'xsltproc'; /** * The absolute path to the XSL to apply to docbook blocks. */ $docbookXsl = '/usr/share/sgml/docbook/xsl-stylesheets-1.69.1/xhtml/docbook.xsl'; // ------------------------------------------------------------------------------------ /** * Syntax plugin for docbook support. * * The text enclosed between and tags is treated as a block of docbook text. * Docbook blocks are transformed in XHTML using XSL stylesheets to be rendered as XHTML. */ class syntax_plugin_docbook extends DokuWiki_Syntax_Plugin { /** * General Info * * Returns an associative array with some info about the plugin */ function getInfo(){ return array( 'author' => 'Daniel Calviño Sánchez', 'email' => 'danxuliu@gmail.com', 'date' => '2006-04-12', 'name' => 'Docbook Plugin', 'desc' => 'Allows Docbook markup and renders it as XHTML', 'url' => 'http://www.dokuwiki.org/plugin:docbook', ); } /** * Sets syntax type as protected. */ function getType(){ return 'protected'; } /** * Paragraph Type * * Set as 'block': Open paragraphs need to be closed before plugin output * * @see Doku_Handler_Block */ function getPType(){ return 'block'; } /** * Where to sort in? */ function getSort(){ return 200; } /** * Connect pattern to lexer */ function connectTo($mode) { $this->Lexer->addEntryPattern('',$mode,'plugin_docbook'); } function postConnect() { $this->Lexer->addExitPattern('','plugin_docbook'); } /** * Handler to prepare matched data for the rendering process * * @param $match string The text matched by the patterns * @param $state int The lexer state for the match * @param $pos int The character position of the matched text * @param $handler ref Reference to the Doku_Handler object * @return array Return an array with all data you want to use in render */ function handle($match, $state, $pos, &$handler){ switch ($state) { case DOKU_LEXER_ENTER: case DOKU_LEXER_EXIT: return array($state, ''); break; case DOKU_LEXER_UNMATCHED: return array($state, $match); break; } return array(); } /** * Handles the actual output creation. * * @param $format string output format to being Rendered * @param $renderer ref reference to the current renderer object * @param $data array data created by handler() * @return boolean rendered correctly? */ function render($mode, &$renderer, $data) { if($mode == 'xhtml'){ list($state, $match) = $data; switch ($state) { case DOKU_LEXER_ENTER : $renderer->doc .= "\n\n"; break; case DOKU_LEXER_UNMATCHED : $renderer->doc .= $this->transformDocbookInXhtml($match); break; case DOKU_LEXER_EXIT : $renderer->doc .= "\n\n"; break; } return true; } return false; } /** * Applies the stylesheet defined in settings to the docbook block to get a XHTML document, * gets body element's children removing the xmlns declaration for XHTML and returns * the resulting string. * * Uses xsltproc program executed in an external shell to do the XSL transformations. * It also creates some cache files with the docbook block and the XHTML document * made when applying the XSLT to the docbook. * * @param $docbookBlock The docbook block to be transformed * @return string The transformed XHTML code */ function transformDocbookInXhtml($docbookBlock) { global $xsltproc, $docbookXsl, $ID; $tmpDocbookFile = getCacheName('tmpDocbookFile'.$ID.$_SERVER['HTTP_HOST'].$_SERVER['SERVER_PORT'],'.docbook'); $tmpXhtmlFile = getCacheName('tmpXhtmlFile'.$ID.$_SERVER['HTTP_HOST'].$_SERVER['SERVER_PORT'],'.html'); //Docbook block must be saved so it can be transformed with xsltproc io_saveFile($tmpDocbookFile,$docbookBlock); //XHTML transformed document must also be saved because the same reason exec("$xsltproc -o $tmpXhtmlFile $docbookXsl $tmpDocbookFile 2>&1", $errors); if ($errors) { return $this->getXhtmlForXsltErrors($errors,$tmpDocbookFile); } //Gets body element's children. No errors should happen here. $returnXhtml = shell_exec("$xsltproc " . DOKU_PLUGIN . "/docbook/xhtmlCleaner.xsl $tmpXhtmlFile"); //Removes xmlns declaration for xhtml in generated elements $returnXhtml = str_replace(" xmlns=\"http://www.w3.org/1999/xhtml\"", "", $returnXhtml); return $returnXhtml; } /** * Returns an error message containing all the error lines in the errors array in a XHTML "pre" element, * on line for each array's element. The name of the temporal file being processed is replaced in the * outputted message with "docbook block". * * @param $errors An array containing the outputted error lines * @param $tmpFile The name of the temporal file that the transformation was applied to * @return string The XHTML code with the error message */ function getXhtmlForXsltErrors($errors, $tmpFile) { $returnXhtml .= '
'; $returnXhtml .= "

An error occured when transforming docbook block:

\n"; $returnXhtml .= "
";
        for ($i = 0; $i < count($errors); $i++) {
            $errors[$i] = str_replace($tmpFile,'docbook block',$errors[$i]);
            $errors[$i] = htmlentities($errors[$i],ENT_COMPAT,'UTF-8');
            $returnXhtml .= $errors[$i]."\n";
        }
        $returnXhtml .= "
\n
"; return $returnXhtml; } } //Setup VIM: ex: et ts=4 enc=utf-8 :