Skip to content

Commit 511b5f6

Browse files
authored
Merge pull request #261 from Automattic/fix/32-nested-shorcode-problem
2 parents 15a0fcb + 392bfae commit 511b5f6

File tree

1 file changed

+35
-11
lines changed

1 file changed

+35
-11
lines changed

syntaxhighlighter.php

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,24 @@ function output_shortcodes_for_tinymce() {
617617
}
618618

619619

620+
/**
621+
* Returns all shortcodes not handled by SyntaxHighlighter unchanged, so they
622+
* can be processed by their original handlers after SyntaxHighlighter has
623+
* run.
624+
*
625+
* @param mixed $output The shortcode's returned value (false by default).
626+
* @param string $tag The name of the shortcode.
627+
* @param array|null $attr The shortcode attributes.
628+
* @param array $m Regular expression match array.
629+
* @return string|false Return the matched shortcode as-is for all shortcodes not handled by SyntaxHighlighter, returns $output otherwise.
630+
*/
631+
function pre_do_shortcode_shortcode_hack_skip_others( $output, $tag, $attr, $m ) {
632+
if ( ! in_array( $tag, $this->shortcodes, true ) ) {
633+
return $m[0];
634+
}
635+
return $output;
636+
}
637+
620638
/**
621639
* Process only this plugin's shortcodes.
622640
*
@@ -628,7 +646,11 @@ function output_shortcodes_for_tinymce() {
628646
*
629647
* First we need to clear out all existing shortcodes, then register
630648
* just this plugin's ones, process them, and then restore the original
631-
* list of shortcodes.
649+
* list of shortcodes. Additionally, we have to add another hack to other
650+
* shortcodes, such as [gallery], to return the entire shortcode string as
651+
* it appears in the original content to allow SyntaxHighlighter's shortcode
652+
* strings (e.g., [c]) be used within other shortcodes without interference
653+
* from SyntaxHighlighter.
632654
*
633655
* To make matters more complicated, if someone has done [[code]foo[/code]]
634656
* in order to display the shortcode (not render it), then do_shortcode()
@@ -639,10 +661,6 @@ function output_shortcodes_for_tinymce() {
639661
* even more brackets escaped shortcodes in order to result in
640662
* the shortcodes actually being displayed instead rendered.
641663
*
642-
* We only need to do this for this plugin's shortcodes however
643-
* as all other shortcodes such as [[gallery]] will be untouched
644-
* by this pass of do_shortcode.
645-
*
646664
* Phew!
647665
*
648666
* @param string $content The post content.
@@ -659,16 +677,22 @@ function shortcode_hack( $content, $callback, $ignore_html = true ) {
659677
return $content;
660678
}
661679

662-
// Backup current registered shortcodes and clear them all out
663-
$orig_shortcode_tags = $shortcode_tags;
680+
// Backup current registered shortcodes and clear them all out (we do not backup our own, because we will add and parse them below)
681+
$orig_shortcode_tags = array_diff_key( $shortcode_tags, array_flip( $this->shortcodes ) );
664682
remove_all_shortcodes();
665683

666684
// Register all of this plugin's shortcodes
667685
foreach ( $this->shortcodes as $shortcode ) {
668686
add_shortcode( $shortcode, $callback );
669687
}
670688

671-
$regex = '/' . get_shortcode_regex( $this->shortcodes ) . '/';
689+
// Register all other shortcodes, ensuring their content remains unchanged using yet another hack.
690+
foreach ( $orig_shortcode_tags as $shortcode_tagname => $shortcode ) {
691+
add_shortcode( $shortcode_tagname, '__return_empty_string' );
692+
}
693+
add_filter( 'pre_do_shortcode_tag', array( $this, 'pre_do_shortcode_shortcode_hack_skip_others' ), 10, 4 );
694+
695+
$regex = '/' . get_shortcode_regex() . '/';
672696

673697
// Parse the shortcodes (only this plugins's are registered)
674698
if ( $ignore_html ) {
@@ -692,8 +716,9 @@ function shortcode_hack( $content, $callback, $ignore_html = true ) {
692716
);
693717
}
694718

695-
// Put the original shortcodes back
719+
// Put the original shortcodes back, and remove the hacky pre_do_shortcode_tag filter
696720
$shortcode_tags = $orig_shortcode_tags;
721+
remove_filter('pre_do_shortcode_tag', array($this, 'pre_do_shortcode_shortcode_hack_skip_others'), 10);
697722

698723
return $content;
699724
}
@@ -749,7 +774,6 @@ function shortcode_hack_extra_escape_escaped_shortcodes_and_parse( $match ) {
749774
return do_shortcode_tag( $match );
750775
}
751776

752-
753777
// The main filter for the post contents. The regular shortcode filter can't be used as it's post-wpautop().
754778
function parse_shortcodes( $content ) {
755779
return $this->shortcode_hack( $content, array( $this, 'shortcode_callback' ) );
@@ -1377,7 +1401,7 @@ function shortcode_callback( $atts, $code = '', $tag = false ) {
13771401
$code = ( false === strpos( $code, '<' ) && false === strpos( $code, '>' ) && 2 == $this->get_code_format( $post ) ) ? strip_tags( $code ) : htmlspecialchars( $code );
13781402

13791403
// Escape shortcodes
1380-
$code = preg_replace( '/\[/', '&#91;', $code );
1404+
$code = preg_replace( '/\[/', '&#x5B;', $code );
13811405

13821406
$params[] = 'notranslate'; // For Google, see http://otto42.com/9k
13831407

0 commit comments

Comments
 (0)