diff --git a/app/assets/javascripts/discourse/tests/unit/lib/pretty-text-test.js b/app/assets/javascripts/discourse/tests/unit/lib/pretty-text-test.js index c633c568bb6..085a971f700 100644 --- a/app/assets/javascripts/discourse/tests/unit/lib/pretty-text-test.js +++ b/app/assets/javascripts/discourse/tests/unit/lib/pretty-text-test.js @@ -18,7 +18,7 @@ const rawOpts = { enable_mentions: true, emoji_set: "twitter", external_emoji_url: "", - highlighted_languages: "json|ruby|javascript", + highlighted_languages: "json|ruby|javascript|xml", default_code_lang: "auto", enable_markdown_linkify: true, markdown_linkify_tlds: "com", @@ -1776,4 +1776,23 @@ var bar = 'bar'; "does not loop infinitely" ); }); + + test("highlighted aliased languages", function (assert) { + // "js" is an alias of "javascript" + assert.cooked( + "```js\nvar foo ='foo';\nvar bar = 'bar';\n```", + `
var foo ='foo';
+var bar = 'bar';
+
`,
+ "code block with js alias works"
+ );
+
+ // "html" is an alias of "xml"
+ assert.cooked(
+ "```html\nfun times\n```",
+ `<strong>fun</strong> times
+
`,
+ "code block with html alias work"
+ );
+ });
});
diff --git a/app/assets/javascripts/pretty-text/addon/highlightjs-aliases.js b/app/assets/javascripts/pretty-text/addon/highlightjs-aliases.js
new file mode 100644
index 00000000000..9a9f27b3ea5
--- /dev/null
+++ b/app/assets/javascripts/pretty-text/addon/highlightjs-aliases.js
@@ -0,0 +1,123 @@
+// DO NOT EDIT THIS FILE!!!
+// Update it by running `rake javascript:update_constants`
+
+export const HLJS_ALIASES = {
+ bash: ["sh"],
+ c: ["h"],
+ cpp: ["cc", "c++", "h++", "hpp", "hh", "hxx", "cxx"],
+ csharp: ["cs", "c#"],
+ diff: ["patch"],
+ go: ["golang"],
+ graphql: ["gql"],
+ ini: ["toml"],
+ java: ["jsp"],
+ javascript: ["js", "jsx", "mjs", "cjs"],
+ kotlin: ["kt", "kts"],
+ makefile: ["mk", "mak", "make"],
+ xml: [
+ "html",
+ "xhtml",
+ "rss",
+ "atom",
+ "xjb",
+ "xsd",
+ "xsl",
+ "plist",
+ "wsf",
+ "svg",
+ ],
+ markdown: ["md", "mkdown", "mkd"],
+ objectivec: ["mm", "objc", "obj-c", "obj-c++", "objective-c++"],
+ perl: ["pl", "pm"],
+ plaintext: ["text", "txt"],
+ python: ["py", "gyp", "ipython"],
+ "python-repl": ["pycon"],
+ ruby: ["rb", "gemspec", "podspec", "thor", "irb"],
+ rust: ["rs"],
+ shell: ["console", "shellsession"],
+ typescript: ["ts", "tsx"],
+ vbnet: ["vb"],
+ yaml: ["yml"],
+ actionscript: ["as"],
+ angelscript: ["asc"],
+ apache: ["apacheconf"],
+ applescript: ["osascript"],
+ arduino: ["ino"],
+ armasm: ["arm"],
+ asciidoc: ["adoc"],
+ autohotkey: ["ahk"],
+ axapta: ["x++"],
+ brainfuck: ["bf"],
+ "c-like": [],
+ capnproto: ["capnp"],
+ clean: ["icl", "dcl"],
+ clojure: ["clj", "edn"],
+ cmake: ["cmake.in"],
+ coffeescript: ["coffee", "cson", "iced"],
+ cos: ["cls"],
+ crmsh: ["crm", "pcmk"],
+ crystal: ["cr"],
+ delphi: ["dpr", "dfm", "pas", "pascal"],
+ django: ["jinja"],
+ dns: ["bind", "zone"],
+ dockerfile: ["docker"],
+ dos: ["bat", "cmd"],
+ dust: ["dst"],
+ elixir: ["ex", "exs"],
+ erlang: ["erl"],
+ excel: ["xlsx", "xls"],
+ fortran: ["f90", "f95"],
+ fsharp: ["fs", "f#"],
+ gams: ["gms"],
+ gauss: ["gss"],
+ gcode: ["nc"],
+ gherkin: ["feature"],
+ handlebars: ["hbs", "html.hbs", "html.handlebars", "htmlbars"],
+ haskell: ["hs"],
+ haxe: ["hx"],
+ htmlbars: ["hbs", "html.hbs", "html.handlebars", "htmlbars"],
+ http: ["https"],
+ hy: ["hylang"],
+ inform7: ["i7"],
+ "jboss-cli": ["wildfly-cli"],
+ "julia-repl": ["jldoctest"],
+ lasso: ["ls", "lassoscript"],
+ latex: ["tex"],
+ livescript: ["ls"],
+ mathematica: ["mma", "wl"],
+ mercury: ["m", "moo"],
+ mipsasm: ["mips"],
+ moonscript: ["moon"],
+ nestedtext: ["nt"],
+ nginx: ["nginxconf"],
+ nimrod: ["nim"],
+ nix: ["nixos"],
+ ocaml: ["ml"],
+ openscad: ["scad"],
+ pf: ["pf.conf"],
+ pgsql: ["postgres", "postgresql"],
+ powershell: ["pwsh", "ps", "ps1"],
+ processing: ["pde"],
+ puppet: ["pp"],
+ purebasic: ["pb", "pbi"],
+ q: ["k", "kdb"],
+ qml: ["qt"],
+ reasonml: ["re"],
+ roboconf: ["graph", "instances"],
+ routeros: ["mikrotik"],
+ scilab: ["sci"],
+ smalltalk: ["st"],
+ sml: ["ml"],
+ sql_more: ["mysql", "oracle"],
+ stan: ["stanfuncs"],
+ stata: ["do", "ado"],
+ step21: ["p21", "step", "stp"],
+ stylus: ["styl"],
+ tcl: ["tk"],
+ twig: ["craftcms"],
+ vbscript: ["vbs"],
+ verilog: ["v", "sv", "svh"],
+ xl: ["tao"],
+ xquery: ["xpath", "xq"],
+ zephir: ["zep"],
+};
diff --git a/app/assets/javascripts/pretty-text/engines/discourse-markdown/code.js b/app/assets/javascripts/pretty-text/engines/discourse-markdown/code.js
index fa935ea7682..b79450cc668 100644
--- a/app/assets/javascripts/pretty-text/engines/discourse-markdown/code.js
+++ b/app/assets/javascripts/pretty-text/engines/discourse-markdown/code.js
@@ -1,3 +1,5 @@
+import { HLJS_ALIASES } from "pretty-text/highlightjs-aliases";
+
// we need a custom renderer for code blocks cause we have a slightly non compliant
// format with special handling for text and so on
const TEXT_CODE_CLASSES = ["text", "pre", "plain"];
@@ -77,10 +79,20 @@ function render(tokens, idx, options, env, slf, md) {
export function setup(helper) {
helper.registerOptions((opts, siteSettings) => {
- opts.defaultCodeLang = siteSettings.default_code_lang;
- opts.acceptableCodeClasses = (siteSettings.highlighted_languages || "")
+ let languageAliases = [];
+ const languages = (siteSettings.highlighted_languages || "")
.split("|")
- .filter(Boolean)
+ .filter(Boolean);
+
+ languages.forEach((lang) => {
+ if (HLJS_ALIASES[lang]) {
+ languageAliases = languageAliases.concat(HLJS_ALIASES[lang]);
+ }
+ });
+
+ opts.defaultCodeLang = siteSettings.default_code_lang;
+ opts.acceptableCodeClasses = languages
+ .concat(languageAliases)
.concat(["auto", "plaintext"]);
});
diff --git a/lib/tasks/javascript.rake b/lib/tasks/javascript.rake
index cd699034ed6..eb544934d67 100644
--- a/lib/tasks/javascript.rake
+++ b/lib/tasks/javascript.rake
@@ -182,6 +182,32 @@ task "javascript:update_constants" => :environment do
export const replacements = #{Emoji.unicode_replacements_json};
JS
+ langs = []
+ Dir
+ .glob("vendor/assets/javascripts/highlightjs/languages/*.min.js")
+ .each { |f| langs << File.basename(f, ".min.js") }
+ bundle = HighlightJs.bundle(langs)
+
+ ctx = MiniRacer::Context.new
+ hljs_aliases = ctx.eval(<<~JS)
+ #{bundle}
+
+ let aliases = {};
+ hljs.listLanguages().forEach((lang) => {
+ if (hljs.getLanguage(lang).aliases) {
+ aliases[lang] = hljs.getLanguage(lang).aliases;
+ }
+ });
+
+ aliases;
+ JS
+
+ write_template("pretty-text/addon/highlightjs-aliases.js", task_name, <<~JS)
+ export const HLJS_ALIASES = #{hljs_aliases.to_json};
+ JS
+
+ ctx.dispose
+
write_template("pretty-text/addon/emoji/version.js", task_name, <<~JS)
export const IMAGE_VERSION = "#{Emoji::EMOJI_VERSION}";
JS