| [ PHPXref.com ] | [ Generated: Sun Jul 20 16:35:25 2008 ] | [ bBlog 0.7.6 ] |
| [ Index ] [ Variables ] [ Functions ] [ Classes ] [ Constants ] [ Statistics ] | ||
[Summary view] [Print] [Text view]
1 <?php 2 /* 3 4 This is Textile 5 A Humane Web Text Generator 6 7 Version 2.0 beta 8 8 July, 2003 9 10 Copyright (c) 2003, Dean Allen, www.textism.com 11 All rights reserved. 12 13 _______ 14 LICENSE 15 16 Redistribution and use in source and binary forms, with or without 17 modification, are permitted provided that the following conditions are met: 18 19 * Redistributions of source code must retain the above copyright notice, 20 this list of conditions and the following disclaimer. 21 22 * Redistributions in binary form must reproduce the above copyright notice, 23 this list of conditions and the following disclaimer in the documentation 24 and/or other materials provided with the distribution. 25 26 * Neither the name Textile nor the names of its contributors may be used to 27 endorse or promote products derived from this software without specific 28 prior written permission. 29 30 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 31 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 32 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 33 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 34 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 35 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 36 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 37 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 38 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 39 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 40 POSSIBILITY OF SUCH DAMAGE. 41 42 */ 43 44 45 // bBlog modifier function : 46 function smarty_modifier_textile ($text) { 47 return textile($text,''); 48 } 49 50 // bBlog plugin identifier function 51 function identify_modifier_textile () { 52 $helptext = ' 53 Block modifier syntax: 54 55 Header: h(1-6). 56 Paragraphs beginning with \'hn. \' (where n is 1-6) are wrapped in header tags. 57 Example: h1. Header... -> <h1>Header...</h1> 58 59 Paragraph: p. (also applied by default) 60 Example: p. Text -> <p>Text</p> 61 62 Blockquote: bq. 63 Example: bq. Block quotation... -> <blockquote>Block quotation...</blockquote> 64 65 Blockquote with citation: bq.:http://citation.url 66 Example: bq.:http://textism.com/ Text... 67 -> <blockquote cite="http://textism.com">Text...</blockquote> 68 69 Footnote: fn(1-100). 70 Example: fn1. Footnote... -> <p id="fn1">Footnote...</p> 71 72 Numeric list: #, ## 73 Consecutive paragraphs beginning with # are wrapped in ordered list tags. 74 Example: <ol><li>ordered list</li></ol> 75 76 Bulleted list: *, ** 77 Consecutive paragraphs beginning with * are wrapped in unordered list tags. 78 Example: <ul><li>unordered list</li></ul> 79 80 Phrase modifier syntax: 81 82 _emphasis_ -> <em>emphasis</em> 83 __italic__ -> <i>italic</i> 84 *strong* -> <strong>strong</strong> 85 **bold** -> <b>bold</b> 86 ??citation?? -> <cite>citation</cite> 87 -deleted text- -> <del>deleted</del> 88 +inserted text+ -> <ins>inserted</ins> 89 ^superscript^ -> <sup>superscript</sup> 90 ~subscript~ -> <sub>subscript</sub> 91 @code@ -> <code>computer code</code> 92 %(bob)span% -> <span class="bob">span</span> 93 94 ==notextile== -> leave text alone (do not format) 95 96 "linktext":url -> <a href="url">linktext</a> 97 "linktext(title)":url -> <a href="url" title="title">linktext</a> 98 99 !imageurl! -> <img src="imageurl" /> 100 !imageurl(alt text)! -> <img src="imageurl" alt="alt text" /> 101 !imageurl!:linkurl -> <a href="linkurl"><img src="imageurl" /></a> 102 103 ABC(Always Be Closing) -> <acronym title="Always Be Closing">ABC</acronym> 104 105 106 Table syntax: 107 108 Simple tables: 109 110 |a|simple|table|row| 111 |And|Another|table|row| 112 113 |_. A|_. table|_. header|_.row| 114 |A|simple|table|row| 115 116 Tables with attributes: 117 118 table{border:1px solid black}. 119 {background:#ddd;color:red}. |{}| | | | 120 121 122 Applying Attributes: 123 124 Most anywhere Textile code is used, attributes such as arbitrary css style, 125 css classes, and ids can be applied. The syntax is fairly consistent. 126 127 The following characters quickly alter the alignment of block elements: 128 129 < -> left align ex. p<. left-aligned para 130 > -> right align h3>. right-aligned header 3 131 = -> centred h4=. centred header 4 132 <> -> justified p<>. justified paragraph 133 134 These will change vertical alignment in table cells: 135 136 ^ -> top ex. |^. top-aligned table cell| 137 - -> middle |-. middle aligned| 138 ~ -> bottom |~. bottom aligned cell| 139 140 Plain (parentheses) inserted between block syntax and the closing dot-space 141 indicate classes and ids: 142 143 p(hector). paragraph -> <p class="hector">paragraph</p> 144 145 p(#fluid). paragraph -> <p id="fluid">paragraph</p> 146 147 (classes and ids can be combined) 148 p(hector#fluid). paragraph -> <p class="hector" id="fluid">paragraph</p> 149 150 Curly {brackets} insert arbitrary css style 151 152 p{line-height:18px}. paragraph -> <p style="line-height:18px">paragraph</p> 153 154 h3{color:red}. header 3 -> <h3 style="color:red">header 3</h3> 155 156 Square [brackets] insert language attributes 157 158 p[no]. paragraph -> <p lang="no">paragraph</p> 159 160 %[fr]phrase% -> <span lang="fr">phrase</span> 161 162 Usually Textile block element syntax requires a dot and space before the block 163 begins, but since lists don\'t, they can be styled just using braces 164 165 #{color:blue} one -> <ol style="color:blue"> 166 # big <li>one</li> 167 # list <li>big</li> 168 <li>list</li> 169 </ol> 170 171 Using the span tag to style a phrase 172 173 It goes like this, %{color:red}the fourth the fifth% 174 -> It goes like this, <span style="color:red">the fourth the fifth</span> 175 '; 176 $help = "<pre>".nl2br(htmlspecialchars($helptext))."</pre>"; 177 return array ( 178 'name' =>'textile', 179 'type' =>'modifier', 180 'nicename' =>'Textile v2', 181 'description' =>'A Humane Web Text Generator', 182 'authors' =>'Dean Allen', 183 'licence' =>'Textile', 184 'help' =>$help 185 ); 186 187 } 188 189 190 $hlgn = "(?:\<(?!>)|(?<!<)\>|\<\>|\=|[()]+)"; 191 $vlgn = "[\-^~]"; 192 $clas = "(?:\([^)]+\))"; 193 $lnge = "(?:\[[^]]+\])"; 194 $styl = "(?:\{[^}]+\})"; 195 $cspn = "(?:\\\\\d+)"; 196 $rspn = "(?:\/\d+)"; 197 $a = "(?:$hlgn?$vlgn?|$vlgn?$hlgn?)"; 198 $s = "(?:$cspn?$rspn?|$rspn?$cspn?)"; 199 $c = "(?:$clas?$styl?$lnge?|$styl?$lnge?$clas?|$lnge?$styl?$clas?)"; 200 $pnct = '[\!"#\$%&\'()\*\+,\-\./:;<=>\?@\[\\\]\^_`{\|}\~]'; 201 202 203 function encodeSpecial($text) 204 { 205 return str_replace(explode(",","á,é,í,ó,ú,ñ,ä,ö,ü,Ä,Ö,Ü,ß") , explode(",","á,é,í,ó,ú,ñ,ä,ö,ü,Ä,Ö,Ü,ß"), $text) ; 206 } 207 208 209 210 function textile($text,$lite='') { 211 212 if (get_magic_quotes_gpc()==1) 213 $text = stripslashes($text); 214 215 $text = incomingEntities($text); 216 $text = encodeSpecial($text); 217 $text = encodeEntities($text); 218 $text = fixEntities($text); 219 $text = cleanWhiteSpace($text); 220 221 $text = getRefs($text); 222 223 $text = noTextile($text); 224 $text = image($text); 225 $text = links($text); 226 $text = code($text); 227 $text = span($text); 228 $text = superscript($text); 229 $text = footnoteRef($text); 230 $text = glyphs($text); 231 $text = retrieve($text); 232 233 if ($lite=='') { 234 $text = lists($text); 235 $text = table($text); 236 $text = block($text); 237 } 238 239 /* clean up <notextile> */ 240 $text = preg_replace('/<\/?notextile>/', "",$text); 241 242 /* turn the temp char back to an ampersand entity */ 243 $text = str_replace("x%x%","&",$text); 244 245 $text = str_replace("<br />","<br />\n",$text); 246 247 return trim($text); 248 } 249 250 // ------------------------------------------------------------- 251 function pba($in,$element="") // "parse block attributes" 252 { 253 global $hlgn,$vlgn,$clas,$styl,$cspn,$rspn,$a,$s,$c; 254 255 $style=''; $class=''; $language=''; $colspan=''; $rowspan=''; $id=''; $atts=''; 256 257 if (!empty($in)) { 258 $matched = $in; 259 if($element=='td'){ 260 if(preg_match("/\\\\(\d+)/",$matched,$csp)) $colspan=$csp[1]; 261 if(preg_match("/\/(\d+)/",$matched,$rsp)) $rowspan=$rsp[1]; 262 263 if (preg_match("/($vlgn)/",$matched,$vert)) 264 $style[] = "vertical-align:".vAlign($vert[1]).";"; 265 } 266 267 if(preg_match("/\{([^}]*)\}/",$matched,$sty)) { 268 $style[]=$sty[1].';'; 269 $matched = str_replace($sty[0],'',$matched); 270 } 271 272 if(preg_match("/\[([^)]+)\]/U",$matched,$lng)) { 273 $language=$lng[1]; 274 $matched = str_replace($lng[0],'',$matched); 275 } 276 277 if(preg_match("/\(([^()]+)\)/U",$matched,$cls)) { 278 $class=$cls[1]; 279 $matched = str_replace($cls[0],'',$matched); 280 } 281 282 if(preg_match("/([(]+)/",$matched,$pl)) { 283 $style[] = "padding-left:".strlen($pl[1])."em;"; 284 $matched = str_replace($pl[0],'',$matched); 285 } 286 if(preg_match("/([)]+)/",$matched,$pr)) { 287 dump($pr); 288 $style[] = "padding-right:".strlen($pr[1])."em;"; 289 $matched = str_replace($pr[0],'',$matched); 290 } 291 292 if (preg_match("/($hlgn)/",$matched,$horiz)) 293 $style[] = "text-align:".hAlign($horiz[1]).";"; 294 295 if (preg_match("/^(.*)#(.*)$/",$class,$ids)) { 296 $id = $ids[2]; 297 $class = $ids[1]; 298 } 299 300 if($style) $atts.=' style="'.join("",$style).'"'; 301 if($class) $atts.=' class="'.$class.'"'; 302 if($language) $atts.=' lang="'.$language.'"'; 303 if($id) $atts.=' id="'.$id.'"'; 304 if($colspan) $atts.=' colspan="'.$colspan.'"'; 305 if($rowspan) $atts.=' rowspan="'.$rowspan.'"'; 306 307 return $atts; 308 } else { 309 return ''; 310 } 311 } 312 313 // ------------------------------------------------------------- 314 function table($text) 315 { 316 global $a,$c,$s; 317 $text = $text."\n\n"; 318 return preg_replace_callback("/^(?:table(_?$s$a$c)\. ?\n)?^($a$c\.? ?\|.*\|)\n\n/smU", 319 "fTable",$text); 320 } 321 322 // ------------------------------------------------------------- 323 function fTable($matches) 324 { 325 global $s,$a,$c; 326 $tatts = pba($matches[1],'table'); 327 328 foreach(preg_split("/\|$/m",$matches[2],-1,PREG_SPLIT_NO_EMPTY) as $row){ 329 if (preg_match("/^($a$c\. )(.*)/m",$row,$rmtch)) { 330 $ratts = pba($rmtch[1],'tr'); 331 $row = $rmtch[2]; 332 } else $ratts = ''; 333 334 foreach(explode("|",$row) as $cell){ 335 $ctyp = "d"; 336 if (preg_match("/^_/",$cell)) $ctyp = "h"; 337 if (preg_match("/^(_?$s$a$c\. )(.*)/",$cell,$cmtch)) { 338 $catts = pba($cmtch[1],'td'); 339 $cell = $cmtch[2]; 340 } else $catts = ''; 341 342 if(trim($cell)!='') 343 $cells[] = "\t\t\t<t$ctyp$catts>$cell</t$ctyp>"; 344 } 345 $rows[] = "\t\t<tr$ratts>\n".join("\n",$cells)."\n\t\t</tr>"; 346 unset($cells,$catts); 347 } 348 return "\t<table$tatts>\n".join("\n",$rows)."\n\t</table>\n\n"; 349 } 350 351 352 // ------------------------------------------------------------- 353 function lists($text) 354 { 355 global $a,$c; 356 return preg_replace_callback("/^([#*]+$c .*)$(?![^#*])/smU","fList",$text); 357 } 358 359 // ------------------------------------------------------------- 360 function fList($m) 361 { 362 global $a,$c; 363 $text = explode("\n",$m[0]); 364 foreach($text as $line){ 365 $nextline = next($text); 366 if(preg_match("/^([#*]+)($a$c) (.*)$/s",$line,$m)) { 367 list(,$tl,$atts,$content) = $m; 368 $nl = preg_replace("/^([#*]+)\s.*/","$1",$nextline); 369 if(!isset($lists[$tl])){ 370 $lists[$tl] = true; 371 $atts = pba($atts); 372 $line = "\t<".lT($tl)."l$atts>\n\t<li>".$content; 373 } else { 374 $line = "\t\t<li>".$content; 375 } 376 377 if ($nl===$tl){ 378 $line .= "</li>"; 379 } elseif($nl=="*" or $nl=="#") { 380 $line .= "</li>\n\t</".lT($tl)."l>\n\t</li>"; 381 unset($lists[$tl]); 382 } 383 if (!$nl) { 384 foreach($lists as $k=>$v){ 385 $line .= "</li>\n\t</".lT($k)."l>"; 386 unset($lists[$k]); 387 } 388 } 389 } 390 $out[] = $line; 391 } 392 return join("\n",$out); 393 } 394 395 // ------------------------------------------------------------- 396 function lT($in) 397 { 398 return preg_match("/^#+/",$in) ? 'o' : 'u'; 399 } 400 401 // ------------------------------------------------------------- 402 function block($text) 403 { 404 global $a,$c; 405 406 $pre = false; 407 $find = array('bq','h[1-6]','fn\d+','p'); 408 409 $text = preg_replace("/(.+)\n(?![#*\s|])/", 410 "$1<br />", $text); 411 412 $text = explode("\n",$text); 413 array_push($text," "); 414 415 foreach($text as $line) { 416 if (preg_match('/<pre>/i',$line)) { $pre = true; } 417 foreach($find as $tag){ 418 $line = ($pre==false) 419 ? preg_replace_callback("/^($tag)($a$c)\.(?::(\S+))? (.*)$/", 420 "fBlock",$line) 421 : $line; 422 } 423 424 $line = preg_replace('/^(?!\t|<\/?pre|<\/?code|$| )(.*)/',"\t<p>$1</p>",$line); 425 426 $line=($pre==true) ? str_replace("<br />","\n",$line):$line; 427 if (preg_match('/<\/pre>/i',$line)) { $pre = false; } 428 429 $out[] = $line; 430 } 431 return join("\n",$out); 432 } 433 434 // ------------------------------------------------------------- 435 function fBlock($m) 436 { 437 # dump($m); 438 list(,$tag,$atts,$cite,$content) = $m; 439 440 $atts = pba($atts); 441 442 if(preg_match("/fn(\d+)/",$tag,$fns)){ 443 $tag = 'p'; 444 $atts.= ' id="fn'.$fns[1].'"'; 445 $content = '<sup>'.$fns[1].'</sup> '.$content; 446 } 447 448 $start = "\t<$tag"; 449 $end = "</$tag>"; 450 451 if ($tag=="bq") { 452 $cite = checkRefs($cite); 453 $cite = ($cite!='') ? ' cite="'.$cite.'"' : ''; 454 $start = "\t<blockquote$cite>\n\t\t<p"; 455 $end = "</p>\n\t</blockquote>"; 456 } 457 458 return "$start$atts>$content$end"; 459 } 460 461 462 // ------------------------------------------------------------- 463 function span($text) 464 { 465 global $c,$pnct; 466 $qtags = array('\*\*','\*','\?\?','-','__','_','%','\+','~'); 467 468 foreach($qtags as $f) { 469 $text = preg_replace_callback( 470 "/(?<=^|\s|\>|[[:punct:]]|[{(\[]) 471 ($f) 472 ($c) 473 (?::(\S+))? 474 (\w.+\w) 475 ([[:punct:]]*) 476 $f 477 (?=[])}]|[[:punct:]]+|\s|$) 478 /xmU","fSpan",$text); 479 } 480 return $text; 481 } 482 483 // ------------------------------------------------------------- 484 function fSpan($m) 485 { 486 # dump($m); 487 global $c; 488 $qtags = array( 489 '*' => 'b', 490 '**' => 'strong', 491 '??' => 'cite', 492 '_' => 'em', 493 '__' => 'i', 494 '-' => 'del', 495 '%' => 'span', 496 '+' => 'ins', 497 '~' => 'sub'); 498 499 list(,$tag,$atts,$cite,$content,$end) = $m; 500 $tag = $qtags[$tag]; 501 $atts = pba($atts); 502 $atts.= ($cite!='') ? 'cite="'.$cite.'"' : ''; 503 504 return "<$tag$atts>$content$end</$tag>"; 505 } 506 507 // ------------------------------------------------------------- 508 function links($text) 509 { 510 global $c; 511 return preg_replace_callback('/ 512 ([\s[{(]|[[:punct:]])? # $pre 513 " # start 514 ('.$c.') # $atts 515 ([^"]+) # $text 516 \s? 517 (?:\(([^)]+)\)(?="))? # $title 518 ": 519 (\S+\b) # $url 520 (\/)? # $slash 521 ([^\w\/;]*) # $post 522 (?=\s|$) 523 /Ux',"fLink",$text); 524 } 525 526 // ------------------------------------------------------------- 527 function fLink($m) 528 { 529 list(,$pre,$atts,$text,$title,$url,$slash,$post) = $m; 530 531 $url = checkRefs($url); 532 533 $atts = pba($atts); 534 $atts.= ($title!='') ? ' title="'.$title.'"' : ''; 535 536 $atts = ($atts!='') ? shelve($atts) : ''; 537 538 return $pre.'<a href="'.$url.$slash.'"'.$atts.'>'.$text.'</a>'.$post; 539 540 } 541 542 // ------------------------------------------------------------- 543 function getRefs($text) 544 { 545 return preg_replace_callback("/(?<=^|\s)\[(.+)\]((?:http:\/\/|\/)\S+)(?=\s|$)/U", 546 "refs",$text); 547 } 548 549 // ------------------------------------------------------------- 550 function refs($m) 551 { 552 list(,$flag,$url) = $m; 553 $GLOBALS['urlrefs'][$flag] = $url; 554 return ''; 555 } 556 557 // ------------------------------------------------------------- 558 function checkRefs($text) 559 { 560 global $urlrefs; 561 return (isset($urlrefs[$text])) ? $urlrefs[$text] : $text; 562 } 563 564 // ------------------------------------------------------------- 565 function image($text) 566 { 567 global $c; 568 return preg_replace_callback("/ 569 \! # opening 570 (\<|\=|\>)? # optional alignment atts 571 ($c) # optional style,class atts 572 (?:\. )? # optional dot-space 573 ([^\s(!]+) # presume this is the src 574 \s? # optional space 575 (?:\(([^\)]+)\))? # optional title 576 \! # closing 577 (?::(\S+))? # optional href 578 (?=\s|$) # lookahead: space or end of string 579 /Ux","fImage",$text); 580 } 581 582 // ------------------------------------------------------------- 583 function fImage($m) 584 { 585 list(,$algn,$atts,$url) = $m; 586 $atts = pba($atts); 587 $atts.= ($algn!='') ? ' align="'.iAlign($algn).'"' : ''; 588 $atts.= (isset($m[4])) ? ' title="'.$m[4].'"' : ''; 589 $size = @getimagesize($url); 590 if($size) $atts.= " $size[3]"; 591 592 $href = (isset($m[5])) ? checkRefs($m[5]) : ''; 593 $url = checkRefs($url); 594 595 $out = ''; 596 $out.= ($href!='') ? '<a href="'.$href.'">' : ''; 597 $out.= '<img src="'.$url.'"'.$atts.' />'; 598 $out.= ($href!='') ? '</a>' : ''; 599 600 return $out; 601 } 602 603 // ------------------------------------------------------------- 604 function code($text) 605 { 606 global $pnct; 607 return preg_replace_callback("/ 608 (?:^|(?<=[\s\(])|([[{])) # 1 open bracket? 609 @ # opening 610 (?:\|(\w+)\|)? # 2 language 611 (.+) # 3 code 612 @ # closing 613 (?:$|([\]}])| 614 (?=[[:punct:]]{1,2}| 615 \s)) # 4 closing bracket? 616 /Ux","fCode",$text); 617 } 618 619 // ------------------------------------------------------------- 620 function fCode($m) 621 { 622 list(,$before,$lang,$code,$after) = $m; 623 $lang = ($lang!='') ? ' language="'.$lang.'"' : ''; 624 return $before.'<code'.$lang.'>'.$code.'</code>'.$after; 625 } 626 627 // ------------------------------------------------------------- 628 function shelve($val) 629 { 630 $GLOBALS['shelf'][] = $val; 631 return ' <'.count($GLOBALS['shelf']).'>'; 632 } 633 634 // ------------------------------------------------------------- 635 function retrieve($text) 636 { 637 global $shelf; 638 $i = 0; 639 if(is_array($shelf)) { 640 foreach($shelf as $r){ 641 $i++; 642 $text = str_replace("<$i>",$r,$text); 643 } 644 } 645 return $text; 646 } 647 648 // ------------------------------------------------------------- 649 function incomingEntities($text) 650 { 651 /* turn any incoming ampersands into a dummy character for now. 652 This uses a negative lookahead for alphanumerics followed by a semicolon, 653 implying an incoming html entity, to be skipped */ 654 655 return preg_replace("/&(?![#a-z0-9]+;)/i","x%x%",$text); 656 } 657 658 // ------------------------------------------------------------- 659 function encodeEntities($text) 660 { 661 /* Convert high and low ascii to entities. If multibyte string functions are 662 available (on by default in php 4.3+), we convert using unicode mapping as 663 defined in the function encode_high(). If not, we use php's nasty 664 built-in htmlentities() */ 665 666 return (function_exists('mb_encode_numericentity')) 667 ? encode_high($text) 668 : htmlentities($text,ENT_NOQUOTES,"utf-8"); 669 } 670 671 // ------------------------------------------------------------- 672 function fixEntities($text) 673 { 674 /* de-entify any remaining angle brackets or ampersands */ 675 return str_replace(array(">", "<", "&"), 676 array(">", "<", "&"), $text); 677 } 678 679 // ------------------------------------------------------------- 680 function cleanWhiteSpace($text) 681 { 682 $out = str_replace(array("\r\n","\t"), array("\n",''), $text); 683 $out = preg_replace("/\n{3,}/","\n\n",$out); 684 $out = preg_replace("/\n *\n/","\n\n",$out); 685 $out = preg_replace('/"$/',"\" ", $out); 686 return $out; 687 } 688 689 // ------------------------------------------------------------- 690 function noTextile($text) 691 { 692 return preg_replace('/(^|\s)==(.*)==(\s|$)?/msU', 693 '$1<notextile>$2</notextile>$3',$text); 694 } 695 696 // ------------------------------------------------------------- 697 function superscript($text) 698 { 699 return preg_replace('/\^(.*)\^/mU','<sup>$1</sup>',$text); 700 } 701 702 // ------------------------------------------------------------- 703 function footnoteRef($text) 704 { 705 return preg_replace('/\b\[([0-9]+)\](\s)?/U', 706 '<sup><a href="#fn$1">$1</a></sup>$2',$text); 707 } 708 709 // ------------------------------------------------------------- 710 function glyphs($text) 711 { 712 // fix: hackish 713 $text = preg_replace('/"\z/',"\" ", $text); 714 715 $glyph_search = array( 716 '/([^\s[{(>])?\'(?(1)|(?=\s|s\b|[[:punct:]]))/', // single closing 717 '/\'/', // single opening 718 '/([^\s[{(>])?"(?(1)|(?=\s|[[:punct:]]))/', // double closing 719 '/"/', // double opening 720 '/\b( )?\.{3}/', // ellipsis 721 '/\b([A-Z][A-Z0-9]{2,})\b(?:[(]([^)]*)[)])/', // 3+ uppercase acronym 722 '/(^|[^"][>\s])([A-Z][A-Z0-9 ]{2,})([^<a-z0-9]|$)/', // 3+ uppercase caps 723 '/\s?--\s?/', // em dash 724 '/\s-\s/', // en dash 725 '/(\d+) ?x ?(\d+)/', // dimension sign 726 '/\b ?[([]TM[])]/i', // trademark 727 '/\b ?[([]R[])]/i', // registered 728 '/\b ?[([]C[])]/i'); // copyright 729 730 $glyph_replace = array( 731 '$1’$2', // single closing 732 '‘', // single opening 733 '$1”', // double closing 734 '“', // double opening 735 '$1…', // ellipsis 736 '<acronym title="$2">$1</acronym>', // 3+ uppercase acronym 737 '$1<span class="caps">$2</span>$3', // 3+ uppercase caps 738 '—', // em dash 739 ' – ', // en dash 740 '$1×$2', // dimension sign 741 '™', // trademark 742 '®', // registered 743 '©'); // copyright 744 745 746 $codepre = false; 747 /* if no html, do a simple search and replace... */ 748 if (!preg_match("/<.*>/",$text)) { 749 $text = preg_replace($glyph_search,$glyph_replace,$text); 750 return $text; 751 } else { 752 $text = preg_split("/(<.*>)/U",$text,-1,PREG_SPLIT_DELIM_CAPTURE); 753 foreach($text as $line) { 754 $offtags = ('code|pre|kbd|notextile'); 755 756 /* matches are off if we're between <code>, <pre> etc. */ 757 if (preg_match('/<('.$offtags.')>/i',$line)) $codepre = true; 758 if (preg_match('/<\/('.$offtags.')>/i',$line)) $codepre = false; 759 760 if (!preg_match("/<.*>/",$line) && $codepre == false) { 761 $line = preg_replace($glyph_search,$glyph_replace,$line); 762 } 763 764 /* do htmlspecial if between <code> */ 765 if ($codepre == true) { 766 $line = htmlspecialchars($line,ENT_NOQUOTES,"UTF-8"); 767 $line = preg_replace('/<(\/?'.$offtags.')>/',"<$1>",$line); 768 } 769 770 $glyph_out[] = $line; 771 } 772 return join('',$glyph_out); 773 } 774 } 775 776 // ------------------------------------------------------------- 777 function iAlign($in) 778 { 779 $vals = array( 780 '<'=>'left', 781 '='=>'center', 782 '>'=>'right'); 783 return (isset($vals[$in])) ? $vals[$in] : ''; 784 } 785 786 // ------------------------------------------------------------- 787 function hAlign($in) 788 { 789 $vals = array( 790 '<'=>'left', 791 '='=>'center', 792 '>'=>'right', 793 '<>'=>'justify'); 794 return (isset($vals[$in])) ? $vals[$in] : ''; 795 } 796 797 // ------------------------------------------------------------- 798 function vAlign($in) 799 { 800 $vals = array( 801 '^'=>'top', 802 '-'=>'middle', 803 '~'=>'bottom'); 804 return (isset($vals[$in])) ? $vals[$in] : ''; 805 } 806 807 // ------------------------------------------------------------- 808 function dump($in) 809 { 810 if (isset($in)) { 811 print "<pre>"; 812 if (is_array($in)) { 813 print_r($in); 814 } else { 815 print $in; 816 } 817 print "</pre>"; 818 } 819 } 820 821 // ------------------------------------------------------------- 822 function encode_high($text,$charset="UTF-8") 823 { 824 $cmap = cmap(); 825 if ((!$out = @mb_encode_numericentity($text, $cmap, $charset)) && (strlen($text))) { 826 return "<p style=\"color:red\">Unrecognised character set: <strong>$charset</strong><br /> 827 Please resave the HTML using another character set.</p>"; 828 } else { 829 return $out; 830 } 831 } 832 833 834 // ------------------------------------------------------------- 835 function decode_high($text,$charset="UTF-8") 836 { 837 $cmap = cmap(); 838 return mb_decode_numericentity($text, $cmap, $charset); 839 } 840 841 // ------------------------------------------------------------- 842 function cmap() 843 { 844 $f = 0xffff; 845 $cmap = array( 846 160, 255, 0, $f, 847 402, 402, 0, $f, 848 913, 929, 0, $f, 849 931, 937, 0, $f, 850 945, 969, 0, $f, 851 977, 978, 0, $f, 852 982, 982, 0, $f, 853 8226, 8226, 0, $f, 854 8230, 8230, 0, $f, 855 8242, 8243, 0, $f, 856 8254, 8254, 0, $f, 857 8260, 8260, 0, $f, 858 8465, 8465, 0, $f, 859 8472, 8472, 0, $f, 860 8476, 8476, 0, $f, 861 8482, 8482, 0, $f, 862 8501, 8501, 0, $f, 863 8592, 8596, 0, $f, 864 8629, 8629, 0, $f, 865 8656, 8660, 0, $f, 866 8704, 8704, 0, $f, 867 8706, 8707, 0, $f, 868 8709, 8709, 0, $f, 869 8711, 8713, 0, $f, 870 8715, 8715, 0, $f, 871 8719, 8719, 0, $f, 872 8721, 8722, 0, $f, 873 8727, 8727, 0, $f, 874 8730, 8730, 0, $f, 875 8733, 8734, 0, $f, 876 8736, 8736, 0, $f, 877 8743, 8747, 0, $f, 878 8756, 8756, 0, $f, 879 8764, 8764, 0, $f, 880 8773, 8773, 0, $f, 881 8776, 8776, 0, $f, 882 8800, 8801, 0, $f, 883 8804, 8805, 0, $f, 884 8834, 8836, 0, $f, 885 8838, 8839, 0, $f, 886 8853, 8853, 0, $f, 887 8855, 8855, 0, $f, 888 8869, 8869, 0, $f, 889 8901, 8901, 0, $f, 890 8968, 8971, 0, $f, 891 9001, 9002, 0, $f, 892 9674, 9674, 0, $f, 893 9824, 9824, 0, $f, 894 9827, 9827, 0, $f, 895 9829, 9830, 0, $f, 896 338, 339, 0, $f, 897 352, 353, 0, $f, 898 376, 376, 0, $f, 899 710, 710, 0, $f, 900 732, 732, 0, $f, 901 8194, 8195, 0, $f, 902 8201, 8201, 0, $f, 903 8204, 8207, 0, $f, 904 8211, 8212, 0, $f, 905 8216, 8218, 0, $f, 906 8218, 8218, 0, $f, 907 8220, 8222, 0, $f, 908 8224, 8225, 0, $f, 909 8240, 8240, 0, $f, 910 8249, 8250, 0, $f, 911 8364, 8364, 0, $f); 912 return $cmap; 913 } 914 915 916 // ------------------------------------------------------------- 917 function textile_popup_help($name,$helpvar,$windowW,$windowH) { 918 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 />'; 919 920 return $out; 921 } 922 923 // ------------------------------------------------------------- 924 function txtgps($thing) 925 { 926 if (isset($_POST[$thing])){ 927 if (get_magic_quotes_gpc()==1){ 928 return stripslashes($_POST[$thing]); 929 } else { 930 return $_POST[$thing]; 931 } 932 } else { 933 return ''; 934 } 935 } 936 937 938 // ------------------------------------------------------------- 939 // The following functions are used to detextile html, a process 940 // still in development. 941 942 943 // ------------------------------------------------------------- 944 function detextile($text) { 945 946 $text = preg_replace("/<br \/>\s*/","\n",$text); 947 948 $oktags = array('p','ol','ul','li','i','b','em','strong','span','a','h[1-6]', 949 'table','tr','td','u','del','sup','sub','blockquote'); 950 951 foreach($oktags as $tag){ 952 $text = preg_replace_callback("/\t*<(".$tag.")\s*([^>]*)>(.*)<\/\\1>/Usi", 953 "processTag",$text); 954 } 955 956 $glyphs = array( 957 '’'=>'\'', # single closing 958 '‘'=>'\'', # single opening 959 '”'=>'"', # double closing 960 '“'=>'"', # double opening 961 '—'=>'--', # em dash 962 '–'=>' - ', # en dash 963 '×' =>'x', # dimension sign 964 '™'=>'(TM)', # trademark 965 '®' =>'(R)', # registered 966 '©' =>'(C)', # copyright 967 '…'=>'...' # ellipsis 968 ); 969 970 foreach($glyphs as $f=>$r){ 971 $text = str_replace($f,$r,$text); 972 } 973 974 $list = false; 975 976 $text = preg_split("/(<.*>)/U",$text,-1,PREG_SPLIT_DELIM_CAPTURE); 977 foreach($text as $line){ 978 979 if ($list == false && preg_match('/<ol/',$line)){ 980 $line = ""; 981 $list = "o"; 982 } else if (preg_match('/<\/ol/',$line)){ 983 $line = ""; 984 $list = false; 985 } else if ($list == false && preg_match('/<ul/',$line)){ 986 $line = ""; 987 $list = "u"; 988 } else if (preg_match('/<\/ul/',$line)){ 989 $line = ""; 990 $list = false; 991 } else if ($list == 'o'){ 992 $line = preg_replace('/<li.*>/U','# ', $line); 993 } else if ($list == 'u'){ 994 $line = preg_replace('/<li.*>/U','* ', $line); 995 } 996 $glyph_out[] = $line; 997 } 998 999 $text = implode('',$glyph_out); 1000 1001 $text = preg_replace('/^\t* *p\. /m','',$text); 1002 1003 return decode_high($text); 1004 } 1005 1006 1007 // ------------------------------------------------------------- 1008 function processTag($matches) 1009 { 1010 list($all,$tag,$atts,$content) = $matches; 1011 $a = splat($atts); 1012 # dump($tag); dump($content); dump($a); 1013 1014 $phr = array( 1015 'em'=>'_', 1016 'i'=>'__', 1017 'b'=>'**', 1018 'strong'=>'*', 1019 'cite'=>'??', 1020 'del'=>'-', 1021 'ins'=>'+', 1022 'sup'=>'^', 1023 'sub'=>'~', 1024 'span'=>'%'); 1025 1026 $blk = array('p','h1','h2','h3','h4','h5','h6'); 1027 1028 if(isset($phr[$tag])) { 1029 return $phr[$tag].sci($a).$content.$phr[$tag]; 1030 } elseif($tag=='blockquote') { 1031 return 'bq.'.sci($a).' '.$content; 1032 } elseif(in_array($tag,$blk)) { 1033 return $tag.sci($a).'. '.$content; 1034 } elseif ($tag=='a') { 1035 $t = filterAtts($a,array('href','title')); 1036 $out = '"'.$content; 1037 $out.= (isset($t['title'])) ? ' ('.$t['title'].')' : ''; 1038 $out.= '":'.$t['href']; 1039 return $out; 1040 } else { 1041 return $all; 1042 } 1043 } 1044 1045 // ------------------------------------------------------------- 1046 function filterAtts($atts,$ok) 1047 { 1048 foreach($atts as $a) { 1049 if(in_array($a['name'],$ok)) { 1050 if($a['att']!='') { 1051 $out[$a['name']] = $a['att']; 1052 } 1053 } 1054 } 1055 # dump($out); 1056 return $out; 1057 } 1058 1059 // ------------------------------------------------------------- 1060 function sci($a) 1061 { 1062 $out = ''; 1063 foreach($a as $t){ 1064 $out.= ($t['name']=='class') ? '(='.$t['att'].')' : ''; 1065 $out.= ($t['name']=='id') ? '[='.$t['att'].']' : ''; 1066 $out.= ($t['name']=='style') ? '{='.$t['att'].'}' : ''; 1067 $out.= ($t['name']=='cite') ? ':'.$t['att'] : ''; 1068 } 1069 return $out; 1070 } 1071 1072 // ------------------------------------------------------------- 1073 function splat($attr) // returns attributes as an array 1074 { 1075 $arr = array(); 1076 $atnm = ''; 1077 $mode = 0; 1078 1079 while (strlen($attr) != 0){ 1080 $ok = 0; 1081 switch ($mode) { 1082 case 0: // name 1083 if (preg_match('/^([a-z]+)/i', $attr, $match)) { 1084 $atnm = $match[1]; $ok = $mode = 1; 1085 $attr = preg_replace('/^[a-z]+/i', '', $attr); 1086 } 1087 break; 1088 1089 case 1: // = 1090 if (preg_match('/^\s*=\s*/', $attr)) { 1091 $ok = 1; $mode = 2; 1092 $attr = preg_replace('/^\s*=\s*/', '', $attr); 1093 break; 1094 } 1095 if (preg_match('/^\s+/', $attr)) { 1096 $ok = 1; $mode = 0; 1097 $arr[] = array('name'=>$atnm,'whole'=>$atnm,'att'=>$atnm); 1098 $attr = preg_replace('/^\s+/', '', $attr); 1099 } 1100 break; 1101 1102 case 2: // value 1103 if (preg_match('/^("[^"]*")(\s+|$)/', $attr, $match)) { 1104 $arr[]=array('name' =>$atnm,'whole'=>$atnm.'='.$match[1], 1105 'att'=>str_replace('"','',$match[1])); 1106 $ok = 1; $mode = 0; 1107 $attr = preg_replace('/^"[^"]*"(\s+|$)/', '', $attr); 1108 break; 1109 } 1110 if (preg_match("/^('[^']*')(\s+|$)/", $attr, $match)) { 1111 $arr[]=array('name' =>$atnm,'whole'=>$atnm.'='.$match[1], 1112 'att'=>str_replace("'",'',$match[1])); 1113 $ok = 1; $mode = 0; 1114 $attr = preg_replace("/^'[^']*'(\s+|$)/", '', $attr); 1115 break; 1116 } 1117 if (preg_match("/^(\w+)(\s+|$)/", $attr, $match)) { 1118 $arr[]= 1119 array('name'=>$atnm,'whole'=>$atnm.'="'.$match[1].'"', 1120 'att'=>$match[1]); 1121 $ok = 1; $mode = 0; 1122 $attr = preg_replace("/^\w+(\s+|$)/", '', $attr); 1123 } 1124 break; 1125 } 1126 if ($ok == 0){ 1127 $attr = preg_replace('/^\S*\s*/', '', $attr); 1128 $mode = 0; 1129 } 1130 } 1131 if ($mode == 1) $arr[] = 1132 array ('name'=>$atnm,'whole'=>$atnm.'="'.$atnm.'"','att'=>$atnm); 1133 1134 return $arr; 1135 } 1136 1137 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| [ Powered by PHPXref - Served by Debian GNU/Linux ] |