This repository has been archived on 2023-03-18. You can view files and clone it, but cannot push or open issues or pull requests.
osr-discourse-src/app/assets/javascripts/discourse/dialects/code_dialect.js
riking 32cc31319f FIX: Use lang- prefixes for HLJS; add nohighlight for ...
text; use a proper whiteListTag() call.

Old posts are not affected - no global rebake is necessary.
2014-10-05 14:58:47 -07:00

76 lines
2.4 KiB
JavaScript

/**
Support for various code blocks
**/
var acceptableCodeClasses =
["auto", "1c", "actionscript", "apache", "applescript", "avrasm", "axapta", "bash", "brainfuck",
"clojure", "cmake", "coffeescript", "cpp", "cs", "css", "d", "delphi", "diff", "xml", "django", "dos",
"erlang-repl", "erlang", "glsl", "go", "handlebars", "haskell", "http", "ini", "java", "javascript",
"json", "lisp", "lua", "markdown", "matlab", "mel", "nginx", "nohighlight", "objectivec", "parser3",
"perl", "php", "profile", "python", "r", "rib", "rsl", "ruby", "rust", "scala", "smalltalk", "sql",
"tex", "text", "vala", "vbscript", "vhdl"];
var textCodeClasses = ["text", "pre"];
function flattenBlocks(blocks) {
var result = "";
blocks.forEach(function(b) {
result += b;
if (b.trailing) { result += b.trailing; }
});
return result;
}
Discourse.Dialect.replaceBlock({
start: /^`{3}([^\n\[\]]+)?\n?([\s\S]*)?/gm,
stop: /^```$/gm,
emitter: function(blockContents, matches) {
var klass = Discourse.SiteSettings.default_code_lang;
if (matches[1] && acceptableCodeClasses.indexOf(matches[1]) !== -1) {
klass = matches[1];
}
if (textCodeClasses.indexOf(matches[1]) !== -1) {
return ['p', ['pre', ['code', {'class': 'lang-nohighlight'}, flattenBlocks(blockContents) ]]];
} else {
return ['p', ['pre', ['code', {'class': 'lang-' + klass}, flattenBlocks(blockContents) ]]];
}
}
});
// Ensure that content in a code block is fully escaped. This way it's not white listed
// and we can use HTML and Javascript examples.
Discourse.Dialect.on('parseNode', function (event) {
var node = event.node,
path = event.path;
if (node[0] === 'code') {
var contents = node[node.length-1],
regexp;
if (path && path[path.length-1] && path[path.length-1][0] && path[path.length-1][0] === "pre") {
regexp = / +$/g;
} else {
regexp = /^ +| +$/g;
}
node[node.length-1] = Handlebars.Utils.escapeExpression(contents.replace(regexp,''));
}
});
Discourse.Dialect.replaceBlock({
start: /(<pre[^\>]*\>)([\s\S]*)/igm,
stop: /<\/pre>/igm,
rawContents: true,
skipIfTradtionalLinebreaks: true,
emitter: function(blockContents) {
return ['p', ['pre', flattenBlocks(blockContents)]];
}
});
// Whitelist the language classes
var regexpSource = "^lang-(" + acceptableCodeClasses.join('|') + ")$";
Discourse.Markdown.whiteListTag('code', 'class', new RegExp(regexpSource, "i"));