'') { print "


" . gettext("WikiFatalError") . "

\n"; print $errormsg; print "\n"; } exit; } /** * pcre_fix_posix_classes is required to autosplit_wikiwords. * Called by the split_pagename function. */ function pcre_fix_posix_classes ($regexp) { // First check to see if our PCRE lib supports POSIX character // classes. If it does, there's nothing to do. if (preg_match('/[[:upper:]]/', 'A')) return $regexp; static $classes = array( 'alnum' => "0-9A-Za-z\xc0-\xd6\xd8-\xf6\xf8-\xff", 'alpha' => "A-Za-z\xc0-\xd6\xd8-\xf6\xf8-\xff", 'upper' => "A-Z\xc0-\xd6\xd8-\xde", 'lower' => "a-z\xdf-\xf6\xf8-\xff" ); $keys = join('|', array_keys($classes)); return preg_replace("/\[:($keys):]/e", '$classes["\1"]', $regexp); } /** * Split WikiWords in page names. * * It has been deemed useful to split WikiWords (into "Wiki Words") * in places like page titles. This is rumored to help search engines * quite a bit. * * @param $page string The page name. * * @return string The split name. */ function split_pagename ($page) { if (preg_match("/\s/", $page)) return $page; // Already split --- don't split any more. // FIXME: this algorithm is Anglo-centric. static $RE; if (!isset($RE)) { // This mess splits between a lower-case letter followed by either an upper-case // or a numeral; except that it wont split the prefixes 'Mc', 'De', or 'Di' off // of their tails. $RE[] = '/([[:lower:]])((? $val) $RE[$key] = pcre_fix_posix_classes($val); } foreach ($RE as $regexp) $page = preg_replace($regexp, '\\1 \\2', $page); return $page; } function LinkExistingWikiWord($wikiword, $linktext='') { global $ScriptUrl; $enc_word = rawurlencode($wikiword); if(empty($linktext)) $linktext = htmlspecialchars($wikiword); if (defined("autosplit_wikiwords")) $linktext=split_pagename($linktext); return "$linktext"; } function LinkUnknownWikiWord($wikiword, $linktext='') { global $ScriptUrl; $enc_word = rawurlencode($wikiword); if(empty($linktext)) $linktext = htmlspecialchars($wikiword); if (defined("autosplit_wikiwords")) $linktext=split_pagename($linktext); return "$linktext?"; } function LinkURL($url, $linktext='') { global $ScriptUrl; if(ereg("[<>\"]", $url)) { return "BAD URL -- remove all of <, >, ""; } if(empty($linktext)) $linktext = htmlspecialchars($url); return "$linktext"; } function LinkImage($url, $alt='[External Image]') { global $ScriptUrl; if(ereg('[<>"]', $url)) { return "BAD URL -- remove all of <, >, ""; } return "\"$alt\""; } function RenderQuickSearch($value = '') { global $ScriptUrl; return "
\n" . "\n" . "
\n"; } function RenderFullSearch($value = '') { global $ScriptUrl; return "
\n" . "\n" . "
\n"; } function RenderMostPopular() { global $ScriptUrl, $dbi; $query = InitMostPopular($dbi, MOST_POPULAR_LIST_LENGTH); $result = "
\n"; while ($qhash = MostPopularNextMatch($dbi, $query)) { $result .= "
$qhash[hits] ... " . LinkExistingWikiWord($qhash['pagename']) . "\n"; } $result .= "
\n"; return $result; } function ParseAdminTokens($line) { global $ScriptUrl; while (preg_match("/%%ADMIN-INPUT-(.*?)-(\w+)%%/", $line, $matches)) { $head = str_replace('_', ' ', $matches[2]); $form = "
" ."$head: " ."" ."
"; $line = str_replace($matches[0], $form, $line); } return $line; } // converts spaces to tabs function CookSpaces($pagearray) { return preg_replace("/ {3,8}/", "\t", $pagearray); } class Stack { var $items = array(); var $size = 0; function push($item) { $this->items[$this->size] = $item; $this->size++; return true; } function pop() { if ($this->size == 0) { return false; // stack is empty } $this->size--; return $this->items[$this->size]; } function cnt() { return $this->size; } function top() { if($this->size) return $this->items[$this->size - 1]; else return ''; } } // end class definition // I couldn't move this to lib/config.php because it wasn't declared yet. $stack = new Stack; /* Wiki HTML output can, at any given time, be in only one mode. It will be something like Unordered List, Preformatted Text, plain text etc. When we change modes we have to issue close tags for one mode and start tags for another. $tag ... HTML tag to insert $tagtype ... ZERO_LEVEL - close all open tags before inserting $tag NESTED_LEVEL - close tags until depths match $level ... nesting level (depth) of $tag nesting is arbitrary limited to 10 levels */ function SetHTMLOutputMode($tag, $tagtype, $level) { global $stack; $retvar = ''; if ($level > 10) { // arbitrarily limit tag nesting //ExitWiki(gettext ("Nesting depth exceeded in SetHTMLOutputMode")); // Now, instead of crapping out when we encounter a deeply // nested list item, we just clamp the the maximum depth. $level = 10; } if ($tagtype == ZERO_LEVEL) { // empty the stack until $level == 0; if ($tag == $stack->top()) { return; // same tag? -> nothing to do } while ($stack->cnt() > 0) { $closetag = $stack->pop(); $retvar .= "\n"; } if ($tag) { $retvar .= "<$tag>\n"; $stack->push($tag); } } elseif ($tagtype == NESTED_LEVEL) { if ($level < $stack->cnt()) { // $tag has fewer nestings (old: tabs) than stack, // reduce stack to that tab count while ($stack->cnt() > $level) { $closetag = $stack->pop(); if ($closetag == false) { //echo "bounds error in tag stack"; break; } $retvar .= "\n"; } // if list type isn't the same, // back up one more and push new tag if ($tag != $stack->top()) { $closetag = $stack->pop(); $retvar .= "<$tag>\n"; $stack->push($tag); } } elseif ($level > $stack->cnt()) { // Test for and close top level elements which are not allowed to contain // other block-level elements. if ($stack->cnt() == 1 and preg_match('/^(p|pre|h\d)$/i', $stack->top())) { $closetag = $stack->pop(); $retvar .= ""; } // we add the diff to the stack // stack might be zero if ($stack->cnt() < $level) { while ($stack->cnt() < $level - 1) { // This is a bit of a hack: // // We're not nested deep enough, and have to make up // some kind of block element to nest within. // // Currently, this can only happen for nested list // element (either