*/
// must be run within Dokuwiki
if (!defined('DOKU_INC')) die();
if (!defined('DOKU_LF')) define('DOKU_LF', "\n");
if (!defined('DOKU_TAB')) define('DOKU_TAB', "\t");
if (!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
require_once(DOKU_PLUGIN.'syntax.php');
class syntax_plugin_cumulus extends DokuWiki_Syntax_Plugin {
function getInfo() {
return confToHash(dirname(__FILE__).'/plugin.info.txt');
}
function getType() { return 'substition'; }
function getPType() { return 'block'; }
function getSort() { return 98; }
function connectTo($mode) {
$this->Lexer->addSpecialPattern('~~\w*?CUMULUS.*?~~',$mode,'plugin_cumulus');
}
function handle($match, $state, $pos, &$handler) {
$flags = explode('&', substr($match, 2, -2));
unset($flags[0]);
foreach ($flags as $flag) {
list($name, $value) = explode('=', $flag);
$data[strtolower(trim($name))] = trim($value);
}
return $data;
}
function render($mode, &$renderer, $data) {
if($mode != 'xhtml') return false;
// prevent caching to ensure the included pages are always fresh
$renderer->info['cache'] = false;
// flash movie options, input filtering
$options['width'] = (int)(is_numeric($data['width']) ? $data['width'] : $this->getConf('width'));
$options['height'] = (int)(is_numeric($data['height']) ? $data['height'] : $this->getConf('height'));
$options['tcolor'] = hsc(isset($data['tcolor']) ? $data['tcolor'] : $this->getConf('tcolor'));
$options['tcolor2'] = hsc(isset($data['tcolor2']) ? $data['tcolor2'] : $this->getConf('tcolor2'));
$options['hicolor'] = hsc(isset($data['hicolor']) ? $data['hicolor'] : $this->getConf('hicolor'));
$options['bgcolor'] = hsc(isset($data['bgcolor']) ? $data['bgcolor'] : $this->getConf('bgcolor'));
$options['speed'] = (int)(is_numeric($data['speed']) ? $data['speed'] : $this->getConf('speed'));
$options['distr'] = hsc(isset($data['distr']) ? $data['distr'] : $this->getConf('distr'));
$options['max'] = (int)(is_numeric($data['max']) ? $data['max'] : $this->getConf('max'));
$options['show'] = $data['show'];
if ($options['show'] == 'tag') $options['show'] = 'tags';
if ($options['show'] == 'namespace') $options['show'] = 'namespaces';
// get the tag cloud...
$tagcloud = $this->_getTagXml($options);
// add random seeds to so name and movie url to avoid collisions and force reloading (needed for IE)
$movie = 'cumulus/tagcloud.swf';
if (!file_exists(DOKU_PLUGIN.$movie)) {
$renderer->doc .= $this->getLang('filenotfound');
return true;
}
$movie = DOKU_BASE.'lib/plugins/'.$movie.'?r='.rand(0,9999999);
// write flash tag
$params = array(
'allowScriptAccess' => 'always' ,
'bgcolor' => '#'.$options['bgcolor'] ,
);
if ($this->getConf('trans')) {
$params['wmode'] = 'transparent';
}
$flashvars = array(
'tcolor' => '0x'.$options['tcolor'] ,
'tcolor2' => '0x'.($options['tcolor2'] == "" ? $options['tcolor'] : $options['tcolor2']) ,
'hicolor' => '0x'.($options['hicolor'] == "" ? $options['tcolor'] : $options['hicolor']) ,
'tspeed' => (int)$options['speed'] ,
'distr' => ($options['distr'] ? 'true' : 'false') ,
'mode' => 'tags' ,
'tagcloud' => '
Download Flash Player 9 or better for full experience.
'.DOKU_LF; $renderer->doc .= html_flashobject($movie, $options['width'], $options['height'], $params, $flashvars, null, $alt); return true; } /** * Returns links with font style attribut representing number of ocurrences * (inspired by DokuWiki Cloud plugin by Gina Häußge, Michael Klier, Esther Brunner) */ function _getTagXml($options) { global $conf; if ($options['show'] == 'tags') { // we need the tag helper plugin if (plugin_isdisabled('tag') || (!$tag = plugin_load('helper', 'tag'))) { msg('The Tag Plugin must be installed to display tag clouds.', -1); return ''; } $cloud = $this->_getTagCloud($options['max'], $min, $max, $tag); } elseif ($options['show'] == 'namespaces') { $cloud = $this->_getNamespaceCloud($options['max'], $min, $max); } else { $cloud = $this->_getWordCloud($options['max'], $min, $max); } if (!is_array($cloud) || empty($cloud)) return ''; $delta = ($max-$min)/16; if ($delta == 0) $delta = 1; foreach ($cloud as $word => $size) { if ($size < $min+round($delta)) $class = 'cloud1'; elseif ($size < $min+round(2*$delta)) $class = 'cloud2'; elseif ($size < $min+round(4*$delta)) $class = 'cloud3'; elseif ($size < $min+round(8*$delta)) $class = 'cloud4'; else $class = 'cloud5'; $name = $word; if ($options['show'] == 'tags') { $id = $word; resolve_pageID($tag->namespace, $id, $exists); if($exists) { $link = wl($id, '', true); if($conf['useheading']) { $name = p_get_first_heading($id, false); } } else { $link = wl($id, array('do'=>'showtag', 'tag'=>noNS($id)), true); } $title = $id; $class .= ($exists ? '_tag1' : '_tag2'); } elseif ($options['show'] == 'namespaces') { $id =''; resolve_pageID($word, $id, $exists); $link = wl($id, '', true); $title = $id; $size = 108; $class = 'cloud5'; } else { if($conf['userewrite'] == 2) { $link = wl($word, array('do'=>'search', 'id'=>$word), true); $title = $size; } else { $link = wl($word, 'do=search', true); $title = $size; } } $fsize = 8 + round(($size-$min)/$delta); $xmlCloude .= '' . hsc($name) . '' . DOKU_LF; } return $xmlCloude; } /** * Returns the sorted namespace cloud array */ function _getNamespaceCloud($num, &$min, &$max) { global $conf; $cloud = array(); $namesp = array(); $opts = array(); search($namesp,$conf['datadir'],'search_namespaces',$opts); foreach ($namesp as $name) { if ($name['ns'] == '') $cloud[$name['id']] = 100; } return $this->_sortCloud($cloud, $num, $min, $max); } /** * Returns the sorted word cloud array * (from DokuWiki Cloud plugin by Gina Häußge, Michael Klier, Esther Brunner) */ function _getWordCloud($num, &$min, &$max) { global $conf; // load stopwords $swfile = DOKU_INC.'inc/lang/'.$conf['lang'].'/stopwords.txt'; if (@file_exists($swfile)) $stopwords = file($swfile); else $stopwords = array(); // load extra local stopwords $swfile = DOKU_CONF.'stopwords.txt'; if (@file_exists($swfile)) $stopwords = array_merge($stopwords, file($swfile)); $cloud = array(); if (@file_exists($conf['indexdir'].'/page.idx')) { // new word-lenght based index require_once(DOKU_INC.'inc/indexer.php'); $n = 2; // minimum word length $lengths = idx_indexLengths($n); foreach ($lengths as $len) { $idx = idx_getIndex('i', $len); $word_idx = idx_getIndex('w', $len); $this->_addWordsToCloud($cloud, $idx, $word_idx, $stopwords); } } else { // old index $idx = file($conf['cachedir'].'/index.idx'); $word_idx = file($conf['cachedir'].'/word.idx'); $this->_addWordsToCloud($cloud, $idx, $word_idx, $stopwords); } return $this->_sortCloud($cloud, $num, $min, $max); } /** * Adds all words in given index as $word => $freq to $cloud array * (from DokuWiki Cloud plugin by Gina Häußge, Michael Klier, Esther Brunner) */ function _addWordsToCloud(&$cloud, $idx, $word_idx, &$stopwords) { $wcount = count($word_idx); // collect the frequency of the words for ($i = 0; $i < $wcount; $i++) { $key = trim($word_idx[$i]); if (!is_int(array_search("$key\n", $stopwords))) { $value = explode(':', $idx[$i]); if (!trim($value[0])) continue; $cloud[$key] = count($value); } } } /** * Returns the sorted tag cloud array * (from DokuWiki Cloud plugin by Gina Häußge, Michael Klier, Esther Brunner) */ function _getTagCloud($num, &$min, &$max, &$tag) { $cloud = $tag->tagOccurrences(NULL, NULL, true); return $this->_sortCloud($cloud, $num, $min, $max); } /** * Sorts and slices the cloud * (from DokuWiki Cloud plugin by Gina Häußge, Michael Klier, Esther Brunner) */ function _sortCloud($cloud, $num, &$min, &$max) { if(empty($cloud)) return; // sort by frequency, then alphabetically arsort($cloud); $cloud = array_chunk($cloud, $num, true); $max = current($cloud[0]); $min = end($cloud[0]); ksort($cloud[0]); return $cloud[0]; } } // vim:ts=4:sw=4:et:enc=utf-8: