<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -3,14 +3,14 @@
 /**
  * Example: get XHTML from a given Textile-markup string ($string)
  *
- *        $textile = new Textile;
- *        echo $textile-&gt;TextileThis($string);
+ *		  $textile = new Textile;
+ *		  echo $textile-&gt;TextileThis($string);
  *
  */
 
 /*
 $Id: classTextile.php 216 2006-10-17 22:31:53Z zem $
-$LastChangedRevision: 216 $
+$LastChangedRevision$
 */
 
 /*
@@ -64,126 +64,126 @@ U S A G E
 
 Block modifier syntax:
 
-    Header: h(1-6).
-    Paragraphs beginning with 'hn. ' (where n is 1-6) are wrapped in header tags.
-    Example: h1. Header... -&gt; &lt;h1&gt;Header...&lt;/h1&gt;
+	Header: h(1-6).
+	Paragraphs beginning with 'hn. ' (where n is 1-6) are wrapped in header tags.
+	Example: h1. Header... -&gt; &lt;h1&gt;Header...&lt;/h1&gt;
 
-    Paragraph: p. (also applied by default)
-    Example: p. Text -&gt; &lt;p&gt;Text&lt;/p&gt;
+	Paragraph: p. (also applied by default)
+	Example: p. Text -&gt; &lt;p&gt;Text&lt;/p&gt;
 
-    Blockquote: bq.
-    Example: bq. Block quotation... -&gt; &lt;blockquote&gt;Block quotation...&lt;/blockquote&gt;
+	Blockquote: bq.
+	Example: bq. Block quotation... -&gt; &lt;blockquote&gt;Block quotation...&lt;/blockquote&gt;
 
-    Blockquote with citation: bq.:http://citation.url
-    Example: bq.:http://textism.com/ Text...
-    -&gt;  &lt;blockquote cite=&quot;http://textism.com&quot;&gt;Text...&lt;/blockquote&gt;
+	Blockquote with citation: bq.:http://citation.url
+	Example: bq.:http://textism.com/ Text...
+	-&gt;	&lt;blockquote cite=&quot;http://textism.com&quot;&gt;Text...&lt;/blockquote&gt;
 
-    Footnote: fn(1-100).
-    Example: fn1. Footnote... -&gt; &lt;p id=&quot;fn1&quot;&gt;Footnote...&lt;/p&gt;
+	Footnote: fn(1-100).
+	Example: fn1. Footnote... -&gt; &lt;p id=&quot;fn1&quot;&gt;Footnote...&lt;/p&gt;
 
-    Numeric list: #, ##
-    Consecutive paragraphs beginning with # are wrapped in ordered list tags.
-    Example: &lt;ol&gt;&lt;li&gt;ordered list&lt;/li&gt;&lt;/ol&gt;
+	Numeric list: #, ##
+	Consecutive paragraphs beginning with # are wrapped in ordered list tags.
+	Example: &lt;ol&gt;&lt;li&gt;ordered list&lt;/li&gt;&lt;/ol&gt;
 
-    Bulleted list: *, **
-    Consecutive paragraphs beginning with * are wrapped in unordered list tags.
-    Example: &lt;ul&gt;&lt;li&gt;unordered list&lt;/li&gt;&lt;/ul&gt;
+	Bulleted list: *, **
+	Consecutive paragraphs beginning with * are wrapped in unordered list tags.
+	Example: &lt;ul&gt;&lt;li&gt;unordered list&lt;/li&gt;&lt;/ul&gt;
 
 Phrase modifier syntax:
 
-           _emphasis_   -&gt;   &lt;em&gt;emphasis&lt;/em&gt;
-           __italic__   -&gt;   &lt;i&gt;italic&lt;/i&gt;
-             *strong*   -&gt;   &lt;strong&gt;strong&lt;/strong&gt;
-             **bold**   -&gt;   &lt;b&gt;bold&lt;/b&gt;
-         ??citation??   -&gt;   &lt;cite&gt;citation&lt;/cite&gt;
-       -deleted text-   -&gt;   &lt;del&gt;deleted&lt;/del&gt;
-      +inserted text+   -&gt;   &lt;ins&gt;inserted&lt;/ins&gt;
-        ^superscript^   -&gt;   &lt;sup&gt;superscript&lt;/sup&gt;
-          ~subscript~   -&gt;   &lt;sub&gt;subscript&lt;/sub&gt;
-               @code@   -&gt;   &lt;code&gt;computer code&lt;/code&gt;
-          %(bob)span%   -&gt;   &lt;span class=&quot;bob&quot;&gt;span&lt;/span&gt;
+		   _emphasis_	-&gt;	 &lt;em&gt;emphasis&lt;/em&gt;
+		   __italic__	-&gt;	 &lt;i&gt;italic&lt;/i&gt;
+			 *strong*	-&gt;	 &lt;strong&gt;strong&lt;/strong&gt;
+			 **bold**	-&gt;	 &lt;b&gt;bold&lt;/b&gt;
+		 ??citation??	-&gt;	 &lt;cite&gt;citation&lt;/cite&gt;
+	   -deleted text-	-&gt;	 &lt;del&gt;deleted&lt;/del&gt;
+	  +inserted text+	-&gt;	 &lt;ins&gt;inserted&lt;/ins&gt;
+		^superscript^	-&gt;	 &lt;sup&gt;superscript&lt;/sup&gt;
+		  ~subscript~	-&gt;	 &lt;sub&gt;subscript&lt;/sub&gt;
+			   @code@	-&gt;	 &lt;code&gt;computer code&lt;/code&gt;
+		  %(bob)span%	-&gt;	 &lt;span class=&quot;bob&quot;&gt;span&lt;/span&gt;
 
-        ==notextile==   -&gt;   leave text alone (do not format)
+		==notextile==	-&gt;	 leave text alone (do not format)
 
-       &quot;linktext&quot;:url   -&gt;   &lt;a href=&quot;url&quot;&gt;linktext&lt;/a&gt;
- &quot;linktext(title)&quot;:url  -&gt;   &lt;a href=&quot;url&quot; title=&quot;title&quot;&gt;linktext&lt;/a&gt;
+	   &quot;linktext&quot;:url	-&gt;	 &lt;a href=&quot;url&quot;&gt;linktext&lt;/a&gt;
+ &quot;linktext(title)&quot;:url	-&gt;	 &lt;a href=&quot;url&quot; title=&quot;title&quot;&gt;linktext&lt;/a&gt;
 
-           !imageurl!   -&gt;   &lt;img src=&quot;imageurl&quot; /&gt;
-  !imageurl(alt text)!  -&gt;   &lt;img src=&quot;imageurl&quot; alt=&quot;alt text&quot; /&gt;
-    !imageurl!:linkurl  -&gt;   &lt;a href=&quot;linkurl&quot;&gt;&lt;img src=&quot;imageurl&quot; /&gt;&lt;/a&gt;
+		   !imageurl!	-&gt;	 &lt;img src=&quot;imageurl&quot; /&gt;
+  !imageurl(alt text)!	-&gt;	 &lt;img src=&quot;imageurl&quot; alt=&quot;alt text&quot; /&gt;
+	!imageurl!:linkurl	-&gt;	 &lt;a href=&quot;linkurl&quot;&gt;&lt;img src=&quot;imageurl&quot; /&gt;&lt;/a&gt;
 
-ABC(Always Be Closing)  -&gt;   &lt;acronym title=&quot;Always Be Closing&quot;&gt;ABC&lt;/acronym&gt;
+ABC(Always Be Closing)	-&gt;	 &lt;acronym title=&quot;Always Be Closing&quot;&gt;ABC&lt;/acronym&gt;
 
 
 Table syntax:
 
-    Simple tables:
+	Simple tables:
 
-        |a|simple|table|row|
-        |And|Another|table|row|
+		|a|simple|table|row|
+		|And|Another|table|row|
 
-        |_. A|_. table|_. header|_.row|
-        |A|simple|table|row|
+		|_. A|_. table|_. header|_.row|
+		|A|simple|table|row|
 
-    Tables with attributes:
+	Tables with attributes:
 
-        table{border:1px solid black}.
-        {background:#ddd;color:red}. |{}| | | |
+		table{border:1px solid black}.
+		{background:#ddd;color:red}. |{}| | | |
 
 
 Applying Attributes:
 
-    Most anywhere Textile code is used, attributes such as arbitrary css style,
-    css classes, and ids can be applied. The syntax is fairly consistent.
+	Most anywhere Textile code is used, attributes such as arbitrary css style,
+	css classes, and ids can be applied. The syntax is fairly consistent.
 
-    The following characters quickly alter the alignment of block elements:
+	The following characters quickly alter the alignment of block elements:
 
-        &lt;  -&gt;  left align    ex. p&lt;. left-aligned para
-        &gt;  -&gt;  right align       h3&gt;. right-aligned header 3
-        =  -&gt;  centred           h4=. centred header 4
-        &lt;&gt; -&gt;  justified         p&lt;&gt;. justified paragraph
+		&lt;  -&gt;  left align	 ex. p&lt;. left-aligned para
+		&gt;  -&gt;  right align		 h3&gt;. right-aligned header 3
+		=  -&gt;  centred			 h4=. centred header 4
+		&lt;&gt; -&gt;  justified		 p&lt;&gt;. justified paragraph
 
-    These will change vertical alignment in table cells:
+	These will change vertical alignment in table cells:
 
-        ^  -&gt;  top         ex. |^. top-aligned table cell|
-        -  -&gt;  middle          |-. middle aligned|
-        ~  -&gt;  bottom          |~. bottom aligned cell|
+		^  -&gt;  top		   ex. |^. top-aligned table cell|
+		-  -&gt;  middle		   |-. middle aligned|
+		~  -&gt;  bottom		   |~. bottom aligned cell|
 
-    Plain (parentheses) inserted between block syntax and the closing dot-space
-    indicate classes and ids:
+	Plain (parentheses) inserted between block syntax and the closing dot-space
+	indicate classes and ids:
 
-        p(hector). paragraph -&gt; &lt;p class=&quot;hector&quot;&gt;paragraph&lt;/p&gt;
+		p(hector). paragraph -&gt; &lt;p class=&quot;hector&quot;&gt;paragraph&lt;/p&gt;
 
-        p(#fluid). paragraph -&gt; &lt;p id=&quot;fluid&quot;&gt;paragraph&lt;/p&gt;
+		p(#fluid). paragraph -&gt; &lt;p id=&quot;fluid&quot;&gt;paragraph&lt;/p&gt;
 
-        (classes and ids can be combined)
-        p(hector#fluid). paragraph -&gt; &lt;p class=&quot;hector&quot; id=&quot;fluid&quot;&gt;paragraph&lt;/p&gt;
+		(classes and ids can be combined)
+		p(hector#fluid). paragraph -&gt; &lt;p class=&quot;hector&quot; id=&quot;fluid&quot;&gt;paragraph&lt;/p&gt;
 
-    Curly {brackets} insert arbitrary css style
+	Curly {brackets} insert arbitrary css style
 
-        p{line-height:18px}. paragraph -&gt; &lt;p style=&quot;line-height:18px&quot;&gt;paragraph&lt;/p&gt;
+		p{line-height:18px}. paragraph -&gt; &lt;p style=&quot;line-height:18px&quot;&gt;paragraph&lt;/p&gt;
 
-        h3{color:red}. header 3 -&gt; &lt;h3 style=&quot;color:red&quot;&gt;header 3&lt;/h3&gt;
+		h3{color:red}. header 3 -&gt; &lt;h3 style=&quot;color:red&quot;&gt;header 3&lt;/h3&gt;
 
-    Square [brackets] insert language attributes
+	Square [brackets] insert language attributes
 
-        p[no]. paragraph -&gt; &lt;p lang=&quot;no&quot;&gt;paragraph&lt;/p&gt;
+		p[no]. paragraph -&gt; &lt;p lang=&quot;no&quot;&gt;paragraph&lt;/p&gt;
 
-        %[fr]phrase% -&gt; &lt;span lang=&quot;fr&quot;&gt;phrase&lt;/span&gt;
+		%[fr]phrase% -&gt; &lt;span lang=&quot;fr&quot;&gt;phrase&lt;/span&gt;
 
-    Usually Textile block element syntax requires a dot and space before the block
-    begins, but since lists don't, they can be styled just using braces
+	Usually Textile block element syntax requires a dot and space before the block
+	begins, but since lists don't, they can be styled just using braces
 
-        #{color:blue} one  -&gt;  &lt;ol style=&quot;color:blue&quot;&gt;
-        # big                   &lt;li&gt;one&lt;/li&gt;
-        # list                  &lt;li&gt;big&lt;/li&gt;
-                                &lt;li&gt;list&lt;/li&gt;
-                               &lt;/ol&gt;
+		#{color:blue} one  -&gt;  &lt;ol style=&quot;color:blue&quot;&gt;
+		# big					&lt;li&gt;one&lt;/li&gt;
+		# list					&lt;li&gt;big&lt;/li&gt;
+								&lt;li&gt;list&lt;/li&gt;
+							   &lt;/ol&gt;
 
-    Using the span tag to style a phrase
+	Using the span tag to style a phrase
 
-        It goes like this, %{color:red}the fourth the fifth%
-              -&gt; It goes like this, &lt;span style=&quot;color:red&quot;&gt;the fourth the fifth&lt;/span&gt;
+		It goes like this, %{color:red}the fourth the fifth%
+			  -&gt; It goes like this, &lt;span style=&quot;color:red&quot;&gt;the fourth the fifth&lt;/span&gt;
 
 */
 
