=====Footnote Action=====
>>==See also:==
- Documentation: FootnoteActionInfo
==works with:==
- Wikka 1.1.6.2 to 1.2
>>//NOT included in any Wikka version//{{lastedit show="3"}}
This is the development page for the Footnote action.
===Installation===
- Save the first code block below as ##actions/footnote.php##
- Give it the same file permissions as the other php files in that directory
- Add four lines to ##handlers/page/show.php## as shown on the second code block below
- Add the line from the third code block below to ##css/wikka.css##
=== Code ===
1. New ##actions/footnote.php## file
<<##actions/footnote.php##<<
%%(php)$msg ");
}
function FNwakka2callback($things)
// the only change made to this function (from formatters/wakka.php in version 1.1.6.3) is in the processing of $things='closetags':
// instead of directly echoing the HTML closing tags, they are returned as a string
{
$thing = $things[1];
$result='';
static $oldIndentLevel = 0;
static $oldIndentLength= 0;
static $indentClosers = array();
static $newIndentSpace= array();
static $br = 1;
static $trigger_bold = 0;
static $trigger_italic = 0;
static $trigger_underline = 0;
static $trigger_monospace = 0;
static $trigger_notes = 0;
static $trigger_strike = 0;
static $trigger_inserted = 0;
static $trigger_deleted = 0;
static $trigger_floatl = 0;
static $trigger_keys = 0;
static $trigger_strike = 0;
static $trigger_inserted = 0;
static $trigger_center = 0;
static $trigger_l = array(-1, 0, 0, 0, 0, 0);
static $output = '';
static $valid_filename = '';
static $invalid = '';
global $wakka;
if ((!is_array($things)) && ($things == 'closetags'))
{
// start of changes to standard wakka2callback
$ret = "";
if ($trigger_strike % 2) $ret .= ('');
if ($trigger_notes % 2) $ret .= ('');
if ($trigger_inserted % 2) $ret .= ('');
if ($trigger_underline % 2) $ret .= ('');
if ($trigger_floatl % 2) $ret .= ('');
if ($trigger_center % 2) $ret .= ('');
if ($trigger_italic % 2) $ret .= ('');
if ($trigger_monospace % 2) $ret .= ('');
if ($trigger_bold % 2) $ret .= ('');
for ($i = 1; $i<=5; $i ++)
if ($trigger_l[$i] % 2) $ret .= ("");
$trigger_bold = $trigger_center = $trigger_floatl = $trigger_inserted = $trigger_deleted = $trigger_italic = $trigger_keys = 0;
$trigger_l = array(-1, 0, 0, 0, 0, 0);
$trigger_monospace = $trigger_notes = $trigger_strike = $trigger_underline = 0;
return $ret;
// end of changes to standard wakka2callback
}
// convert HTML thingies
if ($thing == "<")
return "<";
else if ($thing == ">")
return ">";
// float box left
else if ($thing == "<<")
{
return (++$trigger_floatl % 2 ? "
\n" : "\n
\n");
}
// float box right
else if ($thing == ">>")
{
return (++$trigger_floatl % 2 ? "
\n");
}
// urls
else if (preg_match("/^([a-z]+:\/\/\S+?)([^[:alnum:]^\/])?$/", $thing, $matches))
{
$url = $matches[1];
/* Inline images are disabled for security reason, use {{image action}} #142
But if you still need this functionality, update this file like below
if (preg_match("/\.(gif|jpg|png|svg)$/si", $url)) {
return ''.$wakka->htmlspecialchars_ent($matches[2]);
} else */
// Mind Mapping Mod
if (preg_match("/\.(mm)$/si", $url)) { #145
return $wakka->Action("mindmap ".$url);
} else
return $wakka->Link($url).$matches[2];
}
// header level 5
else if ($thing == "==")
{
$br = 0;
return (++$trigger_l[5] % 2 ? "
\n");
}
// forced line breaks
else if ($thing == "---")
{
return " ";
}
// escaped text
else if (preg_match("/^\"\"(.*)\"\"$/s", $thing, $matches))
{
$allowed_double_doublequote_html = $wakka->GetConfigValue("double_doublequote_html");
if ($allowed_double_doublequote_html == 'safe')
{
$filtered_output = $wakka->ReturnSafeHTML($matches[1]);
return $filtered_output;
}
elseif ($allowed_double_doublequote_html == 'raw')
{
return $matches[1];
}
else
{
return $wakka->htmlspecialchars_ent($matches[1]);
}
}
// code text
else if (preg_match("/^\%\%(.*?)\%\%$/s", $thing, $matches))
{
$output = ''; //reinitialize variable
$code = $matches[1];
// if configuration path isn't set, make sure we'll get an invalid path so we
// don't match anything in the home directory
$geshi_hi_path = isset($wakka->config['geshi_languages_path']) ? $wakka->config['geshi_languages_path'] : '/:/';
$wikka_hi_path = isset($wakka->config['wikka_highlighters_path']) ? $wakka->config['wikka_highlighters_path'] : '/:/';
// check if a language (and an optional starting line or filename) has been specified
if (preg_match('/^'.PATTERN_OPEN_BRACKET.PATTERN_FORMATTER.PATTERN_LINE_NUMBER.PATTERN_FILENAME.PATTERN_CLOSE_BRACKET.PATTERN_CODE.'$/s', $code, $matches))
{
list(, $language, , $start, , $filename, $invalid, $code) = $matches;
}
// get rid of newlines at start and end (and preceding/following whitespace)
// Note: unlike trim(), this preserves any tabs at the start of the first "real" line
$code = preg_replace('/^\s*\n+|\n+\s*$/','',$code);
// check if GeSHi path is set and we have a GeSHi highlighter for this language
if (isset($language) && isset($wakka->config['geshi_path']) && file_exists($geshi_hi_path.'/'.$language.'.php'))
{
// check if specified filename is valid and generate code block header
if (isset($filename) && strlen($filename) > 0 && strlen($invalid) == 0) # TODO: use central regex library for filename validation
{
$valid_filename = $filename;
// create code block header
$output .= '
';
// display filename and start line, if specified
$output .= $filename;
if (strlen($start)>0)
{
$output .= ' (line '.$start.')';
}
$output .= '
'."\n";
}
// use GeSHi for highlighting
$output .= $wakka->GeSHi_Highlight($code, $language, $start);
}
// check Wikka highlighter path is set and if we have an internal Wikka highlighter
elseif (isset($language) && isset($wakka->config['wikka_formatter_path']) && file_exists($wikka_hi_path.'/'.$language.'.php') && 'wakka' != $language)
{
// use internal Wikka highlighter
$output = '
\n";
}
// no language defined or no formatter found: make default code block;
// IncludeBuffered() will complain if 'code' formatter doesn't exist
else
{
$output = '
\n";
}
// display grab button if option is set in the config file
if ($wakka->config['grabcode_button'] == '1')
{
$output .= $wakka->FormOpen("grabcode");
// build form
$output .= '';
$output .= '';
$output .= '';
$output .= $wakka->FormClose();
}
// output
return $output;
}
// forced links
// \S : any character that is not a whitespace character
// \s : any whitespace character
else if (preg_match("/^\[\[(\S*)(\s+(.+))?\]\]$/s", $thing, $matches)) # recognize forced links across lines
{
list (, $url, , $text) = $matches;
if ($url)
{
//if ($url!=($url=(preg_replace("/@@|££||\[\[/","",$url))))$result="";
if (!$text) $text = $url;
//$text=preg_replace("/@@|££|\[\[/","",$text);
return $result.$wakka->Link($url, "", $text);
}
else
{
return "";
}
}
// indented text
elseif (preg_match("/\n([\t~]+)(-|&|([0-9a-zA-ZÄÖÜßäöü]+)\))?(\n|$)/s", $thing, $matches))
{
// new line
$result .= ($br ? " \n" : "\n");
// we definitely want no line break in this one.
$br = 0;
// find out which indent type we want
$newIndentType = $matches[2];
if (!$newIndentType) { $opener = "
";
}
return $result;
}
// new lines
else if ($thing == "\n")
{
// if we got here, there was no tab in the next line; this means that we can close all open indents.
$c = count($indentClosers);
for ($i = 0; $i < $c; $i++)
{
$result .= array_pop($indentClosers);
$br = 0;
}
$oldIndentLevel = 0;
$oldIndentLength= 0;
$newIndentSpace=array();
$result .= ($br ? " \n" : "\n");
$br = 1;
return $result;
}
// Actions
else if (preg_match("/^\{\{(.*?)\}\}$/s", $thing, $matches))
{
if ($matches[1])
return $wakka->Action($matches[1]);
else
return "{{}}";
}
// interwiki links!
else if (preg_match("/^[A-ZÄÖÜ][A-Za-zÄÖÜßäöü]+[:]\S*$/s", $thing))
{
return $wakka->Link($thing);
}
// wiki links!
else if (preg_match("/^[A-ZÄÖÜ]+[a-zßäöü]+[A-Z0-9ÄÖÜ][A-Za-z0-9ÄÖÜßäöü]*$/s", $thing))
{
return $wakka->Link($thing);
}
// separators
else if (preg_match("/-{4,}/", $thing, $matches))
{
// TODO: This could probably be improved for situations where someone puts text on the same line as a separator.
// Which is a stupid thing to do anyway! HAW HAW! Ahem.
$br = 0;
return "\n";
}
// mind map xml
else if (preg_match("/^$/s", $thing))
{
return $wakka->Action("mindmap ".$wakka->Href()."/mindmap.mm");
}
// if we reach this point, it must have been an accident.
return $thing;
}
function FNprint (&$thisone, $method, $note_txt='', $base_url='')
{
if (!isset($footnotes))
{
static $footnotes = array();
static $footnotesindex;
}
$out = '';
if ('addnote' == $method)
{ // display a single footnote and add it to the page's list of footnotes
$footnotesindex = ($footnotesindex) ? $footnotesindex+1 : 1;
// no markup for the 'title' attribute
$title_text = $thisone->ReturnSafeHTML(preg_replace("/(\*\*|\'\'|\#\#|\#\%|\+\+|__|\/\/|\[\[|\]\])/ms", "", $note_txt));
$out = "" . $footnotesindex . "";
$note_txt = preg_replace("('|')", "'", $note_txt);
$note_txt_raw = $thisone->htmlspecialchars_ent($note_txt);
$footnotes[$footnotesindex] = $note_txt_raw;
}
else if ('list' == $method)
{ // display the list of all the page's footnotes
$i = 1;
if (isset($footnotes) && !empty($footnotes))
{
$out = " ';
$footnotes = array();
$footnotesindex = 0;
}
}
else if ('purge' == $method)
{ // empty the footnotes array, so they are not displayed at the bottom of the page
$footnotes = array();
$footnotesindex = 0;
}
// do nothing silently if unknown $method
return $out;
}
} // if !function_exists()
$output = '';
if (!isset($vars['note']))
{
$output .= FNerror(sprintf(FN_ERROR_REQUEST_FORMAT, FN_ERROR_USAGE));
}
else
{
$output .= FNprint($this, 'addnote', $vars['note']);
}
echo $output;
?>
%%
2a. [version 1.1.6.4 only] In ##handlers/page/show.php##, go to line 80 and replace the following code block:
%%(php)
// display page
echo $this->Format($this->page['body'], 'wakka');
echo ''."\n";
echo ''."\n";
echo ''."\n";
%%
with the following code block:
%%(php)
// display page
echo $this->Format($this->page['body'], 'wakka');
echo ''."\n";
// Footnote action
if (function_exists('FNprint'))
{
echo (FNprint($this, 'list', '', $this->Href()));
}
echo ''."\n";
echo ''."\n";
%%
2b. [versions 1.1.6.2 & 1.1.6.3 only] In ##handlers/page/show.php##, go to line 21 and replace the following code block:
%%(php)
// display page
echo $this->Format($this->page['body'], 'wakka');
// if this is an old revision, display some buttons
if ($this->page['latest'] == 'N' && $this->HasAccess('write'))
%%
with the following code block:
%%(php)
// display page
echo $this->Format($this->page['body'], 'wakka');
// Footnote action
if (function_exists('FNprint')) {
echo (FNprint($this, 'list', "", $this->Href()));
}
// if this is an old revision, display some buttons
if ($this->page['latest'] == 'N' && $this->HasAccess('write'))
%%
2c. [version 1.2 only] In ##handlers/page/show.php##, replace the following code block:
%%(php)
'."\n";
}
// display page
if ($raw == 1)
{
echo '