Dotclear

Changeset 263


Ignore:
Timestamp:
11/23/08 18:51:55 (15 years ago)
Author:
olivier
Message:

Textile formatter plugin update.

Location:
plugins/formatting-textiles
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • plugins/formatting-textiles/_admin.php

    r217 r263  
    1111# -- END LICENSE BLOCK ------------------------------------ 
    1212 
    13 require dirname(__FILE__).'/classTextile.php'; 
     13$GLOBALS['__autoload']['Textile'] = dirname(__FILE__).'/classTextile.php'; 
     14$core->addFormater('textile', array('dcTextile','convert')); 
    1415 
    15 $GLOBALS['textile'] = new Textile; 
    16 $core->addFormater('textile', array($GLOBALS['textile'],'TextileThis')); 
     16class dcTextile 
     17{ 
     18     public static function convert($str) 
     19     { 
     20          $o = new Textile; 
     21          return $o->TextileThis($str); 
     22     } 
     23} 
    1724?> 
  • plugins/formatting-textiles/classTextile.php

    r31 r263  
    44 * Example: get XHTML from a given Textile-markup string ($string) 
    55 * 
    6  *        $textile = new Textile; 
    7  *        echo $textile->TextileThis($string); 
     6 *          $textile = new Textile; 
     7 *          echo $textile->TextileThis($string); 
    88 * 
    99 */ 
    1010 
    1111/* 
    12 $HeadURL: http://svn.textpattern.com/development/4.0/textpattern/lib/classTextile.php $ 
    13 $LastChangedRevision: 886 $ 
     12$HeadURL$ 
     13$LastChangedRevision$ 
    1414*/ 
    1515 
     
    2121A Humane Web Text Generator 
    2222 
    23 Version 2.0 beta 
     23Version 2.0 
    2424 
    2525Copyright (c) 2003-2004, Dean Allen <dean@textism.com> 
    2626All rights reserved. 
    2727 
    28 Thanks to Carlo Zottmann <carlo@g-blog.net> for refactoring  
     28Thanks to Carlo Zottmann <carlo@g-blog.net> for refactoring 
    2929Textile's procedural code into a class framework 
     30 
     31Additions and fixes Copyright (c) 2006 Alex Shiels http://thresholdstate.com/ 
    3032 
    3133_____________ 
     
    9092Phrase modifier syntax: 
    9193 
    92            _emphasis_   ->  <em>emphasis</em> 
    93            __italic__   ->  <i>italic</i> 
    94              *strong*   ->  <strong>strong</strong> 
    95              **bold**   ->  <b>bold</b> 
    96          ??citation??   ->  <cite>citation</cite> 
    97        -deleted text-   ->  <del>deleted</del> 
    98       +inserted text+   ->  <ins>inserted</ins> 
    99         ^superscript^   ->  <sup>superscript</sup> 
    100           ~subscript~   ->  <sub>subscript</sub> 
    101                @code@   ->  <code>computer code</code> 
    102           %(bob)span%   ->  <span class="bob">span</span> 
    103  
    104         ==notextile==   ->  leave text alone (do not format) 
    105  
    106        "linktext":url   ->  <a href="url">linktext</a> 
    107  "linktext(title)":url  ->  <a href="url" title="title">linktext</a> 
    108  
    109            !imageurl!   ->  <img src="imageurl" /> 
    110   !imageurl(alt text)!  ->  <img src="imageurl" alt="alt text" /> 
    111     !imageurl!:linkurl  ->  <a href="linkurl"><img src="imageurl" /></a> 
    112  
    113 ABC(Always Be Closing)  ->  <acronym title="Always Be Closing">ABC</acronym> 
     94             _emphasis_  ->    <em>emphasis</em> 
     95             __italic__  ->    <i>italic</i> 
     96                *strong* ->    <strong>strong</strong> 
     97                **bold** ->    <b>bold</b> 
     98           ??citation??  ->    <cite>citation</cite> 
     99        -deleted text-   ->    <del>deleted</del> 
     100       +inserted text+   ->    <ins>inserted</ins> 
     101          ^superscript^  ->    <sup>superscript</sup> 
     102            ~subscript~  ->    <sub>subscript</sub> 
     103                  @code@ ->    <code>computer code</code> 
     104            %(bob)span%  ->    <span class="bob">span</span> 
     105 
     106          ==notextile==  ->    leave text alone (do not format) 
     107 
     108        "linktext":url   ->    <a href="url">linktext</a> 
     109 "linktext(title)":url   ->    <a href="url" title="title">linktext</a> 
     110 
     111             !imageurl!  ->    <img src="imageurl" /> 
     112  !imageurl(alt text)!   ->    <img src="imageurl" alt="alt text" /> 
     113     !imageurl!:linkurl  ->    <a href="linkurl"><img src="imageurl" /></a> 
     114 
     115ABC(Always Be Closing)   ->    <acronym title="Always Be Closing">ABC</acronym> 
    114116 
    115117 
     
    118120     Simple tables: 
    119121 
    120         |a|simple|table|row| 
    121         |And|Another|table|row| 
    122  
    123         |_. A|_. table|_. header|_.row| 
    124         |A|simple|table|row| 
    125  
    126     Tables with attributes: 
    127  
    128         table{border:1px solid black}. 
    129         {background:#ddd;color:red}. |{}| | | | 
     122          |a|simple|table|row| 
     123          |And|Another|table|row| 
     124 
     125          |_. A|_. table|_. header|_.row| 
     126          |A|simple|table|row| 
     127 
     128     Tables with attributes: 
     129 
     130          table{border:1px solid black}. 
     131          {background:#ddd;color:red}. |{}| | | | 
    130132 
    131133 
    132134Applying Attributes: 
    133135 
    134     Most anywhere Textile code is used, attributes such as arbitrary css style, 
    135     css classes, and ids can be applied. The syntax is fairly consistent. 
    136  
    137     The following characters quickly alter the alignment of block elements: 
    138  
    139         <  ->  left align    ex. p<. left-aligned para 
    140         >  ->  right align      h3>. right-aligned header 3 
    141         =  ->  centred          h4=. centred header 4 
    142         <> ->  justified        p<>. justified paragraph 
    143  
    144     These will change vertical alignment in table cells: 
    145  
    146         ^  ->  top         ex. |^. top-aligned table cell| 
    147         -  ->  middle          |-. middle aligned| 
    148         ~  ->  bottom          |~. bottom aligned cell| 
    149  
    150     Plain (parentheses) inserted between block syntax and the closing dot-space 
    151     indicate classes and ids: 
    152  
    153         p(hector). paragraph -> <p class="hector">paragraph</p> 
    154  
    155         p(#fluid). paragraph -> <p id="fluid">paragraph</p> 
    156  
    157         (classes and ids can be combined) 
    158         p(hector#fluid). paragraph -> <p class="hector" id="fluid">paragraph</p> 
    159  
    160     Curly {brackets} insert arbitrary css style 
    161  
    162         p{line-height:18px}. paragraph -> <p style="line-height:18px">paragraph</p> 
    163  
    164         h3{color:red}. header 3 -> <h3 style="color:red">header 3</h3> 
    165  
    166     Square [brackets] insert language attributes 
    167  
    168         p[no]. paragraph -> <p lang="no">paragraph</p> 
    169  
    170         %[fr]phrase% -> <span lang="fr">phrase</span> 
    171  
    172     Usually Textile block element syntax requires a dot and space before the block 
    173     begins, but since lists don't, they can be styled just using braces 
    174  
    175         #{color:blue} one  ->  <ol style="color:blue"> 
    176         # big                   <li>one</li> 
    177         # list                  <li>big</li> 
    178                                 <li>list</li> 
    179                                </ol> 
     136     Most anywhere Textile code is used, attributes such as arbitrary css style, 
     137     css classes, and ids can be applied. The syntax is fairly consistent. 
     138 
     139     The following characters quickly alter the alignment of block elements: 
     140 
     141          <  ->  left align    ex. p<. left-aligned para 
     142          >  ->  right align        h3>. right-aligned header 3 
     143          =  ->  centred            h4=. centred header 4 
     144          <> ->  justified          p<>. justified paragraph 
     145 
     146     These will change vertical alignment in table cells: 
     147 
     148          ^  ->  top             ex. |^. top-aligned table cell| 
     149          -  ->  middle          |-. middle aligned| 
     150          ~  ->  bottom          |~. bottom aligned cell| 
     151 
     152     Plain (parentheses) inserted between block syntax and the closing dot-space 
     153     indicate classes and ids: 
     154 
     155          p(hector). paragraph -> <p class="hector">paragraph</p> 
     156 
     157          p(#fluid). paragraph -> <p id="fluid">paragraph</p> 
     158 
     159          (classes and ids can be combined) 
     160          p(hector#fluid). paragraph -> <p class="hector" id="fluid">paragraph</p> 
     161 
     162     Curly {brackets} insert arbitrary css style 
     163 
     164          p{line-height:18px}. paragraph -> <p style="line-height:18px">paragraph</p> 
     165 
     166          h3{color:red}. header 3 -> <h3 style="color:red">header 3</h3> 
     167 
     168     Square [brackets] insert language attributes 
     169 
     170          p[no]. paragraph -> <p lang="no">paragraph</p> 
     171 
     172          %[fr]phrase% -> <span lang="fr">phrase</span> 
     173 
     174     Usually Textile block element syntax requires a dot and space before the block 
     175     begins, but since lists don't, they can be styled just using braces 
     176 
     177          #{color:blue} one  ->  <ol style="color:blue"> 
     178          # big                         <li>one</li> 
     179          # list                        <li>big</li> 
     180                                        <li>list</li> 
     181                                      </ol> 
    180182 
    181183     Using the span tag to style a phrase 
    182184 
    183         It goes like this, %{color:red}the fourth the fifth% 
    184               -> It goes like this, <span style="color:red">the fourth the fifth</span> 
     185          It goes like this, %{color:red}the fourth the fifth% 
     186                 -> It goes like this, <span style="color:red">the fourth the fifth</span> 
    185187 
    186188*/ 
     189 
     190// define these before including this file to override the standard glyphs 
     191@define('txt_quote_single_open',  '&#8216;'); 
     192@define('txt_quote_single_close', '&#8217;'); 
     193@define('txt_quote_double_open',  '&#8220;'); 
     194@define('txt_quote_double_close', '&#8221;'); 
     195@define('txt_apostrophe',            '&#8217;'); 
     196@define('txt_prime',                 '&#8242;'); 
     197@define('txt_prime_double',     '&#8243;'); 
     198@define('txt_ellipsis',         '&#8230;'); 
     199@define('txt_emdash',                '&#8212;'); 
     200@define('txt_endash',                '&#8211;'); 
     201@define('txt_dimension',        '&#215;'); 
     202@define('txt_trademark',        '&#8482;'); 
     203@define('txt_registered',            '&#174;'); 
     204@define('txt_copyright',        '&#169;'); 
    187205 
    188206class Textile 
    189207{ 
    190     public $hlgn; 
    191     public $vlgn; 
    192     public $clas; 
    193     public $lnge; 
    194     public $styl; 
    195     public $cspn; 
    196     public $rspn; 
    197     public $a; 
    198     public $s; 
    199     public $c; 
    200     public $pnct; 
    201     public $rel; 
    202  
    203 // ------------------------------------------------------------- 
    204     function Textile() 
    205     { 
    206         $this->hlgn = "(?:\<(?!>)|(?<!<)\>|\<\>|\=|[()]+)"; 
    207         $this->vlgn = "[\-^~]"; 
    208         $this->clas = "(?:\([^)]+\))"; 
    209         $this->lnge = "(?:\[[^]]+\])"; 
    210         $this->styl = "(?:\{[^}]+\})"; 
    211         $this->cspn = "(?:\\\\\d+)"; 
    212         $this->rspn = "(?:\/\d+)"; 
    213         $this->a = "(?:{$this->hlgn}?{$this->vlgn}?|{$this->vlgn}?{$this->hlgn}?)"; 
    214         $this->s = "(?:{$this->cspn}?{$this->rspn}?|{$this->rspn}?{$this->cspn}?)"; 
    215         $this->c = "(?:{$this->clas}?{$this->styl}?{$this->lnge}?|{$this->styl}?{$this->lnge}?{$this->clas}?|{$this->lnge}?{$this->styl}?{$this->clas}?)"; 
    216         $this->pnct = '[\!"#\$%&\'()\*\+,\-\./:;<=>\?@\[\\\]\^_`{\|}\~]'; 
    217  
    218     } 
    219  
    220 // ------------------------------------------------------------- 
    221     function TextileThis($text, $lite='', $encode='', $noimage='', $strict='', $rel='') 
    222     { 
    223         if ($rel) 
    224            $this->rel = ' rel="'.$rel.'" '; 
    225  
    226         $text = $this->incomingEntities($text); 
    227          
    228         if ($encode) { 
    229                $text = str_replace("x%x%", "&#38;", $text); 
    230           return $text; 
    231         } else { 
    232          
    233           if(!$strict) { 
    234                     $text = $this->fixEntities($text); 
     208     var $hlgn; 
     209     var $vlgn; 
     210     var $clas; 
     211     var $lnge; 
     212     var $styl; 
     213     var $cspn; 
     214     var $rspn; 
     215     var $a; 
     216     var $s; 
     217     var $c; 
     218     var $pnct; 
     219     var $rel; 
     220     var $fn; 
     221 
     222     var $shelf = array(); 
     223     var $restricted = false; 
     224     var $noimage = false; 
     225     var $lite = false; 
     226     var $url_schemes = array(); 
     227     var $glyph = array(); 
     228     var $hu = ''; 
     229 
     230     var $ver = '2.0.0'; 
     231     var $rev = '$Rev$'; 
     232 
     233     var $doc_root; 
     234 
     235// ------------------------------------------------------------- 
     236     function Textile() 
     237     { 
     238          $this->hlgn = "(?:\<(?!>)|(?<!<)\>|\<\>|\=|[()]+(?! ))"; 
     239          $this->vlgn = "[\-^~]"; 
     240          $this->clas = "(?:\([^)]+\))"; 
     241          $this->lnge = "(?:\[[^]]+\])"; 
     242          $this->styl = "(?:\{[^}]+\})"; 
     243          $this->cspn = "(?:\\\\\d+)"; 
     244          $this->rspn = "(?:\/\d+)"; 
     245          $this->a = "(?:{$this->hlgn}|{$this->vlgn})*"; 
     246          $this->s = "(?:{$this->cspn}|{$this->rspn})*"; 
     247          $this->c = "(?:{$this->clas}|{$this->styl}|{$this->lnge}|{$this->hlgn})*"; 
     248 
     249          $this->pnct = '[\!"#\$%&\'()\*\+,\-\./:;<=>\?@\[\\\]\^_`{\|}\~]'; 
     250          $this->urlch = '[\w"$\-_.+!*\'(),";\/?:@=&%#{}|\\^~\[\]`]'; 
     251 
     252          $this->url_schemes = array('http','https','ftp','mailto'); 
     253 
     254          $this->btag = array('bq', 'bc', 'notextile', 'pre', 'h[1-6]', 'fn\d+', 'p'); 
     255 
     256          $this->glyph = array( 
     257             'quote_single_open'   => txt_quote_single_open, 
     258             'quote_single_close' => txt_quote_single_close, 
     259             'quote_double_open'   => txt_quote_double_open, 
     260             'quote_double_close' => txt_quote_double_close, 
     261             'apostrophe'          => txt_apostrophe, 
     262             'prime'                    => txt_prime, 
     263             'prime_double'        => txt_prime_double, 
     264             'ellipsis'            => txt_ellipsis, 
     265             'emdash'              => txt_emdash, 
     266             'endash'              => txt_endash, 
     267             'dimension'           => txt_dimension, 
     268             'trademark'           => txt_trademark, 
     269             'registered'          => txt_registered, 
     270             'copyright'           => txt_copyright, 
     271          ); 
     272 
     273          if (defined('hu')) 
     274               $this->hu = hu; 
     275 
     276          if (defined('DIRECTORY_SEPARATOR')) 
     277               $this->ds = constant('DIRECTORY_SEPARATOR'); 
     278          else 
     279               $this->ds = '/'; 
     280 
     281          $this->doc_root = @$_SERVER['DOCUMENT_ROOT']; 
     282          if (!$this->doc_root) 
     283               $this->doc_root = @$_SERVER['PATH_TRANSLATED']; // IIS 
     284 
     285          $this->doc_root = rtrim($this->doc_root, $this->ds).$this->ds; 
     286 
     287     } 
     288 
     289// ------------------------------------------------------------- 
     290 
     291     function TextileThis($text, $lite = '', $encode = '', $noimage = '', $strict = '', $rel = '') 
     292     { 
     293          $this->rel = ($rel) ? ' rel="'.$rel.'"' : ''; 
     294 
     295          $this->lite = $lite; 
     296          $this->noimage = $noimage; 
     297 
     298          if ($encode) { 
     299           $text = $this->incomingEntities($text); 
     300               $text = str_replace("x%x%", "&amp;", $text); 
     301               return $text; 
     302          } else { 
     303 
     304               if(!$strict) { 
    235305                    $text = $this->cleanWhiteSpace($text); 
    236306               } 
    237       
    238                $text = $this->getRefs($text); 
    239       
    240                $text = $this->noTextile($text); 
    241                $text = $this->links($text); 
    242                if (!$noimage) { 
    243                     $text = $this->image($text); 
    244                } 
    245                $text = $this->code($text); 
    246                $text = $this->span($text); 
    247                $text = $this->superscript($text); 
    248                $text = $this->footnoteRef($text); 
    249                $text = $this->glyphs($text); 
     307 
     308               if (!$lite) { 
     309                    $text = $this->block($text); 
     310               } 
     311 
    250312               $text = $this->retrieve($text); 
    251       
    252                if (!$lite) { 
    253                     $text = $this->lists($text); 
    254                     $text = $this->table($text); 
    255                     $text = $this->block($text); 
    256                } 
    257  
    258                     // clean up <notextile> 
    259                $text = preg_replace('/<\/?notextile>/', "", $text); 
    260       
    261                     // turn the temp char back to an ampersand entity 
    262                $text = str_replace("x%x%", "&#38;", $text); 
    263       
     313               $text = $this->retrieveURLs($text); 
     314 
    264315                    // just to be tidy 
    265316               $text = str_replace("<br />", "<br />\n", $text); 
    266       
     317 
    267318               return $text; 
    268           } 
    269     } 
    270  
    271 // ------------------------------------------------------------- 
    272     function pba($in, $element = "") // "parse block attributes" 
    273     { 
    274         $style = ''; 
    275         $class = ''; 
    276         $lang = ''; 
    277         $colspan = ''; 
    278         $rowspan = ''; 
    279         $id = ''; 
    280         $atts = ''; 
    281  
    282         if (!empty($in)) { 
    283             $matched = $in; 
    284             if ($element == 'td') { 
    285                 if (preg_match("/\\\\(\d+)/", $matched, $csp)) $colspan = $csp[1]; 
    286                 if (preg_match("/\/(\d+)/", $matched, $rsp)) $rowspan = $rsp[1]; 
    287  
    288                 if (preg_match("/($this->vlgn)/", $matched, $vert)) 
    289                     $style[] = "vertical-align:" . $this->vAlign($vert[1]) . ";"; 
    290             } 
    291  
    292             if (preg_match("/\{([^}]*)\}/", $matched, $sty)) { 
    293                 $style[] = $sty[1] . ';'; 
    294                 $matched = str_replace($sty[0], '', $matched); 
    295             } 
    296  
    297             if (preg_match("/\[([^)]+)\]/U", $matched, $lng)) { 
    298                 $lang = $lng[1]; 
    299                 $matched = str_replace($lng[0], '', $matched); 
    300             } 
    301  
    302             if (preg_match("/\(([^()]+)\)/U", $matched, $cls)) { 
    303                 $class = $cls[1]; 
    304                 $matched = str_replace($cls[0], '', $matched); 
    305             } 
    306  
    307             if (preg_match("/([(]+)/", $matched, $pl)) { 
    308                 $style[] = "padding-left:" . strlen($pl[1]) . "em;"; 
    309                 $matched = str_replace($pl[0], '', $matched); 
    310             } 
    311  
    312             if (preg_match("/([)]+)/", $matched, $pr)) { 
    313                 // $this->dump($pr); 
    314                 $style[] = "padding-right:" . strlen($pr[1]) . "em;"; 
    315                 $matched = str_replace($pr[0], '', $matched); 
    316             } 
    317  
    318             if (preg_match("/($this->hlgn)/", $matched, $horiz)) 
    319                 $style[] = "text-align:" . $this->hAlign($horiz[1]) . ";"; 
    320  
    321             if (preg_match("/^(.*)#(.*)$/", $class, $ids)) { 
    322                 $id = $ids[2]; 
    323                 $class = $ids[1]; 
    324             } 
    325  
    326             return join('',array( 
    327                 ($style)   ? ' style="'   . join("", $style) .'"':'', 
    328                 ($class)   ? ' class="'   . $class           .'"':'', 
    329                 ($lang)    ? ' lang="'    . $lang            .'"':'', 
    330                 ($id)      ? ' id="'      . $id              .'"':'', 
    331                 ($colspan) ? ' colspan="' . $colspan         .'"':'', 
    332                 ($rowspan) ? ' rowspan="' . $rowspan         .'"':'' 
    333             )); 
    334         } 
    335         return ''; 
    336     } 
    337  
    338 // ------------------------------------------------------------- 
    339     function table($text) 
    340     { 
    341         $text = $text . "\n\n"; 
    342         return preg_replace_callback("/^(?:table(_?{$this->s}{$this->a}{$this->c})\. ?\n)?^({$this->a}{$this->c}\.? ?\|.*\|)\n\n/smU",  
    343            array(&$this, "fTable"), $text); 
    344     } 
    345  
    346 // ------------------------------------------------------------- 
    347     function fTable($matches) 
    348     { 
    349         $tatts = $this->pba($matches[1], 'table'); 
    350  
    351         foreach(preg_split("/\|$/m", $matches[2], -1, PREG_SPLIT_NO_EMPTY) as $row) { 
    352             if (preg_match("/^($this->a$this->c\. )(.*)/m", $row, $rmtch)) { 
    353                 $ratts = $this->pba($rmtch[1], 'tr'); 
    354                 $row = $rmtch[2]; 
    355             } else $ratts = ''; 
    356  
    357             foreach(explode("|", $row) as $cell) { 
    358                 $ctyp = "d"; 
    359                 if (preg_match("/^_/", $cell)) $ctyp = "h"; 
    360                 if (preg_match("/^(_?$this->s$this->a$this->c\. )(.*)/", $cell, $cmtch)) { 
    361                     $catts = $this->pba($cmtch[1], 'td'); 
    362                     $cell = $cmtch[2]; 
    363                 } else $catts = ''; 
    364  
    365                 if (trim($cell) != '') 
    366                     $cells[] = "\t\t\t<t$ctyp$catts>$cell</t$ctyp>"; 
    367             } 
    368             $rows[] = "\t\t<tr$ratts>\n" . join("\n", $cells) . "\n\t\t</tr>"; 
    369             unset($cells, $catts); 
    370         } 
    371         return "\t<table$tatts>\n" . join("\n", $rows) . "\n\t</table>\n\n"; 
    372     } 
    373  
    374 // ------------------------------------------------------------- 
    375     function lists($text) 
    376     { 
    377         return preg_replace_callback("/^([#*]+$this->c .*)$(?![^#*])/smU", array(&$this, "fList"), $text); 
    378     } 
    379  
    380 // ------------------------------------------------------------- 
    381     function fList($m) 
    382     { 
    383         $text = explode("\n", $m[0]); 
    384         foreach($text as $line) { 
    385             $nextline = next($text); 
    386             if (preg_match("/^([#*]+)($this->a$this->c) (.*)$/s", $line, $m)) { 
    387                 list(, $tl, $atts, $content) = $m; 
    388                 $nl = preg_replace("/^([#*]+)\s.*/", "$1", $nextline); 
    389                 if (!isset($lists[$tl])) { 
    390                     $lists[$tl] = true; 
    391                     $atts = $this->pba($atts); 
    392                     $line = "\t<" . $this->lT($tl) . "l$atts>\n\t\t<li>" . $content; 
    393                 } else { 
    394                     $line = "\t\t<li>" . $content; 
    395                 } 
    396  
    397                 if(strlen($nl) <= strlen($tl)) $line .= "</li>"; 
    398                 foreach(array_reverse($lists) as $k => $v) { 
    399                     if(strlen($k) > strlen($nl)) { 
    400                         $line .= "\n\t</" . $this->lT($k) . "l>"; 
    401                         if(strlen($k) > 1)  
    402                             $line .= "</li>"; 
    403                         unset($lists[$k]); 
    404                     } 
    405                 } 
    406             } 
    407             $out[] = $line; 
    408         } 
    409         return join("\n", $out); 
    410     } 
    411  
    412 // ------------------------------------------------------------- 
    413     function lT($in) 
    414     { 
    415         return preg_match("/^#+/", $in) ? 'o' : 'u'; 
    416     } 
    417  
    418 // ------------------------------------------------------------- 
    419     function block($text) 
    420     { 
    421         $pre = $php = $txp = false; 
    422         $find = array('bq', 'h[1-6]', 'fn\d+', 'p'); 
    423  
    424         $text = preg_replace("/(.+)\n(?![#*\s|])/", 
    425             "$1<br />", $text); 
    426  
    427         $text = explode("\n", $text); 
    428         array_push($text, " "); 
    429  
    430         foreach($text as $line) { 
    431             if (preg_match('/<pre>/i', $line)) { 
    432                 $pre = true; 
    433             } 
    434             elseif (preg_match('/<txp:php>/i', $line)) { 
    435                 $php = true; 
    436             } 
    437             elseif (preg_match('/^\s*<txp:/i', $line)) { 
    438                 $txp = true; 
    439             } 
    440  
    441  
    442             foreach($find as $tag) { 
    443                 $line = ($pre == false and $php == false and $txp == false) 
    444                 ? preg_replace_callback("/^($tag)($this->a$this->c)\.(?::(\S+))? (.*)$/", 
    445                     array(&$this, "fBlock"), $line) 
    446                 : $line; 
    447             } 
    448  
    449             $line = (!$php and !$txp) ? preg_replace('/^(?!\t|<\/?pre|<\/?code|$| )(.*)/', "\t<p>$1</p>", $line) : $line; 
    450  
    451             $line = ($pre or $php) ? str_replace("<br />", "\n", $line):$line; 
    452             if (preg_match('/<\/pre>/i', $line)) { 
    453                 $pre = false; 
    454             } 
    455             elseif (preg_match('/<\/txp:php>/i', $line)) { 
    456           $php = false; 
    457             } 
    458                if ($txp == true) $txp = false; 
    459             $out[] = $line; 
    460         } 
    461         return join("\n", $out); 
    462     } 
    463  
    464 // ------------------------------------------------------------- 
    465     function fBlock($m) 
    466     { 
    467         // $this->dump($m); 
    468         list(, $tag, $atts, $cite, $content) = $m; 
    469  
    470         $atts = $this->pba($atts); 
    471  
    472         if (preg_match("/fn(\d+)/", $tag, $fns)) { 
    473             $tag = 'p'; 
    474             $atts .= ' id="fn' . $fns[1] . '"'; 
    475             $content = '<sup>' . $fns[1] . '</sup> ' . $content; 
    476         } 
    477  
    478         $start = "\t<$tag"; 
    479         $end = "</$tag>"; 
    480  
    481         if ($tag == "bq") { 
    482             $cite = $this->checkRefs($cite); 
    483             $cite = ($cite != '') ? ' cite="' . $cite . '"' : ''; 
    484             $start = "\t<blockquote$cite>\n\t\t<p"; 
    485             $end = "</p>\n\t</blockquote>"; 
    486         } 
    487  
    488         return "$start$atts>$content$end"; 
    489     } 
    490  
    491 // ------------------------------------------------------------- 
    492     function span($text) 
    493     { 
    494         $qtags = array('\*\*','\*','\?\?','-','__','_','%','\+','~'); 
    495  
    496         foreach($qtags as $f) { 
    497             $text = preg_replace_callback("/ 
    498                 (?<=^|\s|[[:punct:]]|[{([]) 
    499                 ($f) 
    500                 ($this->c) 
    501                 (?::(\S+))? 
    502                 ([\w<&].*) 
    503                 ([[:punct:];]*) 
    504                 $f 
    505                 (?=[])}]|[[:punct:]]+|\s|$) 
    506             /xmU", array(&$this, "fSpan"), $text); 
    507         } 
    508         return $text; 
    509     } 
    510  
    511 // ------------------------------------------------------------- 
    512     function fSpan($m) 
    513     { 
    514         $qtags = array( 
    515           '*'  => 'strong', 
    516             '**' => 'b', 
    517             '??' => 'cite', 
    518             '_'  => 'em', 
    519             '__' => 'i', 
    520             '-'  => 'del', 
    521             '%'  => 'span', 
    522             '+'  => 'ins', 
    523             '~'  => 'sub' 
    524         ); 
    525  
    526         list(, $tag, $atts, $cite, $content, $end) = $m; 
    527         $tag = $qtags[$tag]; 
    528         $atts = $this->pba($atts); 
    529         $atts .= ($cite != '') ? 'cite="' . $cite . '"' : ''; 
    530  
    531         $out = "<$tag$atts>$content$end</$tag>"; 
     319          } 
     320     } 
     321 
     322// ------------------------------------------------------------- 
     323 
     324     function TextileRestricted($text, $lite = 1, $noimage = 1, $rel = 'nofollow') 
     325     { 
     326          $this->restricted = true; 
     327          $this->lite = $lite; 
     328          $this->noimage = $noimage; 
     329 
     330          $this->rel = ($rel) ? ' rel="'.$rel.'"' : ''; 
     331 
     332               // escape any raw html 
     333               $text = $this->encode_html($text, 0); 
     334 
     335               $text = $this->cleanWhiteSpace($text); 
     336 
     337               if ($lite) { 
     338                    $text = $this->blockLite($text); 
     339               } 
     340               else { 
     341                    $text = $this->block($text); 
     342               } 
     343 
     344               $text = $this->retrieve($text); 
     345               $text = $this->retrieveURLs($text); 
     346 
     347                    // just to be tidy 
     348               $text = str_replace("<br />", "<br />\n", $text); 
     349 
     350               return $text; 
     351     } 
     352 
     353// ------------------------------------------------------------- 
     354     function pba($in, $element = "", $include_id = 1) // "parse block attributes" 
     355     { 
     356          $style = ''; 
     357          $class = ''; 
     358          $lang = ''; 
     359          $colspan = ''; 
     360          $rowspan = ''; 
     361          $id = ''; 
     362          $atts = ''; 
     363 
     364          if (!empty($in)) { 
     365               $matched = $in; 
     366               if ($element == 'td') { 
     367                    if (preg_match("/\\\\(\d+)/", $matched, $csp)) $colspan = $csp[1]; 
     368                    if (preg_match("/\/(\d+)/", $matched, $rsp)) $rowspan = $rsp[1]; 
     369               } 
     370 
     371               if ($element == 'td' or $element == 'tr') { 
     372                    if (preg_match("/($this->vlgn)/", $matched, $vert)) 
     373                         $style[] = "vertical-align:" . $this->vAlign($vert[1]) . ";"; 
     374               } 
     375 
     376               if (preg_match("/\{([^}]*)\}/", $matched, $sty)) { 
     377                    $style[] = rtrim($sty[1], ';') . ';'; 
     378                    $matched = str_replace($sty[0], '', $matched); 
     379               } 
     380 
     381               if (preg_match("/\[([^]]+)\]/U", $matched, $lng)) { 
     382                    $lang = $lng[1]; 
     383                    $matched = str_replace($lng[0], '', $matched); 
     384               } 
     385 
     386               if (preg_match("/\(([^()]+)\)/U", $matched, $cls)) { 
     387                    $class = $cls[1]; 
     388                    $matched = str_replace($cls[0], '', $matched); 
     389               } 
     390 
     391               if (preg_match("/([(]+)/", $matched, $pl)) { 
     392                    $style[] = "padding-left:" . strlen($pl[1]) . "em;"; 
     393                    $matched = str_replace($pl[0], '', $matched); 
     394               } 
     395 
     396               if (preg_match("/([)]+)/", $matched, $pr)) { 
     397                    // $this->dump($pr); 
     398                    $style[] = "padding-right:" . strlen($pr[1]) . "em;"; 
     399                    $matched = str_replace($pr[0], '', $matched); 
     400               } 
     401 
     402               if (preg_match("/($this->hlgn)/", $matched, $horiz)) 
     403                    $style[] = "text-align:" . $this->hAlign($horiz[1]) . ";"; 
     404 
     405               if (preg_match("/^(.*)#(.*)$/", $class, $ids)) { 
     406                    $id = $ids[2]; 
     407                    $class = $ids[1]; 
     408               } 
     409 
     410               if ($this->restricted) 
     411                    return ($lang)   ? ' lang="'   . $lang            .'"':''; 
     412 
     413               return join('',array( 
     414                    ($style)   ? ' style="'   . join("", $style) .'"':'', 
     415                    ($class)   ? ' class="'   . $class            .'"':'', 
     416                    ($lang)    ? ' lang="'     . $lang            .'"':'', 
     417                    ($id and $include_id) ? ' id="'     . $id                   .'"':'', 
     418                    ($colspan) ? ' colspan="' . $colspan          .'"':'', 
     419                    ($rowspan) ? ' rowspan="' . $rowspan          .'"':'' 
     420               )); 
     421          } 
     422          return ''; 
     423     } 
     424 
     425// ------------------------------------------------------------- 
     426     function hasRawText($text) 
     427     { 
     428          // checks whether the text has text not already enclosed by a block tag 
     429          $r = trim(preg_replace('@<(p|blockquote|div|form|table|ul|ol|pre|h\d)[^>]*?>.*</\1>@s', '', trim($text))); 
     430          $r = trim(preg_replace('@<(hr|br)[^>]*?/>@', '', $r)); 
     431          return '' != $r; 
     432     } 
     433 
     434// ------------------------------------------------------------- 
     435     function table($text) 
     436     { 
     437          $text = $text . "\n\n"; 
     438          return preg_replace_callback("/^(?:table(_?{$this->s}{$this->a}{$this->c})\. ?\n)?^({$this->a}{$this->c}\.? ?\|.*\|)\n\n/smU", 
     439             array(&$this, "fTable"), $text); 
     440     } 
     441 
     442// ------------------------------------------------------------- 
     443     function fTable($matches) 
     444     { 
     445          $tatts = $this->pba($matches[1], 'table'); 
     446 
     447          foreach(preg_split("/\|$/m", $matches[2], -1, PREG_SPLIT_NO_EMPTY) as $row) { 
     448               if (preg_match("/^($this->a$this->c\. )(.*)/m", ltrim($row), $rmtch)) { 
     449                    $ratts = $this->pba($rmtch[1], 'tr'); 
     450                    $row = $rmtch[2]; 
     451               } else $ratts = ''; 
     452 
     453                    $cells = array(); 
     454               foreach(explode("|", $row) as $cell) { 
     455                    $ctyp = "d"; 
     456                    if (preg_match("/^_/", $cell)) $ctyp = "h"; 
     457                    if (preg_match("/^(_?$this->s$this->a$this->c\. )(.*)/", $cell, $cmtch)) { 
     458                         $catts = $this->pba($cmtch[1], 'td'); 
     459                         $cell = $cmtch[2]; 
     460                    } else $catts = ''; 
     461 
     462                    $cell = $this->graf($cell); 
     463 
     464                    if (trim($cell) != '') 
     465                         $cells[] = $this->doTagBr("t$ctyp", "\t\t\t<t$ctyp$catts>$cell</t$ctyp>"); 
     466               } 
     467               $rows[] = "\t\t<tr$ratts>\n" . join("\n", $cells) . ($cells ? "\n" : "") . "\t\t</tr>"; 
     468               unset($cells, $catts); 
     469          } 
     470          return "\t<table$tatts>\n" . join("\n", $rows) . "\n\t</table>\n\n"; 
     471     } 
     472 
     473// ------------------------------------------------------------- 
     474     function lists($text) 
     475     { 
     476          return preg_replace_callback("/^([#*]+$this->c .*)$(?![^#*])/smU", array(&$this, "fList"), $text); 
     477     } 
     478 
     479// ------------------------------------------------------------- 
     480     function fList($m) 
     481     { 
     482          $text = preg_split('/\n(?=[*#])/m', $m[0]); 
     483          foreach($text as $nr => $line) { 
     484               $nextline = isset($text[$nr+1]) ? $text[$nr+1] : false; 
     485               if (preg_match("/^([#*]+)($this->a$this->c) (.*)$/s", $line, $m)) { 
     486                    list(, $tl, $atts, $content) = $m; 
     487                    $nl = ''; 
     488                    if (preg_match("/^([#*]+)\s.*/", $nextline, $nm)) 
     489                         $nl = $nm[1]; 
     490                    if (!isset($lists[$tl])) { 
     491                         $lists[$tl] = true; 
     492                         $atts = $this->pba($atts); 
     493                         $line = "\t<" . $this->lT($tl) . "l$atts>\n\t\t<li>" . rtrim($content); 
     494                    } else { 
     495                         $line = "\t\t<li>" . rtrim($content); 
     496                    } 
     497 
     498                    if(strlen($nl) <= strlen($tl)) $line .= "</li>"; 
     499                    foreach(array_reverse($lists) as $k => $v) { 
     500                         if(strlen($k) > strlen($nl)) { 
     501                              $line .= "\n\t</" . $this->lT($k) . "l>"; 
     502                              if(strlen($k) > 1) 
     503                                   $line .= "</li>"; 
     504                              unset($lists[$k]); 
     505                         } 
     506                    } 
     507               } 
     508               else { 
     509                    $line .= "\n"; 
     510               } 
     511               $out[] = $line; 
     512          } 
     513          return $this->doTagBr('li', join("\n", $out)); 
     514     } 
     515 
     516// ------------------------------------------------------------- 
     517     function lT($in) 
     518     { 
     519          return preg_match("/^#+/", $in) ? 'o' : 'u'; 
     520     } 
     521 
     522// ------------------------------------------------------------- 
     523     function doTagBr($tag, $in) 
     524     { 
     525          return preg_replace_callback('@<('.preg_quote($tag).')([^>]*?)>(.*)(</\1>)@s', array(&$this, 'doBr'), $in); 
     526     } 
     527 
     528 
     529// ------------------------------------------------------------- 
     530     function doPBr($in) 
     531     { 
     532          return $this->doTagBr('p', $in); 
     533     } 
     534 
     535// ------------------------------------------------------------- 
     536     function doBr($m) 
     537     { 
     538          $content = preg_replace("@(.+)(?<!<br>|<br />)\n(?![#*\s|])@", '$1<br />', $m[3]); 
     539          return '<'.$m[1].$m[2].'>'.$content.$m[4]; 
     540     } 
     541 
     542// ------------------------------------------------------------- 
     543     function block($text) 
     544     { 
     545          $find = $this->btag; 
     546          $tre = join('|', $find); 
     547 
     548          $text = explode("\n\n", $text); 
     549 
     550          $tag = 'p'; 
     551          $atts = $cite = $graf = $ext  = ''; 
     552 
     553          foreach($text as $line) { 
     554               $anon = 0; 
     555               if (preg_match("/^($tre)($this->a$this->c)\.(\.?)(?::(\S+))? (.*)$/s", $line, $m)) { 
     556                    // last block was extended, so close it 
     557                    if ($ext) 
     558                         $out[count($out)-1] .= $c1; 
     559                    // new block 
     560                    list(,$tag,$atts,$ext,$cite,$graf) = $m; 
     561                    list($o1, $o2, $content, $c2, $c1) = $this->fBlock(array(0,$tag,$atts,$ext,$cite,$graf)); 
     562 
     563                    // leave off c1 if this block is extended, we'll close it at the start of the next block 
     564                    if ($ext) 
     565                         $line = $o1.$o2.$content.$c2; 
     566                    else 
     567                         $line = $o1.$o2.$content.$c2.$c1; 
     568               } 
     569               else { 
     570                    // anonymous block 
     571                    $anon = 1; 
     572                    if ($ext or !preg_match('/^ /', $line)) { 
     573                         list($o1, $o2, $content, $c2, $c1) = $this->fBlock(array(0,$tag,$atts,$ext,$cite,$line)); 
     574                         // skip $o1/$c1 because this is part of a continuing extended block 
     575                         if ($tag == 'p' and !$this->hasRawText($content)) { 
     576                              $line = $content; 
     577                         } 
     578                         else { 
     579                              $line = $o2.$content.$c2; 
     580                         } 
     581                    } 
     582                    else { 
     583                       $line = $this->graf($line); 
     584                    } 
     585               } 
     586 
     587               $line = $this->doPBr($line); 
     588               $line = preg_replace('/<br>/', '<br />', $line); 
     589 
     590               if ($ext and $anon) 
     591                    $out[count($out)-1] .= "\n".$line; 
     592               else 
     593                    $out[] = $line; 
     594 
     595               if (!$ext) { 
     596                    $tag = 'p'; 
     597                    $atts = ''; 
     598                    $cite = ''; 
     599                    $graf = ''; 
     600               } 
     601          } 
     602          if ($ext) $out[count($out)-1] .= $c1; 
     603          return join("\n\n", $out); 
     604     } 
     605 
     606 
     607 
     608// ------------------------------------------------------------- 
     609     function fBlock($m) 
     610     { 
     611          // $this->dump($m); 
     612          list(, $tag, $att, $ext, $cite, $content) = $m; 
     613          $atts = $this->pba($att); 
     614 
     615          $o1 = $o2 = $c2 = $c1 = ''; 
     616 
     617          if (preg_match("/fn(\d+)/", $tag, $fns)) { 
     618               $tag = 'p'; 
     619               $fnid = empty($this->fn[$fns[1]]) ? $fns[1] : $this->fn[$fns[1]]; 
     620               $atts .= ' id="fn' . $fnid . '"'; 
     621               if (strpos($atts, 'class=') === false) 
     622                    $atts .= ' class="footnote"'; 
     623               $content = '<sup>' . $fns[1] . '</sup> ' . $content; 
     624          } 
     625 
     626          if ($tag == "bq") { 
     627               $cite = $this->shelveURL($cite); 
     628               $cite = ($cite != '') ? ' cite="' . $cite . '"' : ''; 
     629               $o1 = "\t<blockquote$cite$atts>\n"; 
     630               $o2 = "\t\t<p".$this->pba($att, '', 0).">"; 
     631               $c2 = "</p>"; 
     632               $c1 = "\n\t</blockquote>"; 
     633          } 
     634          elseif ($tag == 'bc') { 
     635               $o1 = "<pre$atts>"; 
     636               $o2 = "<code".$this->pba($att, '', 0).">"; 
     637               $c2 = "</code>"; 
     638               $c1 = "</pre>"; 
     639               $content = $this->shelve($this->r_encode_html(rtrim($content, "\n")."\n")); 
     640          } 
     641          elseif ($tag == 'notextile') { 
     642               $content = $this->shelve($content); 
     643               $o1 = $o2 = ''; 
     644               $c1 = $c2 = ''; 
     645          } 
     646          elseif ($tag == 'pre') { 
     647               $content = $this->shelve($this->r_encode_html(rtrim($content, "\n")."\n")); 
     648               $o1 = "<pre$atts>"; 
     649               $o2 = $c2 = ''; 
     650               $c1 = "</pre>"; 
     651          } 
     652          else { 
     653               $o2 = "\t<$tag$atts>"; 
     654               $c2 = "</$tag>"; 
     655            } 
     656 
     657          $content = $this->graf($content); 
     658 
     659          return array($o1, $o2, $content, $c2, $c1); 
     660     } 
     661 
     662// ------------------------------------------------------------- 
     663     function graf($text) 
     664     { 
     665          // handle normal paragraph text 
     666          if (!$this->lite) { 
     667               $text = $this->noTextile($text); 
     668               $text = $this->code($text); 
     669          } 
     670 
     671          $text = $this->getRefs($text); 
     672          $text = $this->links($text); 
     673          if (!$this->noimage) 
     674               $text = $this->image($text); 
     675 
     676          if (!$this->lite) { 
     677               $text = $this->table($text); 
     678               $text = $this->lists($text); 
     679          } 
     680 
     681          $text = $this->span($text); 
     682          $text = $this->footnoteRef($text); 
     683          $text = $this->glyphs($text); 
     684          return rtrim($text, "\n"); 
     685     } 
     686 
     687// ------------------------------------------------------------- 
     688     function span($text) 
     689     { 
     690          $qtags = array('\*\*','\*','\?\?','-','__','_','%','\+','~','\^'); 
     691          $pnct = ".,\"'?!;:"; 
     692 
     693          foreach($qtags as $f) { 
     694               $text = preg_replace_callback("/ 
     695                    (^|(?<=[\s>$pnct\(])|[{[]) 
     696                    ($f)(?!$f) 
     697                    ({$this->c}) 
     698                    (?::(\S+))? 
     699                    ([^\s$f]+|\S.*?[^\s$f\n]) 
     700                    ([$pnct]*) 
     701                    $f 
     702                    ($|[\]}]|(?=[[:punct:]]{1,2}|\s|\))) 
     703               /x", array(&$this, "fSpan"), $text); 
     704          } 
     705          return $text; 
     706     } 
     707 
     708// ------------------------------------------------------------- 
     709     function fSpan($m) 
     710     { 
     711          $qtags = array( 
     712               '*'  => 'strong', 
     713               '**' => 'b', 
     714               '??' => 'cite', 
     715               '_'  => 'em', 
     716               '__' => 'i', 
     717               '-'  => 'del', 
     718               '%'  => 'span', 
     719               '+'  => 'ins', 
     720               '~'  => 'sub', 
     721               '^'  => 'sup', 
     722          ); 
     723 
     724          list(, $pre, $tag, $atts, $cite, $content, $end, $tail) = $m; 
     725          $tag = $qtags[$tag]; 
     726          $atts = $this->pba($atts); 
     727          $atts .= ($cite != '') ? 'cite="' . $cite . '"' : ''; 
     728 
     729          $out = "<$tag$atts>$content$end</$tag>"; 
     730 
     731          if (($pre and !$tail) or ($tail and !$pre)) 
     732               $out = $pre.$out.$tail; 
    532733 
    533734//        $this->dump($out); 
    534735 
    535         return $out; 
    536      
    537     } 
    538  
    539 // ------------------------------------------------------------- 
    540     function links($text) 
    541     { 
    542         return preg_replace_callback('/ 
    543             ([\s[{(]|[[:punct:]])?       # $pre 
    544             "                            # start 
    545             (' . $this->c . ')           # $atts 
    546             ([^"]+)                      # $text 
    547             \s? 
    548             (?:\(([^)]+)\)(?="))?        # $title 
    549             ": 
    550             (\S+\b)                      # $url 
    551             (\/)?                        # $slash 
    552             ([^\w\/;]*)                  # $post 
    553             (?=\s|$) 
    554         /Ux', array(&$this, "fLink"), $text); 
    555     } 
    556  
    557 // ------------------------------------------------------------- 
    558     function fLink($m) 
    559     { 
    560         list(, $pre, $atts, $text, $title, $url, $slash, $post) = $m; 
    561  
    562         $url = $this->checkRefs($url); 
    563  
    564         $atts = $this->pba($atts); 
    565         $atts .= ($title != '') ? 'title="' . $title . '"' : ''; 
    566  
    567         $atts = ($atts) ? $this->shelve($atts) : ''; 
    568  
    569         $out = $pre . '<a href="' . $url . $slash . '"' . $atts . $this->rel . '>' . $text . '</a>' . $post; 
     736          return $out; 
     737 
     738     } 
     739 
     740// ------------------------------------------------------------- 
     741     function links($text) 
     742     { 
     743          return preg_replace_callback('/ 
     744               (^|(?<=[\s>.$pnct\(])|[{[]) # $pre 
     745               "                                   # start 
     746               (' . $this->c . ')             # $atts 
     747               ([^"]+?)                       # $text 
     748               (?:\(([^)]+?)\)(?="))?         # $title 
     749               ": 
     750               ('.$this->urlch.'+?)           # $url 
     751               (\/)?                               # $slash 
     752               ([^\w\/;]*?)                   # $post 
     753               ([\]}]|(?=\s|$|\))) 
     754          /x', array(&$this, "fLink"), $text); 
     755     } 
     756 
     757// ------------------------------------------------------------- 
     758     function fLink($m) 
     759     { 
     760          list(, $pre, $atts, $text, $title, $url, $slash, $post, $tail) = $m; 
     761 
     762          $atts = $this->pba($atts); 
     763          $atts .= ($title != '') ? ' title="' . $this->encode_html($title) . '"' : ''; 
     764 
     765          if (!$this->noimage) 
     766               $text = $this->image($text); 
     767 
     768          $text = $this->span($text); 
     769          $text = $this->glyphs($text); 
     770 
     771          $url = $this->shelveURL($url.$slash); 
     772 
     773          $out = '<a href="' . $url . '"' . $atts . $this->rel . '>' . trim($text) . '</a>' . $post; 
     774 
     775          if (($pre and !$tail) or ($tail and !$pre)) 
     776               $out = $pre.$out.$tail; 
    570777 
    571778          // $this->dump($out); 
     779          return $this->shelve($out); 
     780 
     781     } 
     782 
     783// ------------------------------------------------------------- 
     784     function getRefs($text) 
     785     { 
     786          return preg_replace_callback("/^\[(.+)\]((?:http:\/\/|\/)\S+)(?=\s|$)/Um", 
     787               array(&$this, "refs"), $text); 
     788     } 
     789 
     790// ------------------------------------------------------------- 
     791     function refs($m) 
     792     { 
     793          list(, $flag, $url) = $m; 
     794          $this->urlrefs[$flag] = $url; 
     795          return ''; 
     796     } 
     797 
     798// ------------------------------------------------------------- 
     799     function shelveURL($text) 
     800     { 
     801          if (!$text) return ''; 
     802          $ref = md5($text); 
     803          $this->urlshelf[$ref] = $text; 
     804          return 'urlref:'.$ref; 
     805     } 
     806 
     807// ------------------------------------------------------------- 
     808     function retrieveURLs($text) 
     809     { 
     810          return preg_replace_callback('/urlref:(\w{32})/', 
     811               array(&$this, "retrieveURL"), $text); 
     812     } 
     813 
     814// ------------------------------------------------------------- 
     815     function retrieveURL($m) 
     816     { 
     817          $ref = $m[1]; 
     818          if (!isset($this->urlshelf[$ref])) 
     819               return $ref; 
     820          $url = $this->urlshelf[$ref]; 
     821          if (isset($this->urlrefs[$url])) 
     822               $url = $this->urlrefs[$url]; 
     823          return $this->r_encode_html($this->relURL($url)); 
     824     } 
     825 
     826// ------------------------------------------------------------- 
     827     function relURL($url) 
     828     { 
     829          $parts = @parse_url(urldecode($url)); 
     830          if ((empty($parts['scheme']) or @$parts['scheme'] == 'http') and 
     831                empty($parts['host']) and 
     832                preg_match('/^\w/', @$parts['path'])) 
     833               $url = $this->hu.$url; 
     834          if ($this->restricted and !empty($parts['scheme']) and 
     835                 !in_array($parts['scheme'], $this->url_schemes)) 
     836               return '#'; 
     837          return $url; 
     838     } 
     839 
     840// ------------------------------------------------------------- 
     841     function isRelURL($url) 
     842     { 
     843          $parts = @parse_url($url); 
     844          return (empty($parts['scheme']) and empty($parts['host'])); 
     845     } 
     846 
     847// ------------------------------------------------------------- 
     848     function image($text) 
     849     { 
     850          return preg_replace_callback("/ 
     851               (?:[[{])?         # pre 
     852               \!                     # opening ! 
     853               (\<|\=|\>)?       # optional alignment atts 
     854               ($this->c)             # optional style,class atts 
     855               (?:\. )?          # optional dot-space 
     856               ([^\s(!]+)             # presume this is the src 
     857               \s?               # optional space 
     858               (?:\(([^\)]+)\))?  # optional title 
     859               \!                     # closing 
     860               (?::(\S+))?       # optional href 
     861               (?:[\]}]|(?=\s|$|\))) # lookahead: space or end of string 
     862          /x", array(&$this, "fImage"), $text); 
     863     } 
     864 
     865// ------------------------------------------------------------- 
     866     function fImage($m) 
     867     { 
     868          list(, $algn, $atts, $url) = $m; 
     869          $atts  = $this->pba($atts); 
     870          $atts .= ($algn != '')   ? ' align="' . $this->iAlign($algn) . '"' : ''; 
     871          $atts .= (isset($m[4])) ? ' title="' . $m[4] . '"' : ''; 
     872          $atts .= (isset($m[4])) ? ' alt="'  . $m[4] . '"' : ' alt=""'; 
     873          $size = false; 
     874          if ($this->isRelUrl($url)) 
     875               $size = @getimagesize(realpath($this->doc_root.ltrim($url, $this->ds))); 
     876          if ($size) $atts .= " $size[3]"; 
     877 
     878          $href = (isset($m[5])) ? $this->shelveURL($m[5]) : ''; 
     879          $url = $this->shelveURL($url); 
     880 
     881          $out = array( 
     882               ($href) ? '<a href="' . $href . '">' : '', 
     883               '<img src="' . $url . '"' . $atts . ' />', 
     884               ($href) ? '</a>' : '' 
     885          ); 
     886 
     887          return $this->shelve(join('',$out)); 
     888     } 
     889 
     890// ------------------------------------------------------------- 
     891     function code($text) 
     892     { 
     893          $text = $this->doSpecial($text, '<code>', '</code>', 'fCode'); 
     894          $text = $this->doSpecial($text, '@', '@', 'fCode'); 
     895          $text = $this->doSpecial($text, '<pre>', '</pre>', 'fPre'); 
     896          return $text; 
     897     } 
     898 
     899// ------------------------------------------------------------- 
     900     function fCode($m) 
     901     { 
     902       @list(, $before, $text, $after) = $m; 
     903       return $before.$this->shelve('<code>'.$this->r_encode_html($text).'</code>').$after; 
     904     } 
     905 
     906// ------------------------------------------------------------- 
     907     function fPre($m) 
     908     { 
     909       @list(, $before, $text, $after) = $m; 
     910       return $before.'<pre>'.$this->shelve($this->r_encode_html($text)).'</pre>'.$after; 
     911     } 
     912// ------------------------------------------------------------- 
     913     function shelve($val) 
     914     { 
     915          $i = uniqid(rand()); 
     916          $this->shelf[$i] = $val; 
     917          return $i; 
     918     } 
     919 
     920// ------------------------------------------------------------- 
     921     function retrieve($text) 
     922     { 
     923          if (is_array($this->shelf)) 
     924               do { 
     925                    $old = $text; 
     926                    $text = strtr($text, $this->shelf); 
     927                } while ($text != $old); 
     928 
     929          return $text; 
     930     } 
     931 
     932// ------------------------------------------------------------- 
     933// NOTE: deprecated 
     934     function incomingEntities($text) 
     935     { 
     936          return preg_replace("/&(?![#a-z0-9]+;)/i", "x%x%", $text); 
     937     } 
     938 
     939// ------------------------------------------------------------- 
     940// NOTE: deprecated 
     941     function encodeEntities($text) 
     942     { 
     943          return (function_exists('mb_encode_numericentity')) 
     944          ?     $this->encode_high($text) 
     945          :     htmlentities($text, ENT_NOQUOTES, "utf-8"); 
     946     } 
     947 
     948// ------------------------------------------------------------- 
     949// NOTE: deprecated 
     950     function fixEntities($text) 
     951     { 
     952          /*   de-entify any remaining angle brackets or ampersands */ 
     953          return str_replace(array("&gt;", "&lt;", "&amp;"), 
     954               array(">", "<", "&"), $text); 
     955     } 
     956 
     957// ------------------------------------------------------------- 
     958     function cleanWhiteSpace($text) 
     959     { 
     960          $out = str_replace("\r\n", "\n", $text);          # DOS line endings 
     961          $out = preg_replace("/^[ \t]*\n/m", "\n", $out);  # lines containing only whitespace 
     962          $out = preg_replace("/\n{3,}/", "\n\n", $out);    # 3 or more line ends 
     963          $out = preg_replace("/^\n*/", "", $out);          # leading blank lines 
    572964          return $out; 
    573  
    574     } 
    575  
    576 // ------------------------------------------------------------- 
    577     function getRefs($text) 
    578     { 
    579         return preg_replace_callback("/(?<=^|\s)\[(.+)\]((?:http:\/\/|\/)\S+)(?=\s|$)/U", 
    580             array(&$this, "refs"), $text); 
    581     } 
    582     // ------------------------------------------------------------- 
    583  
    584 function refs($m) 
    585     { 
    586         list(, $flag, $url) = $m; 
    587         $this->urlrefs[$flag] = $url; 
    588         return ''; 
    589     } 
    590  
    591 // ------------------------------------------------------------- 
    592     function checkRefs($text) 
    593     { 
    594         return (isset($this->urlrefs[$text])) ? $this->urlrefs[$text] : $text; 
    595     } 
    596  
    597 // ------------------------------------------------------------- 
    598     function image($text) 
    599     { 
    600         return preg_replace_callback("/ 
    601             \!                 # opening ! 
    602             (\<|\=|\>)?        # optional alignment atts 
    603             ($this->c)         # optional style,class atts 
    604             (?:\. )?           # optional dot-space 
    605             ([^\s(!]+)         # presume this is the src 
    606             \s?                # optional space 
    607             (?:\(([^\)]+)\))?  # optional title 
    608             \!                 # closing 
    609             (?::(\S+))?        # optional href 
    610             (?=\s|$)           # lookahead: space or end of string 
    611         /Ux", array(&$this, "fImage"), $text); 
    612     } 
    613  
    614 // ------------------------------------------------------------- 
    615     function fImage($m) 
    616     { 
    617         list(, $algn, $atts, $url) = $m; 
    618         $atts  = $this->pba($atts); 
    619         $atts .= ($algn != '')  ? ' align="' . $this->iAlign($algn) . '"' : ''; 
    620         $atts .= (isset($m[4])) ? ' title="' . $m[4] . '"' : ''; 
    621         $atts .= (isset($m[4])) ? ' alt="'   . $m[4] . '"' : ' alt=""'; 
    622         $size = @getimagesize($url); 
    623         if ($size) $atts .= " $size[3]"; 
    624  
    625         $href = (isset($m[5])) ? $this->checkRefs($m[5]) : ''; 
    626         $url = $this->checkRefs($url); 
    627  
    628         $out = array( 
    629             ($href) ? '<a href="' . $href . '">' : '', 
    630             '<img src="' . $url . '"' . $atts . ' />', 
    631             ($href) ? '</a>' : '' 
    632         ); 
    633  
    634         return join('',$out); 
    635     } 
    636  
    637 // ------------------------------------------------------------- 
    638     function code($text) 
    639     { 
    640         return preg_replace_callback("/ 
    641             (?:^|(?<=[\s\(])|([[{]))        # before 
    642             @                                
    643             (?:\|(\w+)\|)?                  # lang 
    644             (.+)                            # code 
    645             @                                
    646             (?:$|([\]}])| 
    647             (?=[[:punct:]]{1,2}| 
    648             \s|$))                           # after 
    649         /Ux", array(&$this, "fCode"), $text); 
    650     } 
    651  
    652 // ------------------------------------------------------------- 
    653     function fCode($m) 
    654     { 
    655         @list(, $before, $lang, $code, $after) = $m; 
    656         $lang = ($lang) ? ' language="' . $lang . '"' : ''; 
    657         return $before . '<code' . $lang . '>' . $code . '</code>' . $after; 
    658     } 
    659  
    660 // ------------------------------------------------------------- 
    661     function shelve($val) 
    662     { 
    663         $this->shelf[] = $val; 
    664         return ' <' . count($this->shelf) . '>'; 
    665     } 
    666  
    667 // ------------------------------------------------------------- 
    668     function retrieve($text) 
    669     { 
    670         $i = 0; 
    671         if (isset($this->shelf) && is_array($this->shelf)) { 
    672             foreach($this->shelf as $r) { 
    673                 $i++; 
    674                 $text = str_replace("<$i>", $r, $text); 
    675             } 
    676         } 
    677         return $text; 
    678     } 
    679  
    680 // ------------------------------------------------------------- 
    681     function incomingEntities($text) 
    682     { 
    683         return preg_replace("/&(?![#a-z0-9]+;)/i", "x%x%", $text); 
    684     } 
    685  
    686 // ------------------------------------------------------------- 
    687     function encodeEntities($text) 
    688     { 
    689         return (function_exists('mb_encode_numericentity')) 
    690         ?    $this->encode_high($text) 
    691         :    htmlentities($text, ENT_NOQUOTES, "utf-8"); 
    692     } 
    693  
    694 // ------------------------------------------------------------- 
    695     function fixEntities($text) 
    696     { 
    697         /*  de-entify any remaining angle brackets or ampersands */ 
    698         return str_replace(array("&gt;", "&lt;", "&amp;"), 
    699             array(">", "<", "&"), $text); 
    700     } 
    701  
    702 // ------------------------------------------------------------- 
    703     function cleanWhiteSpace($text) 
    704     { 
    705         $out = str_replace(array("\r\n", "\t"), array("\n", ''), $text); 
    706         $out = preg_replace("/\n{3,}/", "\n\n", $out); 
    707         $out = preg_replace("/\n *\n/", "\n\n", $out); 
    708         $out = preg_replace('/"$/', "\" ", $out); 
    709         return $out; 
    710     } 
    711  
    712 // ------------------------------------------------------------- 
    713     function noTextile($text) 
    714     { 
    715         $text = preg_replace_callback('/(^|\s)<notextile>(.*)<\/notextile>(\s|$)?/msU',  
    716             array(&$this, "fTextile"), $text); 
    717         return preg_replace_callback('/(^|\s)==(.*)==(\s|$)?/msU',  
    718             array(&$this, "fTextile"), $text); 
    719     }  
    720  
    721 // ------------------------------------------------------------- 
    722     function fTextile($m) 
    723     { 
    724         $modifiers = array(      
    725             '"' => '&#34;', 
    726             '%' => '&#37;', 
    727             '*' => '&#42;', 
    728             '+' => '&#43;', 
    729             '-' => '&#45;', 
    730             '<' => '&#60;', 
    731             '=' => '&#61;', 
    732             '>' => '&#62;', 
    733             '?' => '&#63;',      
    734             '^' => '&#94;', 
    735             '_' => '&#95;', 
    736             '~' => '&#126;',         
    737             ); 
    738          
    739         @list(, $before, $notextile, $after) = $m; 
    740         $notextile = str_replace(array_keys($modifiers), array_values($modifiers), $notextile); 
    741         return $before . '<notextile>' . $notextile . '</notextile>' . $after; 
    742     } 
    743  
    744 // ------------------------------------------------------------- 
    745     function superscript($text) 
    746     { 
    747         return preg_replace('/\^(.*)\^/mU', '<sup>$1</sup>', $text); 
    748     } 
    749  
    750 // ------------------------------------------------------------- 
    751     function footnoteRef($text) 
    752     { 
    753         return preg_replace('/\b\[([0-9]+)\](\s)?/U', 
    754             '<sup><a href="#fn$1">$1</a></sup>$2', $text); 
    755     } 
    756  
    757 // ------------------------------------------------------------- 
    758     function glyphs($text) 
    759     { 
    760         // fix: hackish 
    761         $text = preg_replace('/"\z/', "\" ", $text); 
     965     } 
     966 
     967// ------------------------------------------------------------- 
     968     function doSpecial($text, $start, $end, $method='fSpecial') 
     969     { 
     970       return preg_replace_callback('/(^|\s|[[({>])'.preg_quote($start, '/').'(.*?)'.preg_quote($end, '/').'(\s|$|[\])}])?/ms', 
     971               array(&$this, $method), $text); 
     972     } 
     973 
     974// ------------------------------------------------------------- 
     975     function fSpecial($m) 
     976     { 
     977          // A special block like notextile or code 
     978       @list(, $before, $text, $after) = $m; 
     979          return $before.$this->shelve($this->encode_html($text)).$after; 
     980     } 
     981 
     982// ------------------------------------------------------------- 
     983     function noTextile($text) 
     984     { 
     985           $text = $this->doSpecial($text, '<notextile>', '</notextile>', 'fTextile'); 
     986           return $this->doSpecial($text, '==', '==', 'fTextile'); 
     987 
     988     } 
     989 
     990// ------------------------------------------------------------- 
     991     function fTextile($m) 
     992     { 
     993          @list(, $before, $notextile, $after) = $m; 
     994          #$notextile = str_replace(array_keys($modifiers), array_values($modifiers), $notextile); 
     995          return $before.$this->shelve($notextile).$after; 
     996     } 
     997 
     998// ------------------------------------------------------------- 
     999     function footnoteRef($text) 
     1000     { 
     1001          return preg_replace('/(?<=\S)\[([0-9]+)\](\s)?/Ue', 
     1002               '$this->footnoteID(\'\1\',\'\2\')', $text); 
     1003     } 
     1004 
     1005// ------------------------------------------------------------- 
     1006     function footnoteID($id, $t) 
     1007     { 
     1008          if (empty($this->fn[$id])) 
     1009               $this->fn[$id] = uniqid(rand()); 
     1010          $fnid = $this->fn[$id]; 
     1011          return '<sup class="footnote"><a href="#fn'.$fnid.'">'.$id.'</a></sup>'.$t; 
     1012     } 
     1013 
     1014// ------------------------------------------------------------- 
     1015     function glyphs($text) 
     1016     { 
     1017 
     1018          // fix: hackish 
     1019          $text = preg_replace('/"\z/', "\" ", $text); 
    7621020          $pnc = '[[:punct:]]'; 
    7631021 
    764         $glyph_search = array( 
    765             '/([^\s[{(>_*])?\'(?(1)|(?=\s|s\b|'.$pnc.'))/',      //  single closing 
    766             '/\'/',                                              //  single opening 
    767             '/([^\s[{(>_*])?"(?(1)|(?=\s|'.$pnc.'))/',           //  double closing 
    768             '/"/',                                               //  double opening 
    769             '/\b( )?\.{3}/',                                     //  ellipsis 
    770             '/\b([A-Z][A-Z0-9]{2,})\b(?:[(]([^)]*)[)])/',        //  3+ uppercase acronym 
    771             '/\s?--\s?/',                                        //  em dash 
    772             '/\s-\s/',                                           //  en dash 
    773             '/(\d+) ?x ?(\d+)/',                                 //  dimension sign 
    774             '/\b ?[([]TM[])]/i',                                 //  trademark 
    775             '/\b ?[([]R[])]/i',                                  //  registered 
    776             '/\b ?[([]C[])]/i');                                 //  copyright 
    777  
    778         $glyph_replace = array('$1&#8217;$2',   //  single closing 
    779             '&#8216;',                          //  single opening 
    780             '$1&#8221;',                        //  double closing 
    781             '&#8220;',                          //  double opening 
    782             '$1&#8230;',                        //  ellipsis 
    783             '<acronym title="$2">$1</acronym>', //  3+ uppercase acronym 
    784             '&#8212;',                          //  em dash 
    785             ' &#8211; ',                        //  en dash 
    786             '$1&#215;$2',                       //  dimension sign 
    787             '&#8482;',                          //  trademark 
    788             '&#174;',                           //  registered 
    789             '&#169;');                          //  copyright 
    790  
    791         $codepre = false; 
    792         /*  if no html, do a simple search and replace... */ 
    793         if (!preg_match("/<.*>/", $text)) { 
    794             $text = preg_replace($glyph_search, $glyph_replace, $text); 
    795             return $text; 
    796         } 
    797         else { 
    798             $text = preg_split("/(<.*>)/U", $text, -1, PREG_SPLIT_DELIM_CAPTURE); 
    799             foreach($text as $line) { 
    800                 $offtags = ('code|pre|kbd|notextile|txp:php'); 
    801  
    802                 /*  matches are off if we're between <code>, <pre> etc. */ 
    803                 if (preg_match('/<(' . $offtags . ')>/i', $line)) $codepre = true; 
    804                 if (preg_match('/<\/(' . $offtags . ')>/i', $line)) $codepre = false; 
    805  
    806                 if (!preg_match("/<.*>/", $line) && $codepre == false) { 
    807                     $line = preg_replace($glyph_search, $glyph_replace, $line); 
    808                 } 
    809  
    810                 /* do htmlspecial if between <code> */ 
    811                 if ($codepre == true) { 
    812                     $line = htmlspecialchars($line, ENT_NOQUOTES, "UTF-8"); 
    813                     $line = preg_replace('/&lt;(\/?' . $offtags . ')&gt;/', "<$1>", $line); 
    814                     $line = str_replace("&amp;#","&#",$line); 
    815                 } 
    816  
    817                 $glyph_out[] = $line; 
    818             } 
    819             return join('', $glyph_out); 
    820         } 
    821     } 
    822  
    823 // ------------------------------------------------------------- 
    824     function iAlign($in) 
    825     { 
    826         $vals = array( 
    827             '<' => 'left', 
    828             '=' => 'center', 
    829             '>' => 'right'); 
    830         return (isset($vals[$in])) ? $vals[$in] : ''; 
    831     } 
    832  
    833 // ------------------------------------------------------------- 
    834     function hAlign($in) 
    835     { 
    836         $vals = array( 
    837             '<'  => 'left', 
    838             '='  => 'center', 
    839             '>'  => 'right', 
    840             '<>' => 'justify'); 
    841         return (isset($vals[$in])) ? $vals[$in] : ''; 
    842     } 
    843  
    844 // ------------------------------------------------------------- 
    845     function vAlign($in) 
    846     { 
    847         $vals = array( 
    848             '^' => 'top', 
    849             '-' => 'middle', 
    850             '~' => 'bottom'); 
    851         return (isset($vals[$in])) ? $vals[$in] : ''; 
    852     } 
    853  
    854 // ------------------------------------------------------------- 
    855     function encode_high($text, $charset = "UTF-8") 
    856     { 
    857         return mb_encode_numericentity($text, $this->cmap(), $charset); 
    858     } 
    859  
    860 // ------------------------------------------------------------- 
    861     function decode_high($text, $charset = "UTF-8") 
    862     { 
    863         return mb_decode_numericentity($text, $this->cmap(), $charset); 
    864     } 
    865  
    866 // ------------------------------------------------------------- 
    867     function cmap() 
    868     { 
    869         $f = 0xffff; 
    870         $cmap = array( 
    871             0x0080, 0xffff, 0, $f); 
    872         return $cmap; 
    873     } 
    874  
    875 // ------------------------------------------------------------- 
    876     function textile_popup_help($name, $helpvar, $windowW, $windowH) 
    877     { 
    878         return ' <a target="_blank" href="http://www.textpattern.com/help/?item=' . $helpvar . '" onclick="window.open(this.href, \'popupwindow\', \'width=' . $windowW . ',height=' . $windowH . ',scrollbars,resizable\'); return false;">' . $name . '</a><br />'; 
    879  
    880         return $out; 
    881     } 
    882  
    883 // ------------------------------------------------------------- 
    884     function txtgps($thing) 
    885     { 
    886         if (isset($_POST[$thing])) { 
    887             if (get_magic_quotes_gpc()) { 
    888                 return stripslashes($_POST[$thing]); 
    889             } 
    890             else { 
    891                 return $_POST[$thing]; 
    892             } 
    893         } 
    894         else { 
    895             return ''; 
    896         } 
    897     } 
    898      
    899 // ------------------------------------------------------------- 
    900     function dump() 
    901     { 
     1022          $glyph_search = array( 
     1023               '/(\w)\'(\w)/',                                              // apostrophe's 
     1024               '/(\s)\'(\d+\w?)\b(?!\')/',                             // back in '88 
     1025               '/(\S)\'(?=\s|'.$pnc.'|<|$)/',                               //  single closing 
     1026               '/\'/',                                                      //  single opening 
     1027               '/(\S)\"(?=\s|'.$pnc.'|<|$)/',                               //  double closing 
     1028               '/"/',                                                            //  double opening 
     1029               '/\b([A-Z][A-Z0-9]{2,})\b(?:[(]([^)]*)[)])/',           //  3+ uppercase acronym 
     1030               '/(?<=\s|^|[>(;-])([A-Z]{3,})([a-z]*)(?=\s|'.$pnc.'|<|$)/',  //  3+ uppercase 
     1031               '/([^.]?)\.{3}/',                                            //  ellipsis 
     1032               '/(\s?)--(\s?)/',                                            //  em dash 
     1033               '/\s-(?:\s|$)/',                                             //  en dash 
     1034               '/(\d+)( ?)x( ?)(?=\d+)/',                                   //  dimension sign 
     1035               '/(\b ?|\s|^)[([]TM[])]/i',                             //  trademark 
     1036               '/(\b ?|\s|^)[([]R[])]/i',                                   //  registered 
     1037               '/(\b ?|\s|^)[([]C[])]/i',                                   //  copyright 
     1038           ); 
     1039 
     1040          extract($this->glyph, EXTR_PREFIX_ALL, 'txt'); 
     1041 
     1042          $glyph_replace = array( 
     1043               '$1'.$txt_apostrophe.'$2',               // apostrophe's 
     1044               '$1'.$txt_apostrophe.'$2',               // back in '88 
     1045               '$1'.$txt_quote_single_close,       //  single closing 
     1046               $txt_quote_single_open,             //  single opening 
     1047               '$1'.$txt_quote_double_close,       //  double closing 
     1048               $txt_quote_double_open,             //  double opening 
     1049               '<acronym title="$2">$1</acronym>',  //  3+ uppercase acronym 
     1050               '<span class="caps">$1</span>$2',   //  3+ uppercase 
     1051               '$1'.$txt_ellipsis,                      //  ellipsis 
     1052               '$1'.$txt_emdash.'$2',                   //  em dash 
     1053               ' '.$txt_endash.' ',                     //  en dash 
     1054               '$1$2'.$txt_dimension.'$3',         //  dimension sign 
     1055               '$1'.$txt_trademark,                     //  trademark 
     1056               '$1'.$txt_registered,                    //  registered 
     1057               '$1'.$txt_copyright,                     //  copyright 
     1058           ); 
     1059 
     1060           $text = preg_split("@(<[\w/!?].*>)@Us", $text, -1, PREG_SPLIT_DELIM_CAPTURE); 
     1061           $i = 0; 
     1062           foreach($text as $line) { 
     1063                // text tag text tag text ... 
     1064                if (++$i % 2) { 
     1065                     // raw < > & chars are already entity encoded in restricted mode 
     1066                     if (!$this->restricted) { 
     1067                          $line = $this->encode_raw_amp($line); 
     1068                          $line = $this->encode_lt_gt($line); 
     1069                     } 
     1070                     $line = preg_replace($glyph_search, $glyph_replace, $line); 
     1071                } 
     1072                 $glyph_out[] = $line; 
     1073           } 
     1074           return join('', $glyph_out); 
     1075     } 
     1076 
     1077// ------------------------------------------------------------- 
     1078     function iAlign($in) 
     1079     { 
     1080          $vals = array( 
     1081               '<' => 'left', 
     1082               '=' => 'center', 
     1083               '>' => 'right'); 
     1084          return (isset($vals[$in])) ? $vals[$in] : ''; 
     1085     } 
     1086 
     1087// ------------------------------------------------------------- 
     1088     function hAlign($in) 
     1089     { 
     1090          $vals = array( 
     1091               '<'  => 'left', 
     1092               '='  => 'center', 
     1093               '>'  => 'right', 
     1094               '<>' => 'justify'); 
     1095          return (isset($vals[$in])) ? $vals[$in] : ''; 
     1096     } 
     1097 
     1098// ------------------------------------------------------------- 
     1099     function vAlign($in) 
     1100     { 
     1101          $vals = array( 
     1102               '^' => 'top', 
     1103               '-' => 'middle', 
     1104               '~' => 'bottom'); 
     1105          return (isset($vals[$in])) ? $vals[$in] : ''; 
     1106     } 
     1107 
     1108// ------------------------------------------------------------- 
     1109// NOTE: deprecated 
     1110     function encode_high($text, $charset = "UTF-8") 
     1111     { 
     1112          return mb_encode_numericentity($text, $this->cmap(), $charset); 
     1113     } 
     1114 
     1115// ------------------------------------------------------------- 
     1116// NOTE: deprecated 
     1117     function decode_high($text, $charset = "UTF-8") 
     1118     { 
     1119          return mb_decode_numericentity($text, $this->cmap(), $charset); 
     1120     } 
     1121 
     1122// ------------------------------------------------------------- 
     1123// NOTE: deprecated 
     1124     function cmap() 
     1125     { 
     1126          $f = 0xffff; 
     1127          $cmap = array( 
     1128               0x0080, 0xffff, 0, $f); 
     1129          return $cmap; 
     1130     } 
     1131 
     1132// ------------------------------------------------------------- 
     1133     function encode_raw_amp($text) 
     1134      { 
     1135          return preg_replace('/&(?!#?[a-z0-9]+;)/i', '&amp;', $text); 
     1136     } 
     1137 
     1138// ------------------------------------------------------------- 
     1139     function encode_lt_gt($text) 
     1140      { 
     1141          return strtr($text, array('<' => '&lt;', '>' => '&gt;')); 
     1142     } 
     1143 
     1144// ------------------------------------------------------------- 
     1145     function encode_html($str, $quotes=1) 
     1146     { 
     1147          $a = array( 
     1148               '&' => '&amp;', 
     1149               '<' => '&lt;', 
     1150               '>' => '&gt;', 
     1151          ); 
     1152          if ($quotes) $a = $a + array( 
     1153               "'" => '&#39;', // numeric, as in htmlspecialchars 
     1154               '"' => '&quot;', 
     1155          ); 
     1156 
     1157          return strtr($str, $a); 
     1158     } 
     1159 
     1160// ------------------------------------------------------------- 
     1161     function r_encode_html($str, $quotes=1) 
     1162     { 
     1163          // in restricted mode, input has already been escaped 
     1164          if ($this->restricted) 
     1165               return $str; 
     1166          return $this->encode_html($str, $quotes); 
     1167     } 
     1168 
     1169// ------------------------------------------------------------- 
     1170     function textile_popup_help($name, $helpvar, $windowW, $windowH) 
     1171     { 
     1172          return ' <a target="_blank" href="http://www.textpattern.com/help/?item=' . $helpvar . '" onclick="window.open(this.href, \'popupwindow\', \'width=' . $windowW . ',height=' . $windowH . ',scrollbars,resizable\'); return false;">' . $name . '</a><br />'; 
     1173 
     1174          return $out; 
     1175     } 
     1176 
     1177// ------------------------------------------------------------- 
     1178// NOTE: deprecated 
     1179     function txtgps($thing) 
     1180     { 
     1181          if (isset($_POST[$thing])) { 
     1182               if (get_magic_quotes_gpc()) { 
     1183                    return stripslashes($_POST[$thing]); 
     1184               } 
     1185               else { 
     1186                    return $_POST[$thing]; 
     1187               } 
     1188          } 
     1189          else { 
     1190               return ''; 
     1191          } 
     1192     } 
     1193 
     1194// ------------------------------------------------------------- 
     1195// NOTE: deprecated 
     1196     function dump() 
     1197     { 
    9021198          foreach (func_get_args() as $a) 
    9031199               echo "\n<pre>",(is_array($a)) ? print_r($a) : $a, "</pre>\n"; 
    9041200     } 
    9051201 
     1202// ------------------------------------------------------------- 
     1203 
     1204     function blockLite($text) 
     1205     { 
     1206          $this->btag = array('bq', 'p'); 
     1207          return $this->block($text."\n\n"); 
     1208     } 
     1209 
    9061210 
    9071211} // end class 
Note: See TracChangeset for help on using the changeset viewer.

Sites map