@@ -192,942 +192,1020 @@ Applying Attributes:
 @define('txt_quote_single_close', '&amp;#8217;');
 @define('txt_quote_double_open',  '&amp;#8220;');
 @define('txt_quote_double_close', '&amp;#8221;');
-@define('txt_apostrophe',         '&amp;#8217;');
-@define('txt_prime',              '&amp;#8242;');
-@define('txt_prime_double',       '&amp;#8243;');
-@define('txt_ellipsis',           '&amp;#8230;');
-@define('txt_emdash',             '&amp;#8212;');
-@define('txt_endash',             '&amp;#8211;');
-@define('txt_dimension',          '&amp;#215;');
-@define('txt_trademark',          '&amp;#8482;');
-@define('txt_registered',         '&amp;#174;');
-@define('txt_copyright',          '&amp;#169;');
+@define('txt_apostrophe',		  '&amp;#8217;');
+@define('txt_prime',			  '&amp;#8242;');
+@define('txt_prime_double', 	  '&amp;#8243;');
+@define('txt_ellipsis', 		  '&amp;#8230;');
+@define('txt_emdash',			  '&amp;#8212;');
+@define('txt_endash',			  '&amp;#8211;');
+@define('txt_dimension',		  '&amp;#215;');
+@define('txt_trademark',		  '&amp;#8482;');
+@define('txt_registered',		  '&amp;#174;');
+@define('txt_copyright',		  '&amp;#169;');
 
 class Textile
 {
-    var $hlgn;
-    var $vlgn;
-    var $clas;
-    var $lnge;
-    var $styl;
-    var $cspn;
-    var $rspn;
-    var $a;
-    var $s;
-    var $c;
-    var $pnct;
-    var $rel;
-    var $fn;
-    
-    var $shelf = array();
-    var $restricted = false;
-    var $noimage = false;
-    var $lite = false;
-    var $url_schemes = array();
-    var $glyph = array();
-    var $hu = '';
-    
-    var $ver = '2.0.0';
-    var $rev = '$Rev: 216 $';
+	var $hlgn;
+	var $vlgn;
+	var $clas;
+	var $lnge;
+	var $styl;
+	var $cspn;
+	var $rspn;
+	var $a;
+	var $s;
+	var $c;
+	var $pnct;
+	var $rel;
+	var $fn;
+	
+	var $shelf = array();
+	var $restricted = false;
+	var $noimage = false;
+	var $lite = false;
+	var $url_schemes = array();
+	var $glyph = array();
+	var $hu = '';
+	
+	var $ver = '2.0.0';
+	var $rev = '$Rev$';
+	
+	var $doc_root;
 
 // -------------------------------------------------------------
-    function Textile()
-    {
-        $this-&gt;hlgn = &quot;(?:\&lt;(?!&gt;)|(?&lt;!&lt;)\&gt;|\&lt;\&gt;|\=|[()]+(?! ))&quot;;
-        $this-&gt;vlgn = &quot;[\-^~]&quot;;
-        $this-&gt;clas = &quot;(?:\([^)]+\))&quot;;
-        $this-&gt;lnge = &quot;(?:\[[^]]+\])&quot;;
-        $this-&gt;styl = &quot;(?:\{[^}]+\})&quot;;
-        $this-&gt;cspn = &quot;(?:\\\\\d+)&quot;;
-        $this-&gt;rspn = &quot;(?:\/\d+)&quot;;
-        $this-&gt;a = &quot;(?:{$this-&gt;hlgn}|{$this-&gt;vlgn})*&quot;;
-        $this-&gt;s = &quot;(?:{$this-&gt;cspn}|{$this-&gt;rspn})*&quot;;
-        $this-&gt;c = &quot;(?:{$this-&gt;clas}|{$this-&gt;styl}|{$this-&gt;lnge}|{$this-&gt;hlgn})*&quot;;
-
-        $this-&gt;pnct = '[\!&quot;#\$%&amp;\'()\*\+,\-\./:;&lt;=&gt;\?@\[\\\]\^_`{\|}\~]';
-        $this-&gt;urlch = '[\w&quot;$\-_.+!*\'(),&quot;;\/?:@=&amp;%#{}|\\^~\[\]`]';
-
-        $this-&gt;url_schemes = array('http','https','ftp','mailto');
-
-        $this-&gt;btag = array('bq', 'bc', 'notextile', 'pre', 'h[1-6]', 'fn\d+', 'p');
-
-        $this-&gt;glyph = array(
-           'quote_single_open'  =&gt; txt_quote_single_open,
-           'quote_single_close' =&gt; txt_quote_single_close,
-           'quote_double_open'  =&gt; txt_quote_double_open,
-           'quote_double_close' =&gt; txt_quote_double_close,
-           'apostrophe'         =&gt; txt_apostrophe,
-           'prime'              =&gt; txt_prime,
-           'prime_double'       =&gt; txt_prime_double,
-           'ellipsis'           =&gt; txt_ellipsis,
-           'emdash'             =&gt; txt_emdash,
-           'endash'             =&gt; txt_endash,
-           'dimension'          =&gt; txt_dimension,
-           'trademark'          =&gt; txt_trademark,
-           'registered'         =&gt; txt_registered,
-           'copyright'          =&gt; txt_copyright,
-        );
-
-        if (defined('hu'))
-            $this-&gt;hu = hu;
-
-    }
+	function Textile()
+	{
+		$this-&gt;hlgn = &quot;(?:\&lt;(?!&gt;)|(?&lt;!&lt;)\&gt;|\&lt;\&gt;|\=|[()]+(?! ))&quot;;
+		$this-&gt;vlgn = &quot;[\-^~]&quot;;
+		$this-&gt;clas = &quot;(?:\([^)]+\))&quot;;
+		$this-&gt;lnge = &quot;(?:\[[^]]+\])&quot;;
+		$this-&gt;styl = &quot;(?:\{[^}]+\})&quot;;
+		$this-&gt;cspn = &quot;(?:\\\\\d+)&quot;;
+		$this-&gt;rspn = &quot;(?:\/\d+)&quot;;
+		$this-&gt;a = &quot;(?:{$this-&gt;hlgn}|{$this-&gt;vlgn})*&quot;;
+		$this-&gt;s = &quot;(?:{$this-&gt;cspn}|{$this-&gt;rspn})*&quot;;
+		$this-&gt;c = &quot;(?:{$this-&gt;clas}|{$this-&gt;styl}|{$this-&gt;lnge}|{$this-&gt;hlgn})*&quot;;
+
+		$this-&gt;pnct = '[\!&quot;#\$%&amp;\'()\*\+,\-\./:;&lt;=&gt;\?@\[\\\]\^_`{\|}\~]';
+		$this-&gt;urlch = '[\w&quot;$\-_.+!*\'(),&quot;;\/?:@=&amp;%#{}|\\^~\[\]`]';
+
+		$this-&gt;url_schemes = array('http','https','ftp','mailto');
+
+		$this-&gt;btag = array('bq', 'bc', 'notextile', 'pre', 'h[1-6]', 'fn\d+', 'p');
+
+		$this-&gt;glyph = array(
+		   'quote_single_open'	=&gt; txt_quote_single_open,
+		   'quote_single_close' =&gt; txt_quote_single_close,
+		   'quote_double_open'	=&gt; txt_quote_double_open,
+		   'quote_double_close' =&gt; txt_quote_double_close,
+		   'apostrophe' 		=&gt; txt_apostrophe,
+		   'prime'				=&gt; txt_prime,
+		   'prime_double'		=&gt; txt_prime_double,
+		   'ellipsis'			=&gt; txt_ellipsis,
+		   'emdash' 			=&gt; txt_emdash,
+		   'endash' 			=&gt; txt_endash,
+		   'dimension'			=&gt; txt_dimension,
+		   'trademark'			=&gt; txt_trademark,
+		   'registered' 		=&gt; txt_registered,
+		   'copyright'			=&gt; txt_copyright,
+		);
+
+		if (defined('hu'))
+			$this-&gt;hu = hu;
+
+		if (defined('DIRECTORY_SEPARATOR'))
+			$this-&gt;ds = constant('DIRECTORY_SEPARATOR');
+		else
+			$this-&gt;ds = '/';
+
+		$this-&gt;doc_root = @$_SERVER['DOCUMENT_ROOT'];
+		if (!$this-&gt;doc_root)
+			$this-&gt;doc_root = @$_SERVER['PATH_TRANSLATED']; // IIS
+			
+		$this-&gt;doc_root = rtrim($this-&gt;doc_root, $this-&gt;ds).$this-&gt;ds;
+
+	}
 
 // -------------------------------------------------------------
-    function TextileThis($text, $lite='', $encode='', $noimage='', $strict='', $rel='')
-    {
-        if ($rel)
-           $this-&gt;rel = ' rel=&quot;'.$rel.'&quot; ';
-        $this-&gt;lite = $lite;
-        $this-&gt;noimage = $noimage;
 
-        if ($encode) {
-         $text = $this-&gt;incomingEntities($text);
-            $text = str_replace(&quot;x%x%&quot;, &quot;&amp;#38;&quot;, $text);
-            return $text;
-        } else {
+	function TextileThis($text, $lite = '', $encode = '', $noimage = '', $strict = '', $rel = '')
+	{
+		$this-&gt;rel = ($rel) ? ' rel=&quot;'.$rel.'&quot;' : '';
 
-            if(!$strict) {
-                $text = $this-&gt;cleanWhiteSpace($text);
-            }
+		$this-&gt;lite = $lite;
+		$this-&gt;noimage = $noimage;
 
-            $text = $this-&gt;getRefs($text);
+		if ($encode) {
+		 $text = $this-&gt;incomingEntities($text);
+			$text = str_replace(&quot;x%x%&quot;, &quot;&amp;#38;&quot;, $text);
+			return $text;
+		} else {
 
-            if (!$lite) {
-                $text = $this-&gt;block($text);
-            }
+			if(!$strict) {
+				$text = $this-&gt;cleanWhiteSpace($text);
+			}
 
-            $text = $this-&gt;retrieve($text);
+			if (!$lite) {
+				$text = $this-&gt;block($text);
+			}
 
-                // just to be tidy
-            $text = str_replace(&quot;&lt;br /&gt;&quot;, &quot;&lt;br /&gt;\n&quot;, $text);
+			$text = $this-&gt;retrieve($text);
+			$text = $this-&gt;retrieveURLs($text);
 
-            return $text;
-        }
-    }
+				// just to be tidy
+			$text = str_replace(&quot;&lt;br /&gt;&quot;, &quot;&lt;br /&gt;\n&quot;, $text);
+
+			return $text;
+		}
+	}
 
 // -------------------------------------------------------------
-    function TextileRestricted($text, $lite=1, $noimage=1, $rel='nofollow')
-    {
-        $this-&gt;restricted = true;
-        $this-&gt;lite = $lite;
-        $this-&gt;noimage = $noimage;
-        if ($rel)
-           $this-&gt;rel = ' rel=&quot;'.$rel.'&quot; ';
 
-            // escape any raw html
-            $text = $this-&gt;encode_html($text, 0);
+	function TextileRestricted($text, $lite = 1, $noimage = 1, $rel = 'nofollow')
+	{
+		$this-&gt;restricted = true;
+		$this-&gt;lite = $lite;
+		$this-&gt;noimage = $noimage;
+
+		$this-&gt;rel = ($rel) ? ' rel=&quot;'.$rel.'&quot;' : '';
+
+			// escape any raw html
+			$text = $this-&gt;encode_html($text, 0);
 
-            $text = $this-&gt;cleanWhiteSpace($text);
-            $text = $this-&gt;getRefs($text);
+			$text = $this-&gt;cleanWhiteSpace($text);
 
-            if ($lite) {
-                $text = $this-&gt;blockLite($text);
-            }
-            else {
-                $text = $this-&gt;block($text);
-            }
+			if ($lite) {
+				$text = $this-&gt;blockLite($text);
+			}
+			else {
+				$text = $this-&gt;block($text);
+			}
 
-            $text = $this-&gt;retrieve($text);
+			$text = $this-&gt;retrieve($text);
+			$text = $this-&gt;retrieveURLs($text);
 
-                // just to be tidy
-            $text = str_replace(&quot;&lt;br /&gt;&quot;, &quot;&lt;br /&gt;\n&quot;, $text);
+				// just to be tidy
+			$text = str_replace(&quot;&lt;br /&gt;&quot;, &quot;&lt;br /&gt;\n&quot;, $text);
 
-            return $text;
-    }
+			return $text;
+	}
 
 // -------------------------------------------------------------
-    function pba($in, $element = &quot;&quot;) // &quot;parse block attributes&quot;
-    {
-        $style = '';
-        $class = '';
-        $lang = '';
-        $colspan = '';
-        $rowspan = '';
-        $id = '';
-        $atts = '';
-
-        if (!empty($in)) {
-            $matched = $in;
-            if ($element == 'td') {
-                if (preg_match(&quot;/\\\\(\d+)/&quot;, $matched, $csp)) $colspan = $csp[1];
-                if (preg_match(&quot;/\/(\d+)/&quot;, $matched, $rsp)) $rowspan = $rsp[1];
-            }
-
-            if ($element == 'td' or $element == 'tr') {
-                if (preg_match(&quot;/($this-&gt;vlgn)/&quot;, $matched, $vert))
-                    $style[] = &quot;vertical-align:&quot; . $this-&gt;vAlign($vert[1]) . &quot;;&quot;;
-            }
-
-            if (preg_match(&quot;/\{([^}]*)\}/&quot;, $matched, $sty)) {
-                $style[] = rtrim($sty[1], ';') . ';';
-                $matched = str_replace($sty[0], '', $matched);
-            }
-
-            if (preg_match(&quot;/\[([^]]+)\]/U&quot;, $matched, $lng)) {
-                $lang = $lng[1];
-                $matched = str_replace($lng[0], '', $matched);
-            }
-
-            if (preg_match(&quot;/\(([^()]+)\)/U&quot;, $matched, $cls)) {
-                $class = $cls[1];
-                $matched = str_replace($cls[0], '', $matched);
-            }
-
-            if (preg_match(&quot;/([(]+)/&quot;, $matched, $pl)) {
-                $style[] = &quot;padding-left:&quot; . strlen($pl[1]) . &quot;em;&quot;;
-                $matched = str_replace($pl[0], '', $matched);
-            }
-
-            if (preg_match(&quot;/([)]+)/&quot;, $matched, $pr)) {
-                // $this-&gt;dump($pr);
-                $style[] = &quot;padding-right:&quot; . strlen($pr[1]) . &quot;em;&quot;;
-                $matched = str_replace($pr[0], '', $matched);
-            }
-
-            if (preg_match(&quot;/($this-&gt;hlgn)/&quot;, $matched, $horiz))
-                $style[] = &quot;text-align:&quot; . $this-&gt;hAlign($horiz[1]) . &quot;;&quot;;
-
-            if (preg_match(&quot;/^(.*)#(.*)$/&quot;, $class, $ids)) {
-                $id = $ids[2];
-                $class = $ids[1];
-            }
-
-            if ($this-&gt;restricted)
-                return ($lang)    ? ' lang=&quot;'    . $lang            .'&quot;':'';
-
-            return join('',array(
-                ($style)   ? ' style=&quot;'   . join(&quot;&quot;, $style) .'&quot;':'',
-                ($class)   ? ' class=&quot;'   . $class           .'&quot;':'',
-                ($lang)    ? ' lang=&quot;'    . $lang            .'&quot;':'',
-                ($id)      ? ' id=&quot;'      . $id              .'&quot;':'',
-                ($colspan) ? ' colspan=&quot;' . $colspan         .'&quot;':'',
-                ($rowspan) ? ' rowspan=&quot;' . $rowspan         .'&quot;':''
-            ));
-        }
-        return '';
-    }
+	function pba($in, $element = &quot;&quot;, $include_id = 1) // &quot;parse block attributes&quot;
+	{
+		$style = '';
+		$class = '';
+		$lang = '';
+		$colspan = '';
+		$rowspan = '';
+		$id = '';
+		$atts = '';
+
+		if (!empty($in)) {
+			$matched = $in;
+			if ($element == 'td') {
+				if (preg_match(&quot;/\\\\(\d+)/&quot;, $matched, $csp)) $colspan = $csp[1];
+				if (preg_match(&quot;/\/(\d+)/&quot;, $matched, $rsp)) $rowspan = $rsp[1];
+			}
+
+			if ($element == 'td' or $element == 'tr') {
+				if (preg_match(&quot;/($this-&gt;vlgn)/&quot;, $matched, $vert))
+					$style[] = &quot;vertical-align:&quot; . $this-&gt;vAlign($vert[1]) . &quot;;&quot;;
+			}
+
+			if (preg_match(&quot;/\{([^}]*)\}/&quot;, $matched, $sty)) {
+				$style[] = rtrim($sty[1], ';') . ';';
+				$matched = str_replace($sty[0], '', $matched);
+			}
+
+			if (preg_match(&quot;/\[([^]]+)\]/U&quot;, $matched, $lng)) {
+				$lang = $lng[1];
+				$matched = str_replace($lng[0], '', $matched);
+			}
+
+			if (preg_match(&quot;/\(([^()]+)\)/U&quot;, $matched, $cls)) {
+				$class = $cls[1];
+				$matched = str_replace($cls[0], '', $matched);
+			}
+
+			if (preg_match(&quot;/([(]+)/&quot;, $matched, $pl)) {
+				$style[] = &quot;padding-left:&quot; . strlen($pl[1]) . &quot;em;&quot;;
+				$matched = str_replace($pl[0], '', $matched);
+			}
+
+			if (preg_match(&quot;/([)]+)/&quot;, $matched, $pr)) {
+				// $this-&gt;dump($pr);
+				$style[] = &quot;padding-right:&quot; . strlen($pr[1]) . &quot;em;&quot;;
+				$matched = str_replace($pr[0], '', $matched);
+			}
+
+			if (preg_match(&quot;/($this-&gt;hlgn)/&quot;, $matched, $horiz))
+				$style[] = &quot;text-align:&quot; . $this-&gt;hAlign($horiz[1]) . &quot;;&quot;;
+
+			if (preg_match(&quot;/^(.*)#(.*)$/&quot;, $class, $ids)) {
+				$id = $ids[2];
+				$class = $ids[1];
+			}
+
+			if ($this-&gt;restricted)
+				return ($lang)	  ? ' lang=&quot;'	 . $lang			.'&quot;':'';
+
+			return join('',array(
+				($style)   ? ' style=&quot;'   . join(&quot;&quot;, $style) .'&quot;':'',
+				($class)   ? ' class=&quot;'   . $class			 .'&quot;':'',
+				($lang)    ? ' lang=&quot;'	  . $lang			 .'&quot;':'',
+				($id and $include_id) ? ' id=&quot;' 	 . $id				.'&quot;':'',
+				($colspan) ? ' colspan=&quot;' . $colspan		 .'&quot;':'',
+				($rowspan) ? ' rowspan=&quot;' . $rowspan		 .'&quot;':''
+			));
+		}
+		return '';
+	}
 
 // -------------------------------------------------------------
-    function hasRawText($text)
-    {
-        // checks whether the text has text not already enclosed by a block tag
-        $r = trim(preg_replace('@&lt;(p|blockquote|div|form|table|ul|ol|pre|h\d)[^&gt;]*?&gt;.*&lt;/\1&gt;@s', '', trim($text)));
-        $r = trim(preg_replace('@&lt;(hr|br)[^&gt;]*?/&gt;@', '', $r));
-        return '' != $r;
-    }
+	function hasRawText($text)
+	{
+		// checks whether the text has text not already enclosed by a block tag
+		$r = trim(preg_replace('@&lt;(p|blockquote|div|form|table|ul|ol|pre|h\d)[^&gt;]*?&gt;.*&lt;/\1&gt;@s', '', trim($text)));
+		$r = trim(preg_replace('@&lt;(hr|br)[^&gt;]*?/&gt;@', '', $r));
+		return '' != $r;
+	}
 
 // -------------------------------------------------------------
-    function table($text)
-    {
-        $text = $text . &quot;\n\n&quot;;
-        return preg_replace_callback(&quot;/^(?:table(_?{$this-&gt;s}{$this-&gt;a}{$this-&gt;c})\. ?\n)?^({$this-&gt;a}{$this-&gt;c}\.? ?\|.*\|)\n\n/smU&quot;,
-           array(&amp;$this, &quot;fTable&quot;), $text);
-    }
+	function table($text)
+	{
+		$text = $text . &quot;\n\n&quot;;
+		return preg_replace_callback(&quot;/^(?:table(_?{$this-&gt;s}{$this-&gt;a}{$this-&gt;c})\. ?\n)?^({$this-&gt;a}{$this-&gt;c}\.? ?\|.*\|)\n\n/smU&quot;,
+		   array(&amp;$this, &quot;fTable&quot;), $text);
+	}
 
 // -------------------------------------------------------------
