*/
// 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/');
global $conf;
if (!defined('PAPERS_DATADIR')) define('PAPERS_DATADIR', DOKU_INC . $conf['savedir'] . '/media/');
require_once (DOKU_INC . 'inc/pageutils.php');
require_once (DOKU_INC . 'inc/parserutils.php');
require_once (DOKU_PLUGIN . 'syntax.php');
require_once (DOKU_PLUGIN . 'papers/bibtex.php');
class syntax_plugin_papers extends DokuWiki_Syntax_Plugin
{
function getType() { return 'protected'; }
function getPType() { return 'block'; } // http://www.dokuwiki.org/devel:syntax_plugins#ptype
function getSort() { return 102; }
function connectTo($mode)
{
$this->Lexer->addEntryPattern('(?=.*)', $mode, 'plugin_papers');
$this->Lexer->addEntryPattern('(?=.*)', $mode, 'plugin_papers');
$this->Lexer->addEntryPattern('(?=.*)', $mode, 'plugin_papers');
}
function postConnect()
{
$this->Lexer->addExitPattern('', 'plugin_papers');
$this->Lexer->addExitPattern('', 'plugin_papers');
$this->Lexer->addExitPattern('', 'plugin_papers');
}
function handle($match, $state, $pos, &$handler)
{
static $tag;
switch ($state)
{
case DOKU_LEXER_ENTER :
preg_match('/<(\w+)>/', $match, $tmp);
$tag = $tmp[1];
unset($tmp);
return array($state, $tag, '', array());
case DOKU_LEXER_UNMATCHED :
if ($tag === 'papers' || $tag === 'grants')
{
$spec = array();
$fields = preg_split('/\s*\n\s*/u', $match);
foreach ($fields as &$f)
{
if (preg_match('/\s*(\w+?)\s*=\s*(.*)/u', $f, $m))
{
$spec[mb_strtolower($m[1])] = $m[2];
}
}
// begin: display options, not BiBTeX fields
$source = '';
if (isset($spec['source']))
{
$source = wikiFN($spec['source']);
unset($spec['source']);
}
else
{
$source = wikiFN($this->getConf($tag));
}
$options = array('byyear' => 0);
foreach(array('raw', 'byyear', 'recent') as $o)
{
if (isset($spec[$o]))
{
$options[$o] = $spec[$o];
unset($spec[$o]);
}
}
if (isset($options['recent']))
{
$options['raw'] = 1;
$options['byyear'] = 1;
}
// end: display options, not BiBTeX fields
$bibtex = (!isset($options['byyear']) || $options['byyear']) ?
new BibtexParserTeam() : new BibtexParserWorker();
$bibtex->read_file($source);
unset($source);
$bibtex->expand_years();
$bibtex->select($spec);
unset($spec);
$bibtex->sort();
return array($state, $tag, $bibtex, $options);
}
elseif ($tag === 'bibtex')
{
$bibtex = new BibtexParserTeam();
$bibtex->read_text($match);
$bibtex->expand_years();
$bibtex->select();
$bibtex->sort();
return array($state, $tag, $bibtex, array());
}
case DOKU_LEXER_EXIT :
return array($state, $tag, '', array());
}
return array();
}
function render($mode, &$renderer, $data)
{
if ($mode != 'xhtml') return false;
list($state, $tag, $bibtex, $options) = $data;
switch ($state)
{
case DOKU_LEXER_ENTER:
break;
case DOKU_LEXER_UNMATCHED:
$renderer->doc .= $this->format_bibtex($bibtex, $options);
break;
case DOKU_LEXER_EXIT:
break;
}
return true;
}
function wikirender($text)
{
return p_render('xhtml', p_get_instructions($text), $info);
}
function format_bibtex(&$bibtex, $options = array())
{
$res = '';
$year = ''; $year_prev = '';
$type = ''; $type_prev = '';
$in_list = false;
$dub = array();
$byyear = !isset($options['byyear']) || $options['byyear'];
$raw = !isset($options['raw']) || !$options['raw'];
$recent = isset($options['recent']) ? $options['recent'] : 9999999;
$count = 0;
foreach ($bibtex->SELECTION as &$entry)
{
$count++;
if ($count > $recent)
break;
if ($raw)
{
if ($byyear)
{
preg_match('/.*(\d{4})/u', $entry['year'], $matches);
$year = $matches[1];
if ($year < $this->getConf('year_min'))
break;
if ($year !== $year_prev)
{
if ($in_list)
{
$res .= "\n";
$in_list = false;
}
$year_prev = $year;
$type_prev = '';
$res .= "
$year "
. $this->getLang('year') . "
\n";
}
}
$type = $entry['entry'];
if ($type !== $type_prev)
{
if ($in_list)
{
$res .= "\n\n\n";
$in_list = false;
}
$type_prev = $type;
$res .= '' . $this->getLang($type) . "
\n";
}
}
if (!$in_list)
{
$res .= "\n";
$in_list = true;
}
/* Grants may last for several years.
* We dublicate each grant for every year it lasts.
* If we sort grants by years first, we display grant in
* each year. Otherwise we ignore dublicates.
*/
if (empty($dub[$entry['id']]) || $byyear)
{
$dub[$entry['id']] = true;
$res .= '' . $entry['html'];
$links = array();
foreach ($this->getConf('filetypes') as $type)
{
$file = $this->getConf('papers_ns') . '/' . $entry['id'] . '.' . mb_strtolower($type);
if (file_exists(PAPERS_DATADIR . $file))
{
$size = round(filesize(PAPERS_DATADIR . $file) / 1024) . ' ' . $this->getLang('KiB');
$links[] = '{{:' . preg_replace('/\//u', ':', $file) . "|$type $size}}";
}
}
if (!empty($links))
{
$link_text = $this->wikirender('(' . implode(' | ', $links) . ')');
$link_text = preg_replace('/<\/?p>/u', '', $link_text);
$link_text = preg_replace('/\s+(\d+)\s+/u', ' \1 ', $link_text);
$res .= '' . $link_text . '';
}
$res .= "
\n";
}
}
$res .= "
\n";
return $res;
}
}
// vim:ts=4:sw=4:et:enc=utf-8: