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