-    function fTable($matches)
-    {
-        $tatts = $this-&gt;pba($matches[1], 'table');
-
-        foreach(preg_split(&quot;/\|$/m&quot;, $matches[2], -1, PREG_SPLIT_NO_EMPTY) as $row) {
-            if (preg_match(&quot;/^($this-&gt;a$this-&gt;c\. )(.*)/m&quot;, ltrim($row), $rmtch)) {
-                $ratts = $this-&gt;pba($rmtch[1], 'tr');
-                $row = $rmtch[2];
-            } else $ratts = '';
-
-                $cells = array();
-            foreach(explode(&quot;|&quot;, $row) as $cell) {
-                $ctyp = &quot;d&quot;;
-                if (preg_match(&quot;/^_/&quot;, $cell)) $ctyp = &quot;h&quot;;
-                if (preg_match(&quot;/^(_?$this-&gt;s$this-&gt;a$this-&gt;c\. )(.*)/&quot;, $cell, $cmtch)) {
-                    $catts = $this-&gt;pba($cmtch[1], 'td');
-                    $cell = $cmtch[2];
-                } else $catts = '';
-
-                $cell = $this-&gt;graf($this-&gt;span($cell));
-
-                if (trim($cell) != '')
-                    $cells[] = &quot;\t\t\t&lt;t$ctyp$catts&gt;$cell&lt;/t$ctyp&gt;&quot;;
-            }
-            $rows[] = &quot;\t\t&lt;tr$ratts&gt;\n&quot; . join(&quot;\n&quot;, $cells) . ($cells ? &quot;\n&quot; : &quot;&quot;) . &quot;\t\t&lt;/tr&gt;&quot;;
-            unset($cells, $catts);
-        }
-        return &quot;\t&lt;table$tatts&gt;\n&quot; . join(&quot;\n&quot;, $rows) . &quot;\n\t&lt;/table&gt;\n\n&quot;;
-    }
+	function fTable($matches)
+	{
+		$tatts = $this-&gt;pba($matches[1], 'table');
+
+		foreach(preg_split(&quot;/\|$/m&quot;, $matches[2], -1, PREG_SPLIT_NO_EMPTY) as $row) {
+			if (preg_match(&quot;/^($this-&gt;a$this-&gt;c\. )(.*)/m&quot;, ltrim($row), $rmtch)) {
+				$ratts = $this-&gt;pba($rmtch[1], 'tr');
+				$row = $rmtch[2];
+			} else $ratts = '';
+
+				$cells = array();
+			foreach(explode(&quot;|&quot;, $row) as $cell) {
+				$ctyp = &quot;d&quot;;
+				if (preg_match(&quot;/^_/&quot;, $cell)) $ctyp = &quot;h&quot;;
+				if (preg_match(&quot;/^(_?$this-&gt;s$this-&gt;a$this-&gt;c\. )(.*)/&quot;, $cell, $cmtch)) {
+					$catts = $this-&gt;pba($cmtch[1], 'td');
+					$cell = $cmtch[2];
+				} else $catts = '';
+
+				$cell = $this-&gt;graf($cell);
+
+				if (trim($cell) != '')
+					$cells[] = $this-&gt;doTagBr(&quot;t$ctyp&quot;, &quot;\t\t\t&lt;t$ctyp$catts&gt;$cell&lt;/t$ctyp&gt;&quot;);
+			}
+			$rows[] = &quot;\t\t&lt;tr$ratts&gt;\n&quot; . join(&quot;\n&quot;, $cells) . ($cells ? &quot;\n&quot; : &quot;&quot;) . &quot;\t\t&lt;/tr&gt;&quot;;
+			unset($cells, $catts);
+		}
+		return &quot;\t&lt;table$tatts&gt;\n&quot; . join(&quot;\n&quot;, $rows) . &quot;\n\t&lt;/table&gt;\n\n&quot;;
+	}
 
 // -------------------------------------------------------------
