From c99cf64d70a19e39382b9e634372afb155636d08 Mon Sep 17 00:00:00 2001 From: Robin Ward Date: Thu, 29 Aug 2013 14:42:31 -0400 Subject: [PATCH] FIX: Quoting within code blocks. --- .../discourse/dialects/bbcode_dialect.js | 60 ------------------ .../javascripts/discourse/dialects/dialect.js | 5 +- .../discourse/dialects/github_code_dialect.js | 2 +- .../discourse/dialects/quote_dialect.js | 62 +++++++++++++++++++ test/javascripts/components/markdown_test.js | 6 ++ 5 files changed, 73 insertions(+), 62 deletions(-) create mode 100644 app/assets/javascripts/discourse/dialects/quote_dialect.js diff --git a/app/assets/javascripts/discourse/dialects/bbcode_dialect.js b/app/assets/javascripts/discourse/dialects/bbcode_dialect.js index 90c528bf8fd..9216deada47 100644 --- a/app/assets/javascripts/discourse/dialects/bbcode_dialect.js +++ b/app/assets/javascripts/discourse/dialects/bbcode_dialect.js @@ -112,63 +112,3 @@ Discourse.Dialect.replaceBlock({ } }); -// Support BBCode [quote] blocks -Discourse.Dialect.replaceBlock({ - start: new RegExp("\\[quote=?([^\\[\\]]+)?\\]([\\s\\S]*)", "igm"), - stop: '[/quote]', - emitter: function(blockContents, matches, options) { - - var paramsString = matches[1].replace(/\"/g, ''), - params = {'class': 'quote'}, - paramsSplit = paramsString.split(/\, */), - username = paramsSplit[0]; - - paramsSplit.forEach(function(p,i) { - if (i > 0) { - var assignment = p.split(':'); - if (assignment[0] && assignment[1]) { - params['data-' + assignment[0]] = assignment[1].trim(); - } - } - }); - - var avatarImg; - if (options.lookupAvatarByPostNumber) { - // client-side, we can retrieve the avatar from the post - var postNumber = parseInt(params['data-post'], 10); - avatarImg = options.lookupAvatarByPostNumber(postNumber); - } else if (options.lookupAvatar) { - // server-side, we need to lookup the avatar from the username - avatarImg = options.lookupAvatar(username); - } - - var contents = this.processInline(blockContents.join(" \n \n")); - contents.unshift('blockquote'); - - return ['p', ['aside', params, - ['div', {'class': 'title'}, - ['div', {'class': 'quote-controls'}], - avatarImg ? avatarImg : "", - I18n.t('user.said', {username: username}) - ], - contents - ]]; - } -}); - -Discourse.Dialect.on("parseNode", function(event) { - var node = event.node, - path = event.path; - - // Make sure any quotes are followed by a
. The formatting looks weird otherwise. - if (node[0] === 'aside' && node[1] && node[1]['class'] === 'quote') { - var parent = path[path.length - 1], - location = parent.indexOf(node)+1, - trailing = parent.slice(location); - - if (trailing.length) { - parent.splice(location, 0, ['br']); - } - } - -}); diff --git a/app/assets/javascripts/discourse/dialects/dialect.js b/app/assets/javascripts/discourse/dialects/dialect.js index bac59993b0d..302597b66f2 100644 --- a/app/assets/javascripts/discourse/dialects/dialect.js +++ b/app/assets/javascripts/discourse/dialects/dialect.js @@ -255,7 +255,10 @@ Discourse.Dialect = { result.push(para); } - if (m[2]) { next.unshift(MD.mk_block(m[2], null, lineNumber + 1)); } + + if (m[2]) { + next.unshift(MD.mk_block(m[2], null, lineNumber + 1)); + } lineNumber++; while (next.length > 0) { diff --git a/app/assets/javascripts/discourse/dialects/github_code_dialect.js b/app/assets/javascripts/discourse/dialects/github_code_dialect.js index 1d70d4551c1..f24efb0ddb6 100644 --- a/app/assets/javascripts/discourse/dialects/github_code_dialect.js +++ b/app/assets/javascripts/discourse/dialects/github_code_dialect.js @@ -6,7 +6,7 @@ @namespace Discourse.Dialect **/ Discourse.Dialect.replaceBlock({ - start: /^`{3}([^\n]+)?\n?([\s\S]*)?/gm, + start: /^`{3}([^\n\[\]]+)?\n?([\s\S]*)?/gm, stop: '```', emitter: function(blockContents, matches) { return ['p', ['pre', ['code', {'class': matches[1] || 'lang-auto'}, blockContents.join("\n") ]]]; diff --git a/app/assets/javascripts/discourse/dialects/quote_dialect.js b/app/assets/javascripts/discourse/dialects/quote_dialect.js new file mode 100644 index 00000000000..7bece862c04 --- /dev/null +++ b/app/assets/javascripts/discourse/dialects/quote_dialect.js @@ -0,0 +1,62 @@ +/** + Support for quoting other users. +**/ +Discourse.Dialect.replaceBlock({ + start: new RegExp("\\[quote=?([^\\[\\]]+)?\\]([\\s\\S]*)", "igm"), + stop: '[/quote]', + emitter: function(blockContents, matches, options) { + + var paramsString = matches[1].replace(/\"/g, ''), + params = {'class': 'quote'}, + paramsSplit = paramsString.split(/\, */), + username = paramsSplit[0]; + + paramsSplit.forEach(function(p,i) { + if (i > 0) { + var assignment = p.split(':'); + if (assignment[0] && assignment[1]) { + params['data-' + assignment[0]] = assignment[1].trim(); + } + } + }); + + var avatarImg; + if (options.lookupAvatarByPostNumber) { + // client-side, we can retrieve the avatar from the post + var postNumber = parseInt(params['data-post'], 10); + avatarImg = options.lookupAvatarByPostNumber(postNumber); + } else if (options.lookupAvatar) { + // server-side, we need to lookup the avatar from the username + avatarImg = options.lookupAvatar(username); + } + + var contents = this.processInline(blockContents.join(" \n \n")); + contents.unshift('blockquote'); + + return ['p', ['aside', params, + ['div', {'class': 'title'}, + ['div', {'class': 'quote-controls'}], + avatarImg ? avatarImg : "", + I18n.t('user.said', {username: username}) + ], + contents + ]]; + } +}); + +Discourse.Dialect.on("parseNode", function(event) { + var node = event.node, + path = event.path; + + // Make sure any quotes are followed by a
. The formatting looks weird otherwise. + if (node[0] === 'aside' && node[1] && node[1]['class'] === 'quote') { + var parent = path[path.length - 1], + location = parent.indexOf(node)+1, + trailing = parent.slice(location); + + if (trailing.length) { + parent.splice(location, 0, ['br']); + } + } + +}); \ No newline at end of file diff --git a/test/javascripts/components/markdown_test.js b/test/javascripts/components/markdown_test.js index 118164da528..19ecf7f3655 100644 --- a/test/javascripts/components/markdown_test.js +++ b/test/javascripts/components/markdown_test.js @@ -247,6 +247,12 @@ test("Code Blocks", function() { cooked("```ruby\nhello `eviltrout`\n```", "

hello `eviltrout`

", "it allows code with backticks in it"); + + + cooked("```[quote=\"sam, post:1, topic:9441, full:true\"]This is `` a bug.[/quote]```", + "

[quote="sam, post:1, topic:9441, full:true"]This is `<not>` a bug.[/quote]

", + "it allows code with backticks in it"); + }); test("SanitizeHTML", function() {