Ticket #4539: formatting_latest_fixes_all.diff

File formatting_latest_fixes_all.diff, 8.9 KB (added by norbertm, 3 years ago)
Line 
1Index: wp-testcase/test_includes_formatting.php
2===================================================================
3--- wp-testcase/test_includes_formatting.php    (revision 315)
4+++ wp-testcase/test_includes_formatting.php    (working copy)
5@@ -386,26 +386,43 @@
6                $this->assertEquals('A dog (“Hubertus”) was sent out.', wptexturize('A dog ("Hubertus") was sent out.'));
7        }
8       
9+       //WP Ticket #4539
10+       function test_basic_quotes() {
11+               $this->assertEquals('test’s', wptexturize('test\'s'));
12+               $this->assertEquals('test’s', wptexturize('test\'s'));
13+
14+               $this->assertEquals('‘quoted’', wptexturize('\'quoted\''));
15+               $this->assertEquals('“quoted”', wptexturize('"quoted"'));
16+
17+               $this->assertEquals('(‘quoted’)', wptexturize('(\'quoted\')'));
18+               $this->assertEquals('{“quoted”}', wptexturize('{"quoted"}'));
19+
20+               $this->assertEquals('‘qu(ot)ed’', wptexturize('\'qu(ot)ed\''));
21+               $this->assertEquals('“qu{ot}ed”', wptexturize('"qu{ot}ed"'));
22+
23+               $this->assertEquals('‘test’s quoted’', wptexturize('\'test\'s quoted\''));
24+               $this->assertEquals('“test’s quoted”', wptexturize('"test\'s quoted"'));
25+       }
26+       
27+       //WP Ticket #4539
28        function test_quotes() {
29-               $this->knownWPBug(4539);
30                $this->assertEquals('“Quoted String”', wptexturize('"Quoted String"'));
31                $this->assertEquals('Here is &#8220;<a href="http://example.com">a test with a link</a>&#8221;', wptexturize('Here is "<a href="http://example.com">a test with a link</a>"'));
32-               $this->assertEquals('Here is &#8220;<a href="http://example.com">a test with a link and a period </a>&#8221;.', wptexturize('Here is "<a href="http://example.com">a test with a link and a period</a>".'));
33+               $this->assertEquals('Here is &#8220;<a href="http://example.com">a test with a link and a period</a>&#8221;.', wptexturize('Here is "<a href="http://example.com">a test with a link and a period</a>".'));
34                $this->assertEquals('Here is &#8220;<a href="http://example.com">a test with a link</a>&#8221; and a space.', wptexturize('Here is "<a href="http://example.com">a test with a link</a>" and a space.'));
35                $this->assertEquals('Here is &#8220;<a href="http://example.com">a test with a link</a> and some text quoted&#8221;', wptexturize('Here is "<a href="http://example.com">a test with a link</a> and some text quoted"'));
36                $this->assertEquals('Here is &#8220;<a href="http://example.com">a test with a link</a>&#8221;, and a comma.', wptexturize('Here is "<a href="http://example.com">a test with a link</a>", and a comma.'));
37                $this->assertEquals('Here is &#8220;<a href="http://example.com">a test with a link</a>&#8221;; and a semi-colon.', wptexturize('Here is "<a href="http://example.com">a test with a link</a>"; and a semi-colon.'));
38                $this->assertEquals('Here is &#8220;<a href="http://example.com">a test with a link</a>&#8221;- and a dash.', wptexturize('Here is "<a href="http://example.com">a test with a link</a>"- and a dash.'));
39-               $this->assertEquals('Here is &#8220;<a href="http://example.com">a test with a link</a>&#8221;... and ellipses.', wptexturize('Here is "<a href="http://example.com">a test with a link</a>"... and ellipses.'));
40+               $this->assertEquals('Here is &#8220;<a href="http://example.com">a test with a link</a>&#8221;&#8230; and ellipses.', wptexturize('Here is "<a href="http://example.com">a test with a link</a>"... and ellipses.'));
41                $this->assertEquals('Here is &#8220;a test <a href="http://example.com">with a link</a>&#8221;.', wptexturize('Here is "a test <a href="http://example.com">with a link</a>".'));
42                $this->assertEquals('Here is &#8220;<a href="http://example.com">a test with a link</a>&#8221;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.'));
43                $this->assertEquals('A test with a finishing number, &#8220;like 23&#8221;.', wptexturize('A test with a finishing number, "like 23".'));
44                $this->assertEquals('A test with a number, &#8220;like 62&#8221;, is nice to have.', wptexturize('A test with a number, "like 62", is nice to have.'));
45        }
46       
47-       //WP Ticket #1258
48+       //WP Ticket #4539
49        function test_quotes_before_s() {
50-               $this->knownWPBug(4539);
51                $this->assertEquals('test&#8217;s', wptexturize("test's"));
52                $this->assertEquals('&#8216;test&#8217;s', wptexturize("'test's"));
53                $this->assertEquals('&#8216;test&#8217;s&#8217;', wptexturize("'test's'"));
54@@ -415,16 +432,40 @@
55 
56        //WP Ticket #4539
57        function test_quotes_before_numbers() {
58-               $this->knownWPBug(4539);
59                $this->assertEquals('Class of &#8217;99', wptexturize("Class of '99"));
60+               $this->assertEquals('Class of &#8217;99&#8217;s', wptexturize("Class of '99's"));
61                $this->assertEquals('&#8216;Class of &#8217;99&#8217;', wptexturize("'Class of '99'"));
62+               $this->assertEquals('&#8216;Class of &#8217;99&#8217;s&#8217;', wptexturize("'Class of '99's'"));
63+               $this->assertEquals('&#8216;Class of &#8217;99&#8217;s&#8217;', wptexturize("'Class of '99&#8217;s'"));
64+               $this->assertEquals('&#8220;Class of 99&#8221;', wptexturize("\"Class of 99\""));
65+               $this->assertEquals('&#8220;Class of &#8217;99&#8221;', wptexturize("\"Class of '99\""));
66        }
67       
68+       function test_quotes_after_numbers() {
69+               $this->assertEquals('Class of &#8217;99', wptexturize("Class of '99"));
70+       }
71+       
72+       //WP Ticket #15241
73        function test_other_html() {
74-               $this->knownWPBug(15241);
75-               $this->assertEquals('&#8216;<strong>Quoted Text</strong>&#8217;,', wptexturize("'<strong>Quoted Text</strong>',"));
76+               $this->assertEquals('&#8216;<strong>', wptexturize("'<strong>"));
77+               $this->assertEquals('&#8216;<strong>Quoted Text</strong>&#8217;,', wptexturize('\'<strong>Quoted Text</strong>\','));
78                $this->assertEquals('&#8220;<strong>Quoted Text</strong>&#8221;,', wptexturize('"<strong>Quoted Text</strong>",'));
79        }
80+       
81+       function test_x() {
82+               $this->assertEquals('14&#215;24', wptexturize("14x24"));
83+       }
84+       
85+       function test_minutes_seconds() {
86+               $this->assertEquals('9&#8242;', wptexturize('9\''));
87+               $this->assertEquals('9&#8243;', wptexturize("9\""));
88+
89+               $this->assertEquals('a 9&#8242; b', wptexturize('a 9\' b'));
90+               $this->assertEquals('a 9&#8243; b', wptexturize("a 9\" b"));
91+               
92+               $this->assertEquals('&#8220;a 9&#8242; b&#8221;', wptexturize('"a 9\' b"'));
93+               $this->assertEquals('&#8216;a 9&#8243; b&#8217;', wptexturize("'a 9\" b'"));
94+       }
95 }
96 
97 class TestCleanUrl extends WPTestCase {
98Index: wordpress/wp-includes/formatting.php
99===================================================================
100--- wordpress/wp-includes/formatting.php        (revision 16231)
101+++ wordpress/wp-includes/formatting.php        (working copy)
102@@ -56,9 +56,25 @@
103                $static_characters = array_merge(array('---', ' -- ', '--', ' - ', 'xn&#8211;', '...', '``', '\'\'', ' (tm)'), $cockney);
104                $static_replacements = array_merge(array('&#8212;', ' &#8212; ', '&#8211;', ' &#8211; ', 'xn--', '&#8230;', $opening_quote, $closing_quote, ' &#8482;'), $cockneyreplace);
105 
106-               $dynamic_characters = array('/\'(\d\d(?:&#8217;|\')?s)/', '/\'(\d)/', '/(\s|\A|[([{<]|")\'/', '/(\d)"/', '/(\d)\'/', '/(\S)\'([^\'\s])/', '/(\s|\A|[([{<])"(?!\s)/', '/"(\s|\S|\Z)/', '/\'([\s.]|\Z)/', '/\b(\d+)x(\d+)\b/');
107-               $dynamic_replacements = array('&#8217;$1','&#8217;$1', '$1&#8216;', '$1&#8243;', '$1&#8242;', '$1&#8217;$2', '$1' . $opening_quote . '$2', $closing_quote . '$1', '&#8217;$1', '$1&#215;$2');
108-
109+               $dynamic_map = array(
110+                       '/\'(\d)/' => '&#8217;$1', // '99
111+                       
112+                       '/\'([^\']*)\'([^\']*)\'/' => '&#8216;$1&#8217;$2&#8217;', // 'test's'
113+                       
114+                       '/\'([^\']*)\'/' => '&#8216;$1&#8217;', // 'asd'
115+                       '/"([^"]*)"/' => $opening_quote . '$1' . $closing_quote, // "qwe"
116+                       
117+                       '/(\w)\'(\w)/' => '$1&#8217;$2', // test's
118+                       
119+                       '/(\d)"/' => '$1&#8243;', // 9" -> 9″
120+                       '/(\d)\'/' => '$1&#8242;', // 9' -> 9′
121+                       
122+                       '/\b(\d+)x(\d+)\b/' => '$1&#215;$2' // 10. 97x34 => 97×34
123+               );
124+               
125+               $dynamic_characters = array_keys($dynamic_map);
126+               $dynamic_replacements = array_values($dynamic_map);
127+               
128                $static_setup = true;
129        }
130 
131@@ -69,6 +85,9 @@
132 
133        $no_texturize_tags_stack = array();
134        $no_texturize_shortcodes_stack = array();
135+       
136+       $single_quote_state = '&#8216;';
137+       $doube_quote_state = $opening_quote;
138 
139        for ( $i = 0; $i < $stop; $i++ ) {
140                $curl = $textarr[$i];
141@@ -80,6 +99,15 @@
142                        $curl = str_replace($static_characters, $static_replacements, $curl);
143                        // regular expressions
144                        $curl = preg_replace($dynamic_characters, $dynamic_replacements, $curl);
145+                       // quotes that span multiple tags & shortcodes
146+                       while (($pos = strpos($curl, '\'')) !== FALSE) {
147+                               $curl = preg_replace('/\'/', $single_quote_state, $curl);
148+                               $single_quote_state = (($single_quote_state == '&#8216;') ? '&#8217;' : '&#8216;');
149+                       }
150+                       while (($pos = strpos($curl, '"')) !== FALSE) {
151+                               $curl = preg_replace('/"/', $doube_quote_state, $curl);
152+                               $doube_quote_state = (($doube_quote_state == $opening_quote) ? $closing_quote : $opening_quote);
153+                       }
154                } elseif (!empty($curl)) {
155                        /*
156                         * Only call _wptexturize_pushpop_element if first char is correct