Ok, this is essentially "Revision 3" of this plugin.
If you installed either of the previous versions, you should remove them from your Wiki since the Syntax overlaps a LOT (4 of 5 requests). This version adds to the accepted syntax:
* ~~booknav>~~ <-- NEW
* ~~prev>ID~~
* ~~next>ID~~
* ~~up>ID~~
* ~~down>ID~~
lib/plugins/booknav/syntax.php
==========================
<?php
if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
require_once(DOKU_PLUGIN.'syntax.php');
function booknav_sort($a, $b)
{
if(strcasecmp('start', $a['id']) == 0) { echo "<!-- a['id'] is start -->\n"; return -1; }
if(strcasecmp('start', $b['id']) == 0) { echo "<!-- b['id'] is start -->\n"; return 1; }
return strcasecmp($a['id'], $b['id']);
}
/**
* All DokuWiki plugins to extend the parser/rendering mechanism
* need to inherit from this class
*/
class syntax_plugin_booknav extends DokuWiki_Syntax_Plugin {
/**
* return some info
*/
function getInfo(){
return array(
'author' => 'kite',
'email' => '<kite@puzzlers.org>',
'date' => '2007-3-27',
'name' => 'Booknav Navigation',
'desc' => 'Display Navigation Links.\nsyntax ~~booknav>prevID|upID|nextID~~ or ~~prev>ID~~ or ~~next>ID~~ . Based on Scarecrow\'s plug-in' ,
'url' => 'http://forum.dokuwiki.org/thread/483',
);
}
function getType(){ return 'substition'; }
function getPType(){ return 'block'; }
function getSort(){ return 200; }
function connectTo($mode) {
$this->Lexer->addSpecialPattern("~~booknav>[^~]*~~",$mode,'plugin_booknav'); // THIS IS THE MAGIC
$this->Lexer->addSpecialPattern("~~prev>[^~]*~~",$mode,'plugin_booknav');
$this->Lexer->addSpecialPattern("~~next>[^~]*~~",$mode,'plugin_booknav');
$this->Lexer->addSpecialPattern("~~up>[^~]*~~",$mode,'plugin_booknav');
$this->Lexer->addSpecialPattern("~~down>[^~]*~~",$mode,'plugin_booknav');
}
/**
* Handle the match
*/
function handle($match, $state, $pos, &$handler){
echo "<!-- DEBUG handle() arrow called -->\n";
if (preg_match("/~~(booknav|prev|next|up|down)>([^~]*)~~/", $match, $link)) {
return $link;
}
return array("match", "nothing", "nothing");
}
/**
* Create output
*/
function render($mode, &$renderer, $data) {
global $conf;
if($mode == 'xhtml'){
if(is_array($data)) {
// $data[0] = original markup text
// $data[1] = first regex group: booknav, prev, next, up, or down
// $data[2] = ID value of the page to be pointed to
if($data[1] <> 'booknav') {
$dir = $data[1]; // page relation
if(strlen($data[2]) < 1) { // User gave an ID?
$page = $this->_getrelativepage($data[1]); // Find a page relative to the current one
} else {
$page = $data[2]; // User supplied value
}
$image = DOKU_URL . $this->getConf("booknav_" . $dir . "_image"); // Config value
$pos = $this->getConf("booknav_" . $dir . "_pos"); // Config value
$renderer->doc .= $this->_build_reference( $dir, $pos, $page, $image);
} else {
$page_prev = $this->_getrelativepage('prev');
$page_next = $this->_getrelativepage('next');
$renderer->doc .= "\n<table class=\"plugin_booknav\"><tr>\n\t<td class=\"plugin_booknav\">";
if(strlen($page_prev) > 0) {
$renderer->doc .= $this->_build_reference( 'prev',
$this->getConf("booknav_prev_pos"),
$page_prev,
DOKU_URL . $this->getConf("booknav_prev_image"));
} else {
$renderer->doc .= "<!-- No previous peer page -->";
}
$renderer->doc .= "</td>\n\t<td class=\"plugin_booknav\">" .
$this->_build_reference( 'up',
$this->getConf("booknav_up_pos"),
$this->_getrelativepage('up'),
DOKU_URL . $this->getConf("booknav_up_image"));
$renderer->doc .= "</td>\n\t<td class=\"plugin_booknav\">";
if(strlen($page_next) > 0) {
$renderer->doc .= $this->_build_reference( 'next',
$this->getConf("booknav_next_pos"),
$page_next,
DOKU_URL . $this->getConf("booknav_next_image"));
} else {
$renderer->doc .= "<!-- No following peer page -->";
}
$renderer->doc .= "</td>\n</tr></table>\n";
}
} else {
$renderer->doc .= "<p class=\"plugin_booknav\">Bad values: " . $data . "</p>";
}
return $true;
} else {
return false;
} // if($mode == 'xhtml')
} // render($mode, &$renderer, $data)
function _build_reference( $dir, $pos, $page, $image) {
$url = wl($page); // Just a url
$link = html_wikilink($page); // Complete anchor and title
$result = "<!-- _build_reference(): \$dir=$dir | \$pos=$pos \$page=$page | \$image=$image -->\n";
switch($pos) {
case 'left':
default:
$result .= "<div class=\"plugin_booknav_" . $pos . "\">" .
"<a class=\"plugin_booknav\" href=\"$url\"><img src=\"$image\" " .
"alt=\"$data[1]\"/></a> $link</div>\n";
break;
case 'center':
$result .= "<div class=\"plugin_booknav_" . $pos . "\">" .
"<a class=\"plugin_booknav\" href=\"$url\"><img src=\"$image\" alt=\"$data[1]\"/></a><br />" .
"$link</div>\n";
break;
case 'right':
$result .= "<div class=\"plugin_booknav_" . $pos . "\">$link " .
"<a class=\"plugin_booknav\" href=\"$url\"><img src=\"$image\" alt=\"$data[1]\"/></a></div>\n";
break;
} // switch($pos)
return $result;
} // _build_reference()
function _getrelativepage($relation) {
$dir = dirname(wikiFN(getID()));
$data = array();
$ns = getNS(getID());
$current = noNS(getID());
search($data, $dir,'search_index',array('ns' => $ns));
usort($data, booknav_sort); // Just makes 'start' always the first page
$found = false;
foreach($data as $item) {
$isfile = 0 == strcmp("f", $item["type"]);
if($isfile && $found) {
// find the first file AFTER being found
$next = "$ns:" . $item["id"];
break; // we're done now
}
if(!$found) {
// Once we've found the item, ignore following values
// until we find the item, only consider files
$match = 0 == strcasecmp($item["id"], $current);
$found = ($isfile && $match); // Is this the one we want?
}
if($isfile && !$found) {
// if the one we want hasn't been found, then track the last for $prev
$prev = "$ns:" . $item["id"];
}
}
switch($relation) {
case 'up' :
$result = getNS($ns) . ':start';
break;
case 'prev':
$result = $prev;
break;
case 'next':
$result = $next;
break;
default:
$result = "ns:" . $current;
break;
}
return $result;
} // _getrelativepage()
}
?> // class syntax_plugin_booknav
==========================
lib/plugins/booknav/style.css
==========================
div.plugin_booknav_left { color:#FF0000; margin: 6px; text-align: left; }
div.plugin_booknav_right { color:#FF0000; margin: 6px; text-align: right; }
div.plugin_booknav_center { color:#FF0000; margin: 6px text-align: center; vertical-align: middle; }
a.plugin_booknav { color:#003399; text-decoration:none; }
a.plugin_booknav:hover {color:#0099FF; font-weight:bold; text-decoration:underline; }
a.plugin_booknav:visited { color:#009966; text-decoration:underline; }
table.plugin_booknav { width:100%; }
td.plugin_booknav { width:33%; }
==========================
lib/plugins/booknav/config/default.php
==========================
<?php
/*
* Default Configuration for the booknav plug-in
*/
$conf['booknav_prev_image'] = 'lib/plugins/booknav/prev.gif';
$conf['booknav_next_image'] = 'lib/plugins/booknav/next.gif';
$conf['booknav_up_image'] = 'lib/plugins/booknav/up.gif';
$conf['booknav_down_image'] = 'lib/plugins/booknav/down.gif';
$conf['booknav_prev_pos'] = 'left';
$conf['booknav_next_pos'] = 'right';
$conf['booknav_up_pos'] = 'center';
$conf['booknav_down_pos'] = 'center';
?>
==========================
lib/plugins/booknav/config/metadata.php
<?php
/**
* Configuration-manager metadata for booknav plugin
*
* @license: GPL 2 (http://www.gnu.org/licenses/gpl.html)
* @author: Kite <kite@puzzlers.org>
*/
$meta['booknav_prev_image'] = array('string');
$meta['booknav_next_image'] = array('string');
$meta['booknav_up_image'] = array('string');
$meta['booknav_down_image'] = array('string');
$meta['booknav_prev_pos'] = array('multichoice','_choices' => array('left','center','right'));
$meta['booknav_next_pos'] = array('multichoice','_choices' => array('left','center','right'));
$meta['booknav_up_pos'] = array('multichoice','_choices' => array('left','center','right'));
$meta['booknav_down_pos'] = array('multichoice','_choices' => array('left','center','right'));
?>
Of course, you still need the four arrows to match the style of your Wiki. How to use this in your wiki? I think that to be globally useful, you need to put some code in your main.php template file. For example, this code would work:
<?php if ($ACT == 'show') {
echo "<div id='booknav_plugin'>\n\t";
echo p_render('xhtml',p_get_instructions("~~booknav>~~"),$info);
echo "\n</div>\n";
} ?>
oops ... out of space. /kite