*/
// must be run within DokuWiki
if(!defined('DOKU_INC')) die();
if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
require_once DOKU_PLUGIN.'syntax.php';
require_once DOKU_INC.'inc/parser/parser.php';
require_once DOKU_INC . 'inc/parser/xhtml.php';
/**
* All DokuWiki plugins to extend the parser/rendering mechanism
* need to inherit from this class
*/
class syntax_plugin_dbtables extends DokuWiki_Syntax_Plugin {
// $options is used for rendering options
public $options=array();
function getInfo() {
return array('author' => 'Stephen C',
'email' => 'pontiac76@gmail.com',
'date' => '2010-09-29',
'name' => 'DB Tables',
'desc' => 'Draw Database Tables in a Wiki',
'url' => 'http://ginger.gotdns.com/public/wiki/download/dbtables.zip');
}
function getType() { return 'substition'; }
function getSort() { return 32; }
function connectTo($mode) {
$this->Lexer->addEntryPattern(']*>',$mode,'plugin_dbtables');
}
function postConnect() {
$this->Lexer->addExitPattern('','plugin_dbtables');
}
/**
* Handle the match
*/
function handle($match, $state, $pos, &$handler){
switch ($state) {
case DOKU_LEXER_ENTER :
return array($state, substr($match, 10, -1) );
break;
case DOKU_LEXER_MATCHED :
return array($state,$match);
break;
case DOKU_LEXER_UNMATCHED :
return array($state, $match);
break;
case DOKU_LEXER_EXIT :
return array($state, '');
break;
}
return array();
}
function render_tables($match,$mode,$data) {
// $match is the full text we're to consider
$raw=explode("\n",$match);
$CurrentTable="";
// Run through each line and decide how to render the text
foreach($raw as $rawline) {
if (trim($rawline)!=""){
// Is this row the name of a table?
if (substr($rawline,0,1)==$this->options["thead"]) {
// Yes, so draw the heading
// Remember the current table name
$CurrentTable=substr($rawline,1);
// Draw the Dokuwiki table heading
$TableData[$CurrentTable].="^$CurrentTable".substr("^^^^^^^^^^",0,$this->options["cols"])."\n";
// Draw the descriptors of each field
for($ColPos=1;$ColPos<=$this->options["cols"];$ColPos++)
$TableData[$CurrentTable].="^".$this->options["c".$ColPos]." ";
$TableData[$CurrentTable].="^\n";
} else {
// No, so draw the schema for the current table
// If we haven't seen a table name yet, skip it.
if ($CurrentTable!="") {
// Split the fields up.
$RowInfo=explode($this->options["fdelim"],$rawline);
// $RowsOut keeps track of how many entities we've sent. Add 1
$RowsOut=$this->options["cols"];
// Go through each entity and output it
foreach($RowInfo as $RowData) {
if ($RowsOut>0) {
$TableData[$CurrentTable].="|".$RowData." ";
$RowsOut=$RowsOut-1;
}
}
// Draw the tailing wiki table identifiers, including spaces
$EndOfTable=substr("| | | | | | | | | | ",0,($RowsOut+1)*3);
// SHIP IT!
$TableData[$CurrentTable].=trim($EndOfTable)."\n";
}
}
}
}
// By default, we sort the table listings.
if ($this->options["nosort"]=="")
sort($TableData);
// Start the HTML table rendering
$res="
options["twidth"]!="")
$res.=" width='".$this->options["twidth"]."'>";
else
$res.=">";
// Used to count how many tables we've sent for rendering.
$CurTablePos=0;
foreach($TableData as $TableStruct) {
// Prepare the table information
// The option to not render from Dokuwiki to HTML is available
if ($this->options["norender"]=="")
$td="".p_render($mode,p_get_instructions($TableStruct),$data)." | ";
else
$td="".$TableStruct." | ";
// Decide if we're going to draw a new HTML-table row.
if (($CurTablePos % $this->options["groups"] ) == 0) {
// If we've NOT drawn a DB-table yet, DON'T end the TR
if ($CurTablePos!=0)
$res.="\n";
// Draw the table row
$res.="\n\n";
}
// Write out the table data
$res.=$td."\n";
$CurTablePos=$CurTablePos+1;
}
// Close off the HTML-Table
$res.="
";
return $res;
}
function render($mode, &$renderer, $data) {
// This will only render in xhtml
if($mode == 'xhtml'){
list($state, $match) = $data;
switch ($state) {
// This happens when we first find the
case DOKU_LEXER_ENTER :
$parmsexp=explode(';',$match);
// Set the relevant default values
$this->options["groups"]=4; // How many HTML tables across we want to see
$this->options["cols"]=4; // How many headings for each DB field do we want?
$this->options["c1"]="Field"; // Default texts for fields
$this->options["c2"]="Type";
$this->options["c3"]="Relation";
$this->options["c4"]="Desc";
$this->options["fdelim"]=":"; // The character used to delimit what goes between fields
$this->options["thead"]="_"; // The character used to indicate the table name
// $this->options["twidth"] // Default HTML table width in HTML specifications (IE: 95% - 960px)
// $this->options["nosort"] -> Assign a value to NOT sort the tables
// $this->options["norender"] -> Assign a value to NOT render from Dokuwiki to HTML
// Prepare each option
foreach($parmsexp as $pexp) {
$p=explode("=",$pexp);
$this->options[$p[0]]=$p[1];
}
break;
// This happens each line between and
case DOKU_LEXER_UNMATCHED :
// Send to the rendering function
$renderer->doc.=$this->render_tables($match,$mode,$data);
//$renderer->doc .= $renderer->_xmlEntities($match);
break;
}
return true;
}
return false;
}
}