FIX: Quoting within code blocks.

This commit is contained in:
Robin Ward 2013-08-29 14:42:31 -04:00
parent 1204eb62c3
commit c99cf64d70
5 changed files with 73 additions and 62 deletions

View File

@ -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 <br>. 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']);
}
}
});

View File

@ -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) {

View File

@ -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") ]]];

View File

@ -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 <br>. 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']);
}
}
});

View File

@ -247,6 +247,12 @@ test("Code Blocks", function() {
cooked("```ruby\nhello `eviltrout`\n```",
"<p><pre><code class=\"ruby\">hello &#x60;eviltrout&#x60;</code></pre></p>",
"it allows code with backticks in it");
cooked("```[quote=\"sam, post:1, topic:9441, full:true\"]This is `<not>` a bug.[/quote]```",
"<p><pre><code class=\"lang-auto\">[quote=&quot;sam, post:1, topic:9441, full:true&quot;]This is &#x60;&lt;not&gt;&#x60; a bug.[/quote]</code></pre></p>",
"it allows code with backticks in it");
});
test("SanitizeHTML", function() {