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