text = $text; $this->children = array(); } function AddChild($point) { $this->children[] = $point; } function LastChild() { if(is_array($this->children) && count($this->children)>0) return $this->children[count($this->children)-1]; return null; } function HasChildren() { if(count($this->children)<1) return true; return false; } } class WikiParser { function __construct() { $this->reference_wiki = 'index.php?module=wiki&action=list&name='; $this->image_uri = ''; $this->ignore_images = true; $this->Index = new IndexPoint(); } function BuildIndex() { if(count($this->Index->children)==0) return false; $out = "
"; $this->preformat = true; $output .= $matches[1]; return $output."\n"; } function handle_horizontalrule($matches) { return "
"; } function wiki_link($topic) { return ucfirst(str_replace(' ','_',$topic)); } function handle_image($href,$title,$options) { if ($this->ignore_images) return ""; if (!$this->image_uri) return $title; $href = $this->image_uri . $href; $imagetag = sprintf( '', $href, $title ); foreach ($options as $k=>$option) { switch($option) { case 'frame': $imagetag = sprintf( ''. '%s'. '', $imagetag, $title ); break; case 'right': $imagetag = sprintf( '%s'. '%s', $imagetag ); break; } } return $imagetag; } function handle_internallink($matches) { //var_dump($matches); $nolink = false; $href = $matches[4]; $title = $matches[6] ? $matches[6] : $href.$matches[7]; $namespace = $matches[3]; if ($namespace=='Image') { $options = explode('|',$title); $title = array_pop($options); return $this->handle_image($href,$title,$options); } $title = preg_replace('/\(.*?\)/','',$title); $title = preg_replace('/^.*?\:/','',$title); if ($this->reference_wiki) { $href = $this->reference_wiki.($namespace?$namespace.':':'').$this->wiki_link($href); } else { $nolink = true; } if ($nolink) return $title; return sprintf( '%s', $href, ($newwindow?' target="_blank"':''), $title ); } function handle_externallink($matches) { $href = $matches[2]; $title = $matches[3]; if (!$title) { $this->linknumber++; $title = "[{$this->linknumber}]"; } $newwindow = true; return sprintf( '%s', $href, ($newwindow?' target="_blank"':''), $title ); } function emphasize($amount) { $amounts = array( 2=>array('',''), 3=>array('',''), 4=>array('',''), 5=>array('',''), ); $output = ""; // handle cases where emphasized phrases end in an apostrophe, eg: ''somethin''' // should read somethin' rather than somethin if ( (!$this->emphasis[$amount]) && ($this->emphasis[$amount-1]) ) { $amount--; $output = "'"; } $output .= $amounts[$amount][(int) $this->emphasis[$amount]]; $this->emphasis[$amount] = !$this->emphasis[$amount]; return $output; } function handle_emphasize($matches) { $amount = strlen($matches[1]); return $this->emphasize($amount); } function emphasize_off() { $output = ""; foreach ($this->emphasis as $amount=>$state) { if ($state) $output .= $this->emphasize($amount); } return $output; } function handle_eliminate($matches) { return ""; } function handle_variable($matches) { switch($matches[2]) { case 'CURRENTMONTH': return date('m'); case 'CURRENTMONTHNAMEGEN': case 'CURRENTMONTHNAME': return date('F'); case 'CURRENTDAY': return date('d'); case 'CURRENTDAYNAME': return date('l'); case 'CURRENTYEAR': return date('Y'); case 'CURRENTTIME': return date('H:i'); case 'NUMBEROFARTICLES': return 0; case 'PAGENAME': return $this->page_title; case 'NAMESPACE': return 'None'; case 'SITENAME': return $_SERVER['HTTP_HOST']; default: return ''; } } function parse_line($line) { $line_regexes = array( 'preformat'=>'^\s(.*?)$', 'definitionlist'=>'^([\;\:])\s*(.*?)$', 'newline'=>'^$', 'list'=>'^([\*\#]+)(.*?)$', 'sections'=>'^(={1,6})(.*?)(={1,6})$', 'horizontalrule'=>'^----$', ); $char_regexes = array( // 'link'=>'(\[\[((.*?)\:)?(.*?)(\|(.*?))?\]\]([a-z]+)?)', 'internallink'=>'('. '\[\['. // opening brackets '(([^\]]*?)\:)?'. // namespace (if any) '([^\]]*?)'. // target '(\|([^\]]*?))?'. // title (if any) '\]\]'. // closing brackets '([a-z]+)?'. // any suffixes ')', 'externallink'=>'('. '\['. '([^\]]*?)'. '(\s+[^\]]*?)?'. '\]'. ')', 'emphasize'=>'(\'{2,5})', 'eliminate'=>'(__TOC__|__NOTOC__|__NOEDITSECTION__)', 'variable'=>'('. '\{\{' . '([^\}]*?)' . '\}\}' . ')', ); $this->stop = false; $this->stop_all = false; $called = array(); $line = rtrim($line); foreach ($line_regexes as $func=>$regex) { if (preg_match("/$regex/i",$line,$matches)) { $called[$func] = true; $func = "handle_".$func; $line = $this->$func($matches); if ($this->stop || $this->stop_all) break; } } if (!$this->stop_all) { $this->stop = false; foreach ($char_regexes as $func=>$regex) { $line = preg_replace_callback("/$regex/i",array(&$this,"handle_".$func),$line); if ($this->stop) break; } } $isline = strlen(trim($line))>0; // if this wasn't a list item, and we are in a list, close the list tag(s) if (($this->list_level>0) && !$called['list']) $line = $this->handle_list(false,true) . $line; if ($this->deflist && !$called['definitionlist']) $line = $this->handle_definitionlist(false,true) . $line; if (!empty($this->preformat) && empty($called['preformat'])) $line = $this->handle_preformat(false,true) . $line; // suppress linebreaks for the next line if we just displayed one; otherwise re-enable them if ($isline) $this->suppress_linebreaks = (!empty($called['newline']) || !empty($called['sections'])); return $line; } function test() { $text = "WikiParser stress tester.
Testing... __TOC__ == Nowiki test ==[[wooticles|narf]] and '''test''' and stuff. == Character formatting == This is ''emphasized'', this is '''really emphasized''', this is ''''grossly emphasized'''', and this is just '''''freeking insane'''''. Done. == Variables == {{CURRENTDAY}}/{{CURRENTMONTH}}/{{CURRENTYEAR}} Done. == Image test == [[:Image:bao1.jpg]] [[Image:bao1.jpg|frame|alternate text]] [[Image:bao1.jpg|right|alternate text]] Done. == Horizontal Rule == Above the rule. ---- Done. == Hyperlink test == This is a [[namespace:link target|bitchin hypalink]] to another document for [[click]]ing, with [[(some) hidden text]] and a [[namespace:hidden namespace]]. A link to an external site [http://www.google.ca] as well another [http://www.esitemedia.com], and a [http://www.blitzaffe.com titled link] -- woo! Done. == Preformat == Not preformatted. Totally preformatted 01234 o o Again, this is preformatted b <-- It's a face Again, this is preformatted ---' Done. == Bullet test == * One bullet * Another '''bullet''' *# a list item *# another list item *#* unordered, ordered, unordered *#* again *# back down one Done. == Definition list == ; yes : opposite of no ; no : opposite of yes ; maybe : somewhere in between yes and no Done. == Indent == Normal : indented woo : more indentation Done. "; return $this->parse($text); } function parse($text,$title="") { $this->redirect = false; $this->nowikis = array(); $this->list_level_types = array(); $this->list_level = 0; $this->deflist = false; $this->linknumber = 0; $this->suppress_linebreaks = false; $this->page_title = $title; $output = ""; $text = preg_replace_callback('/([\s\S]*)<\/nowiki>/i',array(&$this,"handle_save_nowiki"),$text); $lines = explode("\n",$text); if (preg_match('/^\#REDIRECT\s+\[\[(.*?)\]\]$/',trim($lines[0]),$matches)) { $this->redirect = $matches[1]; } foreach ($lines as $k=>$line) { $line = $this->parse_line($line); $output .= $line; } $output = preg_replace_callback('/ <\/nowiki>/i',array(&$this,"handle_restore_nowiki"),$output); return $output; } function handle_save_nowiki($matches) { array_push($this->nowikis,$matches[1]); return " "; } function handle_restore_nowiki($matches) { return array_pop($this->nowikis); } } ?>