dokuwiki-source-plugin

Subversion Repositories:
Compare Path: Rev
With Path: Rev
?path1? @ HEAD  →  ?path2? @ 1
/syntax.php
@@ -25,22 +25,22 @@
* @author Christopher Smith <chris@jalakai.co.uk>
*/
if(!defined('DOKU_INC')) die(); // no Dokuwiki, no go
 
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_source extends DokuWiki_Syntax_Plugin {
 
//------------------- [ Security settings ] ---------------------------------------------
var $location = ''; // prepended to all file names, restricting the filespace exposed to the plugin
var $allow = array(); // if not empty, ONLY files with the extensions listed will be allowed
var $deny = array(); // if $allow array is empty, any file with an extension listed in $deny array will be denied
var $rules = array(); // more complex allow/deny rules, refer documentation
 
//------------------------[ Other settings ] ---------------------------------------------
var $extensions = array(
'htm' => 'html4strict',
@@ -47,7 +47,7 @@
'html' => 'html4strict',
'js' => 'javascript'
);
 
/**
* return some info
*/
@@ -62,11 +62,11 @@
'url' => 'http://www.dokuwiki.org/plugin:source',
);
}
 
function getType() { return 'substition'; }
function getPType() { return 'block'; }
function getSort() { return 330; }
 
/**
* Connect pattern to lexer
*/
@@ -73,20 +73,20 @@
function connectTo($mode) {
$this->Lexer->addSpecialPattern('<source.*?>',$mode,substr(get_class($this), 7));
}
 
/**
* Handle the match
*/
function handle($match, $state, $pos, Doku_Handler $handler){
function handle($match, $state, $pos, &$handler){
$match = trim(substr($match,7,-1)); //strip <source from start and > from end
 
// ['|"]?<filename>[\1] [#<line#>-<line#>] <lang> | <title>
list($attr, $title) = preg_split('/\|/u', $match, 2); //split out title
 
$attr = trim($attr);
$pattern = ($attr[0] == '"' || $attr[0] == "'") ? $attr[0] : '\s';
$pattern = ($attr{0} == '"' || $attr{0} == "'") ? $attr{0} : '\s';
list($file, $prop) = preg_split("/$pattern/u", $attr, 3, PREG_SPLIT_NO_EMPTY);
 
if (isset($prop) && trim($prop)) {
$matches = array();
if (preg_match('/\s*(?:(?:#(\d+)-(\d+))\s*)?(\w+)?/',$prop,$matches)) {
@@ -96,20 +96,20 @@
} else {
$start = $end = $lang = '';
}
 
return array(trim($file), $lang, (isset($title)?trim($title):''), $start, $end);
}
 
/**
* Create output
*/
function render($format, Doku_Renderer $renderer, $data) {
function render($format, &$renderer, $data) {
 
$this->_loadSettings();
 
list($file, $lang, $title, $start, $end) = $data;
$ext = substr(strrchr($file, '.'),1);
 
$ok = false;
if (count($this->allow)) {
if (in_array($ext, $this->allow)) $ok = true;
@@ -116,21 +116,21 @@
} else {
if (!in_array($ext, $this->deny)) $ok = true;
}
 
// prevent filenames which attempt to move up directory tree by using ".."
if ($ok && $this->location && preg_match('/(?:^|\/)\.\.(?:\/|$)/', $file)) $ok = false;
if ($ok && $this->rules) $ok = $this->_checkRules($file);
 
if (!$lang) { $lang = isset($this->extensions[$ext]) ? $this->extensions[$ext] : $ext; }
 
switch ($format) {
case 'xhtml' :
 
if ($ok && ($source = $this->_getSource($file,$start,$end))) {
 
$title = ($title) ? "<span>".hsc($title)."</span>"
: $this->_makeTitle($file, $start, $end);
 
$renderer->doc .= "<div class='source'><p>$title</p>";
$renderer->code($source, $lang);
$renderer->doc .= "</div>";
@@ -139,33 +139,33 @@
$renderer->doc .= '<div class="source"><p><span>'.$error.'</span></p></div>';
}
break;
 
case 'metadata' :
if ($ok) {
$renderer->meta['relation']['haspart'][$file] = array('owner'=>$this->getPluginName());
}
break;
 
default :
if ($ok) {
$renderer->code($this->_getSource($file,$start,$end), $lang);
}
}
 
}
 
function _makeTitle($file,$start,$end) {
$lines = $start ? sprintf($this->getLang('lines'),$start,$end) : '';
$title = sprintf($this->getLang('title'),hsc($file),$lines);
 
return $title;
}
 
function _getSource($file,$start,$end) {
 
$source = @file($this->location.$file);
if (empty($source)) return '';
 
// $start is a 1 based index, need to correct to 0 based when slicing arrray
if (!empty($start)) {
$lines = count($source);
@@ -181,10 +181,10 @@
} else {
$source = join('',$source);
}
 
return $source;
}
 
function _checkRules($file) {
$permit = true;
foreach ($this->rules as $rule) {
@@ -195,41 +195,41 @@
if (preg_match($pattern,$file)) $permit = false;
}
}
 
return $permit;
}
 
function _loadSettings() {
static $loaded = false;
 
if ($loaded) return;
 
$this->location = $this->getConf('location');
 
$allow = $this->getConf('allow');
$this->allow = !empty($allow) ? explode('|',$allow) : array();
 
$deny = $this->getConf('deny');
$this->deny = !empty($deny) ? explode('|',$deny) : array();
 
$rules = $this->getConf('rules');
if (!empty($rules)) $this->_parseRules($rules);
 
$loaded = true;
}
 
function _parseRules($rules) {
$rules = explode("\n",$rules);
foreach ($rules as $rule) {
$rule = trim($rule);
if (!$rule || $rule[0] == ';') continue;
if (!$rule || $rule{0} == ';') continue;
 
$match = array();
if (!preg_match('/^(allow|deny)\s+(.+)$/i',$rule,$match)) continue;
 
$this->rules[] = array(strtolower($match[1]),$match[2]);
}
}
}
//Setup VIM: ex: et ts=4 enc=utf-8 :
 
//Setup VIM: ex: et ts=4 enc=utf-8 :