DEV: Add support for aliases in HighlightJS languages (#20380)

We were only supporting the main name of each HighlightJS language. So, by default, you could not use `js` or `jsx` to highlight Javascript, given they are aliases for `javascript`.

This PR adds a list of aliases as a constant to core (built via a rake task), and then checks against the `highlighted_languages` site settings plus the list of aliases when processing a code block.
This commit is contained in:
Penar Musaraj 2023-02-23 15:06:06 -05:00 committed by GitHub
parent 6108eee31d
commit c052df412a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 184 additions and 4 deletions

View File

@ -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```",
`<pre><code class=\"lang-js\">var foo ='foo';
var bar = 'bar';
</code></pre>`,
"code block with js alias works"
);
// "html" is an alias of "xml"
assert.cooked(
"```html\n<strong>fun</strong> times\n```",
`<pre><code class=\"lang-html\">&lt;strong&gt;fun&lt;/strong&gt; times
</code></pre>`,
"code block with html alias work"
);
});
});

View File

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

View File

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

View File

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