around the generated
// line. this is useful for making html of headlines and titles. as it is not too
// handy to have inside your
//
function any_wiki_tohtml ( $s, $options = array() )
{
list($tk, $tk_s) = wiki_tokenizer($s, $options);
$block = array(); // lines for current block
$line = array(); // stacked tokens for current line
$line_s = array(); // stacked texts for current line
$html = ''; // generated html
$i = 0;
$toc = false; // is there a toc or not?
do
{
$tok = $tk[$i];
switch ($tok)
{
case 'br':
$line[] = 'html';
$line_s[] = " \n";
break;
case 'html':
list($_html, $block) = _wiki_reduce_line($block, $line, $line_s);
$html .= $_html . _wiki_reduce_block($block);
if (wiki_allow_html())
{
$html .= "\n" . $tk_s[$i] . "\n";
}
else
{
$html .= ' ' . nl2br(strip_tags($tk_s[$i])) . '
';
}
$line = array();
$line_s = array();
$block = array();
break;
case 'code':
list($_html, $block) = _wiki_reduce_line($block, $line, $line_s);
$html .= $_html . _wiki_reduce_block($block);
$html .= "\n\n" . htmlspecialchars($tk_s[$i]) . " \n";
$line = array();
$line_s = array();
$block = array();
break;
case 'p':
case 'end':
list($_html, $block) = _wiki_reduce_line($block, $line, $line_s);
$html .= $_html . "\n" . _wiki_reduce_block($block);
$line = array();
$line_s = array();
$block = array();
break;
case 'newline':
list($_html, $block) = _wiki_reduce_line($block, $line, $line_s);
$html .= $_html;
$line = array();
$line_s = array();
break;
case 'toc':
$html .= '';
$line = array();
$line_s = array();
$toc = true;
break;
case 'comment':
if ($i == 0)
{
// Comment at the start of a line or in a block
$html .= '';
}
else
{
// Comment in a line
list($line, $line_s) = _wiki_shift_reduce($line, $line_s, $tok, $tk_s[$i]);
}
break;
case 'word':
case ' ':
default:
list($line, $line_s) = _wiki_shift_reduce($line, $line_s, $tok, $tk_s[$i]);
break;
}
$i++;
}
while ($tok != 'end');
// Merge 's over more than one line
$html = preg_replace("|
\n|", " \n", $html);
//PH: \-newline to "skip" newlining.
$html = preg_replace("|\\\\ |", "", $html);
if (!empty($options['target']) && $options['target'] == 'line')
{
// Strip the
tags... the user wants a single line.
$html = trim(preg_replace('||', ' ', $html));
}
else if ($toc)
{
$html = _wiki_toc($html);
}
return trim($html);
}
// Function: wiki_allow_html
// Access: EXTERNAL
// Parameters: -
// Returns: false no html allowed
// true html allowed
// Description: Check if the ACL allows html entry
//
function wiki_allow_html ( )
{
$allow = false;
if (isset($GLOBALS['any_acl']))
{
$allow = $GLOBALS['any_acl']->allowHtml();
}
return $allow;
}
// Function: wiki_filter_uri
// Access: EXTERNAL
// Parameters: $uri uri to be checked
// Returns: false when uri not allowed
// uri when allowed
// Description: Check if the ACL allows the given uri
//
function wiki_filter_uri ( $uri )
{
if (isset($GLOBALS['any_acl']))
{
$uri = $GLOBALS['any_acl']->filterUri($uri);
}
return $uri;
}
// Function: wiki_filter_attrs
// Access: EXTERNAL
// Parameters: $uri uri to be checked
// Returns: false when uri not allowed
// uri when allowed
// Description: Check if the ACL allows the given attrs.
// This function has a short whitelist of allowed attributes.
//
function wiki_filter_attrs ( $attr )
{
$as = array();
foreach ($attr as $a => $v)
{
switch ($a)
{
case 'id':
case 'name':
case 'align':
case 'valign':
case 'title':
case 'width':
case 'height':
case 'rel':
case 'alt':
case 'class':
case 'link':
case 'caption':
$as[$a] = $v;
break;
default:
if ( isset($GLOBALS['any_acl'])
&& $GLOBALS['any_acl']->allowHtml())
{
$as[$a] = $v;
}
break;
}
}
return $as;
}
// Function: _wiki_reduce_block
// Access: INTERNAL
// Parameters: $block the tokens in the block
// Returns: html fragment
// Description: Force the complete reduction of a block to html
//
function _wiki_reduce_block ( $block )
{
if (count($block) > 0)
{
list($html, $block) = _wiki_shift_reduce_block($block, array('end'), array(''));
}
else
{
$html = '';
}
return $html;
}
// Function: _wiki_shift_reduce_block
// Access: INTERNAL
// Parameters: $block the tokens in the block
// $line line tokens
// $line_s line strings
// Returns: array(html-fragment, block)
// Description: (Partially) reduces the block after encountering the given line
//
// Checks for:
// - enumerated lists
// - tables
// - blockquote
//
//
// Each block entry is as follows:
//
// ( class, depth, class-parms, line_tokens, line_strings )
//
// Where class is one of:
//
// table, ul, ol, blockquote, dl
//
// Depth is valid for:
//
// ul, ol, blockqoute
//
function _wiki_shift_reduce_block ( $block, $line, $line_s )
{
if (!empty($line))
{
if ($line[0] == '=' && @$line[1] == ' ')
{
$html = _wiki_reduce_block($block);
list($line, $line_s) = _wiki_merge($line, $line_s, 2, false, true);
$html .= "\n
" . $line_s[2] . "
\n";
return array($html, array());
}
}
$block_line = _wiki_block_line($line, $line_s);
if ($block_line[0] == 'p' || $block_line[0] == 'end')
{
$html = _wiki_reduce_block_lines($block);
if ($block_line[0] == 'p')
{
list($line, $line_s) = _wiki_merge($line, $line_s, 0, false, true);
if (!empty($line_s[0]))
{
$html .= "" . $line_s[0] . "
\n";
}
}
$block = array();
}
else
{
$block[] = $block_line;
$html = '';
}
return array($html, $block);
}
// Function: _wiki_reduce_block_lines
// Access: INTERNAL
// Parameters: $block a complete block
// Returns: html
// Description: recursively reduces a block to html
// all line level reductions have been done
// what we get is a block of lines, each preparsed.
//
function _wiki_reduce_block_lines ( &$block )
{
if (empty($block))
{
return '';
}
$len = count($block);
$class = $block[0][0];
$depth = $block[0][1];
// Collect all lines with the same class and depth
$sub_block = array();
$sub_block[] = array_shift($block);
if ($class == 'ol')
{
$alt_class = 'ul';
}
else if ($class == 'ul')
{
$alt_class = 'ol';
}
else
{
$alt_class = false;
}
while ( !empty($block)
&& $block[0][1] >= $depth
&& ( $block[0][0] == $class
|| $block[0][0] == $alt_class))
{
if ($block[0][1] > $depth || $block[0][0] != $class)
{
// this is a nested block of the same kind
// reduce this one separately and remember the html in the previous block line
$html = _wiki_reduce_block_lines($block);
if (!empty($html))
{
$sub_block[count($sub_block)-1][5] = $html;
}
}
else
{
$sub_block[] = array_shift($block);
}
}
// special handling for a table
$td = 0;
if ($class == 'table')
{
foreach ($sub_block as $sub)
{
$td = max($td, $sub[2]);
}
}
// generate the html for the captured block
$html = "<$class>\n";
$nr = 0;
foreach ($sub_block as $sub)
{
$pars = $sub[2];
$line = $sub[3];
$line_s = $sub[4];
$nested = isset($sub[5]) ? $sub[5] : '';
$nr++;
switch ($class)
{
case 'ol':
case 'ul':
list($line, $line_s) = _wiki_merge($line, $line_s, 2, false, true);
$html .= '' . trim($line_s[2]) . $nested . " \n";
break;
case 'table':
// Generate a row
$html .= _wiki_table_row($td, $line, $line_s, $pars);
break;
case 'blockquote':
if ($nr == 1)
{
$html .= '';
}
list($line, $line_s) = _wiki_merge($line, $line_s, 2, false, true);
$html .= $line_s[2] . $nested;
if ($nr != count($sub_block))
{
$html .= ' ';
}
else
{
$html .= "
\n";
}
break;
case 'dl':
// $pars is the offset of the first ' ' of the ' : ' separating the dt from the dd
list($line, $line_s) = _wiki_merge($line, $line_s, $pars+3, false, true);
// the reduced html of the dd
$dd = array_pop($line_s);
array_pop($line);
// op the ' ' ':' ' ';
array_pop($line_s);
array_pop($line);
array_pop($line_s);
array_pop($line);
array_pop($line_s);
array_pop($line);
// Reduce the dt part
list($line, $line_s) = _wiki_merge($line, $line_s, 2, false, true);
$dt = array_pop($line_s);
$html .= " $dt \n $dd \n";
break;
}
}
$html .= "\n\n";
return $html;
}
// Function: _wiki_table_row
// Access: INTERNAL
// Parameters: $table_cols nr of tds
// $line tokens in line
// $line_s text of tokens
// Returns: html for row
// Description: generates the html for a row
//
function _wiki_table_row ( $table_cols, $line, $line_s )
{
$html = "";
$len = count($line);
$td = array();
$start = 1;
$colspan= 1;
// Split the line in tds
for ($i=1;$i<$len;$i++)
{
if ($line[$i] == '||')
{
if ($line[$i-1] == '||' && $i+1 < $len)
{
$colspan++;
$start++;
}
else
{
// A td from $start to $i-1
if ($i - $start > 0)
{
$td[] = array( array_slice($line, $start, $i - $start),
array_slice($line_s, $start, $i - $start),
$colspan);
}
else
{
$td[] = array(false, false, $colspan);
}
$start = $i+1;
$colspan = 1;
}
}
}
// Generate the html per td
foreach ($td as $t)
{
$line = $t[0];
$line_s = $t[1];
if ($t[2] > 1)
{
$colspan = ' colspan="' . $t[2] . '" ';
}
else
{
$colspan = '';
}
if (!empty($line))
{
$end = "";
switch ($line[0])
{
case '>':
$html .= "\n ";
$start = 1;
break;
case '<':
$html .= "\n ";
$start = 1;
break;
case '=':
$html .= "\n ";
$start = 1;
break;
case '~':
$html .= "\n ";
$end = "";
$start = 1;
break;
default:
$html .= "\n ";
$start = 0;
break;
}
list($line, $line_s) = _wiki_merge($line, $line_s, $start, false, true);
$html .= trim($line_s[$start]) . $end;
}
else
{
$html .= "\n ";
}
}
$html .= "\n\n";
return $html;
}
// Function: _wiki_block_line
// Access: INTERNAL
// Parameters: $line line tokens
// $line_s line strings
// Returns: a block line entry
// Description: checks the line to see what kind of block line the line is
//
function _wiki_block_line ( $line, $line_s )
{
$len = count($line);
if ($len >= 2)
{
// : term : definition
if ( $line[0] == ':'
&& $line[1] == ' ')
{
// Try to find (' ', ':' , ' ');
$i = 2;
$offs = false;
while ($i < $len - 2 && $offs === false)
{
if ($line[$i] == ':' && $line[$i-1] == ' ' && $line[$i+1] == ' ')
{
$offs = $i-1;
}
$i++;
}
if ($offs !== false)
{
return array('dl', 0, $offs, $line, $line_s);
}
}
// || td || .. ||
if ($line[0] == '||' && $line[$len-1] == '||')
{
// count the number of cols
$cols = 0;
for ($i = 0; $i<$len; $i++)
{
if ($line[$i] == '||')
{
$cols++;
}
}
return array('table', 0, $cols-1, $line, $line_s);
}
// > block quoted text
if ($line[0] == '>' && $line[1] == ' ')
{
return array('blockquote', strlen($line_s[0]), 0, $line, $line_s);
}
// * unordered list
if ($line[0] == '*' && $line[1] == ' ')
{
return array('ul', 0, 0, $line, $line_s);
}
if ($line[0] == ' ' && $line[1] == '*' && $line[2] == ' ')
{
return array('ul', strlen($line_s[0]), 0, $line, $line_s);
}
// # ordered list
if ($line[0] == '#' && $line[1] == ' ')
{
return array('ol', 0, 0, $line, $line_s);
}
if ($line[0] == ' ' && $line[1] == '#' && $len > 2 && $line[2] == ' ')
{
return array('ol', strlen($line_s[0]), 0, $line, $line_s);
}
}
// Just another part of a paragraph
if ($len > 0 && $line[0] == 'end')
{
return array('end', 0, 0, $line, $line_s);
}
else
{
return array('p', 0, 0, $line, $line_s);
}
}
// Function: _wiki_reduce_line
// Access: INTERNAL
// Parameters: $block the tokens in the block
// $line the line stack
// $line_s line texts
// Returns: html fragment
// modified block
// Description: Reduce the current line and append it to the current block.
// The reduction of a single line checks for:
// - non reduced :// or mailto: urls
// - non reduced wiki words
// - headers
// - blockquote levels
// - enumerated lists
// - table rows
//
function _wiki_reduce_line ( $block, $line, $line_s )
{
// wiki words
list($line, $line_s) = _wiki_replace_wikiwords($line, $line_s);
if (count($line) == 1 && $line[0] == '-' && (strlen($line_s[0]) == 4 || strlen($line_s[0]) == 3))
{
// horiz \n----\n
$html = _wiki_reduce_block($block);
return array($html . "\n \n", array());
}
if (count($line) > 2 && $line[0] == '+' && $line[1] == ' ' && strlen($line_s[0]) <= 6)
{
// \n+++++ headline 1..6
list($line, $line_s) = _wiki_merge($line, $line_s, 2, false, true);
$html = _wiki_reduce_block($block);
$level = strlen($line_s[0]);
$html .= "\n".trim($line_s[2])." \n";
return array($html, array());
}
return _wiki_shift_reduce_block($block, $line, $line_s);
}
// Function: _wiki_shift_reduce
// Access: INTERNAL
// Parameters: $line
// $line_s
// $tok
// $tok_s
// Returns: the new line state
// Description: Shifts the given token on the stack and reduces the stack
// returning a new line state.
//
function _wiki_shift_reduce ( $line, $line_s, $tok, $tok_s )
{
switch ($tok)
{
case "u":
// "__"
$offs = _wiki_offset($line, _wiki_inline_start($tok));
if ($offs !== false)
{
list($line, $line_s) = _wiki_merge($line, $line_s, $offs+1, false, true);
array_pop($line);
$text = array_pop($line_s);
array_pop($line);
array_pop($line_s);
$line[] = 'html';
$line_s[] = _wiki_inline_html($tok, $text);
}
else
{
$line[] = $tok;
$line_s[] = $tok_s;
}
break;
case "em":
case "strong":
case "sup":
case '}}':
// "//" or "**" or "^^" or {{ }}
$offs = _wiki_offset($line, _wiki_inline_start($tok));
if ($offs !== false)
{
list($line, $line_s) = _wiki_merge($line, $line_s, $offs+1, false, true);
array_pop($line);
$text = array_pop($line_s);
array_pop($line);
array_pop($line_s);
$line[] = 'html';
$line_s[] = _wiki_inline_html($tok, $text);
}
else
{
$line[] = $tok;
$line_s[] = $tok_s;
}
break;
case '@@':
// @@---minus+++revision@@
$offs = _wiki_offset($line, '@@');
if ($offs !== false)
{
list($line, $line_s) = _wiki_reduce_revise($line, $line_s, $offs);
}
else
{
$line[] = $tok;
$line_s[] = $tok_s;
}
break;
case '##':
// ##color|text##
$offs = _wiki_offset($line, '##');
if ($offs !== false)
{
list($line, $line_s) = _wiki_reduce_colortext($line, $line_s, $offs);
}
else
{
$line[] = $tok;
$line_s[] = $tok_s;
}
break;
case ']':
// [uri descr]
$offs = _wiki_offset($line, '[');
if ($offs !== false)
{
list($line, $line_s) = _wiki_reduce_link($line, $line_s, $offs);
}
else
{
$line[] = $tok;
$line_s[] = $tok_s;
}
break;
case ']]':
// [[# anchor-name]]
// [[image image-pars]]
// [[image:image-pars]]
$offs = _wiki_offset($line, '[[');
if ($offs !== false && $line[$offs+1] == '#')
{
list($line, $line_s) = _wiki_reduce_anchor($line, $line_s, $offs);
}
else if ($offs !== false && $line[$offs+1] == 'word' && $line_s[$offs+1] == 'image')
{
list($line, $line_s) = _wiki_reduce_image($line, $line_s, $offs);
}
else #MediaWiki-style link
{
list($line, $line_s) = _wiki_reduce_freelink($line, $line_s, $offs);
}
# else
# {
# $line[] = $tok;
# $line_s[] = $tok_s;
# }
break;
case '))':
// ((name|descr))
$offs = _wiki_offset($line, '((');
if ($offs !== false)
{
list($line, $line_s) = _wiki_reduce_freelink($line, $line_s, $offs);
}
else
{
$line[] = $tok;
$line_s[] = $tok_s;
}
break;
case 'comment':
$line[] = 'html';
$line_s[] = '';
break;
default:
$line[] = $tok;
$line_s[] = $tok_s;
break;
}
return array($line, $line_s);
}
// helper for @@--- +++ @@ revision patterns
function _wiki_reduce_revise ( $line, $line_s, $offs )
{
// @@---minus+++revision@@
$len = count($line_s);
$offs = _wiki_offset($line, '@@');
if ( $offs !== false
&& $offs < $len-1
&& ($line_s[$offs+1] == '---' || $line_s[$offs+1] == '+++'))
{
if ($line_s[$offs+1] === '---')
{
$offs_del = $offs+1;
$offs_ins = $offs+2;
// Try to find the '+++'
while ($offs_ins < $len && $line_s[$offs_ins] != '+++')
{
$offs_ins++;
}
}
else
{
$offs_del = false;
$offs_ins = $offs+1;
}
if ($offs_ins < $len)
{
list($line, $line_s) = _wiki_merge($line, $line_s, $offs_ins+1, false, true);
array_pop($line);
$ins = array_pop($line_s);
// Remove the '+++'
array_pop($line);
array_pop($line_s);
}
else
{
$ins = false;
}
if ($offs_del !== false)
{
list($line, $line_s) = _wiki_merge($line, $line_s, $offs_del+1, false, true);
array_pop($line);
$del = array_pop($line_s);
// Remove the '---'
array_pop($line);
array_pop($line_s);
}
else
{
$del = false;
}
// Remove the '@@';
array_pop($line);
array_pop($line_s);
if (!empty($del))
{
$line[] = 'html';
$line_s[] = _wiki_inline_html('del', $del);
}
if (!empty($ins))
{
$line[] = 'html';
$line_s[] = _wiki_inline_html('ins', $ins);
}
}
return array($line, $line_s);
}
// helper for [[# anchor-name]]
function _wiki_reduce_anchor ( $line, $line_s, $offs )
{
// fetch the anchor name
list($line, $line_s) = _wiki_merge($line, $line_s, $offs+2, -1, false, false);
// pop the name
array_pop($line);
$name = array_pop($line_s);
// pop the #
array_pop($line);
array_pop($line_s);
$line[$offs] = 'html';
$line_s[$offs] = ' ';
return array($line, $line_s);
}
// helper for [[image path/to/image image-pars]]
function _wiki_reduce_image ( $line, $line_s, $offs )
{
// fetch the complete text
list($line, $line_s) = _wiki_merge($line, $line_s, $offs+2, -1, false, false);
// pop the image path and parameters
array_pop($line);
$text = trim(array_pop($line_s));
// pop 'image'
array_pop($line);
array_pop($line_s);
//PH: "image:..." syntax
if ($text[0] == ':') {
$text = substr($text,1);
}
// Extract the interesting parts from the image description
$pos = strpos($text, ' ');
if ($pos === false)
{
$src = $text;
$attr = array();
}
else
{
$src = substr($text, 0, $pos);
$attr = _wiki_get_attrs(substr($text, $pos+1));
}
// Remove double quotes around the uri, some people do type them...
if (strlen($src) >= 2 && $src{0} == '"' && $src{strlen($src)-1} == '"')
{
$src = substr($src, 1, -1);
}
// We have to postpone the image generation till 'showtime' because an image
// typically refers to data that is dynamic. So we just pack the image data
// in a special tag and do an expand in smarty.
if ( ( strpos($src, '://') !== false
|| strpos($src, '/') !== false
|| preg_match('/^[a-zA-Z0-9_]+\.[a-z]{3}$/', $src))
&& ( empty($attr['link'])
|| ( strpos($attr['link'], '://') !== false
&& strncasecmp($attr['link'], 'popup:', 6) != 0)))
{
if (!empty($attr['link']))
{
// Remove double quotes around the uri, some people do type them...
$link = $attr['link'];
if (strlen($link) >= 2 && $link{0} == '"' && $link{strlen($link)-1} == '"')
{
$link = substr($link, 1, -1);
}
$pre = '';
$post = ' ';
unset($attr['link']);
}
else
{
$pre = '';
$post = '';
}
$html = $pre . ' $value)
{
$html .= htmlspecialchars($label) . '="' . htmlspecialchars($value) .'" ';
}
$html .= '/>' . $post;
}
else
{
// Pack the attributes so that we can easily expand them again.
$html = '';
}
$line[$offs] = 'html';
$line_s[$offs] = $html;
return array($line, $line_s);
}
// helper for ##color| ## colored text
function _wiki_reduce_colortext ( $line, $line_s, $offs )
{
// Check for the optional description
$space = _wiki_after($line, '|', $offs);
if ($space != false)
{
// Fetch description of link
list($line, $line_s) = _wiki_merge($line, $line_s, $space+1, -1, true);
array_pop($line);
$text = trim(array_pop($line_s));
array_pop($line);
array_pop($line_s);
}
else
{
$text = false;
}
// Merge all tokens for the color
list($line, $line_s) = _wiki_merge($line, $line_s, $offs+1, -1, false);
array_pop($line);
$color = trim(array_pop($line_s));
if ( (strlen($color) == 3 || strlen($color) === 6)
&& preg_match('/^[0-9a-fA-F]+$/', $color))
{
$color = '#' . $color;
}
// pop the opening '##'
array_pop($line);
array_pop($line_s);
// Create the span
if (!empty($text))
{
$line[] = 'html';
$line_s[] = "$text ";
}
return array($line, $line_s);
}
// helper for [uri descr]
function _wiki_reduce_link ( $line, $line_s, $offs )
{
// Keep a copy of line/line_s in case we don't find an uri
$line0 = $line;
$line_s0 = $line_s;
// Check for the optional description
$space = _wiki_after($line, ' ', $offs);
if ($space != false)
{
// Fetch description of link
list($line, $line_s) = _wiki_merge($line, $line_s, $space, -1, false);
array_pop($line);
$descr = trim(array_pop($line_s));
// Try to fetch any optional attributes
list($descr, $attrs) = _wiki_split_descr_attrs($descr);
}
else
{
$descr = false;
$attrs = false;
}
// Merge all tokens for the uri
list($line, $line_s) = _wiki_merge($line, $line_s, $offs+1, -1, false, false);
array_pop($line);
$uri = array_pop($line_s);
// only accept this construct when the uri looks like an uri
$colon = strpos($uri, ':');
$dot = strpos($uri, '.');
$last = strlen($uri) - 1;
if ( strpos($uri, '/') !== false
|| strpos($uri, '#') !== false
|| ($dot !== false && $dot < $last)
|| ($colon > 0 && $colon < $last))
{
// pop the opening '['
array_pop($line);
array_pop($line_s);
// Create the link
if (empty($descr))
{
// Footnote
$html = '' . _wiki_make_link($uri, '*', '', $attrs) .' ';
}
else
{
// Described link
$html = _wiki_make_link($uri, $descr, '', $attrs);
}
$line[] = 'html';
$line_s[] = $html;
}
else
{
// No uri found, do not reduce the found [uri descr] construct
$line = $line0;
$line_s = $line_s0;
$line[] = ']';
$line_s[] = ']';
}
return array($line, $line_s);
}
// helper for ((uri|descr))
function _wiki_reduce_freelink ( $line, $line_s, $offs )
{
// Check for the optional description
$anchor = false;
$pipe = _wiki_after($line, '|', $offs);
if ($pipe != false)
{
$hash = _wiki_after($line, '#', $pipe, true);
if ($hash !== false)
{
list($line, $line_s) = _wiki_merge($line, $line_s, $hash+1, -1, false, false);
array_pop($line);
$anchor = '#' . trim(array_pop($line_s));
array_pop($line);
array_pop($line_s);
}
// Fetch description of link
list($line, $line_s) = _wiki_merge($line, $line_s, $pipe+1, -1, false);
array_pop($line);
$descr = trim(array_pop($line_s));
list($descr, $attrs) = _wiki_split_descr_attrs($descr);
array_pop($line);
array_pop($line_s);
}
else
{
$descr = false;
$attrs = false;
}
// Merge all tokens for the uri (we will need unescaped text for this one)
list($line, $line_s) = _wiki_merge($line, $line_s, $offs+1, -1, false, false);
array_pop($line);
$uri = array_pop($line_s);
// pop the opening '['
array_pop($line);
array_pop($line_s);
// Create the link
$line[] = 'html';
$line_s[] = _wiki_make_link($uri, $descr, $anchor, $attrs);
return array($line, $line_s);
}
// Function: _wiki_offset
// Access: INTERNAL
// Parameters: $stack stack with tokens
// $tok try to find this token
// $start (optional) look below this offset
// Returns: offset in stack
// false when not found
// Description: try to locate the token the stack in the stack,
// starting to search on top
//
function _wiki_offset ( $stack, $tok, $start = false )
{
if ($start === false)
{
$start = count($stack) - 1;
}
else
{
$start--;
}
// Don't scan through tds...
while ( $start >= 0
&& $stack[$start] != $tok
&& ($tok == '||' || $stack[$start] != '||'))
{
$start--;
}
if ($start < 0 || $stack[$start] != $tok)
{
$start = false;
}
return $start;
}
// Function: _wiki_after
// Access: INTERNAL
// Parameters: $line list of tokens
// $tok token to find
// $offs offset to start above
// $space (optional) set to false to disallow whitespace
// Returns: false when not found
// offset otherwise
// Description: find the given token _after_ the given offset
//
function _wiki_after ( $line, $tok, $offset, $space = true )
{
$ct = count($line);
while ( $offset < $ct && $line[$offset] != $tok
&& ($space || $line[$offset] != ' '))
{
$offset ++;
}
if ($offset == $ct || $line[$offset] != $tok)
{
return false;
}
else
{
return $offset;
}
}
// Function: _wiki_merge
// Access: INTERNAL
// Parameters: $stack the token stack
// $stack_s the texts of the stack
// $depth the offset to start the merge
// $count number of tokens to merge (-1 for all)
// $replace do some wikiword on uri replacements
// $escape (optional) set to false to not escape html specialchars
// Returns: modified token stack
// Description: merges the given entries into one textual entry
// literal and word entries will be escaped with htmlspecialchars.
//
function _wiki_merge ( $stack, $stack_s, $offset, $count, $replace, $escape = true )
{
if ($count <= 0)
{
$len = count($stack);
}
else
{
$len = min(count($stack), $offset+$count);
}
$text = '';
for ($i=$offset; $i<$len; $i++)
{
if ($replace && $stack[$i] == 'wiki-word')
{
$text .= _wiki_make_link($stack_s[$i],'');
}
else if ($stack[$i] == 'html')
{
$text .= $stack_s[$i];
}
else if ($stack[$i] == 'literal')
{
$text .= '' . htmlspecialchars($stack_s[$i]) . '';
}
else if ($replace && $stack[$i] == 'url')
{
@list($protocol, $address) = explode('://', $stack_s[$i]);
$text .= '' . htmlspecialchars($address) . " ";
}
else if ($replace && $stack[$i] == 'mailto')
{
// Add a marker to the mailto so that we can rebuild the wiki text
$text .= ''
. substr(htmlspecialchars($stack_s[$i]), 7)
. '';
}
else if ($escape)
{
$text .= htmlspecialchars($stack_s[$i]);
}
else
{
$text .= $stack_s[$i];
}
}
if ($len == count($stack))
{
array_splice($stack, $offset);
array_splice($stack_s, $offset);
}
else
{
array_splice($stack, $offset, $count);
array_splice($stack_s, $offset, $count);
}
if ($escape)
{
$stack[] = 'html';
}
else
{
$stack[] = 'text';
}
$stack_s[] = $text;
return array($stack, $stack_s);
}
// Function: _wiki_make_link
// Access: INTERNAL
// Parameters: $uri url, not escaped
// $descr description, escaped
// $anchor optional anchor ('#anchor')
// $attrs attributes ( attr="value" )
// Returns: complete anchor tag
// Description: creates the anchor tag for the given uri and descr.
// when descr is empty then the anchor tag is generated from the uri.
//
function _wiki_make_link ( $uri, $descr, $anchor = '', $attrs = array() )
{
$uri = trim($uri);
if (!empty($descr))
{
$descr = trim($descr);
}
// Remove double quotes around the uri, some people do type them...
if (strlen($uri) >= 2 && $uri{0} == '"' && $uri{strlen($uri)-1} == '"')
{
$uri = substr($uri, 1, -1);
}
$pre = '';
$post = '';
if (!empty($attrs))
{
$attrs = ' ' . implode(' ', $attrs);
}
else
{
$attrs = '';
}
// 1. Check if the uri is a complete one
if (strncasecmp($uri, 'mailto:', 7) == 0)
{
// Add a marker to the mailto so that we can rebuild the wiki text
$descr = trim($descr);
if (!empty($descr))
{
$descr = ' '.$descr;
}
$text = ''
. htmlspecialchars(substr($uri, 7)) . htmlspecialchars($descr)
. '';
// Bail out!
return $text;
}
else if ( strpos($uri, '/') === false
&& !preg_match('/^[a-zA-Z0-9_\-]+\.[a-zA-Z]{2,4}/', $uri)
&& strncasecmp($uri, 'javascript:', 11) != 0)
{
// assume symbolic name
if (empty($descr))
{
// Bail Out: Make special runtime tag, we will need the title of the thing we are linking to...
$pre = '';
$post = '';
$descr = htmlspecialchars($uri);
}
if (!empty($uri))
{
$uri = "id.php/" . str_replace(' ', '%20', $uri);
}
else if (empty($anchor))
{
$anchor = '#';
}
}
else if ( !empty($uri)
&& strpos($uri, '://') === false
&& strncasecmp($uri, 'javascript:', 11) != 0
&& preg_match('/^[a-z]+(\.[a-z]+)(\.[a-z]+)+(\/.*)?$/', $uri))
{
// Make sure we have a protocol for our link, better for tags
$uri = 'http://' . $uri;
}
// 2. Extract a description when we don't have one
if (empty($descr) && strpos($uri, '://') !== false)
{
list($protocol, $col, $descr) = explode('://', $uri);
}
if (empty($descr))
{
$descr = $uri;
}
if (isset($GLOBALS['any_acl']))
{
$uri = $GLOBALS['any_acl']->filterUri($uri);
}
return $pre . ' ' . $descr . ' ' . $post;
}
// Function: _wiki_inline_start
// Access: INTERNAL
// Parameters: $descr
// Returns: list($descr, $attrs)
// Description: splits any attr="value" attributes from the given description
// returns the descr and the list of attributes
//
function _wiki_split_descr_attrs ( $descr )
{
global $_attrs;
$_attrs = array();
$descr = preg_replace_callback('/\s([a-zA-Z]+)=("|")(.*?)("|")/', '_wiki_collect_attr', ' ' . $descr);
return array(trim($descr), $_attrs);
}
// Helper function to collect all attributes from the descr
function _wiki_collect_attr ( $match )
{
global $_attrs;
global $any_acl;
if ( $match[1] == 'target'
|| $match[1] == 'class'
|| $any_acl->allowHtml())
{
$_attrs[] = $match[1] . '="' . $match[3] . '"';
return '';
}
else
{
return $match[0];
}
}
// Function: _wiki_inline_start
// Access: INTERNAL
// Parameters: $tok
// Returns: start token for $tok
// Description: returns the start token belonging to the inline token $tok
//
function _wiki_inline_start ( $tok )
{
switch ($tok)
{
case '}}':
return '{{';
default:
break;
}
return $tok;
}
// Function: _wiki_inline_html
// Access: INTERNAL
// Parameters: $tok
// $text
// Returns: html for text
// Description: surrounds text with the correct html tags for $tok
//
function _wiki_inline_html ( $tok, $text )
{
switch ($tok)
{
case '}}':
$tag = 'tt';
break;
default:
$tag = $tok;
break;
}
return "<$tag>$text";
}
// Function: _wiki_replace_wikiwords
// Access: INTERNAL
// Parameters: $line
// $line_s
// $offset (optional) start scanning at offset
// $end (optional) stop at offset
// Returns: (line, line_s)
// Description: scans the line for WikiWords, when found then replaces them
// with HTML fragments for freelinks.
//
function _wiki_replace_wikiwords( $line, $line_s, $offset = 0, $end = false )
{
if ($end === false)
{
$end = count($line);
}
for ($i = $offset; $i< $end; $i++)
{
if ($line[$i] == 'wiki-word')
{
$line[$i] = 'html';
$line_s[$i] = _wiki_make_link($line_s[$i], '');
}
}
return array($line, $line_s);
}
// Function: _wiki_get_attrs
// Access: INTERNAL
// Parameters: $text the text containing 'attr="value"' pairs
// Returns: array with attr=>value pairs
// Description: parses the attributes of a tag
//
function _wiki_get_attrs ( $text )
{
$parts = explode('="', trim($text));
$last = count($parts) - 1;
$attrs = array();
$key = false;
foreach ($parts as $i => $val)
{
if ($i == 0)
{
$key = trim($val);
}
else
{
$pos = strrpos($val, '"');
$attrs[$key] = stripslashes(substr($val, 0, $pos));
$key = trim(substr($val, $pos+1));
}
}
return $attrs;
}
// Function: _wiki_toc
// Access: INTERNAL
// Parameters: $html html with a toc marker
// Returns: html with a table of contents
// Description: Inserts a table of contents into the html
//
function _wiki_toc ( $html )
{
global $toc_nr;
global $toc_base;
global $toc;
$pos = strpos($html, '');
if ($pos !== false)
{
$toc_base = abs(crc32(microtime(true).'-'.rand(0,100)));
$toc_nr = 0;
// 1. Find all tags for insertion in the table of contents, no h1 tags are inserted
$html = preg_replace_callback('|()(.*)( )|U', '_wiki_toc_accum', $html);
// 2. Create the table of contents at the place of the toc tag
$s = "\n\n";
foreach ($toc as $entry)
{
list($anchor, $level, $title) = $entry;
$s .= "$title \n";
}
$s .= " \n\n";
$html = str_replace('', $s, $html);
}
return $html;
}
function _wiki_toc_accum ( $ms )
{
global $toc_nr;
global $toc_base;
global $toc;
$toc_nr++;
$anchor = "$toc_base-$toc_nr";
$toc[] = array($anchor, $ms[1]{2}, $ms[2]);
return $ms[1]." ".$ms[2].$ms[3];
}
?>
uri) when input is an array
// uri when input is a single id
// Description: Translates a thing id to an absolute uri.
// Depending on the sharing status and the refering identity
// the uri will direct to either the own or the refered
// identity.
//
function any_thing_uri_abs ( $thg_id, $idn_id = null, $lang = null, $commit = null )
{
return any_thing_uri($thg_id, $idn_id, $lang, $commit, true);
}
// Function: any_thing_uri
// Access: EXTERNAL
// Parameters: $thg_id Id of thing (may be an array)
// $idn_id (optional) Identity reading the uris
// $lang (optional) The target _must_ have this language
// $commit (optional) not used (for now)
// $abs (optional,internal) Force absolute uri
// Returns: array(id => uri) when input is an array
// uri when input is a single id
// Description: Translates a thing id to an uri.
// Depending on the sharing status and the refering identity
// the uri will direct to either the own or the refered
// identity.
//
function any_thing_uri ( $thg_id, $idn_id = null, $lang = null, $commit = null, $abs = false )
{
if ($abs)
{
return 'http://' . $_SERVER['HTTP_HOST'] . "/id/" . urlencode($thg_id);
}
else
{
return 'id/' . urlencode($thg_id);
}
}
// Function: any_uri_abs
// Access: EXTERNAL
// Parameters: $uri
// Returns: uri with hostname etc.
// Description: Prepends (when needed) the given uri with a full domain name.
//
function any_uri_abs ( $uri )
{
if (strpos($uri, '://') === false)
{
$uri = 'http://' . $_SERVER['HTTP_HOST'] . '/' . ltrim($uri, '/');
}
return $uri;
}
// Function: any_symbolic2id
// Access: EXTERNAL
// Parameters: $symbolic Symbolic name to look for
// $options Options for search
// Returns: id of thing with given symbolic id
// false when no id found
// Description: return id of thing with the given symbolic name
// a thing of the internal source prevails above things
// of external sources.
// Optionally the selection is reduced to only the
// own things and/or things of a certain kind.
// When the symbolic id matches the pattern [0-9]+ then
// the symbolic id is assumed to be a real id and the id
// is returned as is.
//
function any_symbolic2id ( $symbolic, $options = array() )
{
return false;
}
// Function: any_attach_label2pred
// Access: EXTERNAL
// Parameters: label label or nr of attachment
// Returns: list(predicate, ord_nr)
// Description: translates a label or nr to the correct predicate/ order nr.
//
// A label can have the format of FIG01, FIG02, ICON or DOC01
// Or just be a number, in that case we assume that the user
// is refering to a figure.
// The first figure is nr 1. Internally we use nr 0 for the
// first figure.
//
function any_attach_label2pred ( $label )
{
if (strcasecmp($label, 'ICON') == 0)
{
$pred = 'ICON';
$nr = 1;
}
else if (strncasecmp($label, 'FIG', 3) == 0)
{
$pred = 'FIGURE';
$nr = @intval(substr($label, 3));
}
else if (strncasecmp($label, 'DOC', 3) == 0)
{
$pred = 'DOCUMENT';
$nr = @intval(substr($label, 3));
}
else
{
// Assume numeric
$pred = 'FIGURE';
$nr = @intval($label);
}
// We need an offset from 0
if ($nr > 0)
{
$nr--;
}
else
{
$nr = 0;
}
return array($pred, $nr);
}
// Function: any_attach_caption_label
// Access: EXTERNAL
// Parameters: thg_id thing id
// pred predicate (figure, icon, document)
// nr order nr of figure etc. (0..n)
// Returns: list(att_id, alt, caption)
// false when not found
// Description: tryes to find the named attachment.
// returns the found attachment id, the alt and the caption text
// does not consider _any_ access rights!
//
// In anyMeta a 'thing' can have many images attached to it.
// This images are 'things' of the kind 'attachment'.
// We identify a particular image by a predicate on the edge
// to the image and by the order nr.
//
// The alt text is typically a short title describing the image.
// The caption text could be longer and is typically shown underneath
// the image.
//
function any_attach_caption_pred ( $thg_id, $label )
{
return false;
}
// Function: any_attach_caption
// Access: EXTERNAL
// Parameters: thg_id thing id
// Returns: list(alt, caption)
// false when not found
// Description: returns the alt and the caption text of the attachment
// does not consider _any_ access rights!
//
// an attachment is an image, mainly used in the context of
// articles etc. see the function any_attach_caption_label()
// above for a short discussion about attachments.
//
function any_attach_caption ( $thg_id )
{
return false;
}
// Function: any_thing_title_short
// Access: EXTERNAL
// Parameters: $thg_id Id of the thing (may be an array, must be real id)
// $usr_id (optional) User reading the titles
// $lang (optional) Preferred language array
// Returns: array(id=>title)
// error string with error message
// Description: Reads the short titles of the given thing(s).
//
// in anyMeta every thing must have a title. it might also have a
// short title. this function returns the short title, and when
// missing it returns the (long) title.
//
function any_thing_title_short ( $thg_id, $usr_id = null, $lang = null )
{
$ts = array();
if (!is_array($thg_id))
{
foreach ($thg_id as $id)
{
$ts[$id] = 'title of ' . htmlspecialchars($id);
}
}
else
{
$ts[$thg_id] = 'title of ' . htmlspecialchars($thg_id);
}
return $ts;
}
// Function: any_text_utf8
// Access: EXTERNAL
// Parameters: $html text to check
// Returns: utf8 version of text
// Description: This checks the input string to be really utf8, replaces non utf8 characters
// with a question mark. This validity check is needed before you want to parse
// the string with any XML parser.
//
function any_text_utf8 ( $html )
{
if (function_exists('iconv'))
{
do
{
$ok = true;
$text = @iconv('UTF-8', 'UTF-8//TRANSLIT', $html);
if (strlen($text) != strlen($html))
{
// Remove the offending character...
$html = $text . '?' . substr($html, strlen($text) + 1);
$ok = false;
}
}
while (!$ok);
}
return $html;
}
// Function: any_encode_mailto
// Access: EXTERNAL
// Parameters: $href mailto link
// $text (optional) description for link
// Returns: for mailto
// Description: This generates the anchor-tag for an mailto url.
// The email address is encoded so that most web-bots won't recognise
// it as an email address.
//
function any_encode_mailto ( $href, $text = '', $encode = 'javascript' )
{
if (substr($href, 0, 7) == 'mailto:')
{
$href = substr($href, 7);
}
if (empty($text))
{
$text = $href;
}
$html = ' '
. htmlspecialchars(str_replace('@',' [at] ',$text), ENT_QUOTES)
. ' ';
if ($encode == 'javascript' )
{
// Double encode the text using javascript
//
$js = '';
for ($x=0; $x < strlen($html); $x++)
{
if (rand(0,5) == 1)
{
$js .= '\'+\'';
}
if (strchr('><\'@', $html[$x]) !== false || rand(0,2) == 1)
{
$js .= '%' . bin2hex($html[$x]);
}
else
{
$js .= $html[$x];
}
}
$html = '';
$js = '';
for ($x=0; $x < strlen($html); $x++)
{
if (strchr('><\'', $html[$x]) !== false || rand(0,2) == 1)
{
$js .= '%' . bin2hex($html[$x]);
}
else
{
$js .= $html[$x];
}
}
$html = '';
}
else
{
// Simple non-javascript version
//
$text_encode = '';
for ($x=0; $x < strlen($href); $x++)
{
$text_encode .= '&#' . ord($href[$x]) . ';';
}
$href = $text_encode;
$text_encode = '';
$text = str_replace('@', ' [at] ', $text);
for ($x=0; $x < strlen($text); $x++)
{
$text_encode .= '&#' . ord($text[$x]) . ';';
}
$text = $text_encode;
$html = "$text ";
}
return $html;
}
// Class: Anymeta_ACL
// Access: EXTERNAL
// Provides: Access control for the anymeta system
//
class Anymeta_ACL
{
function Anymeta_ACL ()
{
}
// Function: Anymeta_ACL::allowHtml
// Access: PUBLIC
// Parameters: -
// Returns: false when user is not allowed to edit html text
// true when user is allowed to edit html text
// Description: Checks if the current user is allowed to edit html.
// This is a very special right, and should be given
// with caution!
//
// This should be a right of an editor, letting normal users
// enter HTML really defies the idea of an wiki, and of the
// security of letting people enter markup text.
//
function allowHtml ()
{
return defined('ALLOWHTML');
}
// Function: Anymeta_ACL::filterUri
// Access: PUBLIC
// Parameters: uri uri to be filtered
// Returns: '' when uri was not allowed
// uri when uri was allowed
// Description: Checks the given uri with the access permissions of the user.
// The user needs text/html permissions for entering javascrpt uris.
//
function filterUri ( $uri )
{
$allow = false;
$uri = trim($uri);
$u = urldecode($uri);
if ( strpos($u, '&#') === false
&& strpos($u, '"') === false
&& strncasecmp($u, 'javascript:', 11) != 0)
{
$allow = true;
}
if (!$allow)
{
// user needs to have the right to edit HTML
$allow = $this->allowHtml();
}
return $allow ? $uri : '';
}
}
$any_acl = new Anymeta_ACL();
?> base width in pixels for images
// height base height in pixels for images
// thg_id the id of the thing the texts belong to
// (needed to find images)
//
function any_wiki_runtime ( $text, $options = array() )
{
global $_wiki_options;
$_wiki_options = $options;
// 1. Filter remainings of and html tags
$text = preg_replace('//', '', $text);
// 2. Grep all image tags and produce tags.
$text = preg_replace_callback('//', '_wiki_runtime_image', $text);
// 3. Handle the runtime replacement of links
$text = preg_replace_callback('/.+?/', '_wiki_runtime_link', $text);
// 4. Handle the runtime replacement of mailto hrefs
$text = preg_replace_callback('/([^ ]+?)( .+?)?/', '_wiki_runtime_mailto', $text);
if (!empty($options['abs_uri']))
{
// 5. Make the id.php/xxxx uris absolute
$text = preg_replace_callback('||', '_wiki_runtime_anchor_abs_uri', $text);
}
return $text;
}
// Function: any_wiki_runtime_image_labels
// Access: EXTERNAL
// Parameters: $text the text to be expanded
// Returns: array with image indices used
// Description: Fetch all image nrs used in the given text.
// Does recognise the 'FIGxx' format for labels.
// Does also handle numerical references correctly
//
function any_wiki_runtime_image_labels ( $text )
{
$image = array();
if (preg_match_all('//', $text, $ms, PREG_PATTERN_ORDER))
{
foreach ($ms[1] as $m)
{
if (strncasecmp($m, 'FIG', 3) == 0)
{
$image[] = @intval(substr($m,3)) - 1;
}
else if (is_numeric($m) && $m < 100)
{
$image[] = intval($m) - 1;
}
}
sort($image);
}
return $image;
}
// Function: _wiki_runtime_link
// Access: INTERNAL
// Parameters: $matches pattern match of the tag
// Returns: tag
// Description: runtime produces the tag with the correct title.
//
function _wiki_runtime_link ( $matches )
{
global $_wiki_options;
$page = $matches[1];
$abs_uri = !empty($_wiki_options['abs_uri']);
$attr = '';
$ct = count($matches);
for ($i=2; $i<$ct; $i+=3)
{
$attr .= ' ' . $matches[$i];
}
@list($page, $anchor) = explode('#', $page);
if (strncasecmp($page, 'uri:', 4) == 0)
{
$page = substr($page, 4);
}
else if ( strpos($page, '://') === false
&& strpos($page, '/' ) === false)
{
// try to translate the given name to an anymeta id
$thg_id = any_symbolic2id($page);
}
if (!empty($thg_id))
{
// It is an anymeta id, use the anymeta routines to generate the link
$text = any_thing_title_short($thg_id);
if (is_array($text))
{
$text = reset($text);
}
if (empty($text))
{
$text = $page;
}
// Fetch the uri, prefered from the pre-fetched uris in the template
if ($abs_uri)
{
$href = any_thing_uri_abs($thg_id);
}
else
{
$href = any_thing_uri($thg_id);
}
// Add the anchor
if (!empty($anchor))
{
$href .= "#$anchor";
}
$html = ' ' . htmlspecialchars($text) . ' ';
}
else if (strpos($page, '://') !== false)
{
$n = strpos($page, '://');
$text = substr($page, $n+3);
$html = "".htmlspecialchars($text)." ";
}
else
{
// the page does not exist, show the page name and
// the "new page" text
$page = htmlspecialchars($page);
$url = 'id.php/'.urlencode($page);
if ($abs_uri)
{
$url = any_uri_abs($url);
}
$html = "$page ";
}
return $html;
}
// Function: _wiki_runtime_anchor_abs_uri
// Access: INTERNAL
// Parameters: $matches pattern of the tag
// Returns: modified tag
// Description: makes the enclose uri absolute
//
function _wiki_runtime_anchor_abs_uri ( $matches )
{
return ' ';
}
// Function: _wiki_runtime_mailto
// Access: INTERNAL
// Parameters: $matches pattern match of the tag
// Returns: tag
// Description: runtime produces the tag with the correct title.
//
function _wiki_runtime_mailto ( $matches )
{
global $_wiki_options;
if (empty($_wiki_options['nojavascript']))
{
$encode = 'javascript';
}
else
{
$encode = 'entities';
}
return any_encode_mailto($matches[1], @trim($matches[2]), $encode);
}
// Function: _wiki_runtime_image
// Access: INTERNAL
// Parameters: $matches pattern match of the tag
// Returns: tag
// Description: runtime produce the tag for the given image description
//
function _wiki_runtime_image ( $matches )
{
global $_wiki_options;
$attr = array();
$src = $matches[1];
$ct = count($matches);
for ($i=2; $i<$ct; $i+=3)
{
$attr[trim($matches[$i+1])] = $matches[$i+2];
}
$base_thg_id = !empty($_wiki_options['thg_id']) ? $_wiki_options['thg_id'] : false;
$base_width = !empty($_wiki_options['width']) ? $_wiki_options['width'] : 400;
$base_height = !empty($_wiki_options['height']) ? $_wiki_options['height'] : 400;
$abs_uri = !empty($_wiki_options['abs_uri']) ? $_wiki_options['abs_uri'] : false;
// Fetch the requested width and height
if (!empty($attr['width']))
{
$width = _wiki_runtime_img_size($attr['width'], $base_width);
}
else
{
$width = round($base_width);
}
if (!empty($attr['height']))
{
$height = _wiki_runtime_img_size($attr['height'], $base_height);
}
else
{
$height = round($base_height);
}
if (substr($src, 0, 1) == '"' && substr($src, -1) == '"')
{
$src = substr($src, 1, -1);
}
$src = trim($src);
// See where we have to fetch the image from
if (!empty($src))
{
if (strpos($src, 'uri:') === 0)
{
// direct uri
$src = substr($src, 4);
$id = false;
}
else if (strpos($src, '://') === false)
{
if (strpos($src, ':') !== false)
{
list($a, $b) = explode(':', $src);
if (empty($b))
{
$thg_id = $a;
$lbl = false;
}
else if (empty($a))
{
$thg_id = $base_thg_id;
$lbl = $b;
}
else
{
$thg_id = $a;
$lbl = $b;
}
}
else
{
$thg_id = $base_thg_id;
$lbl = $src;
}
// Try to translate to a real thg_id
if (!is_numeric($thg_id))
{
if (empty($lbl))
{
$thg_id = any_symbolic2id($thg_id, array('kind'=>'ATTACHMENT'));
}
else
{
$thg_id = any_symbolic2id($thg_id);
}
}
// Fetch the thing id of the attachment
if (!empty($lbl) && !empty($thg_id))
{
list($pred, $nr) = any_attach_label2pred($lbl);
@list($aid, $alt, $caption) = any_attach_caption_pred($thg_id, $pred, $nr);
}
else
{
// Assume the given src is an attachment id
if (!empty($attr['caption']))
{
@list($alt, $caption) = any_attach_caption($thg_id);
}
else
{
$alt = '';
$caption = '';
}
$aid = $thg_id;
$lbl = false;
}
if (empty($caption) && !empty($alt))
{
$caption = $alt;
}
$alt = strip_tags($alt);
}
else
{
$id = false;
$aid = false;
$lbl = false;
$alt = '';
$caption = '';
}
}
else
{
$src = '#'; // Unknown source
$id = false;
$aid = false;
$lbl = false;
}
if (!empty($attr['caption']))
{
if (!empty($caption))
{
$alt = trim($alt);
$caption = trim(str_replace(array('', '
'), array('',' '), $caption));
while (substr($caption, -5) == ' ')
{
$caption = trim(substr($caption, 0, -5));
}
if (!empty($alt) && !empty($intro))
{
$cap = '';
if (!empty($alt))
{
$cap .= '' . any_wiki_runtime($alt, $_wiki_options) .' ';
}
if (!empty($caption))
{
$cap .= any_wiki_runtime($caption, $_wiki_options);
}
$cap .= ' ';
}
else
{
$cap = '';
}
if (strcasecmp($attr['caption'], 'before') == 0)
{
$cap1 = $cap;
$cap2 = '';
}
else
{
$cap1 = '';
$cap2 = $cap;
}
}
else
{
$cap1 = '';
$cap2 = '';
}
unset($attr['caption']);
}
else
{
$cap1 = '';
$cap2 = '';
}
//
// Expand the anchor tag around the image
//
if (array_key_exists('link',$attr))
{
$link = trim($attr['link']);
}
else
{
$link = false;
}
$expand = false;
if (empty($link) && !empty($aid))
{
// Link to the attachment ;-)
$href = 'id/' . $aid;
if ($abs_uri)
{
$href = any_uri_abs($href);
}
}
else if ($link[0] == '#')
{
// Ref to local anchor
$href = $link;
}
else if ( strpos($link, '://') > 0
|| strpos($link, '.php') !== false
|| strpos($link, '.html') !== false
|| strpos($link, '.htm') !== false)
{
// Literal link
$href = $link;
}
else if (strncmp($link, 'javascript:', 12) == 0)
{
$href = $link;
}
else if (strncmp($link, 'popup:', 6) == 0)
{
$popup = substr($link, 6);
if (strlen($popup) == 0)
{
if (is_numeric($thg_id))
{
$label = addslashes($lbl);
$href = "javascript:popup('$thg_id','$label')";
}
else if (!empty($aid) && is_numeric($aid))
{
$href = "javascript:popup('{$aid}')";
$expand = true;
}
}
else
{
// Undefined behaviour for now...
$href = false;
}
}
else
{
// Assume a thing id
if (!empty($abs_uri))
{
$href = any_thing_uri_abs($link);
}
else
{
$href = any_thing_uri($link);
}
}
// Perform any macro expansion (when needed)
if (!empty($href) && $expand)
{
$href = str_replace(array('{$thg_id}', '{$label}', '{$att_id}'),
array($thg_id, $lbl, $aid),
$href);
}
$href = htmlspecialchars($href);
// unset these so they don't show up as attributes
unset($attr['link']);
// Build the image tag
if (!empty($aid) && is_numeric($aid))
{
if (empty($attr['alt']))
{
$attr['alt'] = $alt;
}
if (empty($attr['title']))
{
$attr['title'] = $alt;
}
unset($attr['height']);
unset($attr['width']);
$pars = $attr;
$pars['abs'] = $abs_uri;
$img = any_attach_img_tag($aid, $pars, $width, $height);
}
else
{
if (!array_key_exists('alt', $attr))
{
$attr['alt'] = basename($src);
}
// A normal src, build the tag ourselves
$attr_s = '';
foreach ($attr as $key => $val)
{
$attr_s .= " $key=\"$val\"";
}
$img = " ";
}
if (!empty($href))
{
$html = "$cap1 $img $cap2";
}
else
{
$html = "$cap1$img$cap2";
}
return $html;
}
// Calculate a size, using a base size and a percentage
//
function _wiki_runtime_img_size ( $req, $base )
{
if (substr($req, -2) == 'px')
{
// Absolute size
$ret = substr($req, 0, -2);
}
else if (is_string($req) && is_numeric($base))
{
// Assume percentage of base size
if (substr($req, -1) == '%')
{
$req = substr($req, 0, -1);
}
$ret = ceil(floatval($req) * floatval($base) / 100.0);
}
else
{
// No size
$ret = null;
}
return $ret;
}
?>
Animeband - About
About Animeband
The origins of Animeband
Take Angband 2.9.3
add many anime/Japanese references
mix with beer
Anime/Anime games/Japanese references used in Animeband:
Akira
Araiguma Rascal
Azumanga Daioh
Bastard!!!
Berserk
Capcom vs SNK
Churasan
Chushingura
Combustible Campus Guardress
Cowboy Bebop
Dagger of Kamui
Darkstalkers
Devil Hunter Yohko
Doraemon
Dragonball Z and GT
Escaflowne
Evangelion
Fighting Foodons
Final Fantasy
Fushigi Yuugi
Godzilla
Great Teacher Onizuka
Guilty Gear
Gundam Wing
Hajime no Ippo
Hello Kitty
Hikaru no Go
Howl's Moving Castle
Inu Yasha
Irresponsible Captain Tylor
IQ Sapuri
Jinzo Ningen Kikaida
Jojo's Bizzare Adventure
Jubei-Chan
Kareshi Kanojo no Jijou
Kikikaikai
Kiki's Delivery Service
Laputa
Last Exile
Lupin the Third
Macross
Magic Knight Rayearth
Mahoromatic
Mahou Tsukai Tai
Marmalade Boy
Marvel vs Capcom
Mimi wo Sumaseba
Mononoke Hime
Muteki Kanban Musume (Noodle Fighter Miki)
Narue no Sekai
Naruto
Ninja Scroll
Photon
Pokemon
Puyo Puyo
Ragnarok Online
Ranma 1/2
Record of Lodoss War
Rival Schools
Ronin Warriors
Sailor Moon
Samurai Showdown
Shinsengumi
Slayers
Soul Calibur
Spirited Away (Sen to Chihiro no Kamikakushi)
Star Ocean the Second Story
Super Mario Bros.
Tenchi Muyo
Tokimeki Memorial
Tokyo Underground
Tonari no Totoro
Trigun
Tsukihime
Utena
Vampire Hunter D
X
Yami no Matsuei
Yu-Gi-Oh