WordPress.org

Make WordPress Core

Changeset 12084


Ignore:
Timestamp:
10/21/09 21:57:27 (4 years ago)
Author:
westi
Message:

Improve wptexturize performance. Fixes #10987 props johanee.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-includes/formatting.php

    r12072 r12084  
    2929function wptexturize($text) { 
    3030    global $wp_cockneyreplace; 
     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; 
    3132    $output = ''; 
    3233    $curl = ''; 
    3334    $textarr = preg_split('/(<.*>|\[.*\])/Us', $text, -1, PREG_SPLIT_DELIM_CAPTURE); 
    3435    $stop = count($textarr); 
    35  
    36     /* translators: opening curly quote */ 
    37     $opening_quote = _x('&#8220;', 'opening curly quote'); 
    38     /* translators: closing curly quote */ 
    39     $closing_quote = _x('&#8221;', 'closing curly quote'); 
    40  
    41     $no_texturize_tags = apply_filters('no_texturize_tags', array('pre', 'code', 'kbd', 'style', 'script', 'tt')); 
    42     $no_texturize_shortcodes = apply_filters('no_texturize_shortcodes', array('code')); 
     36     
     37    // No need to setup these variables more than once 
     38    if (!$static_setup) { 
     39        /* translators: opening curly quote */ 
     40        $opening_quote = _x('&#8220;', 'opening curly quote'); 
     41        /* translators: closing curly quote */ 
     42        $closing_quote = _x('&#8221;', 'closing curly quote'); 
     43 
     44        $default_no_texturize_tags = array('pre', 'code', 'kbd', 'style', 'script', 'tt'); 
     45        $default_no_texturize_shortcodes = array('code'); 
     46 
     47        // if a plugin has provided an autocorrect array, use it 
     48        if ( isset($wp_cockneyreplace) ) { 
     49            $cockney = array_keys($wp_cockneyreplace); 
     50            $cockneyreplace = array_values($wp_cockneyreplace); 
     51        } else { 
     52            $cockney = array("'tain't","'twere","'twas","'tis","'twill","'til","'bout","'nuff","'round","'cause"); 
     53            $cockneyreplace = array("&#8217;tain&#8217;t","&#8217;twere","&#8217;twas","&#8217;tis","&#8217;twill","&#8217;til","&#8217;bout","&#8217;nuff","&#8217;round","&#8217;cause"); 
     54        } 
     55 
     56        $static_characters = array_merge(array('---', ' -- ', '--', ' - ', 'xn&#8211;', '...', '``', '\'s', '\'\'', ' (tm)'), $cockney); 
     57        $static_replacements = array_merge(array('&#8212;', ' &#8212; ', '&#8211;', ' &#8211; ', 'xn--', '&#8230;', $opening_quote, '&#8217;s', $closing_quote, ' &#8482;'), $cockneyreplace); 
     58 
     59        $dynamic_characters = array('/\'(\d\d(?:&#8217;|\')?s)/', '/(\s|\A|[([{<]|")\'/', '/(\d+)"/', '/(\d+)\'/', '/(\S)\'([^\'\s])/', '/(\s|\A|[([{<])"(?!\s)/', '/"(\s|\S|\Z)/', '/\'([\s.]|\Z)/', '/(\d+)x(\d+)/'); 
     60        $dynamic_replacements = array('&#8217;$1','$1&#8216;', '$1&#8243;', '$1&#8242;', '$1&#8217;$2', '$1' . $opening_quote . '$2', $closing_quote . '$1', '&#8217;$1', '$1&#215;$2'); 
     61 
     62        $static_setup = true; 
     63    } 
     64 
     65    // Transform into regexp sub-expression used in _wptexturize_pushpop_element 
     66    // Must do this everytime in case plugins use these filters in a context sensitive manner 
     67    $no_texturize_tags = '(' . implode('|', apply_filters('no_texturize_tags', $default_no_texturize_tags) ) . ')'; 
     68    $no_texturize_shortcodes = '(' . implode('|', apply_filters('no_texturize_shortcodes', $default_no_texturize_shortcodes) ) . ')'; 
     69 
    4370    $no_texturize_tags_stack = array(); 
    4471    $no_texturize_shortcodes_stack = array(); 
    4572 
    46     // if a plugin has provided an autocorrect array, use it 
    47     if ( isset($wp_cockneyreplace) ) { 
    48         $cockney = array_keys($wp_cockneyreplace); 
    49         $cockneyreplace = array_values($wp_cockneyreplace); 
    50     } else { 
    51         $cockney = array("'tain't","'twere","'twas","'tis","'twill","'til","'bout","'nuff","'round","'cause"); 
    52         $cockneyreplace = array("&#8217;tain&#8217;t","&#8217;twere","&#8217;twas","&#8217;tis","&#8217;twill","&#8217;til","&#8217;bout","&#8217;nuff","&#8217;round","&#8217;cause"); 
    53     } 
    54  
    55     $static_characters = array_merge(array('---', ' -- ', '--', ' - ', 'xn&#8211;', '...', '``', '\'s', '\'\'', ' (tm)'), $cockney); 
    56     $static_replacements = array_merge(array('&#8212;', ' &#8212; ', '&#8211;', ' &#8211; ', 'xn--', '&#8230;', $opening_quote, '&#8217;s', $closing_quote, ' &#8482;'), $cockneyreplace); 
    57  
    58     $dynamic_characters = array('/\'(\d\d(?:&#8217;|\')?s)/', '/(\s|\A|[([{<]|")\'/', '/(\d+)"/', '/(\d+)\'/', '/(\S)\'([^\'\s])/', '/(\s|\A|[([{<])"(?!\s)/', '/"(\s|\S|\Z)/', '/\'([\s.]|\Z)/', '/(\d+)x(\d+)/'); 
    59     $dynamic_replacements = array('&#8217;$1','$1&#8216;', '$1&#8243;', '$1&#8242;', '$1&#8217;$2', '$1' . $opening_quote . '$2', $closing_quote . '$1', '&#8217;$1', '$1&#215;$2'); 
    60  
    6173    for ( $i = 0; $i < $stop; $i++ ) { 
    6274        $curl = $textarr[$i]; 
    6375 
    6476        if ( !empty($curl) && '<' != $curl{0} && '[' != $curl{0} 
    65                 && empty($no_texturize_shortcodes_stack) && empty($no_texturize_tags_stack)) { // If it's not a tag 
     77                && empty($no_texturize_shortcodes_stack) && empty($no_texturize_tags_stack)) {  
     78            // This is not a tag, nor is the texturization disabled 
    6679            // static strings 
    6780            $curl = str_replace($static_characters, $static_replacements, $curl); 
    6881            // regular expressions 
    6982            $curl = preg_replace($dynamic_characters, $dynamic_replacements, $curl); 
    70         } else { 
    71             wptexturize_pushpop_element($curl, $no_texturize_tags_stack, $no_texturize_tags, '<', '>'); 
    72             wptexturize_pushpop_element($curl, $no_texturize_shortcodes_stack, $no_texturize_shortcodes, '[', ']'); 
     83        } elseif (!empty($curl)) { 
     84            /* 
     85             * Only call _wptexturize_pushpop_element if first char is correct 
     86             * tag opening 
     87             */ 
     88            if ('<' == $curl{0}) 
     89                _wptexturize_pushpop_element($curl, $no_texturize_tags_stack, $no_texturize_tags, '<', '>'); 
     90            elseif ('[' == $curl{0}) 
     91                _wptexturize_pushpop_element($curl, $no_texturize_shortcodes_stack, $no_texturize_shortcodes, '[', ']'); 
    7392        } 
    7493 
     
    8099} 
    81100 
    82 function wptexturize_pushpop_element($text, &$stack, $disabled_elements, $opening = '<', $closing = '>') { 
    83     $o = preg_quote($opening, '/'); 
    84     $c = preg_quote($closing, '/'); 
    85     foreach($disabled_elements as $element) { 
    86         if (preg_match('/^'.$o.$element.'\b/', $text)) array_push($stack, $element); 
    87         if (preg_match('/^'.$o.'\/'.$element.$c.'/', $text)) { 
     101/** 
     102 * Search for disabled element tags. Push element to stack on tag open and pop 
     103 * on tag close. Assumes first character of $text is tag opening. 
     104 * 
     105 * @access private 
     106 * @since 2.9.0 
     107 * 
     108 * @param string $text Text to check. First character is assumed to be $opening 
     109 * @param array $stack Array used as stack of opened tag elements 
     110 * @param string $disabled_elements Tags to match against formatted as regexp sub-expression 
     111 * @param string $opening Tag opening character, assumed to be 1 character long 
     112 * @param string $opening Tag closing  character 
     113 * @return object 
     114 */ 
     115function _wptexturize_pushpop_element($text, &$stack, $disabled_elements, $opening = '<', $closing = '>') { 
     116    // Check if it is a closing tag -- otherwise assume opening tag 
     117    if (strncmp($opening . '/', $text, 2)) { 
     118        // Opening? Check $text+1 against disabled elements 
     119        if (preg_match('/^' . $disabled_elements . '\b/', substr($text, 1), $matches)) { 
     120            /* 
     121             * This disables texturize until we find a closing tag of our type 
     122             * (e.g. <pre>) even if there was invalid nesting before that 
     123             *  
     124             * Example: in the case <pre>sadsadasd</code>"baba"</pre> 
     125             *          "baba" won't be texturize 
     126             */ 
     127 
     128            array_push($stack, $matches[1]); 
     129        } 
     130    } else { 
     131        // Closing? Check $text+2 against disabled elements 
     132        $c = preg_quote($closing, '/'); 
     133        if (preg_match('/^' . $disabled_elements . $c . '/', substr($text, 2), $matches)) { 
    88134            $last = array_pop($stack); 
    89             // disable texturize until we find a closing tag of our type (e.g. <pre>) 
    90             // even if there was invalid nesting before that 
    91             // Example: in the case <pre>sadsadasd</code>"baba"</pre> "baba" won't be texturized 
    92             if ($last != $element) array_push($stack, $last); 
     135 
     136            // Make sure it matches the opening tag 
     137            if ($last != $matches[1]) 
     138                array_push($stack, $last); 
    93139        } 
    94140    } 
Note: See TracChangeset for help on using the changeset viewer.