diff --git a/README.md b/README.md index cc4a45f..55b292e 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,7 @@ A: Only if Markdown is enabled — and only when those comments are rendered. It ## Roadmap -- [ ] Add support for blockquotes (`>`) +- [x] Add support for blockquotes (`>`) - [ ] Toggle for displaying Markdown helper hint - [ ] Extendable filters/hooks for developers diff --git a/markdown-comments-for-wordpress.php b/markdown-comments-for-wordpress.php index 2c03c98..f51a92f 100644 --- a/markdown-comments-for-wordpress.php +++ b/markdown-comments-for-wordpress.php @@ -3,14 +3,14 @@ * Plugin Name: Markdown Comments for WordPress® * Description: Allow users to write comments in Markdown format and automatically parse them into HTML. * Plugin URI: https://github.com/robertdevore/markdown-comments-for-wordpress/ - * Version: 1.0.0 - * Author: Robert DeVore + * Version: 1.1 + * Author: Robert DeVore, Rodrigo Ghedin * Author URI: https://robertdevore.com * License: GPL-2.0+ * License URI: https://www.gnu.org/licenses/gpl-2.0.html * Text Domain: markdown-comments * Domain Path: /languages - * Update URI: https://github.com/robertdevore/markdown-comments-for-wordpress/ + * Update URI: https://github.com/manualdousuario/markdown-comments-for-wordpress/ */ // Security check to prevent direct access. @@ -54,7 +54,7 @@ function markdown_comments_load_textdomain() { } add_action( 'plugins_loaded', 'markdown_comments_load_textdomain' ); -define( 'MARKDOWN_COMMENTS_VERSION', '1.0.0' ); +define( 'MARKDOWN_COMMENTS_VERSION', '1.1' ); define( 'MARKDOWN_COMMENTS_PLUGIN_DIR', plugin_dir_path( __FILE__ ) ); define( 'MARKDOWN_COMMENTS_PLUGIN_URL', plugin_dir_url( __FILE__ ) ); @@ -138,6 +138,59 @@ function markdown_comments_enqueue_scripts() { } add_action( 'wp_enqueue_scripts', 'markdown_comments_enqueue_scripts' ); +/** + * Process escaped characters in text + * + * @param string $text The text to process + * + * @since 1.0.0 + * @return string The text with escaped characters handled + */ +function markdown_comments_process_escapes( $text ) { + // Replace escaped markdown characters with placeholders + $escapes = [ + '\\\\' => '___ESCAPED_BACKSLASH___', + '\\*' => '___ESCAPED_ASTERISK___', + '\\_' => '___ESCAPED_UNDERSCORE___', + '\\`' => '___ESCAPED_BACKTICK___', + '\\[' => '___ESCAPED_BRACKET_OPEN___', + '\\]' => '___ESCAPED_BRACKET_CLOSE___', + '\\(' => '___ESCAPED_PAREN_OPEN___', + '\\)' => '___ESCAPED_PAREN_CLOSE___', + '\\#' => '___ESCAPED_HASH___', + '\\-' => '___ESCAPED_DASH___', + '\\+' => '___ESCAPED_PLUS___', + ]; + + return str_replace( array_keys( $escapes ), array_values( $escapes ), $text ); +} + +/** + * Restore escaped characters after processing + * + * @param string $text The text to restore + * + * @since 1.0.0 + * @return string The text with escaped characters restored + */ +function markdown_comments_restore_escapes( $text ) { + $restores = [ + '___ESCAPED_BACKSLASH___' => '\\', + '___ESCAPED_ASTERISK___' => '*', + '___ESCAPED_UNDERSCORE___' => '_', + '___ESCAPED_BACKTICK___' => '`', + '___ESCAPED_BRACKET_OPEN___' => '[', + '___ESCAPED_BRACKET_CLOSE___' => ']', + '___ESCAPED_PAREN_OPEN___' => '(', + '___ESCAPED_PAREN_CLOSE___' => ')', + '___ESCAPED_HASH___' => '#', + '___ESCAPED_DASH___' => '-', + '___ESCAPED_PLUS___' => '+', + ]; + + return str_replace( array_keys( $restores ), array_values( $restores ), $text ); +} + /** * Apply inline formatting (bold, italic, code, links) to text * @@ -147,6 +200,9 @@ function markdown_comments_enqueue_scripts() { * @return mixed The formatted text */ function markdown_comments_apply_inline_formatting( $text ) { + // Process line breaks (two spaces at end of line) + $text = preg_replace( '/ \n/', '
' . "\n", $text ); + // Bold **text** or __text__. $text = preg_replace_callback( '/\*\*(.*?)\*\*/', function($matches) { return '' . esc_html($matches[1]) . ''; @@ -187,6 +243,9 @@ function markdown_comments_apply_inline_formatting( $text ) { * @return string The parsed HTML */ function markdown_comments_parse_markdown( $text ) { + // Process escaped characters first + $text = markdown_comments_process_escapes( $text ); + // Split into lines for processing. $lines = explode( "\n", $text ); $output = []; @@ -194,6 +253,7 @@ function markdown_comments_parse_markdown( $text ) { $list_type = ''; foreach ( $lines as $line ) { + $original_line = $line; $line = trim( $line ); // Skip empty lines. @@ -251,12 +311,12 @@ function markdown_comments_parse_markdown( $text ) { continue; } - // Regular paragraph text - keep it raw for now. + // Regular paragraph text - preserve original line for line break detection if ( $in_list ) { $output[] = $list_type === 'ul' ? '' : ''; $in_list = false; } - $output[] = $line; // Keep raw text + $output[] = $original_line; // Keep original with trailing spaces } // Close any remaining list. @@ -270,13 +330,13 @@ function markdown_comments_parse_markdown( $text ) { $current_paragraph = []; foreach ( $lines as $line ) { - $line = trim( $line ); + $trimmed_line = trim( $line ); // If it's an empty line, finish current paragraph. - if ( empty( $line ) ) { + if ( empty( $trimmed_line ) ) { if ( ! empty( $current_paragraph ) ) { // Apply inline formatting and escaping to paragraph content - $paragraph_text = implode( ' ', $current_paragraph ); + $paragraph_text = implode( "\n", $current_paragraph ); $paragraph_text = markdown_comments_apply_inline_formatting( $paragraph_text ); $final_output[] = '

' . $paragraph_text . '

'; $current_paragraph = []; @@ -285,30 +345,33 @@ function markdown_comments_parse_markdown( $text ) { } // If it's a block element (heading, list), add it directly. - if ( preg_match( '/^<(h[1-6]|ul|ol|li)>/', $line ) || preg_match( '/^<\/(ul|ol)>/', $line ) ) { + if ( preg_match( '/^<(h[1-6]|ul|ol|li)>/', $trimmed_line ) || preg_match( '/^<\/(ul|ol)>/', $trimmed_line ) ) { // Finish any current paragraph first. if ( ! empty( $current_paragraph ) ) { - $paragraph_text = implode( ' ', $current_paragraph ); + $paragraph_text = implode( "\n", $current_paragraph ); $paragraph_text = markdown_comments_apply_inline_formatting( $paragraph_text ); $final_output[] = '

' . $paragraph_text . '

'; $current_paragraph = []; } // Block elements are already formatted, add them directly. - $final_output[] = $line; + $final_output[] = $trimmed_line; } else { - // It's regular text, add to current paragraph. + // It's regular text, add to current paragraph (preserve original spacing) $current_paragraph[] = $line; } } // Don't forget the last paragraph. if ( ! empty( $current_paragraph ) ) { - $paragraph_text = implode( ' ', $current_paragraph ); + $paragraph_text = implode( "\n", $current_paragraph ); $paragraph_text = markdown_comments_apply_inline_formatting( $paragraph_text ); $final_output[] = '

' . $paragraph_text . '

'; } - return implode( "\n", $final_output ); + $result = implode( "\n", $final_output ); + + // Restore escaped characters + return markdown_comments_restore_escapes( $result ); } /**