1: <?php
2: class BBCodeParser {
3:
4: private $objTokens;
5:
6: public function __construct($strText) {
7: $strText = str_replace(array("\n", "\r\n", "\r"), "\n", $strText);
8:
9: $objLexer = new QLexer();
10:
11:
12:
13: $objLexer->addEntryPattern("\[b\]", "start_bold", QLexer::DefaultMode, "bold");
14: $objLexer->addExitPattern("\[/b\]", "end_bold", "bold", QLexer::DefaultMode);
15:
16:
17: $objLexer->addEntryPattern("\[i\]", "start_italic", QLexer::DefaultMode, "italic");
18: $objLexer->addExitPattern("\[/i\]", "end_italic", "italic", QLexer::DefaultMode);
19:
20:
21:
22: $objLexer->addPattern("\n", "line_break");
23:
24:
25: $objLexer->addEntryPattern("\[code\]", "start_code", QLexer::DefaultMode, "code");
26: $objLexer->addExitPattern("\[/code\]", "end_code", "code", QLexer::DefaultMode);
27:
28:
29: $objLexer->addEntryPattern("\[img\]", "start_img", QLexer::DefaultMode, "img");
30: $objLexer->addExitPattern("\[/img\]", "end_img", "img", QLexer::DefaultMode);
31:
32:
33: $objLexer->addEntryPattern("\[url=", "start_url", QLexer::DefaultMode, "url");
34: $objLexer->addExitPattern("\[/url\]", "end_url", "url", QLexer::DefaultMode);
35:
36: $this->objTokens = $objLexer->Tokenize($strText);
37: }
38:
39: private function renderRaw($strRaw) {
40: return strip_tags($strRaw);
41: }
42:
43: private function renderLink($objTokens) {
44: $objToken = array_shift($objTokens);
45:
46: $parts = explode("]", $objToken["raw"]);
47: $url = $parts[0];
48: $label = $parts[1];
49: return sprintf("<a href='%s'>%s</a>", $url, $label);
50: }
51:
52: private function renderImage($objTokens) {
53: $objToken = array_shift($objTokens);
54: return sprintf("<img src='%s' />", $objToken["raw"]);
55: }
56:
57: private function renderCode($objTokens) {
58: $strOut = "";
59: foreach ($objTokens as $objToken) {
60: if ($objToken["token"] != QLexer::UNMATCHED)
61: continue;
62: $strOut .= highlight_string(stripslashes(trim($objToken["raw"])), true);
63: }
64: return $strOut;
65: }
66:
67: private function renderFormatting($objTokens, $type, $tag) {
68: $strOut = "";
69: foreach ($objTokens as $objToken) {
70: if ($objToken["token"] == "end_" . $type)
71: break;
72: $strOut .= $this->renderRaw($objToken["raw"]);
73: }
74:
75: return sprintf("<%s>%s</%s>", $tag, $strOut, $tag);
76: }
77:
78: public function Render() {
79: $this->strOut = "";
80:
81: foreach ($this->objTokens as $objToken) {
82: switch ($objToken['token']) {
83: case QLexer::UNMATCHED:
84: $this->strOut .= $this->renderRaw($objToken['raw']);
85: break;
86: case "start_bold":
87: $this->strOut .= $this->renderFormatting($objToken['raw'], "bold", "strong");
88: break;
89: case "start_italic":
90: $this->strOut .= $this->renderFormatting($objToken['raw'], "italic", "em");
91: break;
92: case "line_break":
93: $this->strOut .= "<br />";
94: break;
95: case "start_code":
96: $this->strOut .= $this->renderCode($objToken["raw"]);
97: break;
98: case "start_url":
99: $this->strOut .= $this->renderLink($objToken["raw"]);
100: break;
101: case "start_img":
102: $this->strOut .= $this->renderImage($objToken["raw"]);
103: break;
104: default:
105: $this->strOut .= "#unmatched_token#";
106: break;
107: }
108: }
109:
110: return $this->strOut;
111: }
112: }
113: ?>