@@ -628,7 +628,11 @@ function output_shortcodes_for_tinymce() {
628628 *
629629 * First we need to clear out all existing shortcodes, then register
630630 * just this plugin's ones, process them, and then restore the original
631- * list of shortcodes.
631+ * list of shortcodes. Additionally, we have to add another hack to other
632+ * shortcodes, such as [gallery], to return the entire shortcode string as
633+ * it appears in the original content to allow SyntaxHighlighter's shortcode
634+ * strings (e.g., [c]) be used within other shortcodes without interference
635+ * from SyntaxHighlighter.
632636 *
633637 * To make matters more complicated, if someone has done [[code]foo[/code]]
634638 * in order to display the shortcode (not render it), then do_shortcode()
@@ -639,10 +643,6 @@ function output_shortcodes_for_tinymce() {
639643 * even more brackets escaped shortcodes in order to result in
640644 * the shortcodes actually being displayed instead rendered.
641645 *
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- *
646646 * Phew!
647647 *
648648 * @param string $content The post content.
@@ -668,7 +668,12 @@ function shortcode_hack( $content, $callback, $ignore_html = true ) {
668668 add_shortcode ( $ shortcode , $ callback );
669669 }
670670
671- $ regex = '/ ' . get_shortcode_regex ( $ this ->shortcodes ) . '/ ' ;
671+ // Register all other shortcodes, ensuring their content remains unchanged using yet another hack.
672+ foreach ( $ orig_shortcode_tags as $ shortcode_tagname => $ shortcode ) {
673+ add_shortcode ( $ shortcode_tagname , array ( $ this , 'return_entire_shortcode_callback ' ) );
674+ }
675+
676+ $ regex = '/ ' . get_shortcode_regex ( array_merge ( $ this ->shortcodes , array_keys ( $ orig_shortcode_tags ) ) ) . '/ ' ;
672677
673678 // Parse the shortcodes (only this plugins's are registered)
674679 if ( $ ignore_html ) {
@@ -749,6 +754,44 @@ function shortcode_hack_extra_escape_escaped_shortcodes_and_parse( $match ) {
749754 return do_shortcode_tag ( $ match );
750755 }
751756
757+ /**
758+ * Callback function to return the entire shortcode string as it appears in content.
759+ *
760+ * @param array $atts Array of attributes passed to the shortcode.
761+ * @param string|null $content Content enclosed between the opening and closing shortcode tags. Default is null.
762+ * @param string $tag Shortcode name/tag.
763+ *
764+ * @return string The complete shortcode string including the opening and closing tags, attributes, and content.
765+ */
766+ function return_entire_shortcode_callback ( $ atts , $ content = null , $ tag = '' ) {
767+ $ shortcode_string = '[ ' . $ tag ;
768+
769+ if ( ! empty ( $ atts ) ) {
770+ foreach ( $ atts as $ key => $ value ) {
771+ if ( strpos ( $ value , "' " ) !== false && strpos ( $ value , '" ' ) === false ) {
772+ // Use double quotes if value contains a single quote but not a double quote.
773+ $ shortcode_string .= ' ' . $ key . '=" ' . $ value . '" ' ;
774+ } elseif ( strpos ( $ value , '" ' ) !== false && strpos ( $ value , "' " ) === false ) {
775+ // Use single quotes if value contains a double quote but not a single quote.
776+ $ shortcode_string .= ' ' . $ key . "=' " . $ value . "' " ;
777+ } elseif ( strpos ( $ value , "' " ) !== false && strpos ( $ value , '" ' ) !== false ) {
778+ // If value contains both types of quotes, use double quotes and escape inner double quotes.
779+ $ pattern = '/(?<! \\\\)"/ ' ; // This pattern looks for double quotes that aren't preceded by a backslash.
780+ $ escaped_value = preg_replace ( $ pattern , '\" ' , $ content );
781+ $ shortcode_string .= ' ' . $ key . '=" ' . $ escaped_value . '" ' ;
782+ } else {
783+ $ shortcode_string .= ' ' . $ key . '=" ' . $ value . '" ' ;
784+ }
785+ }
786+ }
787+
788+ $ shortcode_string .= '] ' ;
789+
790+ if ( $ content !== null ) {
791+ $ shortcode_string .= $ content . '[/ ' . $ tag . '] ' ;
792+ }
793+ return $ shortcode_string ;
794+ }
752795
753796 // The main filter for the post contents. The regular shortcode filter can't be used as it's post-wpautop().
754797 function parse_shortcodes ( $ content ) {
0 commit comments