| [ Index ] |
|
Code source de eGroupWare 1.2.106-2 |
1 <?php 2 // $Id: transforms.php 21833 2006-06-14 18:42:08Z ralfbecker $ 3 4 // The main parser components. Each of these takes a line of text and scans it 5 // for particular wiki markup. It converts markup elements to 6 // $FlgChr . x . $FlgChr, where x is an index into the global array $Entity, 7 // which contains descriptions of each markup entity. Later, these will be 8 // converted back into HTML (or, in the future, perhaps some other 9 // representation such as XML). 10 11 function parse_noop($text) 12 { 13 return $text; 14 } 15 16 // The following function "corrects" for PHP's odd preg_replace behavior. 17 // Back-references have backslashes inserted before certain quotes 18 // (specifically, whichever quote was used around the backreference); this 19 // function removes remove those backslashes. 20 21 function q1($text) 22 { return str_replace('\\"', '"', $text); } 23 24 function get_title($page) 25 { 26 if (is_array($page)) 27 { 28 return $page['title'] ? $page['title'] : $page['name']; 29 } 30 return $page; 31 } 32 33 function get_name($page) 34 { 35 if (is_array($page)) 36 { 37 return $page['name'] ? $page['name'] : $page['title']; 38 } 39 return $page; 40 } 41 42 function validate_page($page) 43 { 44 global $FlgChr; 45 46 $page = get_title($page); 47 48 $p = parse_wikiname($page, 1); 49 if(preg_match('/^' . $FlgChr . '\\d+' . $FlgChr . '$/', $p)) 50 { return 1; } 51 $p = parse_freelink('((' . $page . '))', 1); 52 if(preg_match('/^' . $FlgChr . '\\d+' . $FlgChr . '$/', $p)) 53 { return 2; } 54 //echo "<p>parse/transforms::validdate_page('$page')==0</p>\n"; 55 return 0; 56 } 57 58 function parse_elem_flag($text) 59 { 60 global $FlgChr; 61 62 // Hide element flags (0xFF) from view. 63 return preg_replace('/' . $FlgChr . '/e', "new_entity(array('raw', '$FlgChr'))", $text, -1); 64 } 65 66 function new_entity($array) 67 { 68 global $Entity, $FlgChr; 69 70 $Entity[count($Entity)] = $array; 71 return $FlgChr . (count($Entity) - 1) . $FlgChr; 72 } 73 74 function parse_wikiname($text, $validate = 0) 75 { 76 global $LinkPtn, $EnableWikiLinks; 77 78 if(!$EnableWikiLinks) { return $text; } 79 80 if($validate) 81 { $ptn = "/(^|[^A-Za-z])($LinkPtn)(())(\"\")?/e"; } 82 else 83 { $ptn = "/(^|[^A-Za-z])(!?$LinkPtn)((\#[A-Za-z]([-A-Za-z0-9_:.]*[-A-Za-z0-9_])?)?)(\"\")?/e"; } 84 85 return preg_replace($ptn, 86 "q1('\\1').wikiname_token(q1('\\2'),'\\4')", 87 $text, -1); 88 } 89 90 function wikiname_token($name, $anchor) 91 { 92 if($name[0] == '!') // No-link escape sequence. 93 { return substr($name, 1); } // Trim leading '!'. 94 return new_entity(array('ref', $name, $name, '', $anchor, $anchor)); 95 } 96 97 function parse_freelink($text, $validate = 0) 98 { 99 global $EnableFreeLinks; 100 101 if(!$EnableFreeLinks) { return $text; } 102 103 if($validate) 104 { 105 // $ptn = "/\\(\\(([-A-Za-z0-9 _+\\/.,;:!?'\"\\[\\]\\{\\}&\xc0-\xff]+)()()\\)\\)/e"; 106 $ptn = "/\\(\\(([^\\|\\)]+)()()\\)\\)/e"; 107 } 108 else 109 { 110 // $ptn = "/\\(\\(([-A-Za-z0-9 _+\\/.,;:!?'\"\\[\\]\\{\\}&\xc0-\xff]+)(\|[-A-Za-z0-9 _+\\/.,;:!?'\"\\[\\]\\{\\}&\xc0-\xff]+)?(\#[A-Za-z][-A-Za-z0-9_:.]*)?()\\)\\)/e"; 111 $ptn = "/\\(\\(([^\\|\\)]+)(\|[^\\)#]+)?(\#[A-Za-z][-A-Za-z0-9_:.]*)?()\\)\\)/e"; 112 } 113 114 return preg_replace($ptn, 115 "freelink_token(q1('\\1'), q1('\\2'), '\\3', '')", 116 $text, -1); 117 } 118 119 function freelink_token($link, $appearance, $anchor, $anchor_appearance) 120 { 121 if($appearance == '') 122 { $appearance = $link; } 123 else 124 { $appearance = substr($appearance, 1); } // Trim leading '|'. 125 return new_entity(array('ref', $link, $appearance, '', 126 $anchor, $anchor_appearance)); 127 } 128 129 function parse_interwiki($text) 130 { 131 global $InterwikiPtn; 132 133 return preg_replace("/(^|[^A-Za-z])($InterwikiPtn)(\$|[^\\/=&~A-Za-z0-9])/e", 134 "q1('\\1').interwiki_token(q1('\\3'),q1('\\4')).q1('\\6')", 135 $text, -1); 136 } 137 138 function interwiki_token($prefix, $ref) 139 { 140 global $pagestore; 141 142 if(($url = $pagestore->interwiki($prefix)) != '') 143 { 144 return new_entity(array('interwiki', $url . $ref, $prefix . ':' . $ref)); 145 } 146 147 return $prefix . ':' . $ref; 148 } 149 150 function parse_hyperlink_ref($text) 151 { 152 global $UrlPtn; 153 154 return preg_replace("/\\[($UrlPtn)]/Ue", 155 "url_token(q1('\\1'), '')", $text, -1); 156 } 157 158 function parse_hyperlink_description($text) 159 { 160 global $UrlPtn; 161 162 return preg_replace("/\\[($UrlPtn) ([^]]+)]/e", 163 "url_token(q1('\\1'), q1('[\\4]'))", $text, -1); 164 } 165 166 function parse_hyperlink($text) 167 { 168 global $UrlPtn; 169 170 return preg_replace("/(^|[^A-Za-z\"])($UrlPtn)(\$|[^\\/?=&~A-Za-z0-9\"])/e", 171 "q1('\\1').url_token(q1('\\2'), q1('\\2')).q1('\\5')", $text, -1); 172 } 173 174 function url_token($value, $display) 175 { 176 static $count = 1; 177 178 if($display == '') 179 { $display = '[' . $count++ . ']'; } 180 181 return new_entity(array('url', $value, $display)); 182 } 183 184 function parse_macros($text) 185 { 186 return preg_replace('/\\[\\[([^] ]+( [^]]+)?)]]/e', 187 "macro_token(q1('\\1'), q1('\\3'))", $text, -1); 188 } 189 190 function macro_token($macro, $trail) 191 { 192 global $ViewMacroEngine; 193 194 $cmd = strtok($macro, ' '); 195 $args = strtok(''); 196 197 if($ViewMacroEngine[$cmd] != '') 198 { return new_entity(array('raw', $ViewMacroEngine[$cmd]($args))); } 199 else 200 { return '[[' . $macro . ']]' . ($trail == "\n" ? $trail : ''); } 201 } 202 203 function parse_transclude($text) 204 { 205 $text2 = preg_replace('/%%([^%]+)%%/e', 206 "transclude_token(q1('\\1'))", $text, -1); 207 if($text2 != $text) 208 { $text2 = str_replace("\n", '', $text2); } 209 return $text2; 210 } 211 212 function transclude_token($text) 213 { 214 global $pagestore, $ParseEngine, $ParseObject; 215 static $visited_array = array(); 216 static $visited_count = 0; 217 218 if(!validate_page($text)) 219 { return '%%' . $text . '%%'; } 220 221 $visited_array[$visited_count++] = $ParseObject; 222 for($i = 0; $i < $visited_count; $i++) 223 { 224 if($visited_array[$i] == $text) 225 { 226 $visited_count--; 227 return '%%' . $text . '%%'; 228 } 229 } 230 231 $pg = $pagestore->page($text); 232 $pg->read(); 233 if(!$pg->exists) 234 { 235 $visited_count--; 236 return '%%' . $text . '%%'; 237 } 238 239 $result =& new_entity(array('raw', parseText($pg->text, $ParseEngine, $text))); 240 $visited_count--; 241 return $result; 242 } 243 244 function parse_bold($text) 245 { 246 return preg_replace("/'''(()|[^'].*)'''/Ue", "pair_tokens('bold', q1('\\1'))", 247 $text, -1); 248 } 249 250 function parse_italic($text) 251 { 252 return preg_replace("/''(()|[^'].*)''/Ue", "pair_tokens('italic', q1('\\1'))", 253 $text, -1); 254 } 255 256 function parse_teletype($text) 257 { 258 return preg_replace("/{{({*?.*}*?)}}/Ue", 259 "pair_tokens('tt', q1('\\1'))", $text, -1); 260 } 261 262 function pair_tokens($type, $text) 263 { 264 global $Entity, $FlgChr; 265 266 $Entity[count($Entity)] = array($type . '_start'); 267 $Entity[count($Entity)] = array($type . '_end'); 268 269 return $FlgChr . (count($Entity) - 2) . $FlgChr . $text . 270 $FlgChr . (count($Entity) - 1) . $FlgChr; 271 } 272 273 function parse_newline($text) 274 { 275 static $last = array('', ''); 276 global $htmlisms_outside_in_html; 277 if ($htmlisms_outside_in_html) return($text); // no conversation, if inside <html> </html> 278 279 // More than two consecutive newlines fold into two newlines. 280 281 if($last[0] == "\n" && $last[1] == "\n" && $text == "\n") 282 { return ''; } 283 $last[0] = $last[1]; 284 $last[1] = $text; 285 286 return preg_replace("/\\n(\\r)?/e", "new_entity(array('newline'))", 287 $text, -1); 288 } 289 290 function parse_horiz($text) 291 { 292 return preg_replace("/-{4,}(\\n(\\r)?)?/e", "new_entity(array('hr'))", 293 $text, -1); 294 } 295 296 function parse_nowiki($text) 297 { 298 return preg_replace("/```(.*)```/Ue", 299 "new_entity(array('nowiki', parse_elements(q1('\\1'))))", 300 $text, -1); 301 } 302 303 function parse_code($text) 304 { 305 global $Entity, $FlgChr; 306 static $in_code = 0; 307 static $buffer = ''; 308 309 if($in_code) 310 { 311 if(preg_match("|^\s*</code>\s*|", $text)) 312 { 313 $Entity[count($Entity)] = array('code', $buffer); 314 $buffer = ''; 315 $in_code = 0; 316 return $FlgChr . (count($Entity) - 1) . $FlgChr; 317 } 318 319 $buffer = $buffer . parse_elements($text); 320 return ''; 321 } 322 else 323 { 324 if(preg_match("|^\s*<code>\s*|", $text)) 325 { 326 $in_code = 1; 327 return ''; 328 } 329 330 return $text; 331 } 332 } 333 334 function parse_remove_script($text) 335 { 336 return preg_replace('/\<(\/*script)/i','<\\1',$text); 337 } 338 339 function parse_raw_html($text) 340 { 341 global $Entity, $FlgChr; 342 static $in_html = 0; 343 static $buffer = ''; 344 345 if($in_html) 346 { 347 if(strtolower($text) == "</html>\n") 348 { 349 $Entity[count($Entity)] = array('raw', $buffer); 350 $buffer = ''; 351 $in_html = 0; 352 return $FlgChr . (count($Entity) - 1) . $FlgChr; 353 } 354 // the following str-replace gards agains css or script in the html 355 $buffer = $buffer . parse_elements(str_replace(array('<script','</script'),array('<script','</script'),$text)); 356 return ''; 357 } 358 else 359 { 360 if(substr(strtolower($text),0,6) == '<html>') 361 { 362 $in_html = 1; 363 return ''; 364 } 365 366 return $text; 367 } 368 } 369 370 function parse_indents($text) 371 { 372 global $MaxNesting; 373 static $last_prefix = ''; // Last line's prefix. 374 static $steal = ''; // Stealing the next line? 375 376 // Locate the indent prefix characters. 377 378 preg_match('/^([:\\*#]*)(;([^:]*):)?(.*\\n?$)/', $text, $result); 379 380 if($result[2] != '') // Definition list. 381 { $result[1] = $result[1] . ';'; } 382 383 // No list on last line, no list on this line. Bail out: 384 385 if($steal == '' && $last_prefix == '' && $result[1] == '') 386 { return $text; } // Common case fast. 387 388 // Remember lengths of strings. 389 390 $last_len = strlen($last_prefix); 391 $prefix_len = strlen($result[1]); 392 393 if($steal == '') // Not slurping up line. 394 { 395 $text = $result[4]; 396 397 $fixup = ''; 398 399 // Loop through and look for prefix characters in common with the 400 // previous line. 401 402 for($i = 0; 403 $i < $MaxNesting && ($i < $last_len || $i < $prefix_len); 404 $i++) 405 { 406 // If equal, continue. 407 if($i < $last_len && $i < $prefix_len // Neither past end. 408 && $last_prefix[$i] == $result[1][$i]) // Equal content. 409 { continue; } 410 411 // If we've gone deeper than the previous line, we're done. 412 if($i >= $last_len) 413 { break; } 414 415 // If last line goes further than us, end its dangling lists. 416 if($i >= $prefix_len // Current line ended. 417 || $last_prefix[$i] != $result[1][$i]) // Or not, but they differ. 418 { 419 for($j = $i; $j < $MaxNesting && $j < $last_len; $j++) 420 { 421 $fixup = entity_listitem($last_prefix[$j], 'end') 422 . entity_list($last_prefix[$j], 'end') 423 . $fixup; 424 } 425 break; 426 } 427 } 428 429 // End the preceding line's list item if we're starting another one 430 // at the same level. 431 432 if($i > 0 && $i >= $prefix_len) 433 { $fixup = $fixup . entity_listitem($last_prefix[$i - 1], 'end'); } 434 435 // Start fresh new lists for this line as needed. 436 // We start all but the last one as *indents* (definition lists) 437 // instead of what they really may appear as, since their function is 438 // really just to indent. 439 440 for(; $i < $MaxNesting - 1 && $i + 1 < $prefix_len; $i++) 441 { 442 $result[1][$i] = ':'; // Pretend to be an indent. 443 $fixup = $fixup 444 . entity_list(':', 'start') 445 . entity_listitem(':', 'start'); 446 } 447 if($i < $prefix_len) // Start the list itself. 448 { 449 $fixup = $fixup 450 . entity_list($result[1][$i], 'start'); 451 } 452 453 // Start the list *item*. 454 455 if($result[2] != '') // Definition list. 456 { 457 $fixup = $fixup 458 . new_entity(array('term_item_start')) 459 . $result[3] 460 . new_entity(array('term_item_end')); 461 } 462 463 if($result[1] != '') 464 { $text = entity_listitem(substr($result[1], -1), 'start') . $text; } 465 466 $text = $fixup . $text; 467 468 $last_prefix = $result[1]; 469 } 470 471 if($steal != '' || $result[1] != '') 472 { 473 // Check if a previous line used a trailing '\' to "steal" us; 474 // i.e., to insert a new line while continuing with the same list item. 475 476 if($steal == '') 477 { $steal = substr($result[1], -1); } 478 479 // Check if *we* have a trailing '\' to "steal" the next line. If not, 480 // end ourselves right here. 481 482 if(preg_match('/(^|[^\\\\])(\\\\\\\\)*\\\\$/', $text)) 483 { $text = preg_replace('/\\\\$/', "\n", $text); } 484 else 485 { 486 $text = str_replace("\n", '', $text); 487 $steal = ''; 488 } 489 } 490 491 return $text; 492 } 493 494 function entity_list($type, $fn) 495 { 496 if($type == '*') 497 { return new_entity(array('bullet_list_' . $fn)); } 498 else if($type == ':' || $type == ';') 499 { return new_entity(array('indent_list_' . $fn)); } 500 else if($type == '#') 501 { return new_entity(array('numbered_list_' . $fn)); } 502 } 503 504 function entity_listitem($type, $fn) 505 { 506 if($type == '*') 507 { return new_entity(array('bullet_item_' . $fn)); } 508 else if($type == ':' || $type == ';') 509 { return new_entity(array('indent_item_' . $fn)); } 510 else if($type == '#') 511 { return new_entity(array('numbered_item_' . $fn)); } 512 } 513 514 function parse_heading($text) 515 { 516 global $MaxHeading; 517 518 if(!preg_match('/^\s*(=+) (.*) (=+)\s*$/', $text, $result)) 519 { return $text; } 520 521 if(strlen($result[1]) != strlen($result[3])) 522 { return $text; } 523 524 if(($level = strlen($result[1])) > $MaxHeading) 525 { $level = $MaxHeading; } 526 527 return new_entity(array('head_start', $level)) . 528 $result[2] . 529 new_entity(array('head_end', $level)); 530 } 531 532 function parse_htmlisms($text) 533 { 534 $text = str_replace('&', '&', $text); 535 $text = str_replace('<', '<', $text); 536 return $text; 537 } 538 539 global $htmlisms_outside_in_html; $htmlisms_outside_in_html = False; 540 function parse_htmlisms_outside_html($text) 541 { 542 global $htmlisms_outside_in_html; 543 544 $ltext = strtolower($text); 545 if (substr($ltext,0,6) == '<html>') 546 { 547 $htmlisms_outside_in_html = True; 548 } 549 elseif (substr($ltext,0,7) == '</html>') 550 { 551 $htmlisms_outside_in_html = False; 552 } 553 elseif (!$htmlisms_outside_in_html) 554 { 555 $text = str_replace(array('&','<'),array('&','<'), $text); 556 } 557 return $text; 558 } 559 560 function parse_elements($text) 561 { 562 global $FlgChr; 563 return preg_replace("/$FlgChr(\\d+)$FlgChr/e", "generate_element(q1('\\1'))", $text, -1); 564 } 565 566 function generate_element($text) 567 { 568 global $Entity, $DisplayEngine; 569 570 if(function_exists('call_user_func_array')) 571 { 572 return call_user_func_array($DisplayEngine[$Entity[$text][0]], 573 array_slice($Entity[$text], 1)); 574 } 575 else 576 { 577 return $DisplayEngine[$Entity[$text][0]]($Entity[$text][1], 578 $Entity[$text][2], 579 $Entity[$text][3], 580 $Entity[$text][4], 581 $Entity[$text][5]); 582 } 583 } 584 585 function parse_diff_skip($text) 586 { 587 if(preg_match('/^--+/', $text)) 588 { return ''; } 589 if(preg_match('/^\\\\ No newline/', $text)) 590 { return ''; } 591 return $text; 592 } 593 594 function parse_diff_color($text) 595 { 596 static $in_old = 0; 597 static $in_new = 0; 598 599 if(strlen($text) == 0) 600 { $this_old = $this_new = 0; } 601 else 602 { 603 $this_old = ($text[0] == '<'); 604 $this_new = ($text[0] == '>'); 605 } 606 607 if($this_old || $this_new) 608 { $text = substr($text, 2); } 609 610 if($this_old && !$in_old) 611 { $text =& new_entity(array('diff_old_start')) . $text; } 612 else if($this_new && !$in_new) 613 { $text =& new_entity(array('diff_new_start')) . $text; } 614 615 if($in_old && !$this_old) 616 { $text =& new_entity(array('diff_old_end')) . $text; } 617 else if($in_new && !$this_new) 618 { $text =& new_entity(array('diff_new_end')) . $text; } 619 620 $in_old = $this_old; 621 $in_new = $this_new; 622 623 return $text; 624 } 625 626 function parse_diff_message($text) 627 { 628 global $FlgChr; 629 630 $text = preg_replace('/(^(' . $FlgChr . '\\d+' . $FlgChr . ')?)\\d[0-9,]*c[0-9,]*$/e', 631 "q1('\\1').new_entity(array('diff_change'))", $text, -1); 632 $text = preg_replace('/(^(' . $FlgChr . '\\d+' . $FlgChr . ')?)\\d[0-9,]*a[0-9,]*$/e', 633 "q1('\\1').new_entity(array('diff_add'))", $text, -1); 634 $text = preg_replace('/(^(' . $FlgChr . '\\d+' . $FlgChr . ')?)\\d[0-9,]*d[0-9,]*$/e', 635 "q1('\\1').new_entity(array('diff_delete'))", $text, -1); 636 637 return $text; 638 } 639 640 function parse_table($text) 641 { 642 static $in_table = 0; 643 644 $pre = ''; 645 $post = ''; 646 if(preg_match('/^(\|\|)+.*(\|\|)\s*$/', $text)) // Table. 647 { 648 if(!$in_table) 649 { 650 $pre = html_table_start(); 651 $in_table = 1; 652 } 653 $text = preg_replace('/^((\|\|)+)(.*)\|\|\s*$/e', 654 "new_entity(array('raw',html_table_row_start().html_table_cell_start(strlen('\\1')/2))).". 655 "q1('\\3').new_entity(array('raw',html_table_cell_end().html_table_row_end()))", 656 $text, -1); 657 $text = preg_replace('/((\|\|)+)/e', 658 "new_entity(array('raw',html_table_cell_end().html_table_cell_start(strlen('\\1')/2)))", 659 $text, -1); 660 } 661 else if($in_table) // Have exited table. 662 { 663 $in_table = 0; 664 $pre = html_table_end(); 665 } 666 667 if($pre != '') 668 { $text = new_entity(array('raw', $pre)) . $text; } 669 if($post != '') 670 { $text = $text . new_entity(array('raw', $post)); } 671 672 return $text; 673 } 674 675 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Sun Feb 25 17:20:01 2007 | par Balluche grâce à PHPXref 0.7 |