1 |
bareface |
1.1 |
<?php |
2 |
|
|
|
3 |
|
|
class YakkaTextProcessor { |
4 |
|
|
var $engine; |
5 |
|
|
|
6 |
|
|
var $pattern; |
7 |
|
|
|
8 |
|
|
var $tagState; |
9 |
|
|
var $tagCount; |
10 |
|
|
|
11 |
|
|
function YakkaTextProcessor(&$engine) { |
12 |
|
|
$this->engine = &$engine; |
13 |
|
|
|
14 |
|
|
$this->pattern = "/(\%\%.*?\%\%|\"\".*?\"\"|\[\[.*?\]\]|<|>|&|\*\*.*?\*\*|\/\/.*?\/\/|__.*?__|\#\#.*?\#\#|======.*?======|=====.*?=====|====.*?====|===.*?===|==.*?==|----|---|\n[\t\|]+(-|[0-9,a-z,A-Z]+\))?|\{\{.*?\}\}|\b[A-Z][A-Z,a-z]+[:]([A-Z][a-z]+[A-Z,0-9][A-Z,a-z,0-9]*)\b|\b([A-Z][a-z]+[A-Z,0-9][A-Z,a-z,0-9]*)\b|\n)/ms"; |
15 |
|
|
} |
16 |
|
|
|
17 |
|
|
function Process($source) { |
18 |
|
|
$source = str_replace("\r", "", $source); |
19 |
|
|
$source = trim($source)."\n"; |
20 |
|
|
$source = $this->ExecuteBuilder($source); |
21 |
|
|
$source = preg_replace("/<br \/>$/", "", trim($source)); |
22 |
|
|
return $source; |
23 |
|
|
} |
24 |
|
|
|
25 |
|
|
|
26 |
|
|
function ExecuteBuilder($source) { |
27 |
|
|
return preg_replace_callback($this->pattern, array(&$this, "Build"), $source); |
28 |
|
|
} |
29 |
|
|
|
30 |
|
|
function Build($things) { |
31 |
|
|
$thing = $things[1]; |
32 |
|
|
|
33 |
|
|
static $oldIndentLevel = 0; |
34 |
|
|
static $indentClosers = array(); |
35 |
|
|
static $br = 1; |
36 |
|
|
|
37 |
|
|
global $wakka; |
38 |
|
|
|
39 |
|
|
// convert HTML thingies |
40 |
|
|
if ($thing == "<") |
41 |
|
|
return "<"; |
42 |
|
|
else if ($thing == ">") |
43 |
|
|
return ">"; |
44 |
|
|
else if ($thing == "&") |
45 |
|
|
return "&"; |
46 |
|
|
// bold |
47 |
|
|
else if (preg_match("/^\*\*(.*)\*\*$/s", $thing, $matches)) |
48 |
|
|
{ |
49 |
|
|
return "<b>".$this->ExecuteBuilder($matches[1])."</b>"; |
50 |
|
|
} |
51 |
|
|
// italic |
52 |
|
|
else if (preg_match("/^\/\/(.*)\/\/$/s", $thing, $matches)) |
53 |
|
|
{ |
54 |
|
|
return "<i>".$this->ExecuteBuilder($matches[1])."</i>"; |
55 |
|
|
} |
56 |
|
|
// underlinue |
57 |
|
|
else if (preg_match("/^__(.*)__$/s", $thing, $matches)) |
58 |
|
|
{ |
59 |
|
|
return "<u>".$this->ExecuteBuilder($matches[1])."</u>"; |
60 |
|
|
} |
61 |
|
|
// monospace |
62 |
|
|
else if (preg_match("/^\#\#(.*)\#\#$/s", $thing, $matches)) |
63 |
|
|
{ |
64 |
|
|
return "<tt>".$this->ExecuteBuilder($matches[1])."</tt>"; |
65 |
|
|
} |
66 |
|
|
// headers |
67 |
|
|
else if (preg_match("/^======(.*)======$/s", $thing, $matches)) |
68 |
|
|
{ |
69 |
|
|
$br = 0; |
70 |
|
|
return "<h1>".$this->ExecuteBuilder($matches[1])."</h1>"; |
71 |
|
|
} |
72 |
|
|
else if (preg_match("/^=====(.*)=====$/s", $thing, $matches)) |
73 |
|
|
{ |
74 |
|
|
$br = 0; |
75 |
|
|
return "<h2>".$this->ExecuteBuilder($matches[1])."</h2>"; |
76 |
|
|
} |
77 |
|
|
else if (preg_match("/^====(.*)====$/s", $thing, $matches)) |
78 |
|
|
{ |
79 |
|
|
$br = 0; |
80 |
|
|
return "<h3>".$this->ExecuteBuilder($matches[1])."</h3>"; |
81 |
|
|
} |
82 |
|
|
else if (preg_match("/^===(.*)===$/s", $thing, $matches)) |
83 |
|
|
{ |
84 |
|
|
$br = 0; |
85 |
|
|
return "<h4>".$this->ExecuteBuilder($matches[1])."</h4>"; |
86 |
|
|
} |
87 |
|
|
else if (preg_match("/^==(.*)==$/s", $thing, $matches)) |
88 |
|
|
{ |
89 |
|
|
$br = 0; |
90 |
|
|
return "<h5>".$this->ExecuteBuilder($matches[1])."</h5>"; |
91 |
|
|
} |
92 |
|
|
// separators |
93 |
|
|
else if ($thing == "----") |
94 |
|
|
{ |
95 |
|
|
// TODO: This could probably be improved for situations where someone puts text on the same line as a separator. |
96 |
|
|
// Which is a stupid thing to do anyway! HAW HAW! Ahem. |
97 |
|
|
$br = 0; |
98 |
|
|
return "<hr/>"; |
99 |
|
|
} |
100 |
|
|
// forced line breaks |
101 |
|
|
else if ($thing == "---") |
102 |
|
|
{ |
103 |
|
|
return "<br />"; |
104 |
|
|
} |
105 |
|
|
// escaped text |
106 |
|
|
else if (preg_match("/^\"\"(.*)\"\"$/s", $thing, $matches)) |
107 |
|
|
{ |
108 |
|
|
return $matches[1]; |
109 |
|
|
} |
110 |
|
|
// code text |
111 |
|
|
else if (preg_match("/^\%\%(.*)\%\%$/s", $thing, $matches)) |
112 |
|
|
{ |
113 |
|
|
// check if a language has been specified |
114 |
|
|
$code = $matches[1]; |
115 |
|
|
if (preg_match("/^\((.+?)\)(.*)$/s", $code, $matches)) |
116 |
|
|
{ |
117 |
|
|
list(, $language, $code) = $matches; |
118 |
|
|
} |
119 |
|
|
switch ($language) |
120 |
|
|
{ |
121 |
|
|
case "php": |
122 |
|
|
$formatter = "php"; |
123 |
|
|
break; |
124 |
|
|
default: |
125 |
|
|
$formatter = "code"; |
126 |
|
|
} |
127 |
|
|
|
128 |
|
|
$output = "<div class=\"code\">"; |
129 |
|
|
$output .= "CODE";//$wakka->Format(trim($code), $formatter); |
130 |
|
|
$output .= "</div>"; |
131 |
|
|
|
132 |
|
|
return $output; |
133 |
|
|
} |
134 |
|
|
// forced links |
135 |
|
|
else if (preg_match("/^\[\[(\S*)(\s+(.+))?\]\]$/", $thing, $matches)) |
136 |
|
|
{ |
137 |
|
|
list (, $url, , $text) = $matches; |
138 |
|
|
if ($url) |
139 |
|
|
{ |
140 |
|
|
if (!$text) $text = $url; |
141 |
|
|
return $this->CreateLink($url, "", $text); |
142 |
|
|
} |
143 |
|
|
else |
144 |
|
|
{ |
145 |
|
|
return ""; |
146 |
|
|
} |
147 |
|
|
} |
148 |
|
|
// indented text |
149 |
|
|
else if (preg_match("/\n([\t\|]+)(-|([0-9,a-z,A-Z]+)\))?/s", $thing, $matches)) |
150 |
|
|
{ |
151 |
|
|
// new line |
152 |
|
|
$result .= ($br ? "<br />\n" : "\n"); |
153 |
|
|
|
154 |
|
|
// we definitely want no line break in this one. |
155 |
|
|
$br = 0; |
156 |
|
|
|
157 |
|
|
// find out which indent type we want |
158 |
|
|
$newIndentType = $matches[2]; |
159 |
|
|
if (!$newIndentType) { $opener = "<blockquote>"; $closer = "</blockquote>"; $br = 1; } |
160 |
|
|
else if ($newIndentType == "-") { $opener = "<ul>"; $closer = "</ul>"; $li = 1; } |
161 |
|
|
else { $opener = "<ol type=\"".$newIndentType."\">"; $closer = "</ol>"; $li = 1; } |
162 |
|
|
|
163 |
|
|
// get new indent level |
164 |
|
|
$newIndentLevel = strlen($matches[1]); |
165 |
|
|
if ($newIndentLevel > $oldIndentLevel) |
166 |
|
|
{ |
167 |
|
|
for ($i = 0; $i < $newIndentLevel - $oldIndentLevel; $i++) |
168 |
|
|
{ |
169 |
|
|
$result .= $opener; |
170 |
|
|
array_push($indentClosers, $closer); |
171 |
|
|
} |
172 |
|
|
} |
173 |
|
|
else if ($newIndentLevel < $oldIndentLevel) |
174 |
|
|
{ |
175 |
|
|
for ($i = 0; $i < $oldIndentLevel - $newIndentLevel; $i++) |
176 |
|
|
{ |
177 |
|
|
$result .= array_pop($indentClosers); |
178 |
|
|
} |
179 |
|
|
} |
180 |
|
|
|
181 |
|
|
$oldIndentLevel = $newIndentLevel; |
182 |
|
|
|
183 |
|
|
if ($li) $result .= "<li/>"; |
184 |
|
|
|
185 |
|
|
return $result; |
186 |
|
|
} |
187 |
|
|
// new lines |
188 |
|
|
else if ($thing == "\n") |
189 |
|
|
{ |
190 |
|
|
// if we got here, there was no tab in the next line; this means that we can close all open indents. |
191 |
|
|
$c = count($indentClosers); |
192 |
|
|
for ($i = 0; $i < $c; $i++) |
193 |
|
|
{ |
194 |
|
|
$result .= array_pop($indentClosers); |
195 |
|
|
$br = 0; |
196 |
|
|
} |
197 |
|
|
$oldIndentLevel = 0; |
198 |
|
|
|
199 |
|
|
$result .= ($br ? "<br />\n" : "\n"); |
200 |
|
|
$br = 1; |
201 |
|
|
return $result; |
202 |
|
|
} |
203 |
|
|
// events |
204 |
|
|
else if (preg_match("/^\{\{(.*?)\}\}$/s", $thing, $matches)) |
205 |
|
|
{ |
206 |
|
|
if ($matches[1]) |
207 |
|
|
return $this->engine->runAction($matches[1]); |
208 |
|
|
else |
209 |
|
|
return "{{}}"; |
210 |
|
|
} |
211 |
|
|
// interwiki links! |
212 |
|
|
else if (preg_match("/^[A-Z][A-Z,a-z]+[:]([A-Z][a-z]+[A-Z,0-9][A-Z,a-z,0-9]*)$/s", $thing)) |
213 |
|
|
{ |
214 |
|
|
return $this->CreateLink($thing); |
215 |
|
|
} |
216 |
|
|
// wakka links! |
217 |
|
|
else if (preg_match("/^[A-Z][a-z]+[A-Z,0-9][A-Z,a-z,0-9]*$/s", $thing)) |
218 |
|
|
{ |
219 |
|
|
return $this->CreateLink($thing); |
220 |
|
|
} |
221 |
|
|
// if we reach this point, it must have been an accident. |
222 |
|
|
return $thing; |
223 |
|
|
} |
224 |
|
|
|
225 |
|
|
function CreateLink($tag, $method = null, $text = null) { |
226 |
|
|
$track = 1; |
227 |
|
|
if (!$text) $text = $tag; |
228 |
|
|
|
229 |
|
|
// is this an interwiki link? |
230 |
|
|
if (preg_match("/^([A-Z][A-Z,a-z]+)[:]([A-Z][a-z]+[A-Z,0-9][A-Z,a-z,0-9]*)$/", $tag, $matches)) |
231 |
|
|
{ |
232 |
|
|
//$tag = $this->GetInterWikiUrl($matches[1], $matches[2]); |
233 |
|
|
//return "<a href=\"$tag\">$text</a>"; |
234 |
|
|
return "--interwikiurl--"; |
235 |
|
|
} |
236 |
|
|
// is this a full link? ie, does it contain alpha-numeric characters? |
237 |
|
|
else if (preg_match("/[^[:alnum:]]/", $tag)) |
238 |
|
|
{ |
239 |
|
|
// check for email addresses |
240 |
|
|
if (preg_match("/^.+\@.+$/", $tag)) |
241 |
|
|
{ |
242 |
|
|
$tag = "mailto:".$tag; |
243 |
|
|
} |
244 |
|
|
// check for protocol-less URLs |
245 |
|
|
else if (!preg_match("/:/", $tag)) |
246 |
|
|
{ |
247 |
|
|
$tag = "http://".$tag; |
248 |
|
|
} |
249 |
|
|
return "<a href=\"$tag\">$text</a>"; |
250 |
|
|
} |
251 |
|
|
else |
252 |
|
|
{ |
253 |
|
|
// it's a Wakka link! |
254 |
|
|
return ($this->engine->pageStorage->hasPage($tag) ? "<a href=\"".$this->engine->buildCommand($tag, $method)."\">".$text."</a>" : "<span class=\"missingpage\">".$text."<a href=\"".$this->engine->buildCommand($tag, "Create")."\">?</a></span>"); |
255 |
|
|
} |
256 |
|
|
} |
257 |
|
|
|
258 |
|
|
} |
259 |
|
|
|
260 |
|
|
?> |