Ticket #4539: dev-snapshot-2010-11-27-2.php.diff
File dev-snapshot-2010-11-27-2.php.diff, 21.1 KB (added by , 14 years ago) |
---|
-
wordpress/wp-includes/formatting.php
31 31 static $static_setup = false, $opening_quote, $closing_quote, $default_no_texturize_tags, $default_no_texturize_shortcodes, $static_characters, $static_replacements, $dynamic_characters, $dynamic_replacements; 32 32 $output = ''; 33 33 $curl = ''; 34 $textarr = preg_split('/(< .*>|\[.*\])/Us', $text, -1, PREG_SPLIT_DELIM_CAPTURE);34 $textarr = preg_split('/(<!--.*-->|<.*>|\[.*\])/Us', $text, -1, PREG_SPLIT_DELIM_CAPTURE); 35 35 $stop = count($textarr); 36 36 37 37 // No need to set up these variables more than once … … 56 56 $static_characters = array_merge(array('---', ' -- ', '--', ' - ', 'xn–', '...', '``', '\'\'', ' (tm)'), $cockney); 57 57 $static_replacements = array_merge(array('—', ' — ', '–', ' – ', 'xn--', '…', $opening_quote, $closing_quote, ' ™'), $cockneyreplace); 58 58 59 $dynamic_characters = array('/\'(\d\d(?:’|\')?s)/', '/\'(\d)/', '/(\s|\A|[([{<]|")\'/', '/(\d)"/', '/(\d)\'/', '/(\S)\'([^\'\s])/', '/(\s|\A|[([{<])"(?!\s)/', '/"(\s|\S|\Z)/', '/\'([\s.]|\Z)/', '/\b(\d+)x(\d+)\b/'); 60 $dynamic_replacements = array('’$1','’$1', '$1‘', '$1″', '$1′', '$1’$2', '$1' . $opening_quote . '$2', $closing_quote . '$1', '’$1', '$1×$2'); 59 $dynamic_map = array( 60 '/(^|\s)\'([^\'\s]+)([^\']*)\'(\d+)\'(\s|$)/' => '$1\'$2$3’$4\'$5', // 'Class of '99' 61 '/(^|\s)\'(\d+)([^\d\'(?:x\d+)]|\'\w|[\]})]|$)/' => '$1’$2$3', // '99, '99's (?: part meaning not '99x11 - see below) 62 '/([\w\]})])\'([\w])/' => '$1’$2', // test's 63 '/\'([^\']*)\'/' => '‘$1’', // 'asd' 64 '/"([^"]*)"/' => $opening_quote . '$1' . $closing_quote, // "qwe" 65 '/(^|\s)(\d)\'/' => '$1$2′', // 9' 66 '/(^|\s)(\d)"/' => '$1$2″', // 9" 67 '/\b(\d+)x(\d+)\b/' => '$1×$2' // 97x34 68 ); 61 69 70 $dynamic_characters = array_keys( $dynamic_map ); 71 $dynamic_replacements = array_values( $dynamic_map ); 72 62 73 $static_setup = true; 63 74 } 64 75 … … 70 81 $no_texturize_tags_stack = array(); 71 82 $no_texturize_shortcodes_stack = array(); 72 83 84 $single_quote_state = '‘'; 85 $double_quote_state = $opening_quote; 86 87 $text_node_count = 0; 88 $whitespace_before_last_tag = false; 89 73 90 for ( $i = 0; $i < $stop; $i++ ) { 74 91 $curl = $textarr[$i]; 75 92 … … 78 95 // This is not a tag, nor is the texturization disabled 79 96 // static strings 80 97 $curl = str_replace($static_characters, $static_replacements, $curl); 98 // quotes after tags, e.g. <b>somebody</b>'s 99 if ( ( $text_node_count > 0 ) && ( ! $whitespace_before_last_tag ) ) { 100 $curl = preg_replace( '/^(\')/', '’', $curl ); 101 } 102 81 103 // regular expressions 82 104 $curl = preg_replace($dynamic_characters, $dynamic_replacements, $curl); 105 106 // Quotes that span across multiple tags & shortcodes 107 // Dynamic regexps above ensure that there is at most 1 quote left in the string. 108 // Otherwise, the less efficient preg_replace() within a while loop would be required. 109 if ( strpos( $curl, '\'' ) !== false ) { 110 $curl = str_replace( '\'', $single_quote_state, $curl); 111 $single_quote_state = ( ( '‘' == $single_quote_state ) ? '’' : '‘' ); 112 } 113 if ( strpos($curl, '"' ) !== false ) { 114 $curl = str_replace( '"', $double_quote_state, $curl); 115 $double_quote_state = ( $opening_quote == $double_quote_state ) ? $closing_quote : $opening_quote; 116 } 117 // stats for quotes after tags above 118 $text_node_count++; 119 $whitespace_before_last_tag = ( preg_match('/\s$/', $curl) > 0 ); 83 120 } elseif (!empty($curl)) { 84 121 /* 85 122 * Only call _wptexturize_pushpop_element if first char is correct -
wp-testcase/test_includes_formatting.php
371 371 372 372 $invalid_nest = '<pre></code>"baba"</pre>'; 373 373 $this->assertEquals($invalid_nest, wptexturize($invalid_nest)); 374 } 374 375 376 //WP Ticket #8912, #10033 377 function test_skip_html_comments() { 378 $this->assertEquals('<ul><li>Hello.</li><!--<li>Goodbye.</li>--></ul>', wptexturize('<ul><li>Hello.</li><!--<li>Goodbye.</li>--></ul>')); 379 380 $html = '<!--[if !IE]>-->' . "\n"; 381 $html .= '<object type="application/x-shockwave-flash" data="http://www.youtube.com/v/_nkZ3eHeXlc" width="320" height="260">' . "\n"; 382 $html .= '<!--<![endif]-->' . "\n"; 383 $this->assertEquals($html, wptexturize($html)); 384 385 $html = '<!--[if !IE]>-->' . "\n"; 386 $html .= '</object>' . "\n"; 387 $html .= '<!--<![endif]-->' . "\n"; 388 $this->assertEquals($html, wptexturize($html)); 375 389 } 376 390 377 391 //WP Ticket #1418 … … 388 402 389 403 //WP Ticket #4539 390 404 function test_basic_quotes() { 405 $this->assertNotEquals('‘’', wptexturize("''")); // this does not work as expected due to a static replacement 406 $this->assertEquals('“”', wptexturize('""')); 407 $this->assertEquals('“”', wptexturize("``''")); // this is what causes '' to fail 408 $this->assertEquals('‘ ’', wptexturize("' '")); 409 $this->assertEquals('“ ”', wptexturize('" "')); 410 $this->assertEquals('‘<img src="">’', wptexturize('\'<img src="">\'')); 411 $this->assertEquals('“<img src="">”', wptexturize('"<img src="">"')); 412 $this->assertEquals('Peter’s photo: ‘<img src="">’', wptexturize('Peter\'s photo: \'<img src="">\'')); 413 $this->assertEquals('Peter’s photo: “<img src="">”', wptexturize('Peter\'s photo: "<img src="">"')); 414 391 415 $this->assertEquals('test’s', wptexturize('test\'s')); 392 416 $this->assertEquals('test’s', wptexturize('test\'s')); 393 417 394 418 $this->assertEquals('‘quoted’', wptexturize('\'quoted\'')); 395 419 $this->assertEquals('“quoted”', wptexturize('"quoted"')); 420 $this->assertEquals('‘quoted’s’', wptexturize('\'quoted\'s\'')); 421 $this->assertEquals('“quoted’s”', wptexturize('"quoted\'s"')); 396 422 397 423 $this->assertEquals('(‘quoted’)', wptexturize('(\'quoted\')')); 398 424 $this->assertEquals('{“quoted”}', wptexturize('{"quoted"}')); 425 $this->assertEquals('["quoted"]', wptexturize('["quoted"]')); // shortcode 426 $this->assertEquals('<"quoted">', wptexturize('<"quoted">')); // tag 427 $this->assertEquals('(‘quoted’s’)', wptexturize('(\'quoted\'s\')')); 428 $this->assertEquals('{“quoted’s”}', wptexturize('{"quoted\'s"}')); 429 $this->assertEquals('["quoted\'s"]', wptexturize('["quoted\'s"]')); // shortcode 430 $this->assertEquals('<"quoted\'s">', wptexturize('<"quoted\'s">')); // tag 399 431 400 432 $this->assertEquals('‘qu(ot)ed’', wptexturize('\'qu(ot)ed\'')); 401 433 $this->assertEquals('“qu{ot}ed”', wptexturize('"qu{ot}ed"')); 434 $this->assertEquals('“qu[ot]ed”', wptexturize('"qu[ot]ed"')); 435 $this->assertEquals('“qu<ot>ed”', wptexturize('"qu<ot>ed"')); 436 $this->assertEquals('‘qu(ot)ed’s’', wptexturize('\'qu(ot)ed\'s\'')); 437 $this->assertEquals('“qu{ot}ed’s”', wptexturize('"qu{ot}ed\'s"')); 438 $this->assertEquals('“qu[ot]ed’s”', wptexturize('"qu[ot]ed\'s"')); 439 $this->assertEquals('“qu<ot>ed’s”', wptexturize('"qu<ot>ed\'s"')); 440 $this->assertEquals('‘qu(ot)’s’', wptexturize('\'qu(ot)\'s\'')); 441 $this->assertEquals('“qu{ot}’s”', wptexturize('"qu{ot}\'s"')); 442 $this->assertEquals('“qu[ot]’s”', wptexturize('"qu[ot]\'s"')); 443 $this->assertEquals('“qu<ot>’s”', wptexturize('"qu<ot>\'s"')); 402 444 403 445 $this->assertEquals('‘test’s quoted’', wptexturize('\'test\'s quoted\'')); 404 446 $this->assertEquals('“test’s quoted”', wptexturize('"test\'s quoted"')); 405 447 } 448 449 //WP Ticket #4539 450 function test_original_report_4539() { 451 $this->assertEquals("(Bruce Sterling, ’97)", wptexturize("(Bruce Sterling, '97)")); 452 $this->assertEquals("( Bruce Sterling, ’97 )", wptexturize("( Bruce Sterling, '97 )")); 453 $this->assertEquals("<li>Casino Royale ’06</li>", wptexturize("<li>Casino Royale '06</li>")); 454 $this->assertEquals("<li>(Casino Royale ’06)</li>", wptexturize("<li>(Casino Royale '06)</li>")); 455 } 406 456 457 //WP Ticket #14491 458 function test_quoted_numbers() { 459 $this->knownWPBug(14491); 460 461 // 4 digits 462 $this->assertEquals('‘2010’', wptexturize("'2010'")); 463 $this->assertEquals('“2011”', wptexturize('"2011"')); 464 $this->assertEquals('‘ 2010 ’', wptexturize("' 2010 '")); 465 $this->assertEquals('“ 2011 ”', wptexturize('" 2011 "')); 466 $this->assertEquals(' ‘2010’ ', wptexturize(" '2010' ")); 467 $this->assertEquals(' “2011” ', wptexturize(' "2011" ')); 468 $this->assertEquals(' ‘ 2010 ’ ', wptexturize(" ' 2010 ' ")); 469 $this->assertEquals(' “ 2011 ” ', wptexturize(' " 2011 " ')); 470 471 // 2 digits to test against '99' vs '99'ers 472 $this->assertEquals('‘10’', wptexturize("'10'")); 473 $this->assertEquals('“11”', wptexturize('"11"')); 474 $this->assertEquals('‘ 10 ’', wptexturize("' 10 '")); 475 $this->assertEquals('“ 11 ”', wptexturize('" 11 "')); 476 $this->assertEquals(' ‘10’ ', wptexturize(" '10' ")); 477 $this->assertEquals(' “11” ', wptexturize(' "11" ')); 478 $this->assertEquals(' ‘ 10 ’ ', wptexturize(" ' 10 ' ")); 479 $this->assertEquals(' “ 11 ” ', wptexturize(' " 11 " ')); 480 } 481 482 //WP Ticket #4539 483 function test_nested_quotes() { 484 $this->assertEquals('“This is a ‘nested quote’.”', wptexturize('"This is a \'nested quote\'."')); 485 $this->assertEquals('‘This is a “nested quote”.’', wptexturize('\'This is a "nested quote".\'')); 486 $this->assertEquals('“These are some ‘nested’ ‘quotes’.”', wptexturize('"These are some \'nested\' \'quotes\'."')); 487 $this->assertEquals('‘These are some “nested” “quotes”.’', wptexturize('\'These are some "nested" "quotes".\'')); 488 } 489 407 490 //WP Tickets #4539, #15241 408 491 function test_full_sentences_with_unmatched_single_quotes() { 409 492 $this->assertEquals( 410 493 'That means every moment you’re working on something without it being in the public it’s actually dying.', 411 494 wptexturize("That means every moment you're working on something without it being in the public it's actually dying.") 412 495 ); 496 $this->assertEquals( 497 '‘That means every moment you’re working on something without it being in the public it’s actually dying.’', 498 wptexturize("'That means every moment you're working on something without it being in the public it's actually dying.'") 499 ); 500 $this->assertEquals( 501 '“That means every moment you’re working on something without it being in the public it’s actually dying.”', 502 wptexturize("\"That means every moment you're working on something without it being in the public it's actually dying.\"") 503 ); 504 $this->assertEquals( 505 'That means every moment you’re working on ‘something’ without it being in the public it’s actually dying.', 506 wptexturize("That means every moment you're working on 'something' without it being in the public it's actually dying.") 507 ); 508 $this->assertEquals( 509 'That means every moment you’re working on “something” without it being in the public it’s actually dying.', 510 wptexturize("That means every moment you're working on \"something\" without it being in the public it's actually dying.") 511 ); 413 512 } 414 513 415 //WP Ticket #4539514 //WP Tickets #4539, #10606 416 515 function test_quotes() { 417 516 $this->knownWPBug(4539); 418 517 $this->assertEquals('“Quoted String”', wptexturize('"Quoted String"')); 419 518 $this->assertEquals('Here is “<a href="http://example.com">a test with a link</a>”', wptexturize('Here is "<a href="http://example.com">a test with a link</a>"')); 519 $this->assertEquals('Here is “ <a href="http://example.com">a test with a link</a> ”', wptexturize('Here is " <a href="http://example.com">a test with a link</a> "')); 520 $this->assertEquals('Here is “<a href="http://example.com"> a test with a link </a>”', wptexturize('Here is "<a href="http://example.com"> a test with a link </a>"')); 420 521 $this->assertEquals('Here is “<a href="http://example.com">a test with a link and a period</a>”.', wptexturize('Here is "<a href="http://example.com">a test with a link and a period</a>".')); 421 522 $this->assertEquals('Here is “<a href="http://example.com">a test with a link</a>” and a space.', wptexturize('Here is "<a href="http://example.com">a test with a link</a>" and a space.')); 422 523 $this->assertEquals('Here is “<a href="http://example.com">a test with a link</a> and some text quoted”', wptexturize('Here is "<a href="http://example.com">a test with a link</a> and some text quoted"')); … … 424 525 $this->assertEquals('Here is “<a href="http://example.com">a test with a link</a>”; and a semi-colon.', wptexturize('Here is "<a href="http://example.com">a test with a link</a>"; and a semi-colon.')); 425 526 $this->assertEquals('Here is “<a href="http://example.com">a test with a link</a>”- and a dash.', wptexturize('Here is "<a href="http://example.com">a test with a link</a>"- and a dash.')); 426 527 $this->assertEquals('Here is “<a href="http://example.com">a test with a link</a>”… and ellipses.', wptexturize('Here is "<a href="http://example.com">a test with a link</a>"... and ellipses.')); 528 $this->assertEquals('Here is “<a href="http://example.com">a test</a> with a link”.', wptexturize('Here is "<a href="http://example.com">a test</a> with a link".')); 427 529 $this->assertEquals('Here is “a test <a href="http://example.com">with a link</a>”.', wptexturize('Here is "a test <a href="http://example.com">with a link</a>".')); 428 $this->assertEquals('Here is “<a href="http://example.com">a test with a link</a>”and a work stuck to the end.', wptexturize('Here is "<a href="http://example.com">a test with a link</a>"and a work stuck to the end.')); 530 $this->assertEquals('Here is “a test <a href="http://example.com">with a link</a>” .', wptexturize('Here is "a test <a href="http://example.com">with a link</a>" .')); 531 $this->assertEquals('Here is “<a href="http://example.com">a test with a link</a>”and a word stuck to the end.', wptexturize('Here is "<a href="http://example.com">a test with a link</a>"and a word stuck to the end.')); 429 532 $this->assertEquals('A test with a finishing number, “like 23”.', wptexturize('A test with a finishing number, "like 23".')); 430 533 $this->assertEquals('A test with a number, “like 62”, is nice to have.', wptexturize('A test with a number, "like 62", is nice to have.')); 431 534 } … … 443 546 //WP Ticket #4539 444 547 function test_quotes_before_numbers() { 445 548 $this->knownWPBug(4539); 549 $this->assertEquals('’99', wptexturize("'99")); 550 551 $this->assertEquals('’99’s', wptexturize("'99’s")); 552 $this->assertEquals('’99’ers', wptexturize("'99’ers")); 553 $this->assertEquals('’749’ers', wptexturize("'749’ers")); 554 555 $this->assertEquals('’99’s', wptexturize("'99's")); 556 $this->assertEquals('’99’ers', wptexturize("'99'ers")); 557 $this->assertEquals('’749’ers', wptexturize("'749'ers")); 558 446 559 $this->assertEquals('Class of ’99', wptexturize("Class of '99")); 447 560 $this->assertEquals('Class of ’99’s', wptexturize("Class of '99's")); 561 448 562 $this->assertEquals('‘Class of ’99’', wptexturize("'Class of '99'")); 563 $this->assertEquals(' ‘Class of ’99’ ', wptexturize(" 'Class of '99' ")); 564 $this->assertEquals('‘ Class of ’99 ’', wptexturize("' Class of '99 '")); 565 $this->assertEquals(' ‘ Class of ’99 ’ ', wptexturize(" ' Class of '99 ' ")); 566 449 567 $this->assertEquals('‘Class of ’99’s’', wptexturize("'Class of '99's'")); 450 568 $this->assertEquals('‘Class of ’99’s’', wptexturize("'Class of '99’s'")); 569 451 570 $this->assertEquals('“Class of 99”', wptexturize("\"Class of 99\"")); 452 571 $this->assertEquals('“Class of ’99”', wptexturize("\"Class of '99\"")); 572 $this->assertEquals('“Class of ’99’s”', wptexturize("\"Class of '99's\"")); 453 573 } 454 455 function test_quotes_after_numbers() { 456 $this->assertEquals('Class of ’99', wptexturize("Class of '99")); 457 } 458 574 459 575 //WP Ticket #15241 460 576 function test_other_html() { 461 577 $this->knownWPBug(15241); 462 578 $this->assertEquals('‘<strong>', wptexturize("'<strong>")); 579 $this->assertEquals('“<strong>', wptexturize('"<strong>')); 580 $this->assertEquals('‘<strong></strong>’', wptexturize("'<strong></strong>'")); 581 $this->assertEquals('“<strong></strong>”', wptexturize('"<strong></strong>"')); 463 582 $this->assertEquals('‘<strong>Quoted Text</strong>’,', wptexturize("'<strong>Quoted Text</strong>',")); 464 583 $this->assertEquals('“<strong>Quoted Text</strong>”,', wptexturize('"<strong>Quoted Text</strong>",')); 465 584 } 466 585 586 //WP Ticket #15241 587 function test_many_single_quotes() { 588 $this->assertEquals('This isn’t inherently bad, but I don’t think it’s normal.', wptexturize("This isn't inherently bad, but I don't think it's normal.")); 589 } 590 591 //WP Ticket #1258 592 function test_enumeration() { 593 $this->assertEquals("‘products’, ‘services’", wptexturize("'products', 'services'")); 594 $this->assertEquals("‘hello’, ‘world’, ’tis", wptexturize("'hello', 'world', 'tis")); 595 $this->assertEquals("‘hello’, ‘world’, ’tis ", wptexturize("'hello', 'world', 'tis ")); 596 } 597 598 //WP Ticket #11275 599 function test_quoting() { 600 $this->assertEquals('She said—“No!”', wptexturize('She said—"No!"')); 601 $this->assertEquals('She said — “No!”', wptexturize('She said — "No!"')); 602 $this->assertEquals('She said—“<a href="#">No!</a>”', wptexturize('She said—"<a href="#">No!</a>"')); 603 $this->assertEquals('She said—‘<a href="#">It’s Peter’s!</a>’', wptexturize('She said—\'<a href="#">It\'s Peter\'s!</a>\'')); 604 $this->assertEquals('She said—“<a href="#">It’s Peter’s!</a>”', wptexturize('She said—"<a href="#">It\'s Peter\'s!</a>"')); 605 } 606 607 //WP Ticket #15444 608 function test_tag_followed_by_quote() { 609 $this->knownWPBug(15444); 610 $this->assertEquals('<a href="#">Jim</a>’s red bike.', wptexturize('<a href="#">Jim</a>\'s red bike.')); 611 $this->assertEquals('‘<a href="#">Jim</a>’s red bike.’', wptexturize('\'<a href="#">Jim</a>\'s red bike.\'')); 612 $this->assertEquals('“<a href="#">Jim</a>’s red bike.”', wptexturize('"<a href="#">Jim</a>\'s red bike."')); 613 $this->assertEquals('<a href="#">Jim</a>’s ‘red bike.’', wptexturize('<a href="#">Jim</a>\'s \'red bike.\'')); 614 $this->assertEquals('<a href="#">Jim</a>’s “red bike.”', wptexturize('<a href="#">Jim</a>\'s "red bike."')); 615 $this->assertEquals('<a href="#">Jim</a>’s ‘<a href="#">red bike</a>.’', wptexturize('<a href="#">Jim</a>\'s \'<a href="#">red bike</a>.\'')); 616 $this->assertEquals('<a href="#">Jim</a>’s “<a href="#">red bike</a>.”', wptexturize('<a href="#">Jim</a>\'s "<a href="#">red bike</a>."')); 617 } 618 467 619 function test_x() { 468 620 $this->assertEquals('14×24', wptexturize("14x24")); 621 $this->assertEquals(' 14×24', wptexturize(" 14x24")); 622 $this->assertEquals('‘14×24’', wptexturize("'14x24'")); 623 $this->assertEquals('“14×24”', wptexturize('"14x24"')); 624 $this->assertEquals('‘<a href="#">14×24</a>’', wptexturize('\'<a href="#">14x24</a>\'')); 625 $this->assertEquals('“<a href="#">14×24</a>”', wptexturize('"<a href="#">14x24</a>"')); 469 626 } 470 627 628 //WP Ticket #4116 629 function test_x_4116() { 630 $this->knownWPBug(4116); 631 $this->assertEquals('www.a4x3b.com', wptexturize("www.a4x3b.com")); 632 $this->assertEquals('http://www.youtube.com/watch?v=irWR7F0x2uU', wptexturize("http://www.youtube.com/watch?v=irWR7F0x2uU")); 633 } 634 471 635 function test_minutes_seconds() { 472 636 $this->assertEquals('9′', wptexturize('9\'')); 473 637 $this->assertEquals('9″', wptexturize("9\"")); … … 484 648 $this->assertEquals(' “Testing”', wptexturize(' "Testing"')); 485 649 $this->assertEquals('&“Testing”', wptexturize('&"Testing"')); 486 650 } 651 652 //WP Ticket #6969 653 function test_shortcode_skip() { 654 $this->assertEquals('[code lang="php"]$foo = \'bar\';[/code]', wptexturize('[code lang="php"]$foo = \'bar\';[/code]')); 655 } 656 487 657 } 488 658 489 659 class TestCleanUrl extends WPTestCase {