BB Code Parser

Item 1 of 9

» Download this file

1   <?php
2   
3   /**
4    * Class: BB Code Parser
5    *
6    * Parses a text document with BB code into HTML
7    *
8    * @author Dan Pupius
9    * @version 1.1
10   * @copyright ©2004 Daniel Pupius <http://pupius.co.uk>
11   * @filesource
12   */
13  class BB_Parser {
14  
15  	/**
16  	 * @var boolean Whether or not to allow images
17  	 * @access private
18  	 */
19  	var $_allow_images = true;
20  
21  	/**
22  	 * @var boolean Whether or not to allow links
23  	 * @access private
24  	 */
25  	var $_allow_links = true;
26  
27  	/**
28  	 * @var boolean Whether or not to allow formatting such as bold, italic, underline
29  	 * @access private
30  	 */
31  	var $_allow_formatting = true;
32  
33  	/**
34  	 * @var boolean Whether to escape html characters before BB parse
35  	 * @access private
36  	 */
37  	var $_allow_html = false;
38  
39  	/**
40  	 * @var boolean Whether to convert line breaks into html line breaks
41  	 * @access private
42  	 */
43  	var $_convert_nl2br = true;
44  	
45  	/**
46  	 * @var boolean Whether to wrap content in <p> tags
47  	 * @access private
48  	 */
49  	var $_force_paragraph = true;
50  	
51  	/**
52  	 * @var boolean Make quotes and apostrophe's pretty
53  	 * @access private
54  	 */
55  	var $_pretty_chars = true;
56  
57  
58  	/*****************************************************************************************/
59  
60  
61  
62  	/**
63  	 * Setter and getter for allow images
64  	 * 
65  	 * @param boolean $val True/False
66  	 * @access public
67  	 */
68  	function set_allow_images($val) { $this->_allow_images = ($val)?true:false; }
69  	function get_allow_images($val) { return $this->_allow_images; }
70  
71  
72  	/**
73  	 * Setter and getter for allow links
74  	 * 
75  	 * @param boolean $val True/False
76  	 * @access public
77  	 */
78  	function set_allow_links($val) { $this->_allow_links = ($val)?true:false; }
79  	function get_allow_links($val) { return $this->_allow_links; }
80  
81  
82  	/**
83  	 * Setter and getter for allow formatting
84  	 * 
85  	 * @param boolean $val True/False
86  	 * @access public
87  	 */
88  	function set_allow_formatting($val) { $this->_allow_formatting = ($val)?true:false; }
89  	function get_allow_formatting($val) { return $this->_allow_formatting; }
90  
91  
92  	/**
93  	 * Setter and getter for allow html
94  	 * 
95  	 * @param boolean $val True/False
96  	 * @access public
97  	 */
98  	function set_allow_html($val) { $this->_allow_html = ($val)?true:false; }
99  	function get_allow_html($val) { return $this->_allow_html; }
100 
101 
102 	/**
103 	 * Setter and getter for convert nl2br
104 	 * 
105 	 * @param boolean $val True/False
106 	 * @access public
107 	 */
108 	function set_convert_nl2br($val) { $this->_convert_nl2br = ($val)?true:false; }
109 	function get_convert_nl2br($val) { return $this->_convert_nl2br; }
110 
111 	/**
112 	 * Setter and getter for convert force_paragraph
113 	 * 
114 	 * @param boolean $val True/False
115 	 * @access public
116 	 */
117 	function set_para($val) { $this->_force_paragraph = ($val)?true:false; }
118 	function get_para($val) { return $this->_force_paragraph; }
119 
120 	/*****************************************************************************************/
121 
122 	/**
123 	 * Formats a string of code by adding line numbers to the start
124 	 * 
125 	 * @param string $code Code of some kind
126 	 * @return string formatted
127 	 * @access public
128 	 */
129 	function format_code($code) {
130 		$code = str_replace("&#8220;","&quot;",$code);
131 		$code = str_replace("&#8221;","&quot;",$code);
132 		$code = str_replace("&#8217;","'",$code);
133 
134 		$lines = split("\n",$code);
135 
136 		$count = 1;
137 		foreach($lines as $key => $val) {
138 			if($count < 10) $no = "<span class=\"linenumber\">$count</span>   ";
139 			else if($count < 100) $no = "<span class=\"linenumber\">$count</span>  ";
140 			else if($count < 1000) $no = "<span class=\"linenumber\">$count</span> ";
141 
142 			$lines[$key] = $no . $val;			
143 			$count++;
144 		}
145 		return implode("\n",$lines);
146 	}
147 
148 
149 	/**
150 	 * Creates an image tag for an image
151 	 * 
152 	 * @param string $img Image URL (relative to webroot or absolute)
153 	 * @return string formatted
154 	 * @access public
155 	 */
156 	function create_imgtag($img,$class="") {
157 		if(strpos($img,"http://") === false) $url = $GLOBALS['url_base'] . $img;
158 		else $url = $img;
159 
160 		$arr = getimagesize($url);
161 
162 		if($class!="") $class = " class=\"$class\"";
163 
164 		return "<img$class src=\"$img\" " . $arr[3] . " alt=\"$img\" />";
165 
166 	}
167 
168 
169 
170 	/**
171 	 * Parses a string based on current settings and returns a processed version
172 	 * 
173 	 * @param string $string String to process
174 	 * @return string Pricessed string
175 	 * @access public
176 	 */	
177 	function parse($string,$firstclass="") {
178 
179 
180 
181 		//remove HTML
182 		if(!$this->_allow_html) $string = htmlentities($string);
183 
184 		//convert line breaks
185 		if($this->_convert_nl2br) $string = preg_replace("/\n/im","<br />\n",$string);
186 
187 		//make chars pretty before adding the html
188 		if($this->_pretty_chars) {
189 			$string = preg_replace("/\s* — \s*/"," &#8212; ",$string);
190 			$string = preg_replace("/([a-zA-Z0-9])'([a-zA-Z0-9])/","\\1&#8217;\\2",$string);
191 			$string = preg_replace("/([^a-zA-Z0-9])&quot;([\[a-zA-Z0-9])/","\\1&#8220;\\2",$string);
192 			$string = preg_replace("/([a-zA-Z0-9\]])&quot;([^a-zA-Z0-9])/","\\1&#8221;\\2",$string);
193 		}
194 
195 		//do basic formatting
196 		if($this->_allow_formatting) {
197 			$string = preg_replace("(\[b\](.+?)\[\/b])is",'<strong>$1</strong>',$string); 
198 			$string = preg_replace("(\[i\](.+?)\[\/i])is",'<em>$1</em>',$string); 
199 			$string = preg_replace("(\[u\](.+?)\[\/u])is",'<span style=\"text-decoration:underline\">$1</span>',$string); 
200 			$string = preg_replace("(\[s\](.+?)\[\/s])is",'<span style=\"text-decoration:line-through\">$1</span>',$string); 
201 			$string = preg_replace("(\[size=(.+?)\](.+?)\[\/size\])is","<span style=\"font-size: $1px\">$2</span>",$string); 
202 	
203 			$string = preg_replace("/\[quote\](.+?)\[\/quote\]/is","</p>\n<p class=\"quote\">$1</p>\n<p>", $string);
204 			$string = preg_replace("/\[code\](.+?)\[\/code\]/ise","'</p>\n<pre class=\"code\">'.BB_Parser::format_code('$1').'</pre>\n<p>'", $string);
205 		}
206 
207 		if($this->_allow_links) {
208 			$url_chars = " a-zA-Z0-9\:\/\-\?\&\.\=\_\~\#\'\%"; 
209 			$mail_chars = $url_chars . "@"; 			
210 
211 			//convert urls
212 			$string = preg_replace("/\[url\](.*?)\[\/url\]/", '<a href="$1">$1</a>', $string); 
213 			$string = preg_replace("(\[url href\=(.*?)\](.*?)\[/url\])", '<a href="$1">$2</a>', $string);
214 			$string = preg_replace("(\[url class\=(.*?) href\=(.*?)\](.*?)\[/url\])", '<a class="$1" href="$2">$3</a>', $string); 
215 
216 			
217 			//convert images
218 			$string = preg_replace("/\[img\](.+?)\[\/img\]/ise","BB_Parser::create_imgtag('$1')", $string); 
219 			$string = preg_replace("/\[img class\=(.*?)\](.+?)\[\/img\]/ise","BB_Parser::create_imgtag('$2','$1')", $string); 
220 
221 			//convert emails
222 			//$string = preg_replace("/\[email\](.*?)\[\/email\]/", '<a class="email" href="mailto:$1">$1</a>', $string); 
223 			//$string = preg_replace("/([email to\=(.*?)\](.*?)\[/email\])e", "'<a class=\"email\" href=\"mailto:'.urlencode('$1').'\">$2</a>'", $string);
224 		}
225 
226 		//make sure string is in a paragraph
227 		if($firstclass!="" && $this->_force_paragraph) $string = "\n<p class=\"$firstclass\">$string</p>\n\n";
228 		else if($this->_force_paragraph) $string = "\n<p>$string</p>\n\n";
229 
230 		//but remove empty paragraphs just in case
231 		$string = str_replace("<p></p>","",$string);
232 
233 		return $string;
234 	}
235 
236 
237 	/**
238 	 * Echos the parsed string
239 	 * 
240 	 * @param string $string String to process
241 	 * @access public
242 	 */	
243 	function output($string,$firstclass="") { echo $this->parse($string,$firstclass); }
244 
245 }
246 
247 /*
248 $bb = new BB_Parser;
249 $bb->output('
250 [email to=dan@pupius.co.uk]Email me[/email]
251 [email]dan@pupius.co.uk[/email]
252 [url class=external href=http://www.bbc.co.uk]BBC News[/url]
253 ');
254 */
255 
256 ?>
257 

Back to top