From c6b92f0ef77f9ab8bbd94ca601af0b83fdf01434 Mon Sep 17 00:00:00 2001 From: Robin Ward Date: Mon, 9 Jun 2014 17:46:17 -0400 Subject: [PATCH] FIX: Support for nested bold/italics in MD --- .../discourse/dialects/bold_italics_dialect.js | 3 +++ .../javascripts/discourse/dialects/dialect.js | 17 +++++++++++++---- test/javascripts/lib/markdown_test.js | 1 + 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/discourse/dialects/bold_italics_dialect.js b/app/assets/javascripts/discourse/dialects/bold_italics_dialect.js index 3c35b3b777f..bef903c186e 100644 --- a/app/assets/javascripts/discourse/dialects/bold_italics_dialect.js +++ b/app/assets/javascripts/discourse/dialects/bold_italics_dialect.js @@ -7,12 +7,14 @@ Discourse.Dialect.inlineBetween({ between: '***', wordBoundary: true, + spaceBoundary: true, emitter: function(contents) { return ['strong', ['em'].concat(contents)]; } }); Discourse.Dialect.inlineBetween({ between: '___', wordBoundary: true, + spaceBoundary: true, emitter: function(contents) { return ['strong', ['em'].concat(contents)]; } }); @@ -21,6 +23,7 @@ var replaceMarkdown = function(match, tag) { Discourse.Dialect.inlineBetween({ between: match, wordBoundary: true, + spaceBoundary: true, emitter: function(contents) { return [tag].concat(contents) } }); }; diff --git a/app/assets/javascripts/discourse/dialects/dialect.js b/app/assets/javascripts/discourse/dialects/dialect.js index 381b3003022..cd86601b45c 100644 --- a/app/assets/javascripts/discourse/dialects/dialect.js +++ b/app/assets/javascripts/discourse/dialects/dialect.js @@ -118,7 +118,6 @@ function parseTree(tree, path, insideCounts) { @returns {Boolean} whether there is an invalid word boundary **/ function invalidBoundary(args, prev) { - if (!args.wordBoundary && !args.spaceBoundary) { return false; } var last = prev[prev.length - 1]; @@ -260,14 +259,14 @@ Discourse.Dialect = { inlineBetween: function(args) { var start = args.start || args.between, stop = args.stop || args.between, - startLength = start.length; + startLength = start.length, + self = this; this.registerInline(start, function(text, match, prev) { if (invalidBoundary(args, prev)) { return; } - var endPos = text.indexOf(stop, startLength); + var endPos = self.findEndPos(text, stop, args, startLength); if (endPos === -1) { return; } - var between = text.slice(startLength, endPos); // If rawcontents is set, don't process inline @@ -282,6 +281,16 @@ Discourse.Dialect = { }); }, + findEndPos: function(text, stop, args, start) { + var endPos = text.indexOf(stop, start); + if (endPos === -1) { return -1; } + var after = text.charAt(endPos + stop.length); + if (after && after.indexOf(stop) === 0) { + return this.findEndPos(text, stop, args, endPos + stop.length + 1); + } + return endPos; + }, + /** Registers a block for processing. This is more complicated than using one of the other helpers such as `replaceBlock` so consider using them first! diff --git a/test/javascripts/lib/markdown_test.js b/test/javascripts/lib/markdown_test.js index 9ca8307f85a..d375e256c59 100644 --- a/test/javascripts/lib/markdown_test.js +++ b/test/javascripts/lib/markdown_test.js @@ -19,6 +19,7 @@ test("basic cooking", function() { cooked("__bold__", "

bold

", "it bolds text."); cooked("*trout*", "

trout

", "it italicizes text."); cooked("_trout_", "

trout

", "it italicizes text."); + cooked("*this is italic **with some bold** inside*", "

this is italic with some bold inside

", "it handles nested bold in italics"); cooked("***hello***", "

hello

", "it can do bold and italics at once."); cooked("word_with_underscores", "

word_with_underscores

", "it doesn't do intraword italics"); cooked("common/_special_font_face.html.erb", "

common/_special_font_face.html.erb

", "it doesn't intraword with a slash");