-    function lists($text)
-    {
-        return preg_replace_callback(&quot;/^([#*]+$this-&gt;c .*)$(?![^#*])/smU&quot;, array(&amp;$this, &quot;fList&quot;), $text);
-    }
+	function lists($text)
+	{
+		return preg_replace_callback(&quot;/^([#*]+$this-&gt;c .*)$(?![^#*])/smU&quot;, array(&amp;$this, &quot;fList&quot;), $text);
+	}
 
 // -------------------------------------------------------------
-    function fList($m)
-    {
-        $text = explode(&quot;\n&quot;, $m[0]);
-        foreach($text as $line) {
-            $nextline = next($text);
-            if (preg_match(&quot;/^([#*]+)($this-&gt;a$this-&gt;c) (.*)$/s&quot;, $line, $m)) {
-                list(, $tl, $atts, $content) = $m;
-                $nl = '';
-                if (preg_match(&quot;/^([#*]+)\s.*/&quot;, $nextline, $nm))
-                	$nl = $nm[1];
-                if (!isset($lists[$tl])) {
-                    $lists[$tl] = true;
-                    $atts = $this-&gt;pba($atts);
-                    $line = &quot;\t&lt;&quot; . $this-&gt;lT($tl) . &quot;l$atts&gt;\n\t\t&lt;li&gt;&quot; . $this-&gt;graf($content);
-                } else {
-                    $line = &quot;\t\t&lt;li&gt;&quot; . $this-&gt;graf($content);
-                }
-
-                if(strlen($nl) &lt;= strlen($tl)) $line .= &quot;&lt;/li&gt;&quot;;
-                foreach(array_reverse($lists) as $k =&gt; $v) {
-                    if(strlen($k) &gt; strlen($nl)) {
-                        $line .= &quot;\n\t&lt;/&quot; . $this-&gt;lT($k) . &quot;l&gt;&quot;;
-                        if(strlen($k) &gt; 1)
-                            $line .= &quot;&lt;/li&gt;&quot;;
-                        unset($lists[$k]);
-                    }
-                }
-            }
-            $out[] = $line;
-        }
-        return join(&quot;\n&quot;, $out);
-    }
+	function fList($m)
+	{
+		$text = preg_split('/\n(?=[*#])/m', $m[0]);
+		foreach($text as $nr =&gt; $line) {
+			$nextline = isset($text[$nr+1]) ? $text[$nr+1] : false;
+			if (preg_match(&quot;/^([#*]+)($this-&gt;a$this-&gt;c) (.*)$/s&quot;, $line, $m)) {
+				list(, $tl, $atts, $content) = $m;
+				$nl = '';
+				if (preg_match(&quot;/^([#*]+)\s.*/&quot;, $nextline, $nm))
+					$nl = $nm[1];
+				if (!isset($lists[$tl])) {
+					$lists[$tl] = true;
+					$atts = $this-&gt;pba($atts);
+					$line = &quot;\t&lt;&quot; . $this-&gt;lT($tl) . &quot;l$atts&gt;\n\t\t&lt;li&gt;&quot; . rtrim($content);
+				} else {
+					$line = &quot;\t\t&lt;li&gt;&quot; . rtrim($content);
+				}
+
+				if(strlen($nl) &lt;= strlen($tl)) $line .= &quot;&lt;/li&gt;&quot;;
+				foreach(array_reverse($lists) as $k =&gt; $v) {
+					if(strlen($k) &gt; strlen($nl)) {
+						$line .= &quot;\n\t&lt;/&quot; . $this-&gt;lT($k) . &quot;l&gt;&quot;;
+						if(strlen($k) &gt; 1)
+							$line .= &quot;&lt;/li&gt;&quot;;
+						unset($lists[$k]);
+					}
+				}
+			}
+			else {
+				$line .= n;
+			}
+			$out[] = $line;
+		}
+		return $this-&gt;doTagBr('li', join(&quot;\n&quot;, $out));
+	}
 
 // -------------------------------------------------------------
-    function lT($in)
-    {
-        return preg_match(&quot;/^#+/&quot;, $in) ? 'o' : 'u';
-    }
+	function lT($in)
+	{
+		return preg_match(&quot;/^#+/&quot;, $in) ? 'o' : 'u';
+	}
+
+// -------------------------------------------------------------
+	function doTagBr($tag, $in)
+	{
+		return preg_replace_callback('@&lt;('.preg_quote($tag).')([^&gt;]*?)&gt;(.*)(&lt;/\1&gt;)@s', array(&amp;$this, 'doBr'), $in);
+	}
+
 
 // -------------------------------------------------------------
-    function doPBr($in)
-    {
-        return preg_replace_callback('@&lt;(p)([^&gt;]*?)&gt;(.*)(&lt;/\1&gt;)@s', array(&amp;$this, 'doBr'), $in);
-    }
+	function doPBr($in)
+	{
+		return $this-&gt;doTagBr('p', $in);
+	}
 
 // -------------------------------------------------------------
-    function doBr($m)
-    {
-        $content = preg_replace(&quot;@(.+)(?&lt;!&lt;br&gt;|&lt;br /&gt;)\n(?![#*\s|])@&quot;, '$1&lt;br /&gt;', $m[3]);
-        return '&lt;'.$m[1].$m[2].'&gt;'.$content.$m[4];
-    }
+	function doBr($m)
+	{
+		$content = preg_replace(&quot;@(.+)(?&lt;!&lt;br&gt;|&lt;br /&gt;)\n(?![#*\s|])@&quot;, '$1&lt;br /&gt;', $m[3]);
+		return '&lt;'.$m[1].$m[2].'&gt;'.$content.$m[4];
+	}
 
 // -------------------------------------------------------------
-    function block($text)
-    {
-        $find = $this-&gt;btag;
-        $tre = join('|', $find);
-
-        $text = explode(&quot;\n\n&quot;, $text);
-
-        $tag = 'p';
-        $atts = $cite = $graf = $ext  = '';
-
-        foreach($text as $line) {
-            $anon = 0;
-            if (preg_match(&quot;/^($tre)($this-&gt;a$this-&gt;c)\.(\.?)(?::(\S+))? (.*)$/s&quot;, $line, $m)) {
-                // last block was extended, so close it
-                if ($ext)
-                    $out[count($out)-1] .= $c1;
-                // new block
-                list(,$tag,$atts,$ext,$cite,$graf) = $m;
-                list($o1, $o2, $content, $c2, $c1) = $this-&gt;fBlock(array(0,$tag,$atts,$ext,$cite,$graf));
-
-                // leave off c1 if this block is extended, we'll close it at the start of the next block
-                if ($ext)
-                    $line = $o1.$o2.$content.$c2;
-                else
-                    $line = $o1.$o2.$content.$c2.$c1;
-            }
-            else {
-                // anonymous block
-                $anon = 1;
-                if ($ext or !preg_match('/^ /', $line)) {
-                    list($o1, $o2, $content, $c2, $c1) = $this-&gt;fBlock(array(0,$tag,$atts,$ext,$cite,$line));
-                    // skip $o1/$c1 because this is part of a continuing extended block
-                    if ($tag == 'p' and !$this-&gt;hasRawText($content)) {
-                        $line = $content;
-                    }
-                    else {
-                        $line = $o2.$content.$c2;
-                    }
-                }
-                else {
-                   $line = $this-&gt;graf($line);
-                }
-            }
-
-            $line = $this-&gt;doPBr($line);
-            $line = preg_replace('/&lt;br&gt;/', '&lt;br /&gt;', $line);
-
-            if ($ext and $anon)
-                $out[count($out)-1] .= &quot;\n&quot;.$line;
-            else
-                $out[] = $line;
-
-            if (!$ext) {
-                $tag = 'p';
-                $atts = '';
-                $cite = '';
-                $graf = '';
-            }
-        }
-        if ($ext) $out[count($out)-1] .= $c1;
-        return join(&quot;\n\n&quot;, $out);
-    }
+	function block($text)
+	{
+		$find = $this-&gt;btag;
+		$tre = join('|', $find);
+
+		$text = explode(&quot;\n\n&quot;, $text);
+
+		$tag = 'p';
+		$atts = $cite = $graf = $ext  = '';
+
+		foreach($text as $line) {
+			$anon = 0;
+			if (preg_match(&quot;/^($tre)($this-&gt;a$this-&gt;c)\.(\.?)(?::(\S+))? (.*)$/s&quot;, $line, $m)) {
+				// last block was extended, so close it
+				if ($ext)
+					$out[count($out)-1] .= $c1;
+				// new block
+				list(,$tag,$atts,$ext,$cite,$graf) = $m;
+				list($o1, $o2, $content, $c2, $c1) = $this-&gt;fBlock(array(0,$tag,$atts,$ext,$cite,$graf));
+
+				// leave off c1 if this block is extended, we'll close it at the start of the next block
+				if ($ext)
+					$line = $o1.$o2.$content.$c2;
+				else
+					$line = $o1.$o2.$content.$c2.$c1;
+			}
+			else {
+				// anonymous block
+				$anon = 1;
+				if ($ext or !preg_match('/^ /', $line)) {
+					list($o1, $o2, $content, $c2, $c1) = $this-&gt;fBlock(array(0,$tag,$atts,$ext,$cite,$line));
+					// skip $o1/$c1 because this is part of a continuing extended block
+					if ($tag == 'p' and !$this-&gt;hasRawText($content)) {
+						$line = $content;
+					}
+					else {
+						$line = $o2.$content.$c2;
+					}
+				}
+				else {
+				   $line = $this-&gt;graf($line);
+				}
+			}
+
+			$line = $this-&gt;doPBr($line);
+			$line = preg_replace('/&lt;br&gt;/', '&lt;br /&gt;', $line);
+
+			if ($ext and $anon)
+				$out[count($out)-1] .= &quot;\n&quot;.$line;
+			else
+				$out[] = $line;
+
+			if (!$ext) {
+				$tag = 'p';
+				$atts = '';
+				$cite = '';
+				$graf = '';
+			}
+		}
+		if ($ext) $out[count($out)-1] .= $c1;
+		return join(&quot;\n\n&quot;, $out);
+	}
 
 
 
 // -------------------------------------------------------------
-    function fBlock($m)
-    {
-        // $this-&gt;dump($m);
-        list(, $tag, $atts, $ext, $cite, $content) = $m;
-        $atts = $this-&gt;pba($atts);
-
-        $o1 = $o2 = $c2 = $c1 = '';
-
-        if (preg_match(&quot;/fn(\d+)/&quot;, $tag, $fns)) {
-            $tag = 'p';
-            $fnid = empty($this-&gt;fn[$fns[1]]) ? $fns[1] : $this-&gt;fn[$fns[1]];
-            $atts .= ' id=&quot;fn' . $fnid . '&quot;';
-            if (strpos($atts, 'class=') === false)
-                $atts .= ' class=&quot;footnote&quot;';
-            $content = '&lt;sup&gt;' . $fns[1] . '&lt;/sup&gt; ' . $content;
-        }
-
-        if ($tag == &quot;bq&quot;) {
-            $cite = $this-&gt;checkRefs($cite);
-            $cite = ($cite != '') ? ' cite=&quot;' . $cite . '&quot;' : '';
-            $o1 = &quot;\t&lt;blockquote$cite$atts&gt;\n&quot;;
-            $o2 = &quot;\t\t&lt;p$atts&gt;&quot;;
-            $c2 = &quot;&lt;/p&gt;&quot;;
-            $c1 = &quot;\n\t&lt;/blockquote&gt;&quot;;
-        }
-        elseif ($tag == 'bc') {
-            $o1 = &quot;&lt;pre$atts&gt;&quot;;
-            $o2 = &quot;&lt;code$atts&gt;&quot;;
-            $c2 = &quot;&lt;/code&gt;&quot;;
-            $c1 = &quot;&lt;/pre&gt;&quot;;
-            $content = $this-&gt;shelve($this-&gt;encode_html(rtrim($content, &quot;\n&quot;).&quot;\n&quot;));
-        }
-        elseif ($tag == 'notextile') {
-            $content = $this-&gt;shelve($content);
-            $o1 = $o2 = '';
-            $c1 = $c2 = '';
-        }
-        elseif ($tag == 'pre') {
-            $content = $this-&gt;shelve($this-&gt;encode_html(rtrim($content, &quot;\n&quot;).&quot;\n&quot;));
-            $o1 = &quot;&lt;pre$atts&gt;&quot;;
-            $o2 = $c2 = '';
-            $c1 = &quot;&lt;/pre&gt;&quot;;
-        }
-        else {
-            $o2 = &quot;\t&lt;$tag$atts&gt;&quot;;
-            $c2 = &quot;&lt;/$tag&gt;&quot;;
-          }
-
-        $content = $this-&gt;graf($content);
-
-        return array($o1, $o2, $content, $c2, $c1);
-    }
+	function fBlock($m)
+	{
+		// $this-&gt;dump($m);
+		list(, $tag, $att, $ext, $cite, $content) = $m;
+		$atts = $this-&gt;pba($att);
+
+		$o1 = $o2 = $c2 = $c1 = '';
+
+		if (preg_match(&quot;/fn(\d+)/&quot;, $tag, $fns)) {
+			$tag = 'p';
+			$fnid = empty($this-&gt;fn[$fns[1]]) ? $fns[1] : $this-&gt;fn[$fns[1]];
+			$atts .= ' id=&quot;fn' . $fnid . '&quot;';
+			if (strpos($atts, 'class=') === false)
+				$atts .= ' class=&quot;footnote&quot;';
+			$content = '&lt;sup&gt;' . $fns[1] . '&lt;/sup&gt; ' . $content;
+		}
+
+		if ($tag == &quot;bq&quot;) {
+			$cite = $this-&gt;shelveURL($cite);
+			$cite = ($cite != '') ? ' cite=&quot;' . $cite . '&quot;' : '';
+			$o1 = &quot;\t&lt;blockquote$cite$atts&gt;\n&quot;;
+			$o2 = &quot;\t\t&lt;p&quot;.$this-&gt;pba($att, '', 0).&quot;&gt;&quot;;
+			$c2 = &quot;&lt;/p&gt;&quot;;
+			$c1 = &quot;\n\t&lt;/blockquote&gt;&quot;;
+		}
+		elseif ($tag == 'bc') {
+			$o1 = &quot;&lt;pre$atts&gt;&quot;;
+			$o2 = &quot;&lt;code&quot;.$this-&gt;pba($att, '', 0).&quot;&gt;&quot;;
+			$c2 = &quot;&lt;/code&gt;&quot;;
+			$c1 = &quot;&lt;/pre&gt;&quot;;
+			$content = $this-&gt;shelve($this-&gt;r_encode_html(rtrim($content, &quot;\n&quot;).&quot;\n&quot;));
+		}
+		elseif ($tag == 'notextile') {
+			$content = $this-&gt;shelve($content);
+			$o1 = $o2 = '';
+			$c1 = $c2 = '';
+		}
+		elseif ($tag == 'pre') {
+			$content = $this-&gt;shelve($this-&gt;r_encode_html(rtrim($content, &quot;\n&quot;).&quot;\n&quot;));
+			$o1 = &quot;&lt;pre$atts&gt;&quot;;
+			$o2 = $c2 = '';
+			$c1 = &quot;&lt;/pre&gt;&quot;;
+		}
+		else {
+			$o2 = &quot;\t&lt;$tag$atts&gt;&quot;;
+			$c2 = &quot;&lt;/$tag&gt;&quot;;
+		  }
+
+		$content = $this-&gt;graf($content);
+
+		return array($o1, $o2, $content, $c2, $c1);
+	}
 
 // -------------------------------------------------------------
-    function graf($text)
-    {
-        // handle normal paragraph text
-        if (!$this-&gt;lite) {
-            $text = $this-&gt;noTextile($text);
-            $text = $this-&gt;code($text);
-        }
-
-        $text = $this-&gt;links($text);
-        if (!$this-&gt;noimage)
-            $text = $this-&gt;image($text);
-
-        if (!$this-&gt;lite) {
-            $text = $this-&gt;lists($text);
-            $text = $this-&gt;table($text);
-        }
-
-        $text = $this-&gt;span($text);
-        $text = $this-&gt;footnoteRef($text);
-        $text = $this-&gt;glyphs($text);
-        return rtrim($text, &quot;\n&quot;);
-    }
+	function graf($text)
+	{
+		// handle normal paragraph text
+		if (!$this-&gt;lite) {
+			$text = $this-&gt;noTextile($text);
+			$text = $this-&gt;code($text);
+		}
+
+		$text = $this-&gt;getRefs($text);
+		$text = $this-&gt;links($text);
+		if (!$this-&gt;noimage)
+			$text = $this-&gt;image($text);
+
+		if (!$this-&gt;lite) {
+			$text = $this-&gt;table($text);
+			$text = $this-&gt;lists($text);
+		}
+
+		$text = $this-&gt;span($text);
+		$text = $this-&gt;footnoteRef($text);
+		$text = $this-&gt;glyphs($text);
+		return rtrim($text, &quot;\n&quot;);
+	}
 
 // -------------------------------------------------------------
-    function span($text)
-    {
-        $qtags = array('\*\*','\*','\?\?','-','__','_','%','\+','~','\^');
-        $pnct = &quot;.,\&quot;'?!;:&quot;;
-
-        foreach($qtags as $f) {
-            $text = preg_replace_callback(&quot;/
-                (?:^|(?&lt;=[\s&gt;$pnct])|([{[]))
-                ($f)(?!$f)
-                ({$this-&gt;c})
-                (?::(\S+))?
-                ([^\s$f]+|\S[^$f\n]*[^\s$f\n])
-                ([$pnct]*)
-                $f
-                (?:$|([\]}])|(?=[[:punct:]]{1,2}|\s))
-            /x&quot;, array(&amp;$this, &quot;fSpan&quot;), $text);
-        }
-        return $text;
-    }
+	function span($text)
+	{
+		$qtags = array('\*\*','\*','\?\?','-','__','_','%','\+','~','\^');
+		$pnct = &quot;.,\&quot;'?!;:&quot;;
+
+		foreach($qtags as $f) {
+			$text = preg_replace_callback(&quot;/
+				(^|(?&lt;=[\s&gt;$pnct\(])|[{[])
+				($f)(?!$f)
+				({$this-&gt;c})
+				(?::(\S+))?
+				([^\s$f]+|\S.*?[^\s$f\n])
+				([$pnct]*)
+				$f
+				($|[\]}]|(?=[[:punct:]]{1,2}|\s|\)))
+			/x&quot;, array(&amp;$this, &quot;fSpan&quot;), $text);
+		}
+		return $text;
+	}
 
 // -------------------------------------------------------------
-    function fSpan($m)
-    {
-        $qtags = array(
-            '*'  =&gt; 'strong',
-            '**' =&gt; 'b',
-            '??' =&gt; 'cite',
-            '_'  =&gt; 'em',
-            '__' =&gt; 'i',
-            '-'  =&gt; 'del',
-            '%'  =&gt; 'span',
-            '+'  =&gt; 'ins',
-            '~'  =&gt; 'sub',
-            '^'  =&gt; 'sup',
-        );
-
-        list(,, $tag, $atts, $cite, $content, $end) = $m;
-        $tag = $qtags[$tag];
-        $atts = $this-&gt;pba($atts);
-        $atts .= ($cite != '') ? 'cite=&quot;' . $cite . '&quot;' : '';
-
-        $out = &quot;&lt;$tag$atts&gt;$content$end&lt;/$tag&gt;&quot;;
-
-//      $this-&gt;dump($out);
-
-        return $out;
-
-    }
+	function fSpan($m)
+	{
+		$qtags = array(
+			'*'  =&gt; 'strong',
+			'**' =&gt; 'b',
+			'??' =&gt; 'cite',
+			'_'  =&gt; 'em',
+			'__' =&gt; 'i',
+			'-'  =&gt; 'del',
+			'%'  =&gt; 'span',
+			'+'  =&gt; 'ins',
+			'~'  =&gt; 'sub',
+			'^'  =&gt; 'sup',
+		);
+
+		list(, $pre, $tag, $atts, $cite, $content, $end, $tail) = $m;
+		$tag = $qtags[$tag];
+		$atts = $this-&gt;pba($atts);
+		$atts .= ($cite != '') ? 'cite=&quot;' . $cite . '&quot;' : '';
+
+		$out = &quot;&lt;$tag$atts&gt;$content$end&lt;/$tag&gt;&quot;;
+
+		if (($pre and !$tail) or ($tail and !$pre))
+			$out = $pre.$out.$tail;
+
+//		$this-&gt;dump($out);
+
+		return $out;
+
+	}
 
 // -------------------------------------------------------------
-    function links($text)
-    {
-        return preg_replace_callback('/
-            (?:^|(?&lt;=[\s&gt;.$pnct\(])|([{[])) # $pre
-            &quot;                            # start
-            (' . $this-&gt;c . ')           # $atts
-            ([^&quot;]+)                      # $text
-            \s?
-            (?:\(([^)]+)\)(?=&quot;))?        # $title
-            &quot;:
-            ('.$this-&gt;urlch.'+)          # $url
-            (\/)?                        # $slash
-            ([^\w\/;]*)                  # $post
-            (?:([\]}])|(?=\s|$|\)))
-        /Ux', array(&amp;$this, &quot;fLink&quot;), $text);
-    }
+	function links($text)
+	{
+		return preg_replace_callback('/
+			(^|(?&lt;=[\s&gt;.$pnct\(])|[{[]) # $pre
+			&quot;							 # start
+			(' . $this-&gt;c . ')			 # $atts
+			([^&quot;]+?)					 # $text
+			(?:\(([^)]+?)\)(?=&quot;))?		 # $title
+			&quot;:
+			('.$this-&gt;urlch.'+?)		 # $url
+			(\/)?						 # $slash
+			([^\w\/;]*?)				 # $post
+			([\]}]|(?=\s|$|\)))
+		/x', array(&amp;$this, &quot;fLink&quot;), $text);
+	}
 
 // -------------------------------------------------------------
-    function fLink($m)
-    {
-        list(, $pre, $atts, $text, $title, $url, $slash, $post) = $m;
+	function fLink($m)
+	{
+		list(, $pre, $atts, $text, $title, $url, $slash, $post, $tail) = $m;
 
-        $url = $this-&gt;checkRefs($url);
+		$atts = $this-&gt;pba($atts);
+		$atts .= ($title != '') ? ' title=&quot;' . $this-&gt;encode_html($title) . '&quot;' : '';
 
-        $atts = $this-&gt;pba($atts);
-        $atts .= ($title != '') ? ' title=&quot;' . $this-&gt;encode_html($title) . '&quot;' : '';
+		if (!$this-&gt;noimage)
+			$text = $this-&gt;image($text);
 
-        if (!$this-&gt;noimage)
-            $text = $this-&gt;image($text);
+		$text = $this-&gt;span($text);
+		$text = $this-&gt;glyphs($text);
 
-        $text = $this-&gt;span($text);
-        $text = $this-&gt;glyphs($text);
+		$url = $this-&gt;shelveURL($url.$slash);
 
-        $url = $this-&gt;relURL($url);
+		$out = '&lt;a href=&quot;' . $url . '&quot;' . $atts . $this-&gt;rel . '&gt;' . trim($text) . '&lt;/a&gt;' . $post;
+		
+		if (($pre and !$tail) or ($tail and !$pre))
+			$out = $pre.$out.$tail;
 
-        $out = '&lt;a href=&quot;' . $this-&gt;encode_html($url . $slash) . '&quot;' . $atts . $this-&gt;rel . '&gt;' . $text . '&lt;/a&gt;' . $post;
+		// $this-&gt;dump($out);
+		return $this-&gt;shelve($out);
 
-        // $this-&gt;dump($out);
-        return $this-&gt;shelve($out);
+	}
 
-    }
+// -------------------------------------------------------------
+	function getRefs($text)
+	{
+		return preg_replace_callback(&quot;/^\[(.+)\]((?:http:\/\/|\/)\S+)(?=\s|$)/Um&quot;,
+			array(&amp;$this, &quot;refs&quot;), $text);
+	}
+
+// -------------------------------------------------------------
+	function refs($m)
+	{
+		list(, $flag, $url) = $m;
+		$this-&gt;urlrefs[$flag] = $url;
+		return '';
+	}
 
 // -------------------------------------------------------------
-    function getRefs($text)
-    {
-        return preg_replace_callback(&quot;/(?&lt;=^|\s)\[(.+)\]((?:http:\/\/|\/)\S+)(?=\s|$)/U&quot;,
-            array(&amp;$this, &quot;refs&quot;), $text);
-    }
+	function shelveURL($text)
+	{
+		if (!$text) return '';
+		$ref = md5($text);
+		$this-&gt;urlshelf[$ref] = $text;
+		return 'urlref:'.$ref;
+	}
 
 // -------------------------------------------------------------
-    function refs($m)
-    {
-        list(, $flag, $url) = $m;
-        $this-&gt;urlrefs[$flag] = $url;
-        return '';
-    }
+	function retrieveURLs($text)
+	{
+		return preg_replace_callback('/urlref:(\w{32})/',
+			array(&amp;$this, &quot;retrieveURL&quot;), $text);
+	}
 
 // -------------------------------------------------------------
-    function checkRefs($text)
-    {
-        return (isset($this-&gt;urlrefs[$text])) ? $this-&gt;urlrefs[$text] : $text;
-    }
+	function retrieveURL($m)
+	{
+		$ref = $m[1];
+		if (!isset($this-&gt;urlshelf[$ref]))
+			return $ref;
+		$url = $this-&gt;urlshelf[$ref];
+		if (isset($this-&gt;urlrefs[$url]))
+			$url = $this-&gt;urlrefs[$url];
+		return $this-&gt;r_encode_html($this-&gt;relURL($url));
+	}
 
 // -------------------------------------------------------------
-    function relURL($url)
-    {
-        $parts = parse_url($url);
-        if ((empty($parts['scheme']) or @$parts['scheme'] == 'http') and
-             empty($parts['host']) and
-             preg_match('/^\w/', @$parts['path']))
-            $url = $this-&gt;hu.$url;
-        if ($this-&gt;restricted and !empty($parts['scheme']) and
-              !in_array($parts['scheme'], $this-&gt;url_schemes))
-            return '#';
-        return $url;
-    }
+	function relURL($url)
+	{
+		$parts = @parse_url(urldecode($url));
+		if ((empty($parts['scheme']) or @$parts['scheme'] == 'http') and
+			 empty($parts['host']) and
+			 preg_match('/^\w/', @$parts['path']))
+			$url = $this-&gt;hu.$url;
+		if ($this-&gt;restricted and !empty($parts['scheme']) and
+			  !in_array($parts['scheme'], $this-&gt;url_schemes))
+			return '#';
+		return $url;
+	}
 
 // -------------------------------------------------------------
-    function image($text)
-    {
-        return preg_replace_callback(&quot;/
-            (?:[[{])?          # pre
-            \!                 # opening !
-            (\&lt;|\=|\&gt;)??       # optional alignment atts
-            ($this-&gt;c)         # optional style,class atts
-            (?:\. )?           # optional dot-space
-            ([^\s(!]+)         # presume this is the src
-            \s?                # optional space
-            (?:\(([^\)]+)\))?  # optional title
-            \!                 # closing
-            (?::(\S+))?        # optional href
-            (?:[\]}]|(?=\s|$)) # lookahead: space or end of string
-        /Ux&quot;, array(&amp;$this, &quot;fImage&quot;), $text);
-    }
+	function isRelURL($url)
+	{
+		$parts = @parse_url($url);
+		return (empty($parts['scheme']) and empty($parts['host']));
+	}
 
 // -------------------------------------------------------------
-    function fImage($m)
-    {
-        list(, $algn, $atts, $url) = $m;
-        $atts  = $this-&gt;pba($atts);
-        $atts .= ($algn != '')  ? ' align=&quot;' . $this-&gt;iAlign($algn) . '&quot;' : '';
-        $atts .= (isset($m[4])) ? ' title=&quot;' . $m[4] . '&quot;' : '';
-        $atts .= (isset($m[4])) ? ' alt=&quot;'   . $m[4] . '&quot;' : ' alt=&quot;&quot;';
-        $size = @getimagesize($url);
-        if ($size) $atts .= &quot; $size[3]&quot;;
-
-        $href = (isset($m[5])) ? $this-&gt;checkRefs($m[5]) : '';
-        $url = $this-&gt;checkRefs($url);
-
-        $url = $this-&gt;relURL($url);
-
-        $out = array(
-            ($href) ? '&lt;a href=&quot;' . $href . '&quot;&gt;' : '',
-            '&lt;img src=&quot;' . $url . '&quot;' . $atts . ' /&gt;',
-            ($href) ? '&lt;/a&gt;' : ''
-        );
-
-        return join('',$out);
-    }
+	function image($text)
+	{
+		return preg_replace_callback(&quot;/
+			(?:[[{])?		   # pre
+			\!				   # opening !
+			(\&lt;|\=|\&gt;)? 	   # optional alignment atts
+			($this-&gt;c)		   # optional style,class atts
+			(?:\. )?		   # optional dot-space
+			([^\s(!]+)		   # presume this is the src
+			\s? 			   # optional space
+			(?:\(([^\)]+)\))?  # optional title
+			\!				   # closing
+			(?::(\S+))? 	   # optional href
+			(?:[\]}]|(?=\s|$|\))) # lookahead: space or end of string
+		/x&quot;, array(&amp;$this, &quot;fImage&quot;), $text);
+	}
 
 // -------------------------------------------------------------
-    function code($text)
-    {
-        $text = $this-&gt;doSpecial($text, '&lt;code&gt;', '&lt;/code&gt;', 'fCode');
-        $text = $this-&gt;doSpecial($text, '@', '@', 'fCode');
-        $text = $this-&gt;doSpecial($text, '&lt;pre&gt;', '&lt;/pre&gt;', 'fPre');
-        return $text;
-    }
+	function fImage($m)
+	{
+		list(, $algn, $atts, $url) = $m;
+		$atts  = $this-&gt;pba($atts);
+		$atts .= ($algn != '')	? ' align=&quot;' . $this-&gt;iAlign($algn) . '&quot;' : '';
+		$atts .= (isset($m[4])) ? ' title=&quot;' . $m[4] . '&quot;' : '';
+		$atts .= (isset($m[4])) ? ' alt=&quot;'	 . $m[4] . '&quot;' : ' alt=&quot;&quot;';
+		$size = false;
+		if ($this-&gt;isRelUrl($url))
+			$size = @getimagesize(realpath($this-&gt;doc_root.ltrim($url, $this-&gt;ds)));
+		if ($size) $atts .= &quot; $size[3]&quot;;
+
+		$href = (isset($m[5])) ? $this-&gt;shelveURL($m[5]) : '';
+		$url = $this-&gt;shelveURL($url);
+
+		$out = array(
+			($href) ? '&lt;a href=&quot;' . $href . '&quot;&gt;' : '',
+			'&lt;img src=&quot;' . $url . '&quot;' . $atts . ' /&gt;',
+			($href) ? '&lt;/a&gt;' : ''
+		);
+
+		return $this-&gt;shelve(join('',$out));
+	}
 
 // -------------------------------------------------------------
-    function fCode($m)
-    {
-      @list(, $before, $text, $after) = $m;
-      if ($this-&gt;restricted)
-          // $text is already escaped
-            return $before.$this-&gt;shelve('&lt;code&gt;'.$text.'&lt;/code&gt;').$after;
-      else
-            return $before.$this-&gt;shelve('&lt;code&gt;'.$this-&gt;encode_html($text).'&lt;/code&gt;').$after;
-    }
+	function code($text)
+	{
+		$text = $this-&gt;doSpecial($text, '&lt;code&gt;', '&lt;/code&gt;', 'fCode');
+		$text = $this-&gt;doSpecial($text, '@', '@', 'fCode');
+		$text = $this-&gt;doSpecial($text, '&lt;pre&gt;', '&lt;/pre&gt;', 'fPre');
+		return $text;
+	}
 
 // -------------------------------------------------------------
-    function fPre($m)
-    {
-      @list(, $before, $text, $after) = $m;
-      if ($this-&gt;restricted)
-          // $text is already escaped
-            return $before.'&lt;pre&gt;'.$this-&gt;shelve($text).'&lt;/pre&gt;'.$after;
-      else
-            return $before.'&lt;pre&gt;'.$this-&gt;shelve($this-&gt;encode_html($text)).'&lt;/pre&gt;'.$after;
-    }
+	function fCode($m)
+	{
+	  @list(, $before, $text, $after) = $m;
+	  return $before.$this-&gt;shelve('&lt;code&gt;'.$this-&gt;r_encode_html($text).'&lt;/code&gt;').$after;
+	}
+
+// -------------------------------------------------------------
+	function fPre($m)
+	{
+	  @list(, $before, $text, $after) = $m;
+	  return $before.'&lt;pre&gt;'.$this-&gt;shelve($this-&gt;r_encode_html($text)).'&lt;/pre&gt;'.$after;
+	}
 // -------------------------------------------------------------
-    function shelve($val)
-    {
-        $i = uniqid(rand());
-        $this-&gt;shelf[$i] = $val;
-        return $i;
-    }
+	function shelve($val)
+	{
+		$i = uniqid(rand());
+		$this-&gt;shelf[$i] = $val;
+		return $i;
+	}
 
 // -------------------------------------------------------------
-    function retrieve($text)
-    {
-        if (is_array($this-&gt;shelf))
-            do {
-                $old = $text;
-                $text = strtr($text, $this-&gt;shelf);
-             } while ($text != $old);
+	function retrieve($text)
+	{
+		if (is_array($this-&gt;shelf))
+			do {
+				$old = $text;
+				$text = strtr($text, $this-&gt;shelf);
+			 } while ($text != $old);
 
-        return $text;
-    }
+		return $text;
+	}
 
 // -------------------------------------------------------------
 // NOTE: deprecated
-    function incomingEntities($text)
-    {
-        return preg_replace(&quot;/&amp;(?![#a-z0-9]+;)/i&quot;, &quot;x%x%&quot;, $text);
-    }
+	function incomingEntities($text)
+	{
+		return preg_replace(&quot;/&amp;(?![#a-z0-9]+;)/i&quot;, &quot;x%x%&quot;, $text);
+	}
 
 // -------------------------------------------------------------
 // NOTE: deprecated
-    function encodeEntities($text)
-    {
-        return (function_exists('mb_encode_numericentity'))
-        ?    $this-&gt;encode_high($text)
-        :    htmlentities($text, ENT_NOQUOTES, &quot;utf-8&quot;);
-    }
+	function encodeEntities($text)
+	{
+		return (function_exists('mb_encode_numericentity'))
+		?	 $this-&gt;encode_high($text)
+		:	 htmlentities($text, ENT_NOQUOTES, &quot;utf-8&quot;);
+	}
 
 // -------------------------------------------------------------
 // NOTE: deprecated
-    function fixEntities($text)
-    {
-        /*  de-entify any remaining angle brackets or ampersands */
-        return str_replace(array(&quot;&amp;gt;&quot;, &quot;&amp;lt;&quot;, &quot;&amp;amp;&quot;),
-            array(&quot;&gt;&quot;, &quot;&lt;&quot;, &quot;&amp;&quot;), $text);
-    }
+	function fixEntities($text)
+	{
+		/*	de-entify any remaining angle brackets or ampersands */
+		return str_replace(array(&quot;&amp;gt;&quot;, &quot;&amp;lt;&quot;, &quot;&amp;amp;&quot;),
+			array(&quot;&gt;&quot;, &quot;&lt;&quot;, &quot;&amp;&quot;), $text);
+	}
 
 // -------------------------------------------------------------
-    function cleanWhiteSpace($text)
-    {
-        $out = str_replace(&quot;\r\n&quot;, &quot;\n&quot;, $text);
-        $out = preg_replace(&quot;/\n{3,}/&quot;, &quot;\n\n&quot;, $out);
-        $out = preg_replace(&quot;/\n *\n/&quot;, &quot;\n\n&quot;, $out);
-        $out = preg_replace('/&quot;$/', &quot;\&quot; &quot;, $out);
-        return $out;
-    }
+	function cleanWhiteSpace($text)
+	{
+		$out = str_replace(&quot;\r\n&quot;, &quot;\n&quot;, $text);		# DOS line endings
+		$out = preg_replace(&quot;/^[ \t]*\n/m&quot;, &quot;\n&quot;, $out);	# lines containing only whitespace
+		$out = preg_replace(&quot;/\n{3,}/&quot;, &quot;\n\n&quot;, $out);	# 3 or more line ends
+		$out = preg_replace(&quot;/^\n*/&quot;, &quot;&quot;, $out);		# leading blank lines
+		return $out;
+	}
 
 // -------------------------------------------------------------
-    function doSpecial($text, $start, $end, $method='fSpecial')
-    {
-      return preg_replace_callback('/(^|\s|[[({&gt;])'.preg_quote($start, '/').'(.*?)'.preg_quote($end, '/').'(\s|$|[\])}])?/ms',
-            array(&amp;$this, $method), $text);
-    }
+	function doSpecial($text, $start, $end, $method='fSpecial')
+	{
+	  return preg_replace_callback('/(^|\s|[[({&gt;])'.preg_quote($start, '/').'(.*?)'.preg_quote($end, '/').'(\s|$|[\])}])?/ms',
+			array(&amp;$this, $method), $text);
+	}
 
 // -------------------------------------------------------------
-    function fSpecial($m)
-    {
-        // A special block like notextile or code
-      @list(, $before, $text, $after) = $m;
-        return $before.$this-&gt;shelve($this-&gt;encode_html($text)).$after;
-    }
+	function fSpecial($m)
+	{
+		// A special block like notextile or code
+	  @list(, $before, $text, $after) = $m;
+		return $before.$this-&gt;shelve($this-&gt;encode_html($text)).$after;
+	}
 
 // -------------------------------------------------------------
-    function noTextile($text)
-    {
-         $text = $this-&gt;doSpecial($text, '&lt;notextile&gt;', '&lt;/notextile&gt;', 'fTextile');
-         return $this-&gt;doSpecial($text, '==', '==', 'fTextile');
+	function noTextile($text)
+	{
+		 $text = $this-&gt;doSpecial($text, '&lt;notextile&gt;', '&lt;/notextile&gt;', 'fTextile');
+		 return $this-&gt;doSpecial($text, '==', '==', 'fTextile');
 
-    }
+	}
 
 // -------------------------------------------------------------
-    function fTextile($m)
-    {
-        @list(, $before, $notextile, $after) = $m;
-        #$notextile = str_replace(array_keys($modifiers), array_values($modifiers), $notextile);
-        return $before.$this-&gt;shelve($notextile).$after;
-    }
+	function fTextile($m)
+	{
+		@list(, $before, $notextile, $after) = $m;
+		#$notextile = str_replace(array_keys($modifiers), array_values($modifiers), $notextile);
+		return $before.$this-&gt;shelve($notextile).$after;
+	}
 
 // -------------------------------------------------------------
-    function footnoteRef($text)
-    {
-        return preg_replace('/\b\[([0-9]+)\](\s)?/Ue',
-            '$this-&gt;footnoteID(\'\1\',\'\2\')', $text);
-    }
+	function footnoteRef($text)
+	{
+		return preg_replace('/(?&lt;=\S)\[([0-9]+)\](\s)?/Ue',
+			'$this-&gt;footnoteID(\'\1\',\'\2\')', $text);
+	}
 
 // -------------------------------------------------------------
-    function footnoteID($id, $t)
-    {
-        if (empty($this-&gt;fn[$id]))
-            $this-&gt;fn[$id] = uniqid(rand());
-        $fnid = $this-&gt;fn[$id];
-        return '&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#fn'.$fnid.'&quot;&gt;'.$id.'&lt;/a&gt;&lt;/sup&gt;'.$t;
-    }
+	function footnoteID($id, $t)
+	{
+		if (empty($this-&gt;fn[$id]))
+			$this-&gt;fn[$id] = uniqid(rand());
+		$fnid = $this-&gt;fn[$id];
+		return '&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#fn'.$fnid.'&quot;&gt;'.$id.'&lt;/a&gt;&lt;/sup&gt;'.$t;
+	}
 
 // -------------------------------------------------------------
-    function glyphs($text)
-    {
-        // fix: hackish
-        $text = preg_replace('/&quot;\z/', &quot;\&quot; &quot;, $text);
-        $pnc = '[[:punct:]]';
-
-        $glyph_search = array(
-            '/(\w)\'(\w)/',                                      // apostrophe's
-            '/(\s)\'(\d+\w?)\b(?!\')/',                          // back in '88
-            '/(\S)\'(?=\s|'.$pnc.'|&lt;|$)/',                       //  single closing
-            '/\'/',                                              //  single opening
-            '/(\S)\&quot;(?=\s|'.$pnc.'|&lt;|$)/',                       //  double closing
-            '/&quot;/',                                               //  double opening
-            '/\b([A-Z][A-Z0-9]{2,})\b(?:[(]([^)]*)[)])/',        //  3+ uppercase acronym
-            '/\b([A-Z][A-Z\'\-]+[A-Z])(?=[\s.,\)&gt;])/',           //  3+ uppercase
-            '/\b( )?\.{3}/',                                     //  ellipsis
-            '/(\s?)--(\s?)/',                                    //  em dash
-            '/\s-(?:\s|$)/',                                     //  en dash
-            '/(\d+)( ?)x( ?)(?=\d+)/',                           //  dimension sign
-            '/\b ?[([]TM[])]/i',                                 //  trademark
-            '/\b ?[([]R[])]/i',                                  //  registered
-            '/\b ?[([]C[])]/i',                                  //  copyright
-         );
-
-        extract($this-&gt;glyph, EXTR_PREFIX_ALL, 'txt');
-
-        $glyph_replace = array(
-            '$1'.$txt_apostrophe.'$2',           // apostrophe's
-            '$1'.$txt_apostrophe.'$2',           // back in '88
-            '$1'.$txt_quote_single_close,        //  single closing
-            $txt_quote_single_open,              //  single opening
-            '$1'.$txt_quote_double_close,        //  double closing
-            $txt_quote_double_open,              //  double opening
-            '&lt;acronym title=&quot;$2&quot;&gt;$1&lt;/acronym&gt;',  //  3+ uppercase acronym
-            '&lt;span class=&quot;caps&quot;&gt;$1&lt;/span&gt;',      //  3+ uppercase
-            '$1'.$txt_ellipsis,                  //  ellipsis
-            '$1'.$txt_emdash.'$2',               //  em dash
-            ' '.$txt_endash.' ',                 //  en dash
-            '$1$2'.$txt_dimension.'$3',          //  dimension sign
-            $txt_trademark,                      //  trademark
-            $txt_registered,                     //  registered
-            $txt_copyright,                      //  copyright
-         );
-
-         $text = preg_split(&quot;/(&lt;.*&gt;)/U&quot;, $text, -1, PREG_SPLIT_DELIM_CAPTURE);
-         foreach($text as $line) {
-             if (!preg_match(&quot;/&lt;.*&gt;/&quot;, $line)) {
-                 $line = preg_replace($glyph_search, $glyph_replace, $line);
-             }
-              $glyph_out[] = $line;
-         }
-         return join('', $glyph_out);
-    }
+	function glyphs($text)
+	{
+
+		// fix: hackish
+		$text = preg_replace('/&quot;\z/', &quot;\&quot; &quot;, $text);
+		$pnc = '[[:punct:]]';
+
+		$glyph_search = array(
+			'/(\w)\'(\w)/', 									 // apostrophe's
+			'/(\s)\'(\d+\w?)\b(?!\')/', 						 // back in '88
+			'/(\S)\'(?=\s|'.$pnc.'|&lt;|$)/',						 //  single closing
+			'/\'/', 											 //  single opening
+			'/(\S)\&quot;(?=\s|'.$pnc.'|&lt;|$)/',						 //  double closing
+			'/&quot;/',												 //  double opening
+			'/\b([A-Z][A-Z0-9]{2,})\b(?:[(]([^)]*)[)])/',		 //  3+ uppercase acronym
+			'/(?&lt;=\s|^|[&gt;(;-])([A-Z]{3,})([a-z]*)(?=\s|'.$pnc.'|&lt;|$)/',  //  3+ uppercase
+			'/([^.]?)\.{3}/',									 //  ellipsis
+			'/(\s?)--(\s?)/',									 //  em dash
+			'/\s-(?:\s|$)/',									 //  en dash
+			'/(\d+)( ?)x( ?)(?=\d+)/',							 //  dimension sign
+			'/(\b ?|\s|^)[([]TM[])]/i', 						 //  trademark
+			'/(\b ?|\s|^)[([]R[])]/i',							 //  registered
+			'/(\b ?|\s|^)[([]C[])]/i',							 //  copyright
+		 );
+
+		extract($this-&gt;glyph, EXTR_PREFIX_ALL, 'txt');
+
+		$glyph_replace = array(
+			'$1'.$txt_apostrophe.'$2',			 // apostrophe's
+			'$1'.$txt_apostrophe.'$2',			 // back in '88
+			'$1'.$txt_quote_single_close,		 //  single closing
+			$txt_quote_single_open, 			 //  single opening
+			'$1'.$txt_quote_double_close,		 //  double closing
+			$txt_quote_double_open, 			 //  double opening
+			'&lt;acronym title=&quot;$2&quot;&gt;$1&lt;/acronym&gt;',  //  3+ uppercase acronym
+			'&lt;span class=&quot;caps&quot;&gt;$1&lt;/span&gt;$2',	 //  3+ uppercase
+			'$1'.$txt_ellipsis, 				 //  ellipsis
+			'$1'.$txt_emdash.'$2',				 //  em dash
+			' '.$txt_endash.' ',				 //  en dash
+			'$1$2'.$txt_dimension.'$3', 		 //  dimension sign
+			'$1'.$txt_trademark,				 //  trademark
+			'$1'.$txt_registered,				 //  registered
+			'$1'.$txt_copyright,				 //  copyright
+		 );
+
+		 $text = preg_split(&quot;@(&lt;[\w/!?].*&gt;)@Us&quot;, $text, -1, PREG_SPLIT_DELIM_CAPTURE);
+		 $i = 0;
+		 foreach($text as $line) {
+			 // text tag text tag text ...
+			 if (++$i % 2) {
+				 // raw &lt; &gt; &amp; chars are already entity encoded in restricted mode
+				 if (!$this-&gt;restricted) {
+					 $line = $this-&gt;encode_raw_amp($line);
+					 $line = $this-&gt;encode_lt_gt($line);
+				 }
+				 $line = preg_replace($glyph_search, $glyph_replace, $line);
+			 }
+			  $glyph_out[] = $line;
+		 }
+		 return join('', $glyph_out);
+	}
 
 // -------------------------------------------------------------
-    function iAlign($in)
-    {
-        $vals = array(
-            '&lt;' =&gt; 'left',
-            '=' =&gt; 'center',
-            '&gt;' =&gt; 'right');
-        return (isset($vals[$in])) ? $vals[$in] : '';
-    }
+	function iAlign($in)
+	{
+		$vals = array(
+			'&lt;' =&gt; 'left',
+			'=' =&gt; 'center',
+			'&gt;' =&gt; 'right');
+		return (isset($vals[$in])) ? $vals[$in] : '';
+	}
 
 // -------------------------------------------------------------
-    function hAlign($in)
-    {
-        $vals = array(
-            '&lt;'  =&gt; 'left',
-            '='  =&gt; 'center',
-            '&gt;'  =&gt; 'right',
-            '&lt;&gt;' =&gt; 'justify');
-        return (isset($vals[$in])) ? $vals[$in] : '';
-    }
+	function hAlign($in)
+	{
+		$vals = array(
+			'&lt;'  =&gt; 'left',
+			'='  =&gt; 'center',
+			'&gt;'  =&gt; 'right',
+			'&lt;&gt;' =&gt; 'justify');
+		return (isset($vals[$in])) ? $vals[$in] : '';
+	}
 
 // -------------------------------------------------------------
-    function vAlign($in)
-    {
-        $vals = array(
-            '^' =&gt; 'top',
-            '-' =&gt; 'middle',
-            '~' =&gt; 'bottom');
-        return (isset($vals[$in])) ? $vals[$in] : '';
-    }
+	function vAlign($in)
+	{
+		$vals = array(
+			'^' =&gt; 'top',
+			'-' =&gt; 'middle',
+			'~' =&gt; 'bottom');
+		return (isset($vals[$in])) ? $vals[$in] : '';
+	}
 
 // -------------------------------------------------------------
 // NOTE: deprecated
-    function encode_high($text, $charset = &quot;UTF-8&quot;)
-    {
-        return mb_encode_numericentity($text, $this-&gt;cmap(), $charset);
-    }
+	function encode_high($text, $charset = &quot;UTF-8&quot;)
+	{
+		return mb_encode_numericentity($text, $this-&gt;cmap(), $charset);
+	}
 
 // -------------------------------------------------------------
 // NOTE: deprecated
-    function decode_high($text, $charset = &quot;UTF-8&quot;)
-    {
-        return mb_decode_numericentity($text, $this-&gt;cmap(), $charset);
-    }
+	function decode_high($text, $charset = &quot;UTF-8&quot;)
+	{
+		return mb_decode_numericentity($text, $this-&gt;cmap(), $charset);
+	}
 
 // -------------------------------------------------------------
 // NOTE: deprecated
-    function cmap()
-    {
-        $f = 0xffff;
-        $cmap = array(
-            0x0080, 0xffff, 0, $f);
-        return $cmap;
-    }
+	function cmap()
+	{
+		$f = 0xffff;
+		$cmap = array(
+			0x0080, 0xffff, 0, $f);
+		return $cmap;
+	}
+
+// -------------------------------------------------------------
+	function encode_raw_amp($text)
+	 {
+		return preg_replace('/&amp;(?!#?[a-z0-9]+;)/i', '&amp;#38;', $text);
+	}
+
+// -------------------------------------------------------------
+	function encode_lt_gt($text)
+	 {
+		return strtr($text, array('&lt;' =&gt; '&amp;#60;', '&gt;' =&gt; '&amp;#62;'));
+	}
+
+// -------------------------------------------------------------
+	function encode_html($str, $quotes=1)
+	{
+		$a = array(
+			'&amp;' =&gt; '&amp;#38;',
+			'&lt;' =&gt; '&amp;#60;',
+			'&gt;' =&gt; '&amp;#62;',
+		);
+		if ($quotes) $a = $a + array(
+			&quot;'&quot; =&gt; '&amp;#39;',
+			'&quot;' =&gt; '&amp;#34;',
+		);
+
+		return strtr($str, $a);
+	}
 
 // -------------------------------------------------------------
-    function encode_html($str, $quotes=1)
-    {
-        $a = array(
-            '&amp;' =&gt; '&amp;#38;',
-            '&lt;' =&gt; '&amp;#60;',
-            '&gt;' =&gt; '&amp;#62;',
-        );
-        if ($quotes) $a = $a + array(
-            &quot;'&quot; =&gt; '&amp;#39;',
-            '&quot;' =&gt; '&amp;#34;',
-        );
-
-        return strtr($str, $a);
-    }
+	function r_encode_html($str, $quotes=1)
+	{
+		// in restricted mode, input has already been escaped
+		if ($this-&gt;restricted)
+			return $str;
+		return $this-&gt;encode_html($str, $quotes);
+	}
 
 // -------------------------------------------------------------
-    function textile_popup_help($name, $helpvar, $windowW, $windowH)
-    {
-        return ' &lt;a target=&quot;_blank&quot; href=&quot;http://www.textpattern.com/help/?item=' . $helpvar . '&quot; onclick=&quot;window.open(this.href, \'popupwindow\', \'width=' . $windowW . ',height=' . $windowH . ',scrollbars,resizable\'); return false;&quot;&gt;' . $name . '&lt;/a&gt;&lt;br /&gt;';
+	function textile_popup_help($name, $helpvar, $windowW, $windowH)
+	{
+		return ' &lt;a target=&quot;_blank&quot; href=&quot;http://www.textpattern.com/help/?item=' . $helpvar . '&quot; onclick=&quot;window.open(this.href, \'popupwindow\', \'width=' . $windowW . ',height=' . $windowH . ',scrollbars,resizable\'); return false;&quot;&gt;' . $name . '&lt;/a&gt;&lt;br /&gt;';
 
-        return $out;
-    }
+		return $out;
+	}
 
 // -------------------------------------------------------------
 // NOTE: deprecated
-    function txtgps($thing)
-    {
-        if (isset($_POST[$thing])) {
-            if (get_magic_quotes_gpc()) {
-                return stripslashes($_POST[$thing]);
-            }
-            else {
-                return $_POST[$thing];
-            }
-        }
-        else {
-            return '';
-        }
-    }
+	function txtgps($thing)
+	{
+		if (isset($_POST[$thing])) {
+			if (get_magic_quotes_gpc()) {
+				return stripslashes($_POST[$thing]);
+			}
+			else {
+				return $_POST[$thing];
+			}
+		}
+		else {
+			return '';
+		}
+	}
 
 // -------------------------------------------------------------
 // NOTE: deprecated
-    function dump()
-    {
-        foreach (func_get_args() as $a)
-            echo &quot;\n&lt;pre&gt;&quot;,(is_array($a)) ? print_r($a) : $a, &quot;&lt;/pre&gt;\n&quot;;
-    }
+	function dump()
+	{
+		foreach (func_get_args() as $a)
+			echo &quot;\n&lt;pre&gt;&quot;,(is_array($a)) ? print_r($a) : $a, &quot;&lt;/pre&gt;\n&quot;;
+	}
 
 // -------------------------------------------------------------
 
-    function blockLite($text)
-    {
-        $this-&gt;btag = array('bq', 'p');
-        return $this-&gt;block($text.&quot;\n\n&quot;);
-    }
+	function blockLite($text)
+	{
+		$this-&gt;btag = array('bq', 'p');
+		return $this-&gt;block($text.&quot;\n\n&quot;);
+	}
 
 
 } // end class</diff>
      <filename>classTextile.php</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>c07d168a799f11f584cc9956b7706e834191de35</id>
    </parent>
  </parents>
  <author>
    <name>Remko Tron&#231;on</name>
    <email>git@el-tramo.be</email>
  </author>
  <url>http://github.com/tommorris/wigit/commit/823bf244a8f7121de6ced72a592d50ec6877f827</url>
  <id>823bf244a8f7121de6ced72a592d50ec6877f827</id>
  <committed-date>2009-01-09T11:53:10-08:00</committed-date>
  <authored-date>2009-01-09T11:53:10-08:00</authored-date>
  <message>Updated Textile to a PHP5-compatible version.
Thanks to Andrea Fiore for suggesting this.</message>
  <tree>4a066962287d75650021b4d1f23febe20e139068</tree>
  <committer>
    <name>Remko Tron&#231;on</name>
    <email>git@el-tramo.be</email>
  </committer>
</commit>
