web/wp-includes/shortcodes.php
changeset 194 32102edaa81b
parent 136 bde1974c263b
child 204 09a1c134465b
--- a/web/wp-includes/shortcodes.php	Thu Sep 16 15:45:36 2010 +0000
+++ b/web/wp-includes/shortcodes.php	Mon Nov 19 18:26:13 2012 +0100
@@ -148,7 +148,7 @@
 		return $content;
 
 	$pattern = get_shortcode_regex();
-	return preg_replace_callback('/'.$pattern.'/s', 'do_shortcode_tag', $content);
+	return preg_replace_callback( "/$pattern/s", 'do_shortcode_tag', $content );
 }
 
 /**
@@ -157,13 +157,14 @@
  * The regular expression combines the shortcode tags in the regular expression
  * in a regex class.
  *
- * The regular expresion contains 6 different sub matches to help with parsing.
+ * The regular expression contains 6 different sub matches to help with parsing.
  *
- * 1/6 - An extra [ or ] to allow for escaping shortcodes with double [[]]
+ * 1 - An extra [ to allow for escaping shortcodes with double [[]]
  * 2 - The shortcode name
  * 3 - The shortcode argument list
  * 4 - The self closing /
  * 5 - The content of a shortcode when it wraps some content.
+ * 6 - An extra ] to allow for escaping shortcodes with double [[]]
  *
  * @since 2.5
  * @uses $shortcode_tags
@@ -175,8 +176,36 @@
 	$tagnames = array_keys($shortcode_tags);
 	$tagregexp = join( '|', array_map('preg_quote', $tagnames) );
 
-	// WARNING! Do not change this regex without changing do_shortcode_tag() and strip_shortcodes()
-	return '(.?)\[('.$tagregexp.')\b(.*?)(?:(\/))?\](?:(.+?)\[\/\2\])?(.?)';
+	// WARNING! Do not change this regex without changing do_shortcode_tag() and strip_shortcode_tag()
+	return
+		  '\\['                              // Opening bracket
+		. '(\\[?)'                           // 1: Optional second opening bracket for escaping shortcodes: [[tag]]
+		. "($tagregexp)"                     // 2: Shortcode name
+		. '\\b'                              // Word boundary
+		. '('                                // 3: Unroll the loop: Inside the opening shortcode tag
+		.     '[^\\]\\/]*'                   // Not a closing bracket or forward slash
+		.     '(?:'
+		.         '\\/(?!\\])'               // A forward slash not followed by a closing bracket
+		.         '[^\\]\\/]*'               // Not a closing bracket or forward slash
+		.     ')*?'
+		. ')'
+		. '(?:'
+		.     '(\\/)'                        // 4: Self closing tag ...
+		.     '\\]'                          // ... and closing bracket
+		. '|'
+		.     '\\]'                          // Closing bracket
+		.     '(?:'
+		.         '('                        // 5: Unroll the loop: Optionally, anything between the opening and closing shortcode tags
+		.             '[^\\[]*+'             // Not an opening bracket
+		.             '(?:'
+		.                 '\\[(?!\\/\\2\\])' // An opening bracket not followed by the closing shortcode tag
+		.                 '[^\\[]*+'         // Not an opening bracket
+		.             ')*+'
+		.         ')'
+		.         '\\[\\/\\2\\]'             // Closing shortcode tag
+		.     ')?'
+		. ')'
+		. '(\\]?)';                          // 6: Optional second closing brocket for escaping shortcodes: [[tag]]
 }
 
 /**
@@ -190,23 +219,23 @@
  * @param array $m Regular expression match array
  * @return mixed False on failure.
  */
-function do_shortcode_tag($m) {
+function do_shortcode_tag( $m ) {
 	global $shortcode_tags;
 
 	// allow [[foo]] syntax for escaping a tag
-	if ($m[1] == '[' && $m[6] == ']') {
+	if ( $m[1] == '[' && $m[6] == ']' ) {
 		return substr($m[0], 1, -1);
 	}
 
 	$tag = $m[2];
-	$attr = shortcode_parse_atts($m[3]);
+	$attr = shortcode_parse_atts( $m[3] );
 
-	if ( isset($m[5]) ) {
+	if ( isset( $m[5] ) ) {
 		// enclosing tag - extra parameter
-		return $m[1] . call_user_func($shortcode_tags[$tag], $attr, $m[5], $m[2]) . $m[6];
+		return $m[1] . call_user_func( $shortcode_tags[$tag], $attr, $m[5], $tag ) . $m[6];
 	} else {
 		// self-closing tag
-		return $m[1] . call_user_func($shortcode_tags[$tag], $attr, NULL, $m[2]) . $m[6];
+		return $m[1] . call_user_func( $shortcode_tags[$tag], $attr, null,  $tag ) . $m[6];
 	}
 }
 
@@ -290,9 +319,16 @@
 
 	$pattern = get_shortcode_regex();
 
-	return preg_replace('/'.$pattern.'/s', '$1$6', $content);
+	return preg_replace_callback( "/$pattern/s", 'strip_shortcode_tag', $content );
+}
+
+function strip_shortcode_tag( $m ) {
+	// allow [[foo]] syntax for escaping a tag
+	if ( $m[1] == '[' && $m[6] == ']' ) {
+		return substr($m[0], 1, -1);
+	}
+
+	return $m[1] . $m[6];
 }
 
 add_filter('the_content', 'do_shortcode', 11); // AFTER wpautop()
-
-?>
\ No newline at end of file