From 257cfee803426333af25b68da17601aec2663172 Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Tue, 19 Oct 2021 17:09:56 -0400 Subject: [PATCH 01/76] tests(python) Add coverage for digitpart-based imaginary literals (#3366) 009j is a valid literal even though 009 is not. Ref: 21b146644e15ba2b101341da0d3e4dc61db53056 --- test/markup/python/numbers.expect.txt | 4 ++-- test/markup/python/numbers.txt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/markup/python/numbers.expect.txt b/test/markup/python/numbers.expect.txt index 004a36eb08..aed662eaec 100644 --- a/test/markup/python/numbers.expect.txt +++ b/test/markup/python/numbers.expect.txt @@ -24,8 +24,8 @@ .0e10J, .00e+10j, .9e-10J, 4.2E10j, 40.0E+08J, 0.E-10j, 00.e100J, 0010e+10j .0e1_0J, .0_0e+10j, .9e-1_0J, 4.2E1_0j, 4_0.0E+0_8J, 0.E-1_0j, 0_0.e1_0_0J, 00_10e+10j -0j, 00J, 000j, 1234J -0j, 0_0J, 0_0_0j, 12_3_4J +0j, 00J, 000j, 009J, 1234j +0j, 0_0J, 0_0_0j, 0_0_9J, 12_3_4j # expressions containing numeric literals diff --git a/test/markup/python/numbers.txt b/test/markup/python/numbers.txt index a0aeb7dc50..8933000a0f 100644 --- a/test/markup/python/numbers.txt +++ b/test/markup/python/numbers.txt @@ -24,8 +24,8 @@ .0e10J, .00e+10j, .9e-10J, 4.2E10j, 40.0E+08J, 0.E-10j, 00.e100J, 0010e+10j .0e1_0J, .0_0e+10j, .9e-1_0J, 4.2E1_0j, 4_0.0E+0_8J, 0.E-1_0j, 0_0.e1_0_0J, 00_10e+10j -0j, 00J, 000j, 1234J -0j, 0_0J, 0_0_0j, 12_3_4J +0j, 00J, 000j, 009J, 1234j +0j, 0_0J, 0_0_0j, 0_0_9J, 12_3_4j # expressions containing numeric literals From 70286584d2abfafafdfa6a9f462dfd4fed856fd8 Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Fri, 22 Oct 2021 09:08:08 -0400 Subject: [PATCH 02/76] fix(python) Fix recognition of numeric literals followed by keywords without whitespace (#3367) Fixes #2985. * enh(python) Add tests for keyword after numeric literal * fix(python) Fix recognition of numeric literals followed by keywords without whitespace --- CHANGES.md | 8 ++++++++ src/languages/python.js | 18 ++++++++++++------ test/markup/python/keywords.expect.txt | 3 +-- test/markup/python/keywords.txt | 1 - test/markup/python/numbers.expect.txt | 18 ++++++++++++++++++ test/markup/python/numbers.txt | 18 ++++++++++++++++++ 6 files changed, 57 insertions(+), 9 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index da390042c7..ef24a6123c 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,11 @@ +## Version 11.3.2 (most likely) + +Grammars: + +- fix(python) Fix recognition of numeric literals followed by keywords without whitespace (#2985) [Richard Gibson][] + +[Richard Gibson]: https://github.com/gibson042 + ## Version 11.3.1 Build: diff --git a/src/languages/python.js b/src/languages/python.js index ce603a86d4..46ed88a6f0 100644 --- a/src/languages/python.js +++ b/src/languages/python.js @@ -255,6 +255,12 @@ export default function(hljs) { // https://docs.python.org/3.9/reference/lexical_analysis.html#numeric-literals const digitpart = '[0-9](_?[0-9])*'; const pointfloat = `(\\b(${digitpart}))?\\.(${digitpart})|\\b(${digitpart})\\.`; + // Whitespace after a number (or any lexical token) is needed only if its absence + // would change the tokenization + // https://docs.python.org/3.9/reference/lexical_analysis.html#whitespace-between-tokens + // We deviate slightly, requiring a word boundary or a keyword + // to avoid accidentally recognizing *prefixes* (e.g., `0` in `0x41` or `08` or `0__1`) + const lookahead = `\\b|${RESERVED_WORDS.join('|')}`; const NUMBER = { className: 'number', relevance: 0, @@ -270,7 +276,7 @@ export default function(hljs) { // because both MUST contain a decimal point and so cannot be confused with // the interior part of an identifier { - begin: `(\\b(${digitpart})|(${pointfloat}))[eE][+-]?(${digitpart})[jJ]?\\b` + begin: `(\\b(${digitpart})|(${pointfloat}))[eE][+-]?(${digitpart})[jJ]?(?=${lookahead})` }, { begin: `(${pointfloat})[jJ]?` @@ -283,22 +289,22 @@ export default function(hljs) { // decinteger is optionally imaginary // https://docs.python.org/3.9/reference/lexical_analysis.html#imaginary-literals { - begin: '\\b([1-9](_?[0-9])*|0+(_?0)*)[lLjJ]?\\b' + begin: `\\b([1-9](_?[0-9])*|0+(_?0)*)[lLjJ]?(?=${lookahead})` }, { - begin: '\\b0[bB](_?[01])+[lL]?\\b' + begin: `\\b0[bB](_?[01])+[lL]?(?=${lookahead})` }, { - begin: '\\b0[oO](_?[0-7])+[lL]?\\b' + begin: `\\b0[oO](_?[0-7])+[lL]?(?=${lookahead})` }, { - begin: '\\b0[xX](_?[0-9a-fA-F])+[lL]?\\b' + begin: `\\b0[xX](_?[0-9a-fA-F])+[lL]?(?=${lookahead})` }, // imagnumber (digitpart-based) // https://docs.python.org/3.9/reference/lexical_analysis.html#imaginary-literals { - begin: `\\b(${digitpart})[jJ]\\b` + begin: `\\b(${digitpart})[jJ](?=${lookahead})` } ] }; diff --git a/test/markup/python/keywords.expect.txt b/test/markup/python/keywords.expect.txt index 501f670464..f2227af2f5 100644 --- a/test/markup/python/keywords.expect.txt +++ b/test/markup/python/keywords.expect.txt @@ -13,5 +13,4 @@ x = Shorty() exec(123) -# note, numbers still aren't highlighted fully -print(1if 0==0else"b") +print(1if 0==0else"b") diff --git a/test/markup/python/keywords.txt b/test/markup/python/keywords.txt index 0b7835526d..30e3d0a180 100644 --- a/test/markup/python/keywords.txt +++ b/test/markup/python/keywords.txt @@ -13,5 +13,4 @@ for _ in sys.path: exec(123) -# note, numbers still aren't highlighted fully print(1if 0==0else"b") diff --git a/test/markup/python/numbers.expect.txt b/test/markup/python/numbers.expect.txt index aed662eaec..725eb354f7 100644 --- a/test/markup/python/numbers.expect.txt +++ b/test/markup/python/numbers.expect.txt @@ -30,6 +30,24 @@ # expressions containing numeric literals 0..__str__, 1e1.__str__, fn(.5) +0is 0, 0lis 0 +0_0_0is 0, 0_0_0lis 0 +0b0is 0, 0b0lis 0 +0b_0_0is 0, 0b_0_0lis 0 +0o0is 0, 0o0lis 0 +0o_0_0is 0, 0o_0_0lis 0 +0x0ais 0, 0x0elis 0 +0x_0_0is 0, 0x_0_0lis 0 +.0is 0, 0.is 0 +.0_0_0is 0, 0_0_0.is 0 +.0e+0is 0, 0.e-0is 0 +.0_0_0e-0_0_0is 0, 0_0_0.e+0_0_0is 0 +.0jis 0, 0.jis 0 +.0_0_0jis 0, 0_0_0.jis 0 +.0e+0jis 0, 0.e-0jis 0 +.0_0_0e-0_0_0jis 0, 0_0_0.e+0_0_0jis 0 +0jis 0, 009jis 0 +0_0_0jis 0, 0_0_9jis 0 # expressions not containing numeric literals x0.j diff --git a/test/markup/python/numbers.txt b/test/markup/python/numbers.txt index 8933000a0f..0511ce4337 100644 --- a/test/markup/python/numbers.txt +++ b/test/markup/python/numbers.txt @@ -30,6 +30,24 @@ # expressions containing numeric literals 0..__str__, 1e1.__str__, fn(.5) +0is 0, 0lis 0 +0_0_0is 0, 0_0_0lis 0 +0b0is 0, 0b0lis 0 +0b_0_0is 0, 0b_0_0lis 0 +0o0is 0, 0o0lis 0 +0o_0_0is 0, 0o_0_0lis 0 +0x0ais 0, 0x0elis 0 +0x_0_0is 0, 0x_0_0lis 0 +.0is 0, 0.is 0 +.0_0_0is 0, 0_0_0.is 0 +.0e+0is 0, 0.e-0is 0 +.0_0_0e-0_0_0is 0, 0_0_0.e+0_0_0is 0 +.0jis 0, 0.jis 0 +.0_0_0jis 0, 0_0_0.jis 0 +.0e+0jis 0, 0.e-0jis 0 +.0_0_0e-0_0_0jis 0, 0_0_0.e+0_0_0jis 0 +0jis 0, 009jis 0 +0_0_0jis 0, 0_0_9jis 0 # expressions not containing numeric literals x0.j From 2ccec7e16c178a6d4d601929a8d3e4ca6791348c Mon Sep 17 00:00:00 2001 From: jaacko-torus Date: Tue, 26 Oct 2021 16:49:21 -0500 Subject: [PATCH 03/76] (chore) `hljs.regex` helpers are missing from type refs (#3369) --- src/lib/regex.js | 2 +- types/index.d.ts | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/lib/regex.js b/src/lib/regex.js index b914fb4c5f..ec5c6bb87f 100644 --- a/src/lib/regex.js +++ b/src/lib/regex.js @@ -69,7 +69,7 @@ function stripOptionsFromArgs(args) { * Any of the passed expresssions may match * * Creates a huge this | this | that | that match - * @param {(RegExp | string)[] } args + * @param {(RegExp | string | { capture?: boolean })[]} args * @returns {string} */ export function either(...args) { diff --git a/types/index.d.ts b/types/index.d.ts index dae5dff32e..b89fffd52b 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -44,6 +44,13 @@ declare module 'highlight.js' { safeMode: () => void versionString: string vuePlugin: () => VuePlugin + regex: { + concat: (...args: (RegExp | string)[]) => string, + lookahead: (re: RegExp | string) => string, + either: (...args: (RegExp | string | { capture?: boolean })[]) => string, + optional: (re: RegExp | string) => string, + anyNumberOfTimes: (re: RegExp | string) => string + } } interface ModesAPI { From cd1c9dcf109b5d43bb1b7e46e312041fbe4805d2 Mon Sep 17 00:00:00 2001 From: Jan Pilzer Date: Sun, 31 Oct 2021 17:37:00 -0700 Subject: [PATCH 04/76] (chore) apply lint to our tooling scripts also (#3380) --- .eslintrc.js | 7 ++-- package.json | 2 +- tools/build.js | 6 +-- tools/build_browser.js | 32 ++++++++-------- tools/build_cdn.js | 4 +- tools/build_node.js | 27 ++++++------- tools/checkAutoDetect.js | 38 +++++++++---------- tools/checkTheme.js | 9 ++--- tools/lib/bundling.js | 4 +- tools/lib/dependencies.js | 55 +++++++++++++-------------- tools/lib/language.js | 79 ++++++++++++++++++--------------------- tools/lib/makestuff.js | 2 +- tools/perf.js | 8 ++-- 13 files changed, 130 insertions(+), 143 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 1d36330ef0..61ad70d2e8 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -28,9 +28,10 @@ module.exports = { // for now ignore diff between types of quoting quotes: "off", // this is the style we are already using - "operator-linebreak": ["error", "before", { overrides: { - "=": "after" - } + "operator-linebreak": ["error", "before", { + overrides: { + "=": "after" + } }], // sometimes we declare variables with extra spacing indent: ["error", 2, { VariableDeclarator: 2 }], diff --git a/package.json b/package.json index 6f88716be7..a6376bd740 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "types": "./types/index.d.ts", "scripts": { "mocha": "mocha", - "lint": "eslint src/*.js src/lib/*.js demo/*.js", + "lint": "eslint src/*.js src/lib/*.js demo/*.js tools/**/*.js --ignore-pattern vendor", "lint-languages": "eslint --no-eslintrc -c .eslintrc.lang.js src/languages/**/*.js", "build_and_test": "npm run build && npm run test", "build_and_test_browser": "npm run build-browser && npm run test-browser", diff --git a/tools/build.js b/tools/build.js index 0bf5082685..903976d5c2 100755 --- a/tools/build.js +++ b/tools/build.js @@ -62,7 +62,7 @@ const commander = require('commander'); const path = require('path'); -const { clean } = require("./lib/makestuff"); +const { clean } = require("./lib/makestuff.js"); const log = (...args) => console.log(...args); const TARGETS = ["cdn", "browser", "node"]; @@ -73,8 +73,8 @@ commander .option('-n, --no-minify', 'Disable minification') .option('-ne, --no-esm', 'Disable building ESM') .option('-t, --target ', - 'Build for target ' + - '[all, browser, cdn, node]', + 'Build for target ' + + '[all, browser, cdn, node]', 'browser') .parse(process.argv); diff --git a/tools/build_browser.js b/tools/build_browser.js index 48c0f465b6..24ad4fbed8 100644 --- a/tools/build_browser.js +++ b/tools/build_browser.js @@ -6,10 +6,10 @@ const path = require("path"); const zlib = require('zlib'); const Terser = require("terser"); const child_process = require('child_process'); -const { getLanguages } = require("./lib/language"); -const { filter } = require("./lib/dependencies"); -const config = require("./build_config"); -const { install, installCleanCSS, mkdir, renderTemplate } = require("./lib/makestuff"); +const { getLanguages } = require("./lib/language.js"); +const { filter } = require("./lib/dependencies.js"); +const config = require("./build_config.js"); +const { install, installCleanCSS, mkdir, renderTemplate } = require("./lib/makestuff.js"); const log = (...args) => console.log(...args); const { rollupCode } = require("./lib/bundling.js"); const bundling = require('./lib/bundling.js'); @@ -17,16 +17,16 @@ const Table = require('cli-table'); const getDefaultHeader = () => ({ ...require('../package.json'), - git_sha : child_process + git_sha: child_process .execSync("git rev-parse --short=10 HEAD") - .toString().trim(), + .toString().trim() }); function buildHeader(args = getDefaultHeader()) { - return "/*!\n" + - ` Highlight.js v${args.version} (git: ${args.git_sha})\n` + - ` (c) ${config.copyrightYears} ${args.author.name} and other contributors\n` + - ` License: ${args.license}\n` + - ` */`; + return "/*!\n" + + ` Highlight.js v${args.version} (git: ${args.git_sha})\n` + + ` (c) ${config.copyrightYears} ${args.author.name} and other contributors\n` + + ` License: ${args.license}\n` + + ` */`; } function sortByKey(array, key) { @@ -41,9 +41,9 @@ function detailedGrammarSizes(languages) { if (languages.length > 180) return; const resultTable = new Table({ - head: ['lang','minified'], + head: ['lang', 'minified'], // colWidths: [20,20,10,20,10,20], - chars: {'mid': '', 'left-mid': '', 'mid-mid': '', 'right-mid': ''}, + chars: { mid: '', 'left-mid': '', 'mid-mid': '', 'right-mid': '' }, style: { head: ['grey'] } @@ -230,19 +230,19 @@ async function buildCore(name, languages, options) { const sizeInfo = { shas: [] }; const writePromises = []; if (options.minify) { - const { code } = await Terser.minify(index, {...config.terser, module: (options.format === "es") }); + const { code } = await Terser.minify(index, { ...config.terser, module: (options.format === "es") }); const src = `${header}\n${code}`; writePromises.push(fs.writeFile(output.file.replace(/js$/, "min.js"), src)); sizeInfo.minified = src.length; sizeInfo.minifiedSrc = src; - sizeInfo.shas[`${relativePath}${name}.min.js`] = bundling.sha384(src) + sizeInfo.shas[`${relativePath}${name}.min.js`] = bundling.sha384(src); } { const src = `${header}\n${index}`; writePromises.push(fs.writeFile(output.file, src)); sizeInfo.fullSize = src.length; sizeInfo.fullSrc = src; - sizeInfo.shas[`${relativePath}${name}.js`] = bundling.sha384(src) + sizeInfo.shas[`${relativePath}${name}.js`] = bundling.sha384(src); } await Promise.all(writePromises); return sizeInfo; diff --git a/tools/build_cdn.js b/tools/build_cdn.js index 9cc3463ea2..5ca6dc927b 100644 --- a/tools/build_cdn.js +++ b/tools/build_cdn.js @@ -57,7 +57,7 @@ async function buildCDN(options) { if (options.esm) { mkdir("es"); await fs.writeFile(`${process.env.BUILD_DIR}/es/package.json`, `{ "type": "module" }`); - esmCoreSize = await buildCore("core", [], {minify: options.minify, format: "es"}); + esmCoreSize = await buildCore("core", [], { minify: options.minify, format: "es" }); esmCommonSize = await buildCore("highlight", embedLanguages, { minify: options.minify, format: "es" }); } shas = { @@ -157,7 +157,7 @@ async function buildDistributable(language, options) { await fs.mkdir(distDir, { recursive: true }); await fs.writeFile(path.join(language.moduleDir, "dist", filename), language.minified); if (options.esm) { - await fs.writeFile(path.join(language.moduleDir, "dist", filename.replace(".min.js",".es.min.js")), language.minifiedESM); + await fs.writeFile(path.join(language.moduleDir, "dist", filename.replace(".min.js", ".es.min.js")), language.minifiedESM); } } diff --git a/tools/build_node.js b/tools/build_node.js index 9dcc8579b5..d22c2b4e05 100644 --- a/tools/build_node.js +++ b/tools/build_node.js @@ -1,29 +1,29 @@ const fs = require("fs").promises; const fss = require("fs"); -const config = require("./build_config"); +const config = require("./build_config.js"); const glob = require("glob-promise"); -const { getLanguages } = require("./lib/language"); -const { install, mkdir, installCleanCSS } = require("./lib/makestuff"); -const { filter } = require("./lib/dependencies"); +const { getLanguages } = require("./lib/language.js"); +const { install, mkdir, installCleanCSS } = require("./lib/makestuff.js"); +const { filter } = require("./lib/dependencies.js"); const { rollupWrite } = require("./lib/bundling.js"); const log = (...args) => console.log(...args); // https://nodejs.org/api/packages.html#packages_writing_dual_packages_while_avoiding_or_minimizing_hazards async function buildESMStub(name) { const code = - `// https://nodejs.org/api/packages.html#packages_writing_dual_packages_while_avoiding_or_minimizing_hazards\n` + - `import HighlightJS from '../lib/${name}.js';\n` + - `export { HighlightJS };\n` + - `export default HighlightJS;\n`; + `// https://nodejs.org/api/packages.html#packages_writing_dual_packages_while_avoiding_or_minimizing_hazards\n` + + `import HighlightJS from '../lib/${name}.js';\n` + + `export { HighlightJS };\n` + + `export default HighlightJS;\n`; await fs.writeFile(`${process.env.BUILD_DIR}/es/${name}.js`, code); } async function buildCJSIndex(name, languages) { const header = "var hljs = require('./core');"; const footer = - `hljs.HighlightJS = hljs\n` + - `hljs.default = hljs\n` + - `module.exports = hljs;`; + `hljs.HighlightJS = hljs\n` + + `hljs.default = hljs\n` + + `module.exports = hljs;`; const registration = languages.map((lang) => { const require = `require('./languages/${lang.name}')`; @@ -57,7 +57,8 @@ async function buildNodeLanguage(language, options) { if (options.esm) { await fs.writeFile(`${process.env.BUILD_DIR}/es/languages/${language.name}.js.js`, ES_STUB.replace(/%%%%/g, language.name)); - await rollupWrite(input, {...output, + await rollupWrite(input, { + ...output, format: "es", file: output.file.replace("/lib/", "/es/") }); @@ -108,7 +109,7 @@ const generatePackageExports = () => ({ "./lib/languages/*": dual("./lib/languages/*.js"), "./scss/*": "./scss/*", "./styles/*": "./styles/*", - "./types/*": "./types/*", + "./types/*": "./types/*" }); function buildPackageJSON(options) { const packageJson = require("../package.json"); diff --git a/tools/checkAutoDetect.js b/tools/checkAutoDetect.js index 5b101672fb..0a725985a8 100755 --- a/tools/checkAutoDetect.js +++ b/tools/checkAutoDetect.js @@ -1,16 +1,16 @@ #!/usr/bin/env node 'use strict'; -let fs = require('fs') -let hljs = require('../build'); -let path = require('path'); -let utility = require('../test/utility'); -let Table = require('cli-table'); -let colors = require('colors/safe'); +const fs = require('fs'); +const hljs = require('../build.js'); +const path = require('path'); +const utility = require('../test/utility.js'); +const Table = require('cli-table'); +const colors = require('colors/safe.js'); -let resultTable = new Table({ - head: ['expected', 'actual', 'score', '2nd best', 'score','info'], - colWidths: [20,20,10,20,10,20], +const resultTable = new Table({ + head: ['expected', 'actual', 'score', '2nd best', 'score', 'info'], + colWidths: [20, 20, 10, 20, 10, 20], style: { head: ['grey'] } @@ -24,8 +24,8 @@ function testAutoDetection(language, index, languages) { return fs.readFileSync(filename, 'utf-8'); }) .forEach(function(content) { - const expected = language, - actual = hljs.highlightAuto(content); + const expected = language; + const actual = hljs.highlightAuto(content); if (actual.language !== expected && actual.secondBest.language !== expected) { return resultTable.push([ expected, @@ -45,7 +45,7 @@ function testAutoDetection(language, index, languages) { ]); } // equal relevance is flagged - if (actual.relevance == actual.secondBest.relevance) { + if (actual.relevance === actual.secondBest.relevance) { return resultTable.push([ expected, actual.language, @@ -68,18 +68,16 @@ if (process.env.ONLY_LANGUAGES) { console.log('Checking auto-highlighting for ' + colors.grey(languages.length) + ' languages...'); languages.forEach((lang, index) => { if (index % 60 === 0) { console.log(""); } - testAutoDetection(lang) + testAutoDetection(lang); process.stdout.write("."); }); -console.log("\n") +console.log("\n"); if (resultTable.length === 0) { - console.log(colors.green('SUCCESS') + ' - ' + colors.green(languages.length) + ' of ' + colors.gray(languages.length) + ' languages passed auto-highlight check!') + console.log(colors.green('SUCCESS') + ' - ' + colors.green(languages.length) + ' of ' + colors.gray(languages.length) + ' languages passed auto-highlight check!'); } else { console.log( - colors.red('ISSUES') + ' - ' + colors.red(resultTable.length) + ' of ' + colors.gray(languages.length) + ' languages have potential issues.' + - '\n' + - resultTable.toString()); + colors.red('ISSUES') + ' - ' + colors.red(resultTable.length) + ' of ' + colors.gray(languages.length) + ' languages have potential issues.' + + '\n' + + resultTable.toString()); } - - diff --git a/tools/checkTheme.js b/tools/checkTheme.js index 09f72f2245..e40c391ff5 100755 --- a/tools/checkTheme.js +++ b/tools/checkTheme.js @@ -2,7 +2,6 @@ const fs = require("fs"); const css = require("css"); -const { match } = require("assert"); require("colors"); const CODE = { @@ -166,19 +165,19 @@ function check_group(group, rules) { }); - let doesNotSupport = has_rules.map(x => x[1]).includes(false); - let skipped = has_rules.find(x => x[2]); + const doesNotSupport = has_rules.map(x => x[1]).includes(false); + const skipped = has_rules.find(x => x[2]); if (doesNotSupport || skipped) { console.log(group.name.yellow); if (doesNotSupport) { console.log(`- Theme does not fully support.`.brightMagenta); } - has_rules.filter(x => !x[1]).forEach(([scope,_]) => { + has_rules.filter(x => !x[1]).forEach(([scope, _]) => { const selector = scopeToSelector(scope); console.log(`- scope ${scope.cyan} is not highlighted\n (css: ${selector.green})`); }); - has_rules.filter(x => x[2]).forEach(([scope,_]) => { + has_rules.filter(x => x[2]).forEach(([scope, _]) => { console.log(` - scope ${scope.cyan} [purposely] un-highlighted.`.cyan); }); console.log(); diff --git a/tools/lib/bundling.js b/tools/lib/bundling.js index 1ca11a71c6..55360c6ee9 100644 --- a/tools/lib/bundling.js +++ b/tools/lib/bundling.js @@ -1,8 +1,8 @@ -const rollup = require('rollup') +const rollup = require('rollup'); const crypto = require("crypto"); async function rollupCode(inputOptions, outputOptions) { - const output = await generate(inputOptions, outputOptions) + const output = await generate(inputOptions, outputOptions); return output[0].code; } diff --git a/tools/lib/dependencies.js b/tools/lib/dependencies.js index edc621adf7..c2201d3396 100644 --- a/tools/lib/dependencies.js +++ b/tools/lib/dependencies.js @@ -6,20 +6,19 @@ const DependencyResolver = require('dependency-resolver'); * * @param {array} languages list of languages to be reordered * @returns {array} ordered list of languages -*/ - + */ const reorderDependencies = (languages) => { - let resolver = new DependencyResolver(); - for (let lang of languages) { + const resolver = new DependencyResolver(); + for (const lang of languages) { resolver.add(lang.name); - for (let required of lang.requires) { + for (const required of lang.requires) { resolver.setDependency(lang.name, required); } } return resolver.sort().map((name) => - languages.find((l) => l.name == name) + languages.find((l) => l.name === name) ); -} +}; /** * Filters languages by group (common, etc) @@ -28,14 +27,13 @@ const reorderDependencies = (languages) => { * * @param {array} languages full list of languages * @returns {array} filtered list -*/ - + */ const languagesByGroup = (languages, groupIdentifier) => { - let groupName = groupIdentifier.replace(":",""); + const groupName = groupIdentifier.replace(":", ""); return languages.filter((el) => el.categories.includes(groupName)); -} +}; // :common is a group identifier, "common" is the group name -const isGroup = (id) => id[0] == ":" +const isGroup = (id) => id[0] === ":"; /** @@ -48,39 +46,36 @@ const isGroup = (id) => id[0] == ":" * @param {array} includes - which languages or groups to include * example: ":common elixir ruby" * @returns {array} filtered list if languages -*/ + */ const filter = (allLanguages, includes) => { - if (includes==undefined || includes.length==0) - return reorderDependencies(allLanguages); + if (!includes || includes.length === 0) { return reorderDependencies(allLanguages); } let languages = []; - for (let item of includes) { + for (const item of includes) { if (isGroup(item)) { - languages = languages.concat(languagesByGroup(allLanguages, item)) + languages = languages.concat(languagesByGroup(allLanguages, item)); } else { - let languageName = item; - let found = allLanguages.find((el) => el.name == languageName ) - if (found) - languages.push(found) - else { - console.error(`[ERROR] Language '${languageName}' could not be found.`) - process.exit(1) + const languageName = item; + const found = allLanguages.find((el) => el.name === languageName); + if (found) { languages.push(found); } else { + console.error(`[ERROR] Language '${languageName}' could not be found.`); + process.exit(1); } } } // resolve requires - for (let lang of languages) { + for (const lang of languages) { lang.requires.forEach(needed => { - if (!languages.find((el) => el.name == needed)) { - console.info(`[INFO] Adding ${needed}... ${lang.name} requires ${needed}.`) - languages.push(allLanguages.find((el) => el.name == needed)) + if (!languages.find((el) => el.name === needed)) { + console.info(`[INFO] Adding ${needed}... ${lang.name} requires ${needed}.`); + languages.push(allLanguages.find((el) => el.name === needed)); } }); } // make sure our dependencies are in the correct order return reorderDependencies(languages); -} +}; -module.exports = { reorderDependencies, filter } +module.exports = { reorderDependencies, filter }; diff --git a/tools/lib/language.js b/tools/lib/language.js index 3a1c20c978..8da727e101 100644 --- a/tools/lib/language.js +++ b/tools/lib/language.js @@ -1,37 +1,35 @@ -const fs = require("fs") -const fsProm = require("fs").promises +const fs = require("fs"); const Terser = require("terser"); -const glob = require("glob") -const path = require("path") -const build_config = require("../build_config") +const glob = require("glob"); +const path = require("path"); +const build_config = require("../build_config.js"); -const packageJSON = require("../../package.json") -const REQUIRES_REGEX = /\/\*.*?Requires: (.*?)\r?\n/s -const CATEGORY_REGEX = /\/\*.*?Category: (.*?)\r?\n/s -const LANGUAGE_REGEX = /\/\*.*?Language: (.*?)\r?\n/s -const {rollupCode} = require("./bundling.js") -const { getThirdPartyPackages } = require("./external_language") +const packageJSON = require("../../package.json"); +const REQUIRES_REGEX = /\/\*.*?Requires: (.*?)\r?\n/s; +const CATEGORY_REGEX = /\/\*.*?Category: (.*?)\r?\n/s; +const LANGUAGE_REGEX = /\/\*.*?Language: (.*?)\r?\n/s; +const { rollupCode } = require("./bundling.js"); +const { getThirdPartyPackages } = require("./external_language.js"); class Language { - constructor(name, path) { - this.name = name - this.prettyName = name - this.requires = [] - this.categories = [] - this.third_party = false + this.name = name; + this.prettyName = name; + this.requires = []; + this.categories = []; + this.third_party = false; // compiled code - this.module = "" - this.minified = "" + this.module = ""; + this.minified = ""; - this.path = path - this.data = fs.readFileSync(path, {encoding: "utf8"}) - this.loadMetadata() + this.path = path; + this.data = fs.readFileSync(path, { encoding: "utf8" }); + this.loadMetadata(); } async compile(options) { - await compileLanguage(this,options); + await compileLanguage(this, options); return this; } @@ -39,8 +37,7 @@ class Language { if (this._sample) return this._sample; this._sample = ""; - if (fs.existsSync(this.samplePath)) - this._sample = fs.readFileSync(this.samplePath, {encoding: "utf8"}); + if (fs.existsSync(this.samplePath)) { this._sample = fs.readFileSync(this.samplePath, { encoding: "utf8" }); } return this._sample; } @@ -48,38 +45,34 @@ class Language { if (this.moduleDir) { // this is the 'extras' case. return `${this.moduleDir}/test/detect/${this.name}/default.txt`; - } - else { + } else { // this is the common/built-in case. return `./test/detect/${this.name}/default.txt`; } } loadMetadata() { - var requiresMatch = REQUIRES_REGEX.exec(this.data) - var categoryMatch = CATEGORY_REGEX.exec(this.data) - var languageMatch = LANGUAGE_REGEX.exec(this.data) + const requiresMatch = REQUIRES_REGEX.exec(this.data); + const categoryMatch = CATEGORY_REGEX.exec(this.data); + const languageMatch = LANGUAGE_REGEX.exec(this.data); - if (requiresMatch) - this.requires = requiresMatch[1].split(", ").map((n) => n.replace(".js","")) + if (requiresMatch) { this.requires = requiresMatch[1].split(", ").map((n) => n.replace(".js", "")); } - if (categoryMatch) - this.categories = categoryMatch[1].split(/,\s?/) + if (categoryMatch) { this.categories = categoryMatch[1].split(/,\s?/); } - if (languageMatch) - this.prettyName = languageMatch[1] + if (languageMatch) { this.prettyName = languageMatch[1]; } } static fromFile(filename) { return new Language( - path.basename(filename).replace(".js",""), + path.basename(filename).replace(".js", ""), filename ); } } -async function compileLanguage (language, options) { +async function compileLanguage(language, options) { const HEADER = `/*! \`${language.name}\` grammar compiled for Highlight.js ${packageJSON.version} */`; // TODO: cant we use the source we already have? @@ -105,14 +98,14 @@ async function compileLanguage (language, options) { } async function getLanguages() { - let languages = []; + const languages = []; glob.sync("./src/languages/*.js").forEach((file) => { languages.push(Language.fromFile(file)); }); - let extraPackages = await getThirdPartyPackages(); - for (let ext of extraPackages) { - for (let file of ext.files) { - let l = Language.fromFile(file); + const extraPackages = await getThirdPartyPackages(); + for (const ext of extraPackages) { + for (const file of ext.files) { + const l = Language.fromFile(file); l.loader = ext.loader; l.third_party = true; l.moduleDir = ext.dir; diff --git a/tools/lib/makestuff.js b/tools/lib/makestuff.js index 44e0035c25..9f3f7da707 100644 --- a/tools/lib/makestuff.js +++ b/tools/lib/makestuff.js @@ -2,8 +2,8 @@ const fs = require("fs"); const CleanCSS = require('clean-css'); const path = require('path'); const _ = require('lodash'); -const config = require("../build_config"); const del = require('del'); +const config = require("../build_config.js"); async function clean(directory) { del.sync([directory]); diff --git a/tools/perf.js b/tools/perf.js index 0c31b59b44..3c37ead0a1 100755 --- a/tools/perf.js +++ b/tools/perf.js @@ -20,7 +20,7 @@ const timeTest = (name, func) => { func(); const t1 = performance.now(); console.log(` done! [${((t1 - t0) / 1000).toFixed(2)}s elapsed]`); -} +}; const oneLanguageMarkupTests = (lang) => { for (let i = 0; i < 50; i++) { @@ -52,10 +52,10 @@ const globalCheckAutoDetect = () => { }; const highlightFile = (lang) => { - const source = fs.readFileSync(`./tools/sample_files/${lang}.txt`, { encoding:'utf8' }); - const hljs = require('../build'); + const source = fs.readFileSync(`./tools/sample_files/${lang}.txt`, { encoding: 'utf8' }); + const hljs = require('../build.js'); for (let i = 0; i < 2000; i++) { - hljs.highlight(source, {language: lang}); + hljs.highlight(source, { language: lang }); } }; From 8c00856391ba0120981543fb5b4660af0b2ded93 Mon Sep 17 00:00:00 2001 From: Bradley Mackey Date: Tue, 2 Nov 2021 05:48:47 +0000 Subject: [PATCH 05/76] enh(swift) add SE-0290 unavailability condition (#3382) --- CHANGES.md | 2 ++ src/languages/lib/kws_swift.js | 4 ++-- src/languages/swift.js | 2 +- test/markup/swift/attributes.expect.txt | 1 - test/markup/swift/attributes.txt | 1 - test/markup/swift/availability.expect.txt | 11 +++++++++++ test/markup/swift/availability.txt | 11 +++++++++++ 7 files changed, 27 insertions(+), 5 deletions(-) create mode 100644 test/markup/swift/availability.expect.txt create mode 100644 test/markup/swift/availability.txt diff --git a/CHANGES.md b/CHANGES.md index ef24a6123c..0036c3a5fa 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,8 +3,10 @@ Grammars: - fix(python) Fix recognition of numeric literals followed by keywords without whitespace (#2985) [Richard Gibson][] +- enh(swift) add SE-0290 unavailability condition (#3382) [Bradley Mackey][] [Richard Gibson]: https://github.com/gibson042 +[Bradley Mackey]: https://github.com/bradleymackey ## Version 11.3.1 diff --git a/src/languages/lib/kws_swift.js b/src/languages/lib/kws_swift.js index d54e6ed3a7..be06394ba8 100644 --- a/src/languages/lib/kws_swift.js +++ b/src/languages/lib/kws_swift.js @@ -141,7 +141,7 @@ export const precedencegroupKeywords = [ ]; // Keywords that start with a number sign (#). -// #available is handled separately. +// #(un)available is handled separately. export const numberSignKeywords = [ '#colorLiteral', '#column', @@ -307,7 +307,7 @@ export const keywordAttributes = [ 'usableFromInline' ]; -// Contextual keywords used in @available and #available. +// Contextual keywords used in @available and #(un)available. export const availabilityKeywords = [ 'iOS', 'iOSApplicationExtension', diff --git a/src/languages/swift.js b/src/languages/swift.js index 0adc30d957..15fb39c9e9 100644 --- a/src/languages/swift.js +++ b/src/languages/swift.js @@ -221,7 +221,7 @@ export default function(hljs) { // https://docs.swift.org/swift-book/ReferenceManual/Attributes.html const AVAILABLE_ATTRIBUTE = { - match: /(@|#)available/, + match: /(@|#(un)?)available/, className: "keyword", starts: { contains: [ diff --git a/test/markup/swift/attributes.expect.txt b/test/markup/swift/attributes.expect.txt index 885e678a6b..22d4e60978 100644 --- a/test/markup/swift/attributes.expect.txt +++ b/test/markup/swift/attributes.expect.txt @@ -1,4 +1,3 @@ -@available(iOS 14, deprecated: "reason", *) @convention(swift) @objc @objc(name) diff --git a/test/markup/swift/attributes.txt b/test/markup/swift/attributes.txt index 24fe9a41bf..8628043613 100644 --- a/test/markup/swift/attributes.txt +++ b/test/markup/swift/attributes.txt @@ -1,4 +1,3 @@ -@available(iOS 14, deprecated: "reason", *) @convention(swift) @objc @objc(name) diff --git a/test/markup/swift/availability.expect.txt b/test/markup/swift/availability.expect.txt new file mode 100644 index 0000000000..7435c86838 --- /dev/null +++ b/test/markup/swift/availability.expect.txt @@ -0,0 +1,11 @@ +#available() +#available(iOS 15.0, *) +@available() +@available(iOS 15.0, *) +@available(iOS 14, deprecated: "reason", *) + +#unavailable() +#unavailable(iOS 15.0, *) +// not a keyword +@unavailable() +@unavailable(iOS 15.0, *) diff --git a/test/markup/swift/availability.txt b/test/markup/swift/availability.txt new file mode 100644 index 0000000000..87cd134e35 --- /dev/null +++ b/test/markup/swift/availability.txt @@ -0,0 +1,11 @@ +#available() +#available(iOS 15.0, *) +@available() +@available(iOS 15.0, *) +@available(iOS 14, deprecated: "reason", *) + +#unavailable() +#unavailable(iOS 15.0, *) +// not a keyword +@unavailable() +@unavailable(iOS 15.0, *) From 998e25e41b030f5d949accd6fa9b65a990fc484d Mon Sep 17 00:00:00 2001 From: jaacko-torus Date: Tue, 2 Nov 2021 00:50:41 -0500 Subject: [PATCH 06/76] fixed type of `either` in `src/lib/regex.js` (#3374) --- src/lib/regex.js | 4 +++- types/index.d.ts | 7 ++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/lib/regex.js b/src/lib/regex.js index ec5c6bb87f..da6cc457c8 100644 --- a/src/lib/regex.js +++ b/src/lib/regex.js @@ -65,11 +65,13 @@ function stripOptionsFromArgs(args) { } } +/** @typedef { {capture?: boolean} } RegexEitherOptions */ + /** * Any of the passed expresssions may match * * Creates a huge this | this | that | that match - * @param {(RegExp | string | { capture?: boolean })[]} args + * @param {(RegExp | string)[] | [...(RegExp | string)[], RegexEitherOptions]} args * @returns {string} */ export function either(...args) { diff --git a/types/index.d.ts b/types/index.d.ts index b89fffd52b..c1ff73b12d 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -23,6 +23,11 @@ declare module 'highlight.js' { install: (vue: any) => void } + // perhaps make this an interface? + type RegexEitherOptions = { + capture?: boolean + } + interface PublicApi { highlight: (codeOrLanguageName: string, optionsOrCode: string | HighlightOptions, ignoreIllegals?: boolean) => HighlightResult highlightAuto: (code: string, languageSubset?: string[]) => AutoHighlightResult @@ -47,7 +52,7 @@ declare module 'highlight.js' { regex: { concat: (...args: (RegExp | string)[]) => string, lookahead: (re: RegExp | string) => string, - either: (...args: (RegExp | string | { capture?: boolean })[]) => string, + either: (...args: (RegExp | string)[] | [...(RegExp | string)[], RegexEitherOptions]) => string, optional: (re: RegExp | string) => string, anyNumberOfTimes: (re: RegExp | string) => string } From 7eb21e5524b1db3de76ba077d4d6034b35e11945 Mon Sep 17 00:00:00 2001 From: Jan Pilzer Date: Tue, 2 Nov 2021 16:12:36 -0700 Subject: [PATCH 07/76] (docs) make demo page more keyboard accessible (#3371) --- demo/demo.js | 16 ++++++++++++---- demo/index.html | 6 +++--- demo/style.css | 13 ++++++++----- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/demo/demo.js b/demo/demo.js index 079080e67a..49f6bcef1f 100644 --- a/demo/demo.js +++ b/demo/demo.js @@ -1,8 +1,10 @@ hljs.debugMode(); hljs.highlightAll(); -document.querySelectorAll(".categories > li").forEach((category) => { +document.querySelectorAll(".categories li a").forEach((category) => { category.addEventListener("click", (event) => { + event.preventDefault(); + const current = document.querySelector(".categories .current"); const currentCategory = current.dataset.category; const nextCategory = event.target.dataset.category; @@ -23,15 +25,21 @@ document.querySelectorAll(".categories > li").forEach((category) => { }); }); -document.querySelectorAll(".styles > li").forEach((style) => { +document.querySelectorAll(".styles li a").forEach((style) => { style.addEventListener("click", (event) => { + event.preventDefault(); + const current = document.querySelector(".styles .current"); const currentStyle = current.textContent; const nextStyle = event.target.textContent; if (currentStyle !== nextStyle) { - document.querySelector(`link[title="${nextStyle}"]`).removeAttribute("disabled"); - document.querySelector(`link[title="${currentStyle}"]`).setAttribute("disabled", "disabled"); + document + .querySelector(`link[title="${nextStyle}"]`) + .removeAttribute("disabled"); + document + .querySelector(`link[title="${currentStyle}"]`) + .setAttribute("disabled", "disabled"); current.classList.remove("current"); event.target.classList.add("current"); diff --git a/demo/index.html b/demo/index.html index f7ee27df84..ad6371748c 100644 --- a/demo/index.html +++ b/demo/index.html @@ -23,14 +23,14 @@

highlight.js demo

Language Categories

Themes

    -
  • Default
  • +
  • Default
  • <% styles.forEach(({name}) => {%> -
  • <%= name %>
  • +
  • <%= name %>
  • <% }); %>
diff --git a/demo/style.css b/demo/style.css index 9073c14c24..e23f06d2e7 100644 --- a/demo/style.css +++ b/demo/style.css @@ -102,16 +102,19 @@ aside ul::-webkit-scrollbar-thumb:active { background: #5d3333; } -aside li { - padding: 1px 1em; - cursor: pointer; +aside ul a { + display: block; + padding: 1px 0.5em 1px 1em; + text-decoration: none; } -aside li:hover { +aside ul a:focus, +aside ul a:hover { background: #500; + outline: none; } -aside li.current:before { +aside ul a.current:before { content: "▶"; font-size: smaller; position: absolute; From c100a39fa1f9f6e731f00ab7725453c1680db234 Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Tue, 2 Nov 2021 23:25:25 -0400 Subject: [PATCH 08/76] (docs) update fiddle links --- .github/ISSUE_TEMPLATE/1_incorrect-syntax-highlighting.md | 2 +- CONTRIBUTING.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/1_incorrect-syntax-highlighting.md b/.github/ISSUE_TEMPLATE/1_incorrect-syntax-highlighting.md index 0083dfb43d..2da7594b42 100644 --- a/.github/ISSUE_TEMPLATE/1_incorrect-syntax-highlighting.md +++ b/.github/ISSUE_TEMPLATE/1_incorrect-syntax-highlighting.md @@ -24,7 +24,7 @@ Please specify exactly *which* language grammar you are using to highlight (`pyt Please include plain text examples of the code that fails to highlight properly or can reproduce the bug you are seeing. If you attach a screenshot PLEASE also provide the actually code that we can copy/paste if necessary to help resolve the issue. A jsfiddle can sometimes be even better. You can fork an example test case: -https://jsfiddle.net/ajoshguy/gfzujpyt/ +https://jsfiddle.net/ajoshguy/cjhvre2k/ --> diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c67163c962..7c7c60b823 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -66,7 +66,7 @@ If you wish we supported a language we don't, first read [On requesting new lang ## Reporting Issues If you find a bug or think of an improvement, feel free to [open an issue](https://github.com/highlightjs/highlight.js/issues/new/choose). -- If you've found a language highlighting issue, you can use [this JSFiddle](https://jsfiddle.net/ajoshguy/2bmdswn6/) to create a test case. +- If you've found a language highlighting issue, you can use [this JSFiddle](https://jsfiddle.net/ajoshguy/cjhvre2k/) to create a test case. ## Fixing Issues (PRs) From 99e05df083dff1feefd4bce278785d1b2ea4b897 Mon Sep 17 00:00:00 2001 From: Bradley Mackey Date: Wed, 3 Nov 2021 08:34:56 +0000 Subject: [PATCH 09/76] enh(java) add `sealed` and `non-sealed` keywords (#3386) --- CHANGES.md | 1 + src/languages/java.js | 8 +++++++- test/markup/java/titles.expect.txt | 8 ++++++++ test/markup/java/titles.txt | 8 ++++++++ 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 0036c3a5fa..5f77890137 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,6 +4,7 @@ Grammars: - fix(python) Fix recognition of numeric literals followed by keywords without whitespace (#2985) [Richard Gibson][] - enh(swift) add SE-0290 unavailability condition (#3382) [Bradley Mackey][] +- enh(java) add `sealed` and `non-sealed` keywords (#3386) [Bradley Mackey][] [Richard Gibson]: https://github.com/gibson042 [Bradley Mackey]: https://github.com/bradleymackey diff --git a/src/languages/java.js b/src/languages/java.js index 17e73e66ea..8c55aae215 100644 --- a/src/languages/java.js +++ b/src/languages/java.js @@ -73,7 +73,8 @@ export default function(hljs) { 'module', 'requires', 'exports', - 'do' + 'do', + 'sealed' ]; const BUILT_INS = [ @@ -179,6 +180,11 @@ export default function(hljs) { 3: "title.class" } }, + { + // Exceptions for hyphenated keywords + match: /non-sealed/, + scope: "keyword" + }, { begin: [ JAVA_IDENT_RE, diff --git a/test/markup/java/titles.expect.txt b/test/markup/java/titles.expect.txt index 571bd0fe51..2043511c9a 100644 --- a/test/markup/java/titles.expect.txt +++ b/test/markup/java/titles.expect.txt @@ -8,3 +8,11 @@ } } } + +sealed interface Command permits LoginCommand { + void run(); +} + +non-sealed abstract class UserPluginCommand extends Command { + void runAsUser(); +} diff --git a/test/markup/java/titles.txt b/test/markup/java/titles.txt index c43f696c92..a4d553fbb6 100644 --- a/test/markup/java/titles.txt +++ b/test/markup/java/titles.txt @@ -8,3 +8,11 @@ public class Greet { } } } + +sealed interface Command permits LoginCommand { + void run(); +} + +non-sealed abstract class UserPluginCommand extends Command { + void runAsUser(); +} From 1d8031b2a59f6d9a5f9704857d953b8af8b7cf89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ebbinghaus?= Date: Tue, 9 Nov 2021 15:48:16 +0100 Subject: [PATCH 10/76] fix(clojure) comment macro should not be `comment` scope (#3395) --- CHANGES.md | 2 ++ src/languages/clojure.js | 1 - test/markup/clojure/comment-macro.expect.txt | 2 ++ test/markup/clojure/comment-macro.txt | 2 ++ 4 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 test/markup/clojure/comment-macro.expect.txt create mode 100644 test/markup/clojure/comment-macro.txt diff --git a/CHANGES.md b/CHANGES.md index 5f77890137..b43a548aee 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,9 +5,11 @@ Grammars: - fix(python) Fix recognition of numeric literals followed by keywords without whitespace (#2985) [Richard Gibson][] - enh(swift) add SE-0290 unavailability condition (#3382) [Bradley Mackey][] - enh(java) add `sealed` and `non-sealed` keywords (#3386) [Bradley Mackey][] +- fix(clojure) `comment` macro catches more than it should [Björn Ebbinghaus][] [Richard Gibson]: https://github.com/gibson042 [Bradley Mackey]: https://github.com/bradleymackey +[Björn Ebbinghaus]: https://github.com/MrEbbinghaus ## Version 11.3.1 diff --git a/src/languages/clojure.js b/src/languages/clojure.js index c34d0527a6..34c9ff18af 100644 --- a/src/languages/clojure.js +++ b/src/languages/clojure.js @@ -132,7 +132,6 @@ export default function(hljs) { }; LIST.contains = [ - hljs.COMMENT('comment', ''), GLOBAL, NAME, BODY diff --git a/test/markup/clojure/comment-macro.expect.txt b/test/markup/clojure/comment-macro.expect.txt new file mode 100644 index 0000000000..55260ddbb3 --- /dev/null +++ b/test/markup/clojure/comment-macro.expect.txt @@ -0,0 +1,2 @@ +(comment "comment is a macro that emits no code. It can contain clojure code in itself.") +(comment-and-something "This is a valid function name") \ No newline at end of file diff --git a/test/markup/clojure/comment-macro.txt b/test/markup/clojure/comment-macro.txt new file mode 100644 index 0000000000..8ebcefc043 --- /dev/null +++ b/test/markup/clojure/comment-macro.txt @@ -0,0 +1,2 @@ +(comment "comment is a macro that emits no code. It can contain clojure code in itself.") +(comment-and-something "This is a valid function name") \ No newline at end of file From 0f73808b50249e7f4aa75304da0ba6b4e2387b19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ebbinghaus?= Date: Wed, 10 Nov 2021 23:57:33 +0100 Subject: [PATCH 11/76] fix(clojure) Several issues with Clojure highlighting (#3397) - fix(clojure) `$` in symbol breaks highlighting - fix(clojure) Add complete regex for number detection - enh(clojure) Add character mode for character literals - fix(clojure) Inconsistent namespaced map highlighting - enh(clojure) Add `regex` mode to regex literal - fix(clojure) Remove inconsistent/broken highlighting for metadata - enh(clojure) Add `punctuation` mode for commas. --- CHANGES.md | 10 ++- src/languages/clojure.js | 56 ++++++++++----- test/markup/clojure/character.expect.txt | 5 ++ test/markup/clojure/character.txt | 5 ++ test/markup/clojure/deps_edn.expect.txt | 18 ++--- .../clojure/globals_definition.expect.txt | 13 ++-- test/markup/clojure/globals_definition.txt | 7 +- test/markup/clojure/hint_col.expect.txt | 34 --------- test/markup/clojure/hint_col.txt | 34 --------- test/markup/clojure/number.expect.txt | 69 +++++++++++++++++++ test/markup/clojure/number.txt | 69 +++++++++++++++++++ .../markup/clojure/symbols-numbers.expect.txt | 3 + test/markup/clojure/symbols-numbers.txt | 3 + 13 files changed, 225 insertions(+), 101 deletions(-) create mode 100644 test/markup/clojure/character.expect.txt create mode 100644 test/markup/clojure/character.txt delete mode 100644 test/markup/clojure/hint_col.expect.txt delete mode 100644 test/markup/clojure/hint_col.txt create mode 100644 test/markup/clojure/number.expect.txt create mode 100644 test/markup/clojure/number.txt diff --git a/CHANGES.md b/CHANGES.md index b43a548aee..da9423a0c6 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,7 +5,15 @@ Grammars: - fix(python) Fix recognition of numeric literals followed by keywords without whitespace (#2985) [Richard Gibson][] - enh(swift) add SE-0290 unavailability condition (#3382) [Bradley Mackey][] - enh(java) add `sealed` and `non-sealed` keywords (#3386) [Bradley Mackey][] -- fix(clojure) `comment` macro catches more than it should [Björn Ebbinghaus][] +- fix(clojure) Several issues with Clojure highlighting (#3397) [Björn Ebbinghaus][] + - fix(clojure) `comment` macro catches more than it should (#3395) + - fix(clojure) `$` in symbol breaks highlighting + - fix(clojure) Add complete regex for number detection + - enh(clojure) Add character mode for character literals + - fix(clojure) Inconsistent namespaced map highlighting + - enh(clojure) Add `regex` mode to regex literal + - fix(clojure) Remove inconsistent/broken highlighting for metadata + - enh(clojure) Add `punctuation` mode for commas. [Richard Gibson]: https://github.com/gibson042 [Bradley Mackey]: https://github.com/bradleymackey diff --git a/src/languages/clojure.js b/src/languages/clojure.js index 34c9ff18af..34a4dc7fe4 100644 --- a/src/languages/clojure.js +++ b/src/languages/clojure.js @@ -8,8 +8,8 @@ Category: lisp /** @type LanguageFn */ export default function(hljs) { - const SYMBOLSTART = 'a-zA-Z_\\-!.?+*=<>&#\''; - const SYMBOL_RE = '[' + SYMBOLSTART + '][' + SYMBOLSTART + '0-9/;:]*'; + const SYMBOLSTART = 'a-zA-Z_\\-!.?+*=<>&\''; + const SYMBOL_RE = '[#]?[' + SYMBOLSTART + '][' + SYMBOLSTART + '0-9/;:$#]*'; const globals = 'def defonce defprotocol defstruct defmulti defmethod defn- defn defmacro deftype defrecord'; const keywords = { $pattern: SYMBOL_RE, @@ -45,20 +45,44 @@ export default function(hljs) { 'lazy-seq spread list* str find-keyword keyword symbol gensym force rationalize' }; - const SIMPLE_NUMBER_RE = '[-+]?\\d+(\\.\\d+)?'; - const SYMBOL = { begin: SYMBOL_RE, relevance: 0 }; const NUMBER = { - className: 'number', - begin: SIMPLE_NUMBER_RE, - relevance: 0 + scope: 'number', + relevance: 0, + variants: [ + {match: /[-+]?0[xX][0-9a-fA-F]+N?/}, // hexadecimal // 0x2a + {match: /[-+]?0[0-7]+N?/}, // octal // 052 + {match: /[-+]?[1-9][0-9]?[rR][0-9a-zA-Z]+N?/}, // variable radix from 2 to 36 // 2r101010, 8r52, 36r16 + {match: /[-+]?[0-9]+\/[0-9]+N?/}, // ratio // 1/2 + {match: /[-+]?[0-9]+((\.[0-9]*([eE][+-]?[0-9]+)?M?)|([eE][+-]?[0-9]+M?|M))/}, // float // 0.42 4.2E-1M 42E1 42M + {match: /[-+]?([1-9][0-9]*|0)N?/}, // int (don't match leading 0) // 42 42N + ] }; + const CHARACTER = { + scope: 'character', + variants: [ + {match: /\\o[0-3]?[0-7]{1,2}/}, // Unicode Octal 0 - 377 + {match: /\\u[0-9a-fA-F]{4}/}, // Unicode Hex 0000 - FFFF + {match: /\\(newline|space|tab|formfeed|backspace|return)/}, // special characters + {match: /\\\S/, relevance: 0} // any non-whitespace char + ] + } + const REGEX = { + scope: 'regex', + begin: /#"/, + end: /"/ + } const STRING = hljs.inherit(hljs.QUOTE_STRING_MODE, { illegal: null }); + const COMMA = { + scope: 'punctuation', + match: /,/, + relevance: 0 + } const COMMENT = hljs.COMMENT( ';', '$', @@ -71,15 +95,10 @@ export default function(hljs) { begin: /\b(true|false|nil)\b/ }; const COLLECTION = { - begin: '[\\[\\{]', + begin: "\\[|(#::?" + SYMBOL_RE + ")?\\{", end: '[\\]\\}]', relevance: 0 }; - const HINT = { - className: 'comment', - begin: '\\^' + SYMBOL_RE - }; - const HINT_COL = hljs.COMMENT('\\^\\{', '\\}'); const KEY = { className: 'symbol', begin: '[:]{1,2}' + SYMBOL_RE @@ -100,10 +119,11 @@ export default function(hljs) { starts: BODY }; const DEFAULT_CONTAINS = [ + COMMA, LIST, + CHARACTER, + REGEX, STRING, - HINT, - HINT_COL, COMMENT, KEY, COLLECTION, @@ -138,17 +158,17 @@ export default function(hljs) { ]; BODY.contains = DEFAULT_CONTAINS; COLLECTION.contains = DEFAULT_CONTAINS; - HINT_COL.contains = [ COLLECTION ]; return { name: 'Clojure', aliases: [ 'clj', 'edn' ], illegal: /\S/, contains: [ + COMMA, LIST, + CHARACTER, + REGEX, STRING, - HINT, - HINT_COL, COMMENT, KEY, COLLECTION, diff --git a/test/markup/clojure/character.expect.txt b/test/markup/clojure/character.expect.txt new file mode 100644 index 0000000000..1b7cf05082 --- /dev/null +++ b/test/markup/clojure/character.expect.txt @@ -0,0 +1,5 @@ +\A +\a +\formfeed +\u00DF +\o303 \ No newline at end of file diff --git a/test/markup/clojure/character.txt b/test/markup/clojure/character.txt new file mode 100644 index 0000000000..7cf4531ab9 --- /dev/null +++ b/test/markup/clojure/character.txt @@ -0,0 +1,5 @@ +\A +\a +\formfeed +\u00DF +\o303 \ No newline at end of file diff --git a/test/markup/clojure/deps_edn.expect.txt b/test/markup/clojure/deps_edn.expect.txt index fdedd183bd..9d36af63ad 100644 --- a/test/markup/clojure/deps_edn.expect.txt +++ b/test/markup/clojure/deps_edn.expect.txt @@ -1,14 +1,14 @@ -{:aliases {:export {:exec-fn stelcodes.dev-blog.generator/export}, - :repl {:extra-deps {cider/cider-nrepl {:mvn/version "0.25.2"}, - nrepl/nrepl {:mvn/version "0.8.3"}}, - :extra-paths ["dev"], +{:aliases {:export {:exec-fn stelcodes.dev-blog.generator/export}, + :repl {:extra-deps {cider/cider-nrepl {:mvn/version "0.25.2"}, + nrepl/nrepl {:mvn/version "0.8.3"}}, + :extra-paths ["dev"], :main-opts ["-m" "nrepl.cmdline" "--middleware" "[cider.nrepl/cider-middleware]" - "--interactive"]}, - :webhook {:exec-fn stelcodes.dev-blog.webhook/listen}}, - :deps {http-kit/http-kit {:mvn/version "2.5.3"}, - org.clojure/clojure {:mvn/version "1.10.1"}, - stasis/stasis {:mvn/version "2.5.1"}}, + "--interactive"]}, + :webhook {:exec-fn stelcodes.dev-blog.webhook/listen}}, + :deps {http-kit/http-kit {:mvn/version "2.5.3"}, + org.clojure/clojure {:mvn/version "1.10.1"}, + stasis/stasis {:mvn/version "2.5.1"}}, :paths ["src" "resources"]} diff --git a/test/markup/clojure/globals_definition.expect.txt b/test/markup/clojure/globals_definition.expect.txt index e387a1b63c..93ce3c17a2 100644 --- a/test/markup/clojure/globals_definition.expect.txt +++ b/test/markup/clojure/globals_definition.expect.txt @@ -5,8 +5,8 @@ ; function (defn clojure-function [args] (let [string "multiline\nstring" - regexp #"regexp" - number 100,000 + regexp #"regexp" + number 100000 booleans [false true] keyword ::the-keyword] ;; this is comment @@ -14,12 +14,17 @@ (->> (list [vector] {:map map} #{'set}))))) +#:person{:first "Han" + :last "Solo" + :ship #:ship{:name "Millenium Falcon"}} +#::{:a 1, :b 2} + ; global (def some-var) ; another one (def alternative-var "132") ; defonce -(defonce ^:private another-var #"foo") +(defonce ^:private another-var #"foo") ; private function (defn- add [x y] (+ x y)) @@ -58,4 +63,4 @@ ;; create a couple shapes and get their area (def myCircle (Circle. 10)) -(def mySquare (Square. 5 11)) +(def mySquare (Square. 5 11)) \ No newline at end of file diff --git a/test/markup/clojure/globals_definition.txt b/test/markup/clojure/globals_definition.txt index 6faeee7942..fadd808156 100644 --- a/test/markup/clojure/globals_definition.txt +++ b/test/markup/clojure/globals_definition.txt @@ -6,7 +6,7 @@ (defn clojure-function [args] (let [string "multiline\nstring" regexp #"regexp" - number 100,000 + number 100000 booleans [false true] keyword ::the-keyword] ;; this is comment @@ -14,6 +14,11 @@ (->> (list [vector] {:map map} #{'set}))))) +#:person{:first "Han" + :last "Solo" + :ship #:ship{:name "Millenium Falcon"}} +#::{:a 1, :b 2} + ; global (def some-var) ; another one diff --git a/test/markup/clojure/hint_col.expect.txt b/test/markup/clojure/hint_col.expect.txt deleted file mode 100644 index cb833d9027..0000000000 --- a/test/markup/clojure/hint_col.expect.txt +++ /dev/null @@ -1,34 +0,0 @@ -(import [java.lang.annotation Retention RetentionPolicy Target ElementType] - [javax.xml.ws WebServiceRef WebServiceRefs]) - -(definterface Foo (foo [])) - -;; annotation on type -(deftype ^{Deprecated true - Retention RetentionPolicy/RUNTIME - javax.annotation.processing.SupportedOptions ["foo" "bar" "baz"] - javax.xml.ws.soap.Addressing {:enabled false :required true} - WebServiceRefs [(WebServiceRef {:name "fred" :type String}) - (WebServiceRef {:name "ethel" :mappedName "lucy"})]} - Bar [^int a - ;; on field - ^{:tag int - Deprecated true - Retention RetentionPolicy/RUNTIME - javax.annotation.processing.SupportedOptions ["foo" "bar" "baz"] - javax.xml.ws.soap.Addressing {:enabled false :required true} - WebServiceRefs [(WebServiceRef {:name "fred" :type String}) - (WebServiceRef {:name "ethel" :mappedName "lucy"})]} - b] - ;; on method - Foo (^{Deprecated true - Retention RetentionPolicy/RUNTIME - javax.annotation.processing.SupportedOptions ["foo" "bar" "baz"] - javax.xml.ws.soap.Addressing {:enabled false :required true} - WebServiceRefs [(WebServiceRef {:name "fred" :type String}) - (WebServiceRef {:name "ethel" :mappedName "lucy"})]} - foo [this] 42)) - -(seq (.getAnnotations Bar)) -(seq (.getAnnotations (.getField Bar "b"))) -(seq (.getAnnotations (.getMethod Bar "foo" nil))) diff --git a/test/markup/clojure/hint_col.txt b/test/markup/clojure/hint_col.txt deleted file mode 100644 index 9584dec9d0..0000000000 --- a/test/markup/clojure/hint_col.txt +++ /dev/null @@ -1,34 +0,0 @@ -(import [java.lang.annotation Retention RetentionPolicy Target ElementType] - [javax.xml.ws WebServiceRef WebServiceRefs]) - -(definterface Foo (foo [])) - -;; annotation on type -(deftype ^{Deprecated true - Retention RetentionPolicy/RUNTIME - javax.annotation.processing.SupportedOptions ["foo" "bar" "baz"] - javax.xml.ws.soap.Addressing {:enabled false :required true} - WebServiceRefs [(WebServiceRef {:name "fred" :type String}) - (WebServiceRef {:name "ethel" :mappedName "lucy"})]} - Bar [^int a - ;; on field - ^{:tag int - Deprecated true - Retention RetentionPolicy/RUNTIME - javax.annotation.processing.SupportedOptions ["foo" "bar" "baz"] - javax.xml.ws.soap.Addressing {:enabled false :required true} - WebServiceRefs [(WebServiceRef {:name "fred" :type String}) - (WebServiceRef {:name "ethel" :mappedName "lucy"})]} - b] - ;; on method - Foo (^{Deprecated true - Retention RetentionPolicy/RUNTIME - javax.annotation.processing.SupportedOptions ["foo" "bar" "baz"] - javax.xml.ws.soap.Addressing {:enabled false :required true} - WebServiceRefs [(WebServiceRef {:name "fred" :type String}) - (WebServiceRef {:name "ethel" :mappedName "lucy"})]} - foo [this] 42)) - -(seq (.getAnnotations Bar)) -(seq (.getAnnotations (.getField Bar "b"))) -(seq (.getAnnotations (.getMethod Bar "foo" nil))) diff --git a/test/markup/clojure/number.expect.txt b/test/markup/clojure/number.expect.txt new file mode 100644 index 0000000000..25bb636d60 --- /dev/null +++ b/test/markup/clojure/number.expect.txt @@ -0,0 +1,69 @@ +; integer +00 +42 ++42 +-42 + +; BigInt +42N +0N ++42N +-42N + +; octal +052 +00N ++052 +-00N + +; hex +0x2a +0x0N ++0x2a +-0x0N + +; radix +2r101010 +8r52 +16r2a +36r16 +-2r101010 ++36r16 + +; radix BigInt +2r101010N +8r52N +16r2aN +36r16N ++8r52N +-16r2aN + +;; ratios +1/2 +-1/2 ++123/224 + +;; floats +42.0 +-42.0 ++42.0 +42. ++42. +-42. + +; BigDecimal +42.0M +-42M +42.M +42M + +; with Exponent +42.0E2 +-42.0E+9 +42E-0 ++42E-0 + +42.0E2M +42E+9M +-42E+9M ++42.0E2M \ No newline at end of file diff --git a/test/markup/clojure/number.txt b/test/markup/clojure/number.txt new file mode 100644 index 0000000000..01a0374c09 --- /dev/null +++ b/test/markup/clojure/number.txt @@ -0,0 +1,69 @@ +; integer +00 +42 ++42 +-42 + +; BigInt +42N +0N ++42N +-42N + +; octal +052 +00N ++052 +-00N + +; hex +0x2a +0x0N ++0x2a +-0x0N + +; radix +2r101010 +8r52 +16r2a +36r16 +-2r101010 ++36r16 + +; radix BigInt +2r101010N +8r52N +16r2aN +36r16N ++8r52N +-16r2aN + +;; ratios +1/2 +-1/2 ++123/224 + +;; floats +42.0 +-42.0 ++42.0 +42. ++42. +-42. + +; BigDecimal +42.0M +-42M +42.M +42M + +; with Exponent +42.0E2 +-42.0E+9 +42E-0 ++42E-0 + +42.0E2M +42E+9M +-42E+9M ++42.0E2M \ No newline at end of file diff --git a/test/markup/clojure/symbols-numbers.expect.txt b/test/markup/clojure/symbols-numbers.expect.txt index 87595d111b..7813d22876 100644 --- a/test/markup/clojure/symbols-numbers.expect.txt +++ b/test/markup/clojure/symbols-numbers.expect.txt @@ -1 +1,4 @@ (def +x [(a 1) +2 -3.0 y-5]) +(System/getProperty "java.vm.version") +(.getEnclosingClass java.util.Map$Entry) +(java.util.Map$Entry. .getEnclosingClass) diff --git a/test/markup/clojure/symbols-numbers.txt b/test/markup/clojure/symbols-numbers.txt index 01e839b555..97c92bb562 100644 --- a/test/markup/clojure/symbols-numbers.txt +++ b/test/markup/clojure/symbols-numbers.txt @@ -1 +1,4 @@ (def +x [(a 1) +2 -3.0 y-5]) +(System/getProperty "java.vm.version") +(.getEnclosingClass java.util.Map$Entry) +(java.util.Map$Entry. .getEnclosingClass) \ No newline at end of file From f86713bf3f39018b52d4dcb6f41e054371d5ab66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ebbinghaus?= Date: Thu, 11 Nov 2021 20:03:44 +0100 Subject: [PATCH 12/76] Fix clojure regex mode not allowing backslash escape (#3399) --- src/languages/clojure.js | 3 ++- test/markup/clojure/globals_definition.expect.txt | 6 ++++++ test/markup/clojure/globals_definition.txt | 6 ++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/languages/clojure.js b/src/languages/clojure.js index 34a4dc7fe4..a5565e0680 100644 --- a/src/languages/clojure.js +++ b/src/languages/clojure.js @@ -73,7 +73,8 @@ export default function(hljs) { const REGEX = { scope: 'regex', begin: /#"/, - end: /"/ + end: /"/, + contains: [hljs.BACKSLASH_ESCAPE] } const STRING = hljs.inherit(hljs.QUOTE_STRING_MODE, { illegal: null diff --git a/test/markup/clojure/globals_definition.expect.txt b/test/markup/clojure/globals_definition.expect.txt index 93ce3c17a2..832e283cd4 100644 --- a/test/markup/clojure/globals_definition.expect.txt +++ b/test/markup/clojure/globals_definition.expect.txt @@ -14,6 +14,12 @@ (->> (list [vector] {:map map} #{'set}))))) +#"\"abc\\" + +"real +multiline +string" + #:person{:first "Han" :last "Solo" :ship #:ship{:name "Millenium Falcon"}} diff --git a/test/markup/clojure/globals_definition.txt b/test/markup/clojure/globals_definition.txt index fadd808156..0858484786 100644 --- a/test/markup/clojure/globals_definition.txt +++ b/test/markup/clojure/globals_definition.txt @@ -14,6 +14,12 @@ (->> (list [vector] {:map map} #{'set}))))) +#"\"abc\\" + +"real +multiline +string" + #:person{:first "Han" :last "Solo" :ship #:ship{:name "Millenium Falcon"}} From 59b8f1fc0654400569a8d37f8c1990af4a4d1824 Mon Sep 17 00:00:00 2001 From: DanBarkus Date: Fri, 12 Nov 2021 16:29:01 -0500 Subject: [PATCH 13/76] (docs) added GSQL to supported languages (#3389) --- SUPPORTED_LANGUAGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/SUPPORTED_LANGUAGES.md b/SUPPORTED_LANGUAGES.md index 6d53724dde..aa6db49636 100644 --- a/SUPPORTED_LANGUAGES.md +++ b/SUPPORTED_LANGUAGES.md @@ -87,6 +87,7 @@ The table below shows the full list of languages (and corresponding classes/alia | Golo | golo, gololang | | | Gradle | gradle | | | Groovy | groovy | | +| GSQL | gsql | [highlightjs-gsql](https://github.com/DanBarkus/highlightjs-gsql) | | HTML, XML | xml, html, xhtml, rss, atom, xjb, xsd, xsl, plist, svg | | | HTTP | http, https | | | Haml | haml | | From ef45496df863838e77409fbff431db9a3d6b4dc6 Mon Sep 17 00:00:00 2001 From: Bradley Mackey Date: Sun, 14 Nov 2021 18:41:00 +0000 Subject: [PATCH 14/76] (chore) add gzip size compression report (#3400) This will report the gzip'd size of the CDN build output on every pull request, being run via GitHub actions. * Workflow: only report size of minified files --- .github/workflows/size_report.yml | 21 +++++++++++++++++++++ CHANGES.md | 4 ++++ 2 files changed, 25 insertions(+) create mode 100644 .github/workflows/size_report.yml diff --git a/.github/workflows/size_report.yml b/.github/workflows/size_report.yml new file mode 100644 index 0000000000..c542bff3e2 --- /dev/null +++ b/.github/workflows/size_report.yml @@ -0,0 +1,21 @@ +# This workflow computes the size of a CDN build's output on all Javascript files. +# Reported file sizes are after the result of gzip compression. +# Compression action used: https://github.com/preactjs/compressed-size-action + +name: Size Report (gzip) + +on: [pull_request] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Compute Compressed Size + uses: preactjs/compressed-size-action@v2 + with: + build-script: "build-cdn" + compression: "gzip" + pattern: "./build/{*.min.js,es/*.min.js,languages/*.min.js,es/languages/*.min.js}" diff --git a/CHANGES.md b/CHANGES.md index da9423a0c6..59324b44b6 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -15,6 +15,10 @@ Grammars: - fix(clojure) Remove inconsistent/broken highlighting for metadata - enh(clojure) Add `punctuation` mode for commas. +Developer Tools: + +- (chore) add gzip size compression report (#3400) [Bradley Mackey][] + [Richard Gibson]: https://github.com/gibson042 [Bradley Mackey]: https://github.com/bradleymackey [Björn Ebbinghaus]: https://github.com/MrEbbinghaus From 10b322dc436333b04df8295c9bdf4bad324849e0 Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Tue, 16 Nov 2021 12:13:38 -0500 Subject: [PATCH 15/76] fix(python) `def`, `class` keywords detected mid-identifier (#3381) --- CHANGES.md | 2 ++ src/languages/python.js | 6 +++--- test/markup/python/false_positives.expect.txt | 5 +++++ test/markup/python/false_positives.txt | 5 +++++ 4 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 test/markup/python/false_positives.expect.txt create mode 100644 test/markup/python/false_positives.txt diff --git a/CHANGES.md b/CHANGES.md index 59324b44b6..5ca677923e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,7 @@ Grammars: +- fix(python) def, class keywords detected mid-identifier (#3381) [Josh Goebel][] - fix(python) Fix recognition of numeric literals followed by keywords without whitespace (#2985) [Richard Gibson][] - enh(swift) add SE-0290 unavailability condition (#3382) [Bradley Mackey][] - enh(java) add `sealed` and `non-sealed` keywords (#3386) [Bradley Mackey][] @@ -22,6 +23,7 @@ Developer Tools: [Richard Gibson]: https://github.com/gibson042 [Bradley Mackey]: https://github.com/bradleymackey [Björn Ebbinghaus]: https://github.com/MrEbbinghaus +[Josh Goebel]: https://github.com/joshgoebel ## Version 11.3.1 diff --git a/src/languages/python.js b/src/languages/python.js index 46ed88a6f0..cb152d1b6c 100644 --- a/src/languages/python.js +++ b/src/languages/python.js @@ -384,7 +384,7 @@ export default function(hljs) { hljs.HASH_COMMENT_MODE, { match: [ - /def/, /\s+/, + /\bdef/, /\s+/, IDENT_RE, ], scope: { @@ -397,14 +397,14 @@ export default function(hljs) { variants: [ { match: [ - /class/, /\s+/, + /\bclass/, /\s+/, IDENT_RE, /\s*/, /\(\s*/, IDENT_RE,/\s*\)/ ], }, { match: [ - /class/, /\s+/, + /\bclass/, /\s+/, IDENT_RE ], } diff --git a/test/markup/python/false_positives.expect.txt b/test/markup/python/false_positives.expect.txt new file mode 100644 index 0000000000..cce88e6df8 --- /dev/null +++ b/test/markup/python/false_positives.expect.txt @@ -0,0 +1,5 @@ +foo = _undef +bar + +booger = _unclass +burger diff --git a/test/markup/python/false_positives.txt b/test/markup/python/false_positives.txt new file mode 100644 index 0000000000..cce88e6df8 --- /dev/null +++ b/test/markup/python/false_positives.txt @@ -0,0 +1,5 @@ +foo = _undef +bar + +booger = _unclass +burger From 59c02d1725639b11da3182f49d34eabb0fa90d07 Mon Sep 17 00:00:00 2001 From: wkania Date: Mon, 29 Nov 2021 18:28:00 +0100 Subject: [PATCH 16/76] chore(php) Remove duplicated code from default.txt (#3404) --- test/detect/php/default.txt | 8 -------- 1 file changed, 8 deletions(-) diff --git a/test/detect/php/default.txt b/test/detect/php/default.txt index 70ba114640..54a9edc624 100644 --- a/test/detect/php/default.txt +++ b/test/detect/php/default.txt @@ -56,14 +56,6 @@ enum Foo: string { case Test = 'test'; } -match ($key) { - 1 => 'Integer 1', - '1' => 'String 1', - true => 'Bool true', - [] => 'Empty array', - [1] => 'Array [1]', -}; - echo URI::ME . URI::$st1; __halt_compiler () ; datahere From 238e073ee8d9f1dc7d05cda2f5b5e5a5f6e78af8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Melvyn=20La=C3=AFly?= Date: Mon, 29 Nov 2021 22:30:46 +0100 Subject: [PATCH 17/76] enh(fsharp) myriad of fixes and improvements (#3357) - fix: Stop highlighting type names everywhere. Only match them in type annotations. - Since the names are not reserved and can be re-used for variable/binding names shadowing, it can be confusing and misleading. - enh: Highlight operators. Operators are a big part of F#, so highlighting them brings a lot of value for legibility, etc... - enh: Support quoted identifiers (` ``...`` `. They can contain pretty much anything inside the double backquotes) - fix: Fix type names and symbols matching * Type names can contain apostrophes. * Type symbols can contain quoted identifiers, but no apostrophes. - enh: Match attributes in more places (not just at the start of a line), and match more of the things they can contain (not just basic strings and numbers). --- CHANGES.md | 2 + src/languages/fsharp.js | 183 +++++++++++++++--- test/markup/fsharp/attributes.expect.txt | 6 +- test/markup/fsharp/bang-keywords.expect.txt | 2 +- test/markup/fsharp/bang-keywords.txt | 2 +- test/markup/fsharp/comments.expect.txt | 18 +- .../fsharp/computation-expressions.expect.txt | 10 +- .../fsharp/fsi-and-preprocessor.expect.txt | 6 +- test/markup/fsharp/generic-types.expect.txt | 43 ---- test/markup/fsharp/generic-types.txt | 43 ---- test/markup/fsharp/numbers.expect.txt | 10 +- test/markup/fsharp/operators.expect.txt | 95 ++++++--- test/markup/fsharp/operators.txt | 49 +++++ test/markup/fsharp/strings.expect.txt | 36 ++-- test/markup/fsharp/types.expect.txt | 143 ++++++++++++++ test/markup/fsharp/types.txt | 143 ++++++++++++++ 16 files changed, 605 insertions(+), 186 deletions(-) delete mode 100644 test/markup/fsharp/generic-types.expect.txt delete mode 100644 test/markup/fsharp/generic-types.txt create mode 100644 test/markup/fsharp/types.expect.txt create mode 100644 test/markup/fsharp/types.txt diff --git a/CHANGES.md b/CHANGES.md index 5ca677923e..6a8581edfd 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,6 +5,7 @@ Grammars: - fix(python) def, class keywords detected mid-identifier (#3381) [Josh Goebel][] - fix(python) Fix recognition of numeric literals followed by keywords without whitespace (#2985) [Richard Gibson][] - enh(swift) add SE-0290 unavailability condition (#3382) [Bradley Mackey][] +- fix(fsharp) Highlight operators, match type names only in type annotations, support quoted identifiers, and other smaller fixes. [Melvyn Laïly][] - enh(java) add `sealed` and `non-sealed` keywords (#3386) [Bradley Mackey][] - fix(clojure) Several issues with Clojure highlighting (#3397) [Björn Ebbinghaus][] - fix(clojure) `comment` macro catches more than it should (#3395) @@ -22,6 +23,7 @@ Developer Tools: [Richard Gibson]: https://github.com/gibson042 [Bradley Mackey]: https://github.com/bradleymackey +[Melvyn Laïly]: https://github.com/mlaily [Björn Ebbinghaus]: https://github.com/MrEbbinghaus [Josh Goebel]: https://github.com/joshgoebel diff --git a/src/languages/fsharp.js b/src/languages/fsharp.js index 81f30539d3..f130d0c71f 100644 --- a/src/languages/fsharp.js +++ b/src/languages/fsharp.js @@ -119,7 +119,9 @@ export default function(hljs) { "__SOURCE_FILE__" ]; - const TYPES = [ + // Since it's possible to re-bind/shadow names (e.g. let char = 'c'), + // these builtin types should only be matched when a type name is expected. + const KNOWN_TYPES = [ // basic types "bool", "byte", @@ -157,7 +159,9 @@ export default function(hljs) { "nativeptr", "obj", "outref", - "voidptr" + "voidptr", + // other important FSharp types + "Result" ]; const BUILTINS = [ @@ -172,6 +176,7 @@ export default function(hljs) { "dict", "readOnlyDict", "set", + "get", "enum", "sizeof", "typeof", @@ -201,7 +206,6 @@ export default function(hljs) { ]; const ALL_KEYWORDS = { - type: TYPES, keyword: KEYWORDS, literal: LITERALS, built_in: BUILTINS, @@ -221,16 +225,138 @@ export default function(hljs) { ] }; - // 'a or ^a + // Most identifiers can contain apostrophes + const IDENTIFIER_RE = /[a-zA-Z_](\w|')*/; + + const QUOTED_IDENTIFIER = { + scope: 'variable', + begin: /``/, + end: /``/ + }; + + // 'a or ^a where a can be a ``quoted identifier`` + const BEGIN_GENERIC_TYPE_SYMBOL_RE = /\B('|\^)/ const GENERIC_TYPE_SYMBOL = { - match: regex.concat(/('|\^)/, hljs.UNDERSCORE_IDENT_RE), scope: 'symbol', + variants: [ + // the type name is a quoted identifier: + { match: regex.concat(BEGIN_GENERIC_TYPE_SYMBOL_RE, /``.*?``/) }, + // the type name is a normal identifier (we don't use IDENTIFIER_RE because there cannot be another apostrophe here): + { match: regex.concat(BEGIN_GENERIC_TYPE_SYMBOL_RE, hljs.UNDERSCORE_IDENT_RE) } + ], relevance: 0 }; + const makeOperatorMode = function({ includeEqual }) { + // List or symbolic operator characters from the FSharp Spec 4.1, minus the dot, and with `?` added, used for nullable operators. + let allOperatorChars; + if (includeEqual) + allOperatorChars = "!%&*+-/<=>@^|~?"; + else + allOperatorChars = "!%&*+-/<>@^|~?"; + const OPERATOR_CHARS = Array.from(allOperatorChars); + const OPERATOR_CHAR_RE = regex.concat('[', ...OPERATOR_CHARS.map(regex.escape), ']'); + // The lone dot operator is special. It cannot be redefined, and we don't want to highlight it. It can be used as part of a multi-chars operator though. + const OPERATOR_CHAR_OR_DOT_RE = regex.either(OPERATOR_CHAR_RE, /\./); + // When a dot is present, it must be followed by another operator char: + const OPERATOR_FIRST_CHAR_OF_MULTIPLE_RE = regex.concat(OPERATOR_CHAR_OR_DOT_RE, regex.lookahead(OPERATOR_CHAR_OR_DOT_RE)); + const SYMBOLIC_OPERATOR_RE = regex.either( + regex.concat(OPERATOR_FIRST_CHAR_OF_MULTIPLE_RE, OPERATOR_CHAR_OR_DOT_RE, '*'), // Matches at least 2 chars operators + regex.concat(OPERATOR_CHAR_RE, '+'), // Matches at least one char operators + ); + return { + scope: 'operator', + match: regex.either( + // symbolic operators: + SYMBOLIC_OPERATOR_RE, + // other symbolic keywords: + // Type casting and conversion operators: + /:\?>/, + /:\?/, + /:>/, + /:=/, // Reference cell assignment + /::?/, // : or :: + /\$/), // A single $ can be used as an operator + relevance: 0 + }; + } + + const OPERATOR = makeOperatorMode({ includeEqual: true }); + // This variant is used when matching '=' should end a parent mode: + const OPERATOR_WITHOUT_EQUAL = makeOperatorMode({ includeEqual: false }); + + const makeTypeAnnotationMode = function(prefix, prefixScope) { + return { + begin: regex.concat( // a type annotation is a + prefix, // should be a colon or the 'of' keyword + regex.lookahead( // that has to be followed by + regex.concat( + /\s*/, // optional space + regex.either( // then either of: + /\w/, // word + /'/, // generic type name + /\^/, // generic type name + /#/, // flexible type name + /``/, // quoted type name + /\(/, // parens type expression + /{\|/, // anonymous type annotation + )))), + beginScope: prefixScope, + // BUG: because ending with \n is necessary for some cases, multi-line type annotations are not properly supported. + // Examples where \n is required at the end: + // - abstract member definitions in classes: abstract Property : int * string + // - return type annotations: let f f' = f' () : returnTypeAnnotation + // - record fields definitions: { A : int \n B : string } + end: regex.lookahead( + regex.either( + /\n/, + /=/)), + relevance: 0, + // we need the known types, and we need the type constraint keywords and literals. e.g.: when 'a : null + keywords: hljs.inherit(ALL_KEYWORDS, { type: KNOWN_TYPES }), + contains: [ + COMMENT, + GENERIC_TYPE_SYMBOL, + hljs.inherit(QUOTED_IDENTIFIER, { scope: null }), // match to avoid strange patterns inside that may break the parsing + OPERATOR_WITHOUT_EQUAL + ] + }; + } + + const TYPE_ANNOTATION = makeTypeAnnotationMode(/:/, 'operator'); + const DISCRIMINATED_UNION_TYPE_ANNOTATION = makeTypeAnnotationMode(/\bof\b/, 'keyword'); + + // type MyType<'a> = ... + const TYPE_DECLARATION = { + begin: [ + /(^|\s+)/, // prevents matching the following: `match s.stype with` + /type/, + /\s+/, + IDENTIFIER_RE + ], + beginScope: { + 2: 'keyword', + 4: 'title.class' + }, + end: regex.lookahead(/\(|=|$/), + keywords: ALL_KEYWORDS, // match keywords in type constraints. e.g.: when 'a : null + contains: [ + COMMENT, + hljs.inherit(QUOTED_IDENTIFIER, { scope: null }), // match to avoid strange patterns inside that may break the parsing + GENERIC_TYPE_SYMBOL, + { + // For visual consistency, highlight type brackets as operators. + scope: 'operator', + match: /<|>/ + }, + TYPE_ANNOTATION // generic types can have constraints, which are type annotations. e.g. type MyType<'T when 'T : delegate> = + ] + }; + const COMPUTATION_EXPRESSION = { // computation expressions: scope: 'computation-expression', + // BUG: might conflict with record deconstruction. e.g. let f { Name = name } = name // will highlight f match: /\b[_a-z]\w*(?=\s*\{)/ }; @@ -365,10 +491,13 @@ export default function(hljs) { CHAR_LITERAL, BANG_KEYWORD_MODE, COMMENT, + QUOTED_IDENTIFIER, + TYPE_ANNOTATION, COMPUTATION_EXPRESSION, PREPROCESSOR, NUMBER, - GENERIC_TYPE_SYMBOL + GENERIC_TYPE_SYMBOL, + OPERATOR ]; const STRING = { variants: [ @@ -397,42 +526,32 @@ export default function(hljs) { BANG_KEYWORD_MODE, STRING, COMMENT, + QUOTED_IDENTIFIER, + TYPE_DECLARATION, { - // type MyType<'a> = ... - begin: [ - /type/, - /\s+/, - hljs.UNDERSCORE_IDENT_RE - ], - beginScope: { - 1: 'keyword', - 3: 'title.class' - }, - end: regex.lookahead(/\(|=|$/), - contains: [ - GENERIC_TYPE_SYMBOL - ] - }, - { - // [] + // e.g. [] or [<``module``: MyCustomAttributeThatWorksOnModules>] + // or [] scope: 'meta', - begin: /^\s*\[\]/), + begin: /\[\]/, relevance: 2, contains: [ - { - scope: 'string', - begin: /"/, - end: /"/ - }, + QUOTED_IDENTIFIER, + // can contain any constant value + TRIPLE_QUOTED_STRING, + VERBATIM_STRING, + QUOTED_STRING, + CHAR_LITERAL, NUMBER ] }, + DISCRIMINATED_UNION_TYPE_ANNOTATION, + TYPE_ANNOTATION, COMPUTATION_EXPRESSION, PREPROCESSOR, NUMBER, - GENERIC_TYPE_SYMBOL + GENERIC_TYPE_SYMBOL, + OPERATOR ] }; } diff --git a/test/markup/fsharp/attributes.expect.txt b/test/markup/fsharp/attributes.expect.txt index 8543437864..5fb83bfcf3 100644 --- a/test/markup/fsharp/attributes.expect.txt +++ b/test/markup/fsharp/attributes.expect.txt @@ -1,4 +1,4 @@ // Strings and numbers are highlighted inside the attribute -[<Foo>] -[<Bar("bar"); Foo(1, 2)>] -let x () = () \ No newline at end of file +[<Foo>] +[<Bar("bar"); Foo(1, 2)>] +let x () = () \ No newline at end of file diff --git a/test/markup/fsharp/bang-keywords.expect.txt b/test/markup/fsharp/bang-keywords.expect.txt index 56aa58dc26..c47d939e94 100644 --- a/test/markup/fsharp/bang-keywords.expect.txt +++ b/test/markup/fsharp/bang-keywords.expect.txt @@ -1 +1 @@ -let! (result2 : byte[]) = stream.AsyncRead(bufferSize) +let! (result2 : byte[]) = stream.AsyncRead(bufferSize) \ No newline at end of file diff --git a/test/markup/fsharp/bang-keywords.txt b/test/markup/fsharp/bang-keywords.txt index 5824ca88db..796afd6609 100644 --- a/test/markup/fsharp/bang-keywords.txt +++ b/test/markup/fsharp/bang-keywords.txt @@ -1 +1 @@ -let! (result2 : byte[]) = stream.AsyncRead(bufferSize) +let! (result2 : byte[]) = stream.AsyncRead(bufferSize) diff --git a/test/markup/fsharp/comments.expect.txt b/test/markup/fsharp/comments.expect.txt index bd0f7d6a23..7d71bcbd14 100644 --- a/test/markup/fsharp/comments.expect.txt +++ b/test/markup/fsharp/comments.expect.txt @@ -14,12 +14,12 @@ asdf *) -let index = +let index = len - |> float - |> Operators.(*) 0.1 // (*) here is not comment - |> Operators.(+) 1 // (+) here is not comment - |> Operators.(-) len // (-) here is not comment + |> float + |> Operators.(*) 0.1 // (*) here is not comment + |> Operators.(+) 1 // (+) here is not comment + |> Operators.(-) len // (-) here is not comment // foobar @@ -34,11 +34,11 @@ asdf /// Longer comments can be associated with a type or member through /// the remarks tag. /// </remarks> -let x = () +let x = () // the next one is not a comment -(*) (*) +(*) (*) -/* +/* this one is not a valid comment either -*/ \ No newline at end of file +*/ \ No newline at end of file diff --git a/test/markup/fsharp/computation-expressions.expect.txt b/test/markup/fsharp/computation-expressions.expect.txt index a78a366724..76cb4486bd 100644 --- a/test/markup/fsharp/computation-expressions.expect.txt +++ b/test/markup/fsharp/computation-expressions.expect.txt @@ -3,21 +3,21 @@ open System.Threading.Tasks // Single line, and contains a capital letter -let unitTask = unitTask { return () } +let unitTask = unitTask { return () } -let work = +let work = async { - let delayTask () = + let delayTask () = // Nested computation task { printfn "Delay..." do! Task.Delay 1000 return 42 } - let! result = delayTask () |> Async.AwaitTask + let! result = delayTask () |> Async.AwaitTask printfn "Async F# sleep..." do! Async.Sleep 1000 return result } -let result = work |> Async.RunSynchronously \ No newline at end of file +let result = work |> Async.RunSynchronously \ No newline at end of file diff --git a/test/markup/fsharp/fsi-and-preprocessor.expect.txt b/test/markup/fsharp/fsi-and-preprocessor.expect.txt index 6889c0e9ef..181ff72bfb 100644 --- a/test/markup/fsharp/fsi-and-preprocessor.expect.txt +++ b/test/markup/fsharp/fsi-and-preprocessor.expect.txt @@ -7,7 +7,7 @@ #nowarn #if DEBUG // whitespace is allowed before -let x = 0 #if DEBUG // but the preprocessor directive must be the first non-whitespace +let x = 0 #if DEBUG // but the preprocessor directive must be the first non-whitespace #IF asdf // should not match wrongly cased keywords #iftest // should not match @@ -15,8 +15,8 @@ #r "file.dll";; // Reference (dynamically load) the given DLL #i "package source uri";; // Include package source uri when searching for packages #I "path";; // Add the given search path for referenced DLLs -#load "file.fs" ...;; // Load the given file(s) as if compiled and referenced -#time ["on"|"off"];; // Toggle timing on/off +#load "file.fs" ...;; // Load the given file(s) as if compiled and referenced +#time ["on"|"off"];; // Toggle timing on/off #help;; // Display help #r "nuget:FSharp.Data, 3.1.2";; // Load Nuget Package 'FSharp.Data' version '3.1.2' #r "nuget:FSharp.Data";; // Load Nuget Package 'FSharp.Data' with the highest version diff --git a/test/markup/fsharp/generic-types.expect.txt b/test/markup/fsharp/generic-types.expect.txt deleted file mode 100644 index e1a5aa0414..0000000000 --- a/test/markup/fsharp/generic-types.expect.txt +++ /dev/null @@ -1,43 +0,0 @@ -// Primarily testing for generic parameters highlighting... - -type Ref<'a> = -{ mutable contents: 'a } - -type Bla<'a> = {X: string} -type Blah< - 'a - > = { x: 'a } -type Blah < - 'a - > = { x: 'a } -type Bla <'a> = {X: string} -let inline asdf x: Bla<'a> = {X = ""} - -let inline asdf x: Bla<^a> = {X = ""} -let inline asdf x: Bla< ^a > = {X = ""} - -let genericSumUnits ( x : float<'u>) (y: float<'u>) = x + y - -let inline konst x _ = x - -type CFunctor() = - static member inline fmap (f: ^a -> ^b, a: ^a list) = List.map f a - static member inline fmap (f: ^a -> ^b, a: ^a option) = - match a with - | None -> None - | Some x -> Some (f x) - - // default implementation of replace - static member inline replace< ^a, ^b, ^c, ^d, ^e when ^a :> CFunctor and (^a or ^d): (static member fmap: (^b -> ^c) * ^d -> ^e) > (a, f) = - ((^a or ^d) : (static member fmap : (^b -> ^c) * ^d -> ^e) (konst a, f)) - - // call overridden replace if present - static member inline replace< ^a, ^b, ^c when ^b: (static member replace: ^a * ^b -> ^c)>(a: ^a, f: ^b) = - (^b : (static member replace: ^a * ^b -> ^c) (a, f)) - -let inline replace_instance< ^a, ^b, ^c, ^d when (^a or ^c): (static member replace: ^b * ^c -> ^d)> (a: ^b, f: ^c) = - ((^a or ^c): (static member replace: ^b * ^c -> ^d) (a, f)) - -// Note the concrete type 'CFunctor' specified in the signature -let inline replace (a: ^a) (f: ^b): ^a0 when (CFunctor or ^b): (static member replace: ^a * ^b -> ^a0) = - replace_instance<CFunctor, _, _, _> (a, f) \ No newline at end of file diff --git a/test/markup/fsharp/generic-types.txt b/test/markup/fsharp/generic-types.txt deleted file mode 100644 index a700edc5be..0000000000 --- a/test/markup/fsharp/generic-types.txt +++ /dev/null @@ -1,43 +0,0 @@ -// Primarily testing for generic parameters highlighting... - -type Ref<'a> = -{ mutable contents: 'a } - -type Bla<'a> = {X: string} -type Blah< - 'a - > = { x: 'a } -type Blah < - 'a - > = { x: 'a } -type Bla <'a> = {X: string} -let inline asdf x: Bla<'a> = {X = ""} - -let inline asdf x: Bla<^a> = {X = ""} -let inline asdf x: Bla< ^a > = {X = ""} - -let genericSumUnits ( x : float<'u>) (y: float<'u>) = x + y - -let inline konst x _ = x - -type CFunctor() = - static member inline fmap (f: ^a -> ^b, a: ^a list) = List.map f a - static member inline fmap (f: ^a -> ^b, a: ^a option) = - match a with - | None -> None - | Some x -> Some (f x) - - // default implementation of replace - static member inline replace< ^a, ^b, ^c, ^d, ^e when ^a :> CFunctor and (^a or ^d): (static member fmap: (^b -> ^c) * ^d -> ^e) > (a, f) = - ((^a or ^d) : (static member fmap : (^b -> ^c) * ^d -> ^e) (konst a, f)) - - // call overridden replace if present - static member inline replace< ^a, ^b, ^c when ^b: (static member replace: ^a * ^b -> ^c)>(a: ^a, f: ^b) = - (^b : (static member replace: ^a * ^b -> ^c) (a, f)) - -let inline replace_instance< ^a, ^b, ^c, ^d when (^a or ^c): (static member replace: ^b * ^c -> ^d)> (a: ^b, f: ^c) = - ((^a or ^c): (static member replace: ^b * ^c -> ^d) (a, f)) - -// Note the concrete type 'CFunctor' specified in the signature -let inline replace (a: ^a) (f: ^b): ^a0 when (CFunctor or ^b): (static member replace: ^a * ^b -> ^a0) = - replace_instance (a, f) \ No newline at end of file diff --git a/test/markup/fsharp/numbers.expect.txt b/test/markup/fsharp/numbers.expect.txt index 2fa768f80d..77a1bd63d3 100644 --- a/test/markup/fsharp/numbers.expect.txt +++ b/test/markup/fsharp/numbers.expect.txt @@ -31,10 +31,10 @@ 9999999999999999999999999999I // Distance, meters. -[<Measure>] type m +[<Measure>] type m // Time, seconds. -[<Measure>] type s +[<Measure>] type s -let v1 = 3.1<m/s> -let x1 = 1.2<m> -let t1 = 1.0<s> \ No newline at end of file +let v1 = 3.1<m/s> +let x1 = 1.2<m> +let t1 = 1.0<s> \ No newline at end of file diff --git a/test/markup/fsharp/operators.expect.txt b/test/markup/fsharp/operators.expect.txt index 188baa2275..ac71ba62f3 100644 --- a/test/markup/fsharp/operators.expect.txt +++ b/test/markup/fsharp/operators.expect.txt @@ -1,28 +1,77 @@ - >= <= <> > < = + - * / % - >=? <=? <>? >? <? =? +? -? *? /? %? -?>=? ?<=? ?<>? ?>? ?<? ?=? ?+? ?-? ?*? ?/? ?%? -?>= ?<= ?<> ?> ?< ?= ?+ ?- ?* ?/ ?% - -** - -<- -> -.. -:: -:> :? :?> -<< >> -<<< >>> ~~~ ^^^ &&& ||| -| || -<| <|| <||| -|> ||> |||> -~~ ~- ~+ - -? ^ ! -!= == -& && + >= <= <> > < = + - * / % + >=? <=? <>? >? <? =? +? -? *? /? %? +?>=? ?<=? ?<>? ?>? ?<? ?=? ?+? ?-? ?*? ?/? ?%? +?>= ?<= ?<> ?> ?< ?= ?+ ?- ?* ?/ ?% + +** + +<- -> +.. +:: +:> :? :?> +<< >> +<<< >>> ~~~ ^^^ &&& ||| +| || +<| <|| <||| +|> ||> |||> +~~ ~- ~+ + +? ^ ! +!= == +& && + +let array = [| 0 |] +let anonymousRecord = {| x = 42 |} +let range = [ for i in 0..10 -> i ] + +// Custom operators + +let inline (+?) (x: int) (y: int) = x + 2*y +printf "%d" (10 +? 1) + +let inline (<!>) (f: 'T->'U) (x: '``Functor<'T>``) : '``Functor<'U>`` = Map.Invoke f x + +let inline (<<|) (f: 'T->'U) (x: '``Functor<'T>``) : '``Functor<'U>`` = Map.Invoke f x + +let inline (|>>) (x: '``Functor<'T>``) (f: 'T->'U) : '``Functor<'U>`` = Map.Invoke f x + +let inline (<*>) (f: '``Applicative<'T -> 'U>``) (x: '``Applicative<'T>``) : '``Applicative<'U>`` = Apply.Invoke f x + +let inline ( *>) (x: '``Applicative<'T>``) (y: '``Applicative<'U>``) : '``Applicative<'U>`` = ((fun (_: 'T) (k: 'U) -> k) <!> x : '``Applicative<'U->'U>``) <*> y + +let inline (<* ) (x: '``Applicative<'U>``) (y: '``Applicative<'T>``): '``Applicative<'U>`` = ((fun (k: 'U) (_: 'T) -> k ) <!> x : '``Applicative<'T->'U>``) <*> y + +let inline (<**>) (x: '``Applicative<'T>``) : '``Applicative<'T -> 'U>``->'``Applicative<'U>`` = flip (<*>) x + +let inline (>>=) (x: '``Monad<'T>``) (f: 'T->'``Monad<'U>``) : '``Monad<'U>`` = Bind.Invoke x f + +let inline (=<<) (f: 'T->'``Monad<'U>``) (x: '``Monad<'T>``) : '``Monad<'U>`` = Bind.Invoke x f + +let inline (>=>) (f: 'T->'``Monad<'U>``) (g: 'U->'``Monad<'V>``) : 'T -> '``Monad<'V>`` = fun x -> Bind.Invoke (f x) g + +let inline (<=<) (g: 'b->'``Monad<'V>``) (f: 'T->'``Monad<'U>``) : 'T -> '``Monad<'V>`` = fun x -> Bind.Invoke (f x) g + +let inline (++) (x: 'Monoid) (y: 'Monoid) : 'Monoid = Plus.Invoke x y + +let inline (<|>) (x: '``Functor<'T>``) (y: '``Functor<'T>``) : '``Functor<'T>`` = Append.Invoke x y + +let inline (=>>) (s: '``Comonad<'T>``) (g: '``Comonad<'T>``->'U) : '``Comonad<'U>`` = Extend.Invoke g s + +// Code quotation open Microsoft.FSharp.Quotations // A typed code quotation. -let expr : Expr<int> = <@ 1 + 1 @> +let expr : Expr<int> = <@ 1 + 1 @> // An untyped code quotation. -let expr2 : Expr = <@@ 1 + 1 @@> \ No newline at end of file +let expr2 : Expr = <@@ 1 + 1 @@> + +// Active patterns + +let (|Integer|_|) (str: string) = + let mutable intvalue = 0 + if System.Int32.TryParse(str, &intvalue) then Some(intvalue) + else None + +let (|Even|Odd|) input = if input % 2 = 0 then Even else Odd +// \ No newline at end of file diff --git a/test/markup/fsharp/operators.txt b/test/markup/fsharp/operators.txt index 97272294f8..503eb76295 100644 --- a/test/markup/fsharp/operators.txt +++ b/test/markup/fsharp/operators.txt @@ -21,8 +21,57 @@ != == & && +let array = [| 0 |] +let anonymousRecord = {| x = 42 |} +let range = [ for i in 0..10 -> i ] + +// Custom operators + +let inline (+?) (x: int) (y: int) = x + 2*y +printf "%d" (10 +? 1) + +let inline () (f: 'T->'U) (x: '``Functor<'T>``) : '``Functor<'U>`` = Map.Invoke f x + +let inline (<<|) (f: 'T->'U) (x: '``Functor<'T>``) : '``Functor<'U>`` = Map.Invoke f x + +let inline (|>>) (x: '``Functor<'T>``) (f: 'T->'U) : '``Functor<'U>`` = Map.Invoke f x + +let inline (<*>) (f: '``Applicative<'T -> 'U>``) (x: '``Applicative<'T>``) : '``Applicative<'U>`` = Apply.Invoke f x + +let inline ( *>) (x: '``Applicative<'T>``) (y: '``Applicative<'U>``) : '``Applicative<'U>`` = ((fun (_: 'T) (k: 'U) -> k) x : '``Applicative<'U->'U>``) <*> y + +let inline (<* ) (x: '``Applicative<'U>``) (y: '``Applicative<'T>``): '``Applicative<'U>`` = ((fun (k: 'U) (_: 'T) -> k ) x : '``Applicative<'T->'U>``) <*> y + +let inline (<**>) (x: '``Applicative<'T>``) : '``Applicative<'T -> 'U>``->'``Applicative<'U>`` = flip (<*>) x + +let inline (>>=) (x: '``Monad<'T>``) (f: 'T->'``Monad<'U>``) : '``Monad<'U>`` = Bind.Invoke x f + +let inline (=<<) (f: 'T->'``Monad<'U>``) (x: '``Monad<'T>``) : '``Monad<'U>`` = Bind.Invoke x f + +let inline (>=>) (f: 'T->'``Monad<'U>``) (g: 'U->'``Monad<'V>``) : 'T -> '``Monad<'V>`` = fun x -> Bind.Invoke (f x) g + +let inline (<=<) (g: 'b->'``Monad<'V>``) (f: 'T->'``Monad<'U>``) : 'T -> '``Monad<'V>`` = fun x -> Bind.Invoke (f x) g + +let inline (++) (x: 'Monoid) (y: 'Monoid) : 'Monoid = Plus.Invoke x y + +let inline (<|>) (x: '``Functor<'T>``) (y: '``Functor<'T>``) : '``Functor<'T>`` = Append.Invoke x y + +let inline (=>>) (s: '``Comonad<'T>``) (g: '``Comonad<'T>``->'U) : '``Comonad<'U>`` = Extend.Invoke g s + +// Code quotation + open Microsoft.FSharp.Quotations // A typed code quotation. let expr : Expr = <@ 1 + 1 @> // An untyped code quotation. let expr2 : Expr = <@@ 1 + 1 @@> + +// Active patterns + +let (|Integer|_|) (str: string) = + let mutable intvalue = 0 + if System.Int32.TryParse(str, &intvalue) then Some(intvalue) + else None + +let (|Even|Odd|) input = if input % 2 = 0 then Even else Odd +// \ No newline at end of file diff --git a/test/markup/fsharp/strings.expect.txt b/test/markup/fsharp/strings.expect.txt index fad7761fa2..75e6ceaf31 100644 --- a/test/markup/fsharp/strings.expect.txt +++ b/test/markup/fsharp/strings.expect.txt @@ -26,7 +26,7 @@ bar""" '\u0041' '\U0001F47D' -$"{1+1}" +$"{1+1}" "" // end "fo\"o" // end @@ -53,7 +53,7 @@ bar""" // end '\u0041' // end '\U0001F47D' // end -$"{1+1}" // end +$"{1+1}" // end 0 "string \'" // end @@ -71,15 +71,15 @@ string" // end string""" // end 5 $"interpola\ {{ -ted \' {1 + 1 // can contain comments and " in placeholders +ted \' {1 + 1 // can contain comments and " in placeholders }string" // end 6 $@"interpolated "" \' {{ -verbatim{1 + 1 // can contain comments and " in placeholders +verbatim{1 + 1 // can contain comments and " in placeholders }string" // end 7 @$"interpolated "" \' {{ -verbatim{1 + 1 // can contain comments and " in placeholders +verbatim{1 + 1 // can contain comments and " in placeholders }string" // end 8 $"""interpolated triple quoted " \' {{ { (sprintf "%d%s" 42) @@ -88,15 +88,15 @@ verbatim{1 + 9 $"""test { @"{it's not a placeholder!}" } asdf""" // end 10 -$"""test { $"but this is:{1+1}" } asdf""" // end +$"""test { $"but this is:{1+1}" } asdf""" // end 11 $"interpola\ {{ -ted \' {1 + 1 // can contain comments in placeholders +ted \' {1 + 1 // can contain comments in placeholders // placeholders cannot contain " }string" // end 12 $@"interpolated "" \' {{ -verbatim{1 + 1 // can contain comments in placeholders +verbatim{1 + 1 // can contain comments in placeholders // placeholders cannot contain " }string" // end 13 @@ -104,14 +104,14 @@ verbatim{1 + // and comments... }string""" // end 14 -let list = [1] -$"""test{ list |> List.map (fun x -> x + 1) }test""" // end +let list = [1] +$"""test{ list |> List.map (fun x -> x + 1) }test""" // end 15 $"test{1 (* " Does it break the string? " *) }test" // end 16 $"test\ { - let x = 42 // valid comment contains " quote " ... + let x = 42 // valid comment contains " quote " ... x (* " Does it break the string? " *) }test" // end 17 @@ -119,18 +119,18 @@ verbatim{1 + { #if DEBUG #endif - let asdf = "}" // """ does it break? - let x = $@"test{2+2 (* " what about double nesting? " *) }test" - let lit = 0 - let x = unitTask { return () } + let asdf = "}" // """ does it break? + let x = $@"test{2+2 (* " what about double nesting? " *) }test" + let lit = 0 + let x = unitTask { return () } asdf }test""" 18 -let list = [1] +let list = [1] $"""test { - let asdf = "}" - list |> List.map (fun x -> x + 1) + let asdf = "}" + list |> List.map (fun x -> x + 1) }test""" // end 19 \ No newline at end of file diff --git a/test/markup/fsharp/types.expect.txt b/test/markup/fsharp/types.expect.txt new file mode 100644 index 0000000000..0ad8b0c6a7 --- /dev/null +++ b/test/markup/fsharp/types.expect.txt @@ -0,0 +1,143 @@ +// Testing type definition and type annotation highlighting: + +let test'test = 15 // compiles +let bla = test'test // compiles +type test'test<'a> = Test<'a> // compiles + +let ``type`` = "hello" // compiles +let ``type` is a keyword but I can use it in my 'd funky \ \\ \n " ^d binding`` = "hello" // compiles + +// Type names (here with char) can be used to redefine bindings: +let char : char = + let char = box (char "a") + let result = unbox<char> char + try () + with | :? ArgumentException -> failwith "..." + result + +// All the following type annotation examples are valid F# +type ``my = type`` = {a:string} +let x : char array = [|'a'|] +let f f' = f' () : 'returnType // the type annotation should end now +and not color this as a type. let's end this with an end pattern: = +let f (a: int, (b: string)) = () +let f (a: int, b: string) = () +let anonymousRecordAnnotation : {| X: string; Y: int array * string |} = ... +let nested : {| X: string; Y: {| Nested: bool |} |} = () +let test (a: {| X: string; (* this is a comment *) Y: {| Nested: bool |} |}) = () +let f (a: (string[])) = a +let f (a: int -> (unit -> string) -> string) (b: ('a -> 'b -> _ -> ``my = type`` -> {| Prop: '``quoted``|}) -> 'a list -> 'b list) = a +let f (a: ('a -> 'b) -> 'a list -> 'b list -> (unit -> string) -> {| X: string |}) : _ * (int -> unit) = a, (fun x -> ()) +let f (a: ('a -> 'b) // multiline! (currently not supported) + -> {| X: (int -> {| Y: (string -> (unit (*this is getting*))(*really nested...*)); A: ``my = type`` |}) |} + -> 'b list -> (unit -> string) -> {| X: string |}) = a +let test : string (* this is a comment *) = ... +let f (a: 'a when 'a : null, b: string) = () +let iterate2 (f : unit -> #seq<int>) = + for e in f() do printfn "%d" e +type record = + { X: int -> ('a -> 'b) -> (unit -> string) -> 'a list -> 'b list // comment + Y: {| Bla: string (*comment*) array -> unit |} } +type record = + { X: string // comment + Y: {| + Bla: string (*comment*) array + -> unit |} } + +type FancyClass(thing:int, var2 : string -> string, ``ddzdz``: string list, extra) as xxx = + + let pf() = xxx.Test() + let mutable myInternalValue = null + + member xxx.Test() = "F#" + + // A read-only property. + member __.MyReadOnlyProperty = myInternalValue + // A write-only property. + member __.MyWriteOnlyProperty with set (value) = myInternalValue <- value + // A read-write property. + member __.MyReadWriteProperty + with get () = myInternalValue + and set (value) = myInternalValue <- value + + member __.ReadAndWriteWithSignature + with get (count : int) : string = string count + and set (value : int) : unit = failwith "" + + member __.MyReadWriteProperty with get () = myInternalValue + member __.MyReadWriteProperty with set (value) = myInternalValue <- value + + abstract Update : int * string * string option * obj -> FancyClass + default this.Update (thing:int, var2 : string, ``name with spaces``: string option, extra) = this + + member val Property1 = thing + member val Property2 = "" with get, set + +// Testing for generic parameters highlighting: + +type Ref<'a> = +{ mutable contents: 'a } + +type Bla<'a> = {X: string} +type Blah< + 'a + > = { x: 'a } +type Blah < + 'a + > = { x: 'a } +type Bla <'a> = {X: string} +let inline asdf x: Bla<'a> = {X = ""} + +let inline asdf x: Bla<^a> = {X = ""} +let inline asdf x: Bla< ^a > = {X = ""} + +let a : '``asdf``_asdf = () // This is not valid and should not be parsed as a single generic type symbol + +type MyType<'T when 'T : null> = ... +type MyType<'T when 'T : unmanaged> = ... +type MyType<'T when 'T : (member Method1 : 'T -> int)> = ... +type MyType<'T when 'T : delegate<obj * System.EventArgs, unit>> = ... + +let genericSumUnits ( x : float<'u>) (y: float<'u>) = x + y + +let inline konst x _ = x + +type CFunctor() = + static member inline fmap (f: ^a -> ^b, a: ^a list) = List.map f a + static member inline fmap (f: ^a -> ^b, a: ^a option) = + match a with + | None -> None + | Some x -> Some (f x) + + // default implementation of replace + static member inline replace< ^a, ^b, ^c, ^d, ^e when ^a :> CFunctor and (^a or ^d): (static member fmap: (^b -> ^c) * ^d -> ^e) > (a, f) = + ((^a or ^d) : (static member fmap : (^b -> ^c) * ^d -> ^e) (konst a, f)) + + // call overridden replace if present + static member inline replace< ^a, ^b, ^c when ^b: (static member replace: ^a * ^b -> ^c)>(a: ^a, f: ^b) = + (^b : (static member replace: ^a * ^b -> ^c) (a, f)) + +let inline replace_instance< ^a, ^b, ^c, ^d when (^a or ^c): (static member replace: ^b * ^c -> ^d)> (a: ^b, f: ^c) = + ((^a or ^c): (static member replace: ^b * ^c -> ^d) (a, f)) + +// Note the concrete type 'CFunctor' specified in the signature +let inline replace (a: ^a) (f: ^b): ^a0 when (CFunctor or ^b): (static member replace: ^a * ^b -> ^a0) = + replace_instance<CFunctor, _, _, _> (a, f) + +type DUType = + | CaseA + | CaseB of int + | CaseC of (int * (string * string) list) + | CaseD of name :string * age:int + | CaseE of client: Client + | CaseF of client: Client (*comment tests*) * (*comment tests*) string * port : int + | CaseG of (obj -> unit) + | CaseH of string * (obj -> unit) + // Check multiple declaration on one line + | CaseI of int | CaseJ of int + | CaseF2 of client: Client // * string * port : int + | FetchDomainsSuccess of Result<int list * ``type with spaces`` * int, ``type * with * spaces``> + | CaseK of ``var with spaces``: string + | CaseL of ``var with spaces``: ``type with spaces`` + | CaseM of v1 : ``type with spaces`` + | CaseN of ``type with spaces`` \ No newline at end of file diff --git a/test/markup/fsharp/types.txt b/test/markup/fsharp/types.txt new file mode 100644 index 0000000000..490afa4e46 --- /dev/null +++ b/test/markup/fsharp/types.txt @@ -0,0 +1,143 @@ +// Testing type definition and type annotation highlighting: + +let test'test = 15 // compiles +let bla = test'test // compiles +type test'test<'a> = Test<'a> // compiles + +let ``type`` = "hello" // compiles +let ``type` is a keyword but I can use it in my 'd funky \ \\ \n " ^d binding`` = "hello" // compiles + +// Type names (here with char) can be used to redefine bindings: +let char : char = + let char = box (char "a") + let result = unbox char + try () + with | :? ArgumentException -> failwith "..." + result + +// All the following type annotation examples are valid F# +type ``my = type`` = {a:string} +let x : char array = [|'a'|] +let f f' = f' () : 'returnType // the type annotation should end now +and not color this as a type. let's end this with an end pattern: = +let f (a: int, (b: string)) = () +let f (a: int, b: string) = () +let anonymousRecordAnnotation : {| X: string; Y: int array * string |} = ... +let nested : {| X: string; Y: {| Nested: bool |} |} = () +let test (a: {| X: string; (* this is a comment *) Y: {| Nested: bool |} |}) = () +let f (a: (string[])) = a +let f (a: int -> (unit -> string) -> string) (b: ('a -> 'b -> _ -> ``my = type`` -> {| Prop: '``quoted``|}) -> 'a list -> 'b list) = a +let f (a: ('a -> 'b) -> 'a list -> 'b list -> (unit -> string) -> {| X: string |}) : _ * (int -> unit) = a, (fun x -> ()) +let f (a: ('a -> 'b) // multiline! (currently not supported) + -> {| X: (int -> {| Y: (string -> (unit (*this is getting*))(*really nested...*)); A: ``my = type`` |}) |} + -> 'b list -> (unit -> string) -> {| X: string |}) = a +let test : string (* this is a comment *) = ... +let f (a: 'a when 'a : null, b: string) = () +let iterate2 (f : unit -> #seq) = + for e in f() do printfn "%d" e +type record = + { X: int -> ('a -> 'b) -> (unit -> string) -> 'a list -> 'b list // comment + Y: {| Bla: string (*comment*) array -> unit |} } +type record = + { X: string // comment + Y: {| + Bla: string (*comment*) array + -> unit |} } + +type FancyClass(thing:int, var2 : string -> string, ``ddzdz``: string list, extra) as xxx = + + let pf() = xxx.Test() + let mutable myInternalValue = null + + member xxx.Test() = "F#" + + // A read-only property. + member __.MyReadOnlyProperty = myInternalValue + // A write-only property. + member __.MyWriteOnlyProperty with set (value) = myInternalValue <- value + // A read-write property. + member __.MyReadWriteProperty + with get () = myInternalValue + and set (value) = myInternalValue <- value + + member __.ReadAndWriteWithSignature + with get (count : int) : string = string count + and set (value : int) : unit = failwith "" + + member __.MyReadWriteProperty with get () = myInternalValue + member __.MyReadWriteProperty with set (value) = myInternalValue <- value + + abstract Update : int * string * string option * obj -> FancyClass + default this.Update (thing:int, var2 : string, ``name with spaces``: string option, extra) = this + + member val Property1 = thing + member val Property2 = "" with get, set + +// Testing for generic parameters highlighting: + +type Ref<'a> = +{ mutable contents: 'a } + +type Bla<'a> = {X: string} +type Blah< + 'a + > = { x: 'a } +type Blah < + 'a + > = { x: 'a } +type Bla <'a> = {X: string} +let inline asdf x: Bla<'a> = {X = ""} + +let inline asdf x: Bla<^a> = {X = ""} +let inline asdf x: Bla< ^a > = {X = ""} + +let a : '``asdf``_asdf = () // This is not valid and should not be parsed as a single generic type symbol + +type MyType<'T when 'T : null> = ... +type MyType<'T when 'T : unmanaged> = ... +type MyType<'T when 'T : (member Method1 : 'T -> int)> = ... +type MyType<'T when 'T : delegate> = ... + +let genericSumUnits ( x : float<'u>) (y: float<'u>) = x + y + +let inline konst x _ = x + +type CFunctor() = + static member inline fmap (f: ^a -> ^b, a: ^a list) = List.map f a + static member inline fmap (f: ^a -> ^b, a: ^a option) = + match a with + | None -> None + | Some x -> Some (f x) + + // default implementation of replace + static member inline replace< ^a, ^b, ^c, ^d, ^e when ^a :> CFunctor and (^a or ^d): (static member fmap: (^b -> ^c) * ^d -> ^e) > (a, f) = + ((^a or ^d) : (static member fmap : (^b -> ^c) * ^d -> ^e) (konst a, f)) + + // call overridden replace if present + static member inline replace< ^a, ^b, ^c when ^b: (static member replace: ^a * ^b -> ^c)>(a: ^a, f: ^b) = + (^b : (static member replace: ^a * ^b -> ^c) (a, f)) + +let inline replace_instance< ^a, ^b, ^c, ^d when (^a or ^c): (static member replace: ^b * ^c -> ^d)> (a: ^b, f: ^c) = + ((^a or ^c): (static member replace: ^b * ^c -> ^d) (a, f)) + +// Note the concrete type 'CFunctor' specified in the signature +let inline replace (a: ^a) (f: ^b): ^a0 when (CFunctor or ^b): (static member replace: ^a * ^b -> ^a0) = + replace_instance (a, f) + +type DUType = + | CaseA + | CaseB of int + | CaseC of (int * (string * string) list) + | CaseD of name :string * age:int + | CaseE of client: Client + | CaseF of client: Client (*comment tests*) * (*comment tests*) string * port : int + | CaseG of (obj -> unit) + | CaseH of string * (obj -> unit) + // Check multiple declaration on one line + | CaseI of int | CaseJ of int + | CaseF2 of client: Client // * string * port : int + | FetchDomainsSuccess of Result + | CaseK of ``var with spaces``: string + | CaseL of ``var with spaces``: ``type with spaces`` + | CaseM of v1 : ``type with spaces`` + | CaseN of ``type with spaces`` From e1abb9b85646517dba60c70229c2aa2ede99e5e9 Mon Sep 17 00:00:00 2001 From: Samia <39127633+samiaab1990@users.noreply.github.com> Date: Tue, 30 Nov 2021 15:17:10 -0500 Subject: [PATCH 18/76] enh(themes) Tweak background color for Gradient Light and Gradient Dark (#3408) --- CHANGES.md | 8 +++++++- highlight.js | 1 + src/styles/gradient-dark.css | 4 ++-- src/styles/gradient-light.css | 7 ++++--- 4 files changed, 14 insertions(+), 6 deletions(-) create mode 160000 highlight.js diff --git a/CHANGES.md b/CHANGES.md index 6a8581edfd..a0b1160598 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -21,11 +21,17 @@ Developer Tools: - (chore) add gzip size compression report (#3400) [Bradley Mackey][] +Themes: + +- Modified background color in css for Gradient Light and Gradient Dark themes [Samia Ali][] + [Richard Gibson]: https://github.com/gibson042 [Bradley Mackey]: https://github.com/bradleymackey [Melvyn Laïly]: https://github.com/mlaily [Björn Ebbinghaus]: https://github.com/MrEbbinghaus [Josh Goebel]: https://github.com/joshgoebel +[Samia Ali]: https://github.com/samiaab1990 + ## Version 11.3.1 @@ -736,6 +742,7 @@ Parser Engine: - (fix) When ignoring a potential match highlighting can terminate early (#2649) [Josh Goebel][] + New themes: - *Gradient Light* by [Samia Ali]() @@ -771,7 +778,6 @@ Language Improvements: [eytienne]: https://github.com/eytienne [sirosen]: https://github.com/sirosen - ## Version 10.1.1 Fixes: diff --git a/highlight.js b/highlight.js new file mode 160000 index 0000000000..10b322dc43 --- /dev/null +++ b/highlight.js @@ -0,0 +1 @@ +Subproject commit 10b322dc436333b04df8295c9bdf4bad324849e0 diff --git a/src/styles/gradient-dark.css b/src/styles/gradient-dark.css index d9e42138c2..4fb49b2378 100644 --- a/src/styles/gradient-dark.css +++ b/src/styles/gradient-dark.css @@ -6,8 +6,8 @@ Gradient Dark (c) Samia Ali .hljs { -background: rgb(80,31,122); -background: linear-gradient(166deg, rgba(80,31,122,1) 0%, rgba(40,32,179,1) 80%); +background-color: #652487; +background-image: linear-gradient(160deg, #652487 0%, #443ac3 35%, #0174b7 68%, #04988e 100%); color:#e7e4eb; } diff --git a/src/styles/gradient-light.css b/src/styles/gradient-light.css index 574534cb56..a5c4f5edc2 100644 --- a/src/styles/gradient-light.css +++ b/src/styles/gradient-light.css @@ -6,8 +6,8 @@ Gradient Light (c) Samia Ali .hljs { -background: rgb(255,253,141); -background: linear-gradient(142deg, rgba(255,253,141,1) 0%, rgba(252,183,255,1) 35%, rgba(144,236,255,1) 100%); +background-color: #f9ccff; +background-image: linear-gradient(295deg, #f9ccff 0%, #e6bbf9 11%, #9ec6f9 32%, #55e6ee 60%, #91f5d1 74%, #f9ffbf 98%); color:#250482; } @@ -46,6 +46,7 @@ color:#01958B; .hljs-section, .hljs-meta .hljs-keyword, + .hljs-symbol, .hljs-type @@ -64,7 +65,7 @@ color:#01958B; .hljs-string { - color: #38c0ff; + color: #2681ab; } From b1990ceb2622c18f99c75b980dfd4ca8a0f0ed6c Mon Sep 17 00:00:00 2001 From: "Jan T. Sott" Date: Fri, 3 Dec 2021 18:51:42 +0100 Subject: [PATCH 19/76] enh(nsis) Update defines pattern to allow `!` (#3417) Defines can include `!`-characters, as seen in this example: https://nsis.sourceforge.io/Check_if_a_file_exists_at_compile_time --- CHANGES.md | 3 ++- src/languages/nsis.js | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index a0b1160598..7d6636393f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -7,6 +7,7 @@ Grammars: - enh(swift) add SE-0290 unavailability condition (#3382) [Bradley Mackey][] - fix(fsharp) Highlight operators, match type names only in type annotations, support quoted identifiers, and other smaller fixes. [Melvyn Laïly][] - enh(java) add `sealed` and `non-sealed` keywords (#3386) [Bradley Mackey][] +- enh(nsis) Update defines pattern to allow `!` (#3417) [idleberg][] - fix(clojure) Several issues with Clojure highlighting (#3397) [Björn Ebbinghaus][] - fix(clojure) `comment` macro catches more than it should (#3395) - fix(clojure) `$` in symbol breaks highlighting @@ -31,7 +32,7 @@ Themes: [Björn Ebbinghaus]: https://github.com/MrEbbinghaus [Josh Goebel]: https://github.com/joshgoebel [Samia Ali]: https://github.com/samiaab1990 - +[idleberg]: https://github.com/idleberg ## Version 11.3.1 diff --git a/src/languages/nsis.js b/src/languages/nsis.js index fa3b2e547f..fd64106d27 100644 --- a/src/languages/nsis.js +++ b/src/languages/nsis.js @@ -153,7 +153,7 @@ export default function(hljs) { const DEFINES = { // ${defines} className: 'variable', - begin: /\$+\{[\w.:-]+\}/ + begin: /\$+\{[\!\w.:-]+\}/ }; const VARIABLES = { From 9274b2d2c80dd73f804cdcba48a0d46479df764f Mon Sep 17 00:00:00 2001 From: "Jan T. Sott" Date: Fri, 3 Dec 2021 02:23:19 +0100 Subject: [PATCH 20/76] enh(nsis) Update variables pattern to include `.` --- CHANGES.md | 1 + src/languages/nsis.js | 2 +- test/markup/nsis/variables.expect.txt | 7 +++++++ test/markup/nsis/variables.txt | 7 +++++++ 4 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 test/markup/nsis/variables.expect.txt create mode 100644 test/markup/nsis/variables.txt diff --git a/CHANGES.md b/CHANGES.md index 7d6636393f..9b44a09a05 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -17,6 +17,7 @@ Grammars: - enh(clojure) Add `regex` mode to regex literal - fix(clojure) Remove inconsistent/broken highlighting for metadata - enh(clojure) Add `punctuation` mode for commas. + - enh(nsis) Update variables pattern (#3416) [idleberg][] Developer Tools: diff --git a/src/languages/nsis.js b/src/languages/nsis.js index fd64106d27..570d13e0ff 100644 --- a/src/languages/nsis.js +++ b/src/languages/nsis.js @@ -159,7 +159,7 @@ export default function(hljs) { const VARIABLES = { // $variables className: 'variable', - begin: /\$+\w+/, + begin: /\$+\w[\w\.]*/, illegal: /\(\)\{\}/ }; diff --git a/test/markup/nsis/variables.expect.txt b/test/markup/nsis/variables.expect.txt new file mode 100644 index 0000000000..8af1046ba6 --- /dev/null +++ b/test/markup/nsis/variables.expect.txt @@ -0,0 +1,7 @@ +Var CustomVariable +StrCpy $CustomVariable "Hello World" +MessageBox MB_OK "$$CustomVariable is: $CustomVariable" + +Var Variable.With.Dots +StrCpy $Variable.With.Dots "Hello World" +MessageBox MB_OK "$$Variable.With.Dots is: $Variable.With.Dots" diff --git a/test/markup/nsis/variables.txt b/test/markup/nsis/variables.txt new file mode 100644 index 0000000000..a97f06c5ce --- /dev/null +++ b/test/markup/nsis/variables.txt @@ -0,0 +1,7 @@ +Var CustomVariable +StrCpy $CustomVariable "Hello World" +MessageBox MB_OK "$$CustomVariable is: $CustomVariable" + +Var Variable.With.Dots +StrCpy $Variable.With.Dots "Hello World" +MessageBox MB_OK "$$Variable.With.Dots is: $Variable.With.Dots" From b6bfd7edf58e0c27065a79bd1ab074f940e4a2ef Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Fri, 3 Dec 2021 18:30:01 -0500 Subject: [PATCH 21/76] enh(nsis) support newer scope `char.escape` --- src/languages/nsis.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/languages/nsis.js b/src/languages/nsis.js index 570d13e0ff..fbdfff32ea 100644 --- a/src/languages/nsis.js +++ b/src/languages/nsis.js @@ -184,9 +184,9 @@ export default function(hljs) { ) }; - const METACHARS = { + const ESCAPE_CHARS = { // $\n, $\r, $\t, $$ - className: 'meta', + className: 'char.escape', begin: /\$(\\[nrt]|\$)/ }; @@ -214,7 +214,7 @@ export default function(hljs) { ], illegal: /\n/, contains: [ - METACHARS, + ESCAPE_CHARS, CONSTANTS, DEFINES, VARIABLES, From 4a73506e68f189d7ec8d17464dc17d145ed40037 Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Fri, 3 Dec 2021 18:25:31 -0500 Subject: [PATCH 22/76] enh(nsis) Var mode, supports /GLOBAL param also --- src/languages/nsis.js | 21 +++++++++++++++++++-- test/markup/nsis/default.expect.txt | 4 ++-- test/markup/nsis/variables.expect.txt | 8 ++++---- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/languages/nsis.js b/src/languages/nsis.js index fbdfff32ea..aedc187ee9 100644 --- a/src/languages/nsis.js +++ b/src/languages/nsis.js @@ -8,6 +8,7 @@ Website: https://nsis.sourceforge.io/Main_Page import * as regex from '../lib/regex.js'; export default function(hljs) { + const regex = hljs.regex; const LANGUAGE_CONSTANTS = [ "ADMINTOOLS", "APPDATA", @@ -493,7 +494,7 @@ export default function(hljs) { "zlib" ]; - const FUNCTION_DEF = { + const FUNCTION_DEFINITION = { match: [ /Function/, /\s+/, @@ -505,6 +506,21 @@ export default function(hljs) { } }; + const VARIABLE_NAME_RE = regex.concat(hljs.IDENT_RE, "(\.", hljs.IDENT_RE, ")*"); + const VARIABLE_DEFINITION = { + match: [ + /Var/, + /\s+/, + /(?:\/GLOBAL\s+)?/, + VARIABLE_NAME_RE + ], + scope: { + 1: "keyword", + 3: "params", + 4: "variable" + } + }; + return { name: 'NSIS', case_insensitive: true, @@ -522,7 +538,8 @@ export default function(hljs) { relevance: 0 } ), - FUNCTION_DEF, + VARIABLE_DEFINITION, + FUNCTION_DEFINITION, { beginKeywords: 'Function PageEx Section SectionGroup FunctionEnd SectionEnd', }, diff --git a/test/markup/nsis/default.expect.txt b/test/markup/nsis/default.expect.txt index 9574047d8f..24c8e434a1 100644 --- a/test/markup/nsis/default.expect.txt +++ b/test/markup/nsis/default.expect.txt @@ -32,6 +32,6 @@ ; Functions Function .onInit DetailPrint "The install button reads $(^InstallBtn)" - DetailPrint 'Here comes a$\n$\rline-break!' - DetailPrint `Escape the dollar-sign: $$` + DetailPrint 'Here comes a$\n$\rline-break!' + DetailPrint `Escape the dollar-sign: $$` FunctionEnd diff --git a/test/markup/nsis/variables.expect.txt b/test/markup/nsis/variables.expect.txt index 8af1046ba6..7798d8b3d6 100644 --- a/test/markup/nsis/variables.expect.txt +++ b/test/markup/nsis/variables.expect.txt @@ -1,7 +1,7 @@ -Var CustomVariable +Var CustomVariable StrCpy $CustomVariable "Hello World" -MessageBox MB_OK "$$CustomVariable is: $CustomVariable" +MessageBox MB_OK "$$CustomVariable is: $CustomVariable" -Var Variable.With.Dots +Var Variable.With.Dots StrCpy $Variable.With.Dots "Hello World" -MessageBox MB_OK "$$Variable.With.Dots is: $Variable.With.Dots" +MessageBox MB_OK "$$Variable.With.Dots is: $Variable.With.Dots" From b46301e3184f885da56a27e14c638c1183672c00 Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Fri, 3 Dec 2021 18:53:56 -0500 Subject: [PATCH 23/76] (security) fix reDOS caught by tests --- src/languages/nsis.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/languages/nsis.js b/src/languages/nsis.js index aedc187ee9..40f359d731 100644 --- a/src/languages/nsis.js +++ b/src/languages/nsis.js @@ -506,7 +506,9 @@ export default function(hljs) { } }; - const VARIABLE_NAME_RE = regex.concat(hljs.IDENT_RE, "(\.", hljs.IDENT_RE, ")*"); + // Var Custom.Variable.Name.Item + // Var /GLOBAL Custom.Variable.Name.Item + const VARIABLE_NAME_RE = /[A-Za-z][\w.]*/; const VARIABLE_DEFINITION = { match: [ /Var/, From 91c522877af9c016fbb862fa3f429e35ef65f824 Mon Sep 17 00:00:00 2001 From: "Jan T. Sott" Date: Mon, 6 Dec 2021 21:50:30 +0100 Subject: [PATCH 24/76] enh(nsis) Update language string pattern (#3420) --- CHANGES.md | 1 + src/languages/nsis.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 9b44a09a05..78c9fbe6c7 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,6 +8,7 @@ Grammars: - fix(fsharp) Highlight operators, match type names only in type annotations, support quoted identifiers, and other smaller fixes. [Melvyn Laïly][] - enh(java) add `sealed` and `non-sealed` keywords (#3386) [Bradley Mackey][] - enh(nsis) Update defines pattern to allow `!` (#3417) [idleberg][] +- enh(nsis) Update language strings pattern to allow `!` (#3420) [idleberg][] - fix(clojure) Several issues with Clojure highlighting (#3397) [Björn Ebbinghaus][] - fix(clojure) `comment` macro catches more than it should (#3395) - fix(clojure) `$` in symbol breaks highlighting diff --git a/src/languages/nsis.js b/src/languages/nsis.js index 40f359d731..17438c682d 100644 --- a/src/languages/nsis.js +++ b/src/languages/nsis.js @@ -167,7 +167,7 @@ export default function(hljs) { const LANGUAGES = { // $(language_strings) className: 'variable', - begin: /\$+\([\w^.:-]+\)/ + begin: /\$+\([\w^.:!-]+\)/ }; const PARAMETERS = { From b63b12d6918e0b3ed1f77e3183a2c5f02e7fefd8 Mon Sep 17 00:00:00 2001 From: Deepto Date: Tue, 7 Dec 2021 05:38:47 +0530 Subject: [PATCH 25/76] enh(MATLAB ) Removed backslashes as escape characters (#3354) * removed backslashes as escape characters * fixup tests Co-authored-by: Josh Goebel --- src/languages/matlab.js | 2 -- test/markup/matlab/transpose.expect.txt | 4 ++-- test/markup/matlab/transpose.txt | 4 ++-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/languages/matlab.js b/src/languages/matlab.js index 06f99fe23e..684b0c5188 100644 --- a/src/languages/matlab.js +++ b/src/languages/matlab.js @@ -80,7 +80,6 @@ export default function(hljs) { className: 'string', begin: '\'', end: '\'', contains: [ - hljs.BACKSLASH_ESCAPE, {begin: '\'\''}] }, { @@ -92,7 +91,6 @@ export default function(hljs) { className: 'string', begin: '"', end: '"', contains: [ - hljs.BACKSLASH_ESCAPE, {begin: '""'} ], starts: TRANSPOSE diff --git a/test/markup/matlab/transpose.expect.txt b/test/markup/matlab/transpose.expect.txt index 996c83bdac..c19049c508 100644 --- a/test/markup/matlab/transpose.expect.txt +++ b/test/markup/matlab/transpose.expect.txt @@ -31,9 +31,9 @@ c2 = {'a',& s = ['a','bc']'; % you can transpose vectors of strings (they are really 'char' arrays) s = s'; % and transpose back % (s')' is a double transpose of a string -x = [(s')', ' xyz ', 'a single quote in a string'', escape \', two quotes in a string''''']; +x = [(s')', ' xyz ', 'a single quote in a string'', two quotes in a string''''']; -s2 = "abc\"def""ghi"; % newer versions of MATLAB support double quoted strings +s2 = "abcdef""ghi"; % newer versions of MATLAB support double quoted strings s3 = (["abc", "defg"]')'; % transpose a vectors of quoted string twice s4 = "abc"!; % transpose a quoted string diff --git a/test/markup/matlab/transpose.txt b/test/markup/matlab/transpose.txt index d1da28e3df..9f69a0cc9f 100644 --- a/test/markup/matlab/transpose.txt +++ b/test/markup/matlab/transpose.txt @@ -31,9 +31,9 @@ c2 = {'a','bc'}'; % transpose of a cell of strings s = ['a','bc']'; % you can transpose vectors of strings (they are really 'char' arrays) s = s'; % and transpose back % (s')' is a double transpose of a string -x = [(s')', ' xyz ', 'a single quote in a string'', escape \', two quotes in a string''''']; +x = [(s')', ' xyz ', 'a single quote in a string'', two quotes in a string''''']; -s2 = "abc\"def""ghi"; % newer versions of MATLAB support double quoted strings +s2 = "abcdef""ghi"; % newer versions of MATLAB support double quoted strings s3 = (["abc", "defg"]')'; % transpose a vectors of quoted string twice s4 = "abc"!; % transpose a quoted string From 5c8c87660ab7c7919cbcccf8a51ce07040562ef5 Mon Sep 17 00:00:00 2001 From: MrYamous Date: Tue, 7 Dec 2021 21:28:58 +0100 Subject: [PATCH 26/76] enh(twig): update keywords list (#3415) * enh(twig): update keywords list * chore(twig) major twig refatoring, add new functionality (Josh) Co-authored-by: Josh Goebel --- CHANGES.md | 2 + src/languages/twig.js | 219 ++++++++++++++---- .../clojure/globals_definition.expect.txt | 2 +- .../markup/clojure/symbols-numbers.expect.txt | 2 +- test/markup/fsharp/bang-keywords.expect.txt | 2 +- .../fsharp/computation-expressions.expect.txt | 2 +- test/markup/fsharp/types.expect.txt | 2 +- .../twig/filter_with_underscore.expect.txt | 2 +- test/markup/twig/template_tags.expect.txt | 12 +- tools/checkAutoDetect.js | 2 +- 10 files changed, 195 insertions(+), 52 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 78c9fbe6c7..de2488e9ea 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,7 @@ Grammars: +- enh(twig) update keywords list (#3415) [Matthieu Lempereur][] - fix(python) def, class keywords detected mid-identifier (#3381) [Josh Goebel][] - fix(python) Fix recognition of numeric literals followed by keywords without whitespace (#2985) [Richard Gibson][] - enh(swift) add SE-0290 unavailability condition (#3382) [Bradley Mackey][] @@ -34,6 +35,7 @@ Themes: [Björn Ebbinghaus]: https://github.com/MrEbbinghaus [Josh Goebel]: https://github.com/joshgoebel [Samia Ali]: https://github.com/samiaab1990 +[Matthieu Lempereur]: https://github.com/MrYamous [idleberg]: https://github.com/idleberg ## Version 11.3.1 diff --git a/src/languages/twig.js b/src/languages/twig.js index 4ea7bd041a..3e4a26257d 100644 --- a/src/languages/twig.js +++ b/src/languages/twig.js @@ -8,67 +8,208 @@ Category: template */ export default function(hljs) { - var PARAMS = { - className: 'params', - begin: '\\(', end: '\\)' + const regex = hljs.regex; + const FUNCTION_NAMES = [ + "attribute", + "block", + "constant", + "country_timezones", + "cycle", + "date", + "dump", + "html_classes", + "include", + "max", + "min", + "parent", + "random", + "range", + "source", + "template_from_string" + ]; + + const FILTERS = [ + "abs", + "batch", + "capitalize", + "column", + "convert_encoding", + "country_name", + "currency_name", + "currency_symbol", + "data_uri", + "date", + "date_modify", + "default", + "escape", + "filter", + "first", + "format", + "format_currency", + "format_date", + "format_datetime", + "format_number", + "format_time", + "html_to_markdown", + "inky_to_html", + "inline_css", + "join", + "json_encode", + "keys", + "language_name", + "last", + "length", + "locale_name", + "lower", + "map", + "markdown", + "markdown_to_html", + "merge", + "nl2br", + "number_format", + "raw", + "reduce", + "replace", + "reverse", + "round", + "slice", + "slug", + "sort", + "spaceless", + "split", + "striptags", + "timezone_name", + "title", + "trim", + "u|0", + "upper", + "url_encode" + ]; + + let TAG_NAMES = [ + "apply", + "autoescape", + "block", + "cache", + "deprecated", + "do", + "embed", + "extends", + "filter", + "flush", + "for", + "from", + "if", + "import", + "include", + "macro", + "sandbox", + "set", + "use", + "verbatim", + "with" + ]; + + TAG_NAMES = TAG_NAMES.concat(TAG_NAMES.map(t => `end${t}`)); + + const STRING = { + scope: 'string', + variants: [ + { + begin: /'/, + end: /'/ + }, + { + begin: /"/, + end: /"/ + }, + ] }; - var FUNCTION_NAMES = 'attribute block constant cycle date dump include ' + - 'max min parent random range source template_from_string'; + const NUMBER = { + scope: "number", + match: /\d+/ + }; - var FUNCTIONS = { - beginKeywords: FUNCTION_NAMES, - keywords: {name: FUNCTION_NAMES}, - relevance: 0, + const PARAMS = { + begin: /\(/, + end: /\)/, + excludeBegin: true, + excludeEnd: true, contains: [ - PARAMS + STRING, + NUMBER ] }; - var FILTER = { - begin: /\|[A-Za-z_]+:?/, - keywords: - 'abs batch capitalize column convert_encoding date date_modify default ' + - 'escape filter first format inky_to_html inline_css join json_encode keys last ' + - 'length lower map markdown merge nl2br number_format raw reduce replace ' + - 'reverse round slice sort spaceless split striptags title trim upper url_encode', + + const FUNCTIONS = { + beginKeywords: FUNCTION_NAMES.join(" "), + keywords: { name: FUNCTION_NAMES }, + relevance: 0, + contains: [ PARAMS ] + }; + + const FILTER = { + match: /\|(?=[A-Za-z_]+:?)/, + beginScope: "punctuation", + relevance: 0, contains: [ - FUNCTIONS + { + match: /[A-Za-z_]+:?/, + keywords: FILTERS + }, ] }; - var TAGS = 'apply autoescape block deprecated do embed extends filter flush for from ' + - 'if import include macro sandbox set use verbatim with'; + const tagNamed = (tagnames, {relevance}) => { + return { + beginScope: { + 1: 'template-tag', + 3: 'name' + }, + relevance: relevance || 2, + endScope: 'template-tag', + begin: [ + /\{%/, + /\s*/, + regex.either(...tagnames) + ], + end: /%\}/, + keywords: "in", + contains: [ + FILTER, + FUNCTIONS, + STRING, + NUMBER + ] + }; + }; - TAGS = TAGS + ' ' + TAGS.split(' ').map(function(t){return 'end' + t}).join(' '); + const CUSTOM_TAG_RE = /[a-z_]+/; + const TAG = tagNamed(TAG_NAMES, { relevance: 2 }); + const CUSTOM_TAG = tagNamed([ CUSTOM_TAG_RE ], { relevance: 1 }); return { name: 'Twig', - aliases: ['craftcms'], + aliases: [ 'craftcms' ], case_insensitive: true, subLanguage: 'xml', contains: [ hljs.COMMENT(/\{#/, /#\}/), + TAG, + CUSTOM_TAG, { - className: 'template-tag', - begin: /\{%/, end: /%\}/, + className: 'template-variable', + begin: /\{\{/, + end: /\}\}/, contains: [ - { - className: 'name', - begin: /\w+/, - keywords: TAGS, - starts: { - endsWithParent: true, - contains: [FILTER, FUNCTIONS], - relevance: 0 - } - } + 'self', + FILTER, + FUNCTIONS, + STRING, + NUMBER ] - }, - { - className: 'template-variable', - begin: /\{\{/, end: /\}\}/, - contains: ['self', FILTER, FUNCTIONS] } ] }; diff --git a/test/markup/clojure/globals_definition.expect.txt b/test/markup/clojure/globals_definition.expect.txt index 832e283cd4..efc8a15c9a 100644 --- a/test/markup/clojure/globals_definition.expect.txt +++ b/test/markup/clojure/globals_definition.expect.txt @@ -69,4 +69,4 @@ string" ;; create a couple shapes and get their area (def myCircle (Circle. 10)) -(def mySquare (Square. 5 11)) \ No newline at end of file +(def mySquare (Square. 5 11)) diff --git a/test/markup/clojure/symbols-numbers.expect.txt b/test/markup/clojure/symbols-numbers.expect.txt index 7813d22876..2808223dcc 100644 --- a/test/markup/clojure/symbols-numbers.expect.txt +++ b/test/markup/clojure/symbols-numbers.expect.txt @@ -1,4 +1,4 @@ (def +x [(a 1) +2 -3.0 y-5]) (System/getProperty "java.vm.version") (.getEnclosingClass java.util.Map$Entry) -(java.util.Map$Entry. .getEnclosingClass) +(java.util.Map$Entry. .getEnclosingClass) \ No newline at end of file diff --git a/test/markup/fsharp/bang-keywords.expect.txt b/test/markup/fsharp/bang-keywords.expect.txt index c47d939e94..f681697fdf 100644 --- a/test/markup/fsharp/bang-keywords.expect.txt +++ b/test/markup/fsharp/bang-keywords.expect.txt @@ -1 +1 @@ -let! (result2 : byte[]) = stream.AsyncRead(bufferSize) \ No newline at end of file +let! (result2 : byte[]) = stream.AsyncRead(bufferSize) diff --git a/test/markup/fsharp/computation-expressions.expect.txt b/test/markup/fsharp/computation-expressions.expect.txt index 76cb4486bd..af296f3f2c 100644 --- a/test/markup/fsharp/computation-expressions.expect.txt +++ b/test/markup/fsharp/computation-expressions.expect.txt @@ -20,4 +20,4 @@ return result } -let result = work |> Async.RunSynchronously \ No newline at end of file +let result = work |> Async.RunSynchronously diff --git a/test/markup/fsharp/types.expect.txt b/test/markup/fsharp/types.expect.txt index 0ad8b0c6a7..e48881af06 100644 --- a/test/markup/fsharp/types.expect.txt +++ b/test/markup/fsharp/types.expect.txt @@ -140,4 +140,4 @@ | CaseK of ``var with spaces``: string | CaseL of ``var with spaces``: ``type with spaces`` | CaseM of v1 : ``type with spaces`` - | CaseN of ``type with spaces`` \ No newline at end of file + | CaseN of ``type with spaces`` diff --git a/test/markup/twig/filter_with_underscore.expect.txt b/test/markup/twig/filter_with_underscore.expect.txt index 72c93fd877..9d2928531a 100644 --- a/test/markup/twig/filter_with_underscore.expect.txt +++ b/test/markup/twig/filter_with_underscore.expect.txt @@ -1 +1 @@ -{{ "string with spaces"|url_encode }} \ No newline at end of file +{{ "string with spaces"|url_encode }} \ No newline at end of file diff --git a/test/markup/twig/template_tags.expect.txt b/test/markup/twig/template_tags.expect.txt index 410fb24347..0127a33510 100644 --- a/test/markup/twig/template_tags.expect.txt +++ b/test/markup/twig/template_tags.expect.txt @@ -1,12 +1,12 @@ -{% if posts|length %} - {% for article in articles %} +{% if posts|length %} + {% for article in articles %} &lt;div&gt; - {{ article.title|upper() }} + {{ article.title|upper() }} {# outputs 'WELCOME' #} &lt;/div&gt; - {% endfor %} -{% endif %} + {% endfor %} +{% endif %} -{% set user = json_encode(user) %} +{% set user = json_encode(user) %} \ No newline at end of file diff --git a/tools/checkAutoDetect.js b/tools/checkAutoDetect.js index 0a725985a8..0da66c8dfd 100755 --- a/tools/checkAutoDetect.js +++ b/tools/checkAutoDetect.js @@ -2,7 +2,7 @@ 'use strict'; const fs = require('fs'); -const hljs = require('../build.js'); +const hljs = require('../build/lib/index.js'); const path = require('path'); const utility = require('../test/utility.js'); const Table = require('cli-table'); From 0bf3adeecd5ba76cef8ee843e38722089b232da1 Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Wed, 8 Dec 2021 18:40:50 -0500 Subject: [PATCH 27/76] (docs) Make example 100% explicit regarding minified files --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 96a8ca1c06..19a7ae0c88 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ The bare minimum for using highlight.js on a web page is linking to the library along with one of the themes and calling [`highlightAll`][1]: ```html - + ``` From 4ddfbe4bd469d582c7577e73f859d56334361bde Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Thu, 9 Dec 2021 10:40:17 -0500 Subject: [PATCH 28/76] enh(js/ts) fix => async function title highlights (#3414) --- CHANGES.md | 1 + src/languages/javascript.js | 2 ++ 2 files changed, 3 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index de2488e9ea..262bc2100a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,7 @@ Grammars: +- enh(js/ts) fix => async function title highlights (#3405) [Josh Goebel][] - enh(twig) update keywords list (#3415) [Matthieu Lempereur][] - fix(python) def, class keywords detected mid-identifier (#3381) [Josh Goebel][] - fix(python) Fix recognition of numeric literals followed by keywords without whitespace (#2985) [Richard Gibson][] diff --git a/src/languages/javascript.js b/src/languages/javascript.js index b09065dd85..b3282e1725 100644 --- a/src/languages/javascript.js +++ b/src/languages/javascript.js @@ -406,8 +406,10 @@ export default function(hljs) { /const|var|let/, /\s+/, IDENT_RE, /\s*/, /=\s*/, + /(async\s*)?/, // async is optional regex.lookahead(FUNC_LEAD_IN_RE) ], + keywords: "async", className: { 1: "keyword", 3: "title.function" From c37ef5b7b906bf0c757b94d2aae4947857b527f7 Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Thu, 9 Dec 2021 10:52:21 -0500 Subject: [PATCH 29/76] (enh) improve default theme accessibility (#3402) * first pass at accessibility report in checkTheme * resolve CSS color names when necessary * (enh) default Dark theme is WCAG AAA wrt contrast * (enh) improve accessibility of default theme --- CHANGES.md | 9 ++++- package-lock.json | 55 ++++++++++++++++++++++++++++- package.json | 4 ++- src/styles/dark.css | 4 +-- src/styles/default.css | 10 +++--- tools/checkTheme.js | 78 ++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 150 insertions(+), 10 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 262bc2100a..fc60632dd1 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,4 +1,11 @@ -## Version 11.3.2 (most likely) +## Version 11.4 (most likely) + +Themes: + +- `Default` is now much closer WCAG AA (contrast) (#3402) [Josh Goebel] +- `Dark` now meets WCAG AA (contrast) (#3402) [Josh Goebel] + +These changes should be for the better and should not be super noticeable but if you're super picky about your colors you may want to intervene here or copy over the older themes from 11.3 or prior. Grammars: diff --git a/package-lock.json b/package-lock.json index 877b12bf68..55b90dec9d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ "colors": "^1.1.2", "commander": "8.2", "css": "^3.0.0", + "css-color-names": "^1.0.1", "deep-freeze-es6": "^1.4.1", "del": "^6.0.0", "dependency-resolver": "^2.0.1", @@ -38,7 +39,8 @@ "should": "^13.2.3", "terser": "^5.7.0", "tiny-worker": "^2.3.0", - "typescript": "^4.4.4" + "typescript": "^4.4.4", + "wcag-contrast": "^3.0.0" }, "engines": { "node": ">=12.0.0" @@ -1042,6 +1044,15 @@ "source-map-resolve": "^0.6.0" } }, + "node_modules/css-color-names": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-1.0.1.tgz", + "integrity": "sha512-/loXYOch1qU1biStIFsHH8SxTmOseh1IJqFvy8IujXOm1h+QjUdDhkzOrR5HG8K8mlxREj0yfi8ewCHx0eMxzA==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/cssom": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", @@ -3358,6 +3369,15 @@ "node": ">=8" } }, + "node_modules/relative-luminance": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/relative-luminance/-/relative-luminance-2.0.1.tgz", + "integrity": "sha512-wFuITNthJilFPwkK7gNJcULxXBcfFZvZORsvdvxeOdO44wCeZnuQkf3nFFzOR/dpJNxYsdRZJLsepWbyKhnMww==", + "dev": true, + "dependencies": { + "esm": "^3.0.84" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -4075,6 +4095,15 @@ "node": ">=12" } }, + "node_modules/wcag-contrast": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/wcag-contrast/-/wcag-contrast-3.0.0.tgz", + "integrity": "sha512-RWbpg/S7FOXDCwqC2oFhN/vh8dHzj0OS6dpyOSDHyQFSmqmR+lAUStV/ziTT1GzDqL9wol+nZQB4vCi5yEak+w==", + "dev": true, + "dependencies": { + "relative-luminance": "^2.0.0" + } + }, "node_modules/webidl-conversions": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", @@ -5111,6 +5140,12 @@ "source-map-resolve": "^0.6.0" } }, + "css-color-names": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-1.0.1.tgz", + "integrity": "sha512-/loXYOch1qU1biStIFsHH8SxTmOseh1IJqFvy8IujXOm1h+QjUdDhkzOrR5HG8K8mlxREj0yfi8ewCHx0eMxzA==", + "dev": true + }, "cssom": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", @@ -6839,6 +6874,15 @@ "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", "dev": true }, + "relative-luminance": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/relative-luminance/-/relative-luminance-2.0.1.tgz", + "integrity": "sha512-wFuITNthJilFPwkK7gNJcULxXBcfFZvZORsvdvxeOdO44wCeZnuQkf3nFFzOR/dpJNxYsdRZJLsepWbyKhnMww==", + "dev": true, + "requires": { + "esm": "^3.0.84" + } + }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -7399,6 +7443,15 @@ "xml-name-validator": "^4.0.0" } }, + "wcag-contrast": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/wcag-contrast/-/wcag-contrast-3.0.0.tgz", + "integrity": "sha512-RWbpg/S7FOXDCwqC2oFhN/vh8dHzj0OS6dpyOSDHyQFSmqmR+lAUStV/ziTT1GzDqL9wol+nZQB4vCi5yEak+w==", + "dev": true, + "requires": { + "relative-luminance": "^2.0.0" + } + }, "webidl-conversions": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", diff --git a/package.json b/package.json index a6376bd740..985b47fdd6 100644 --- a/package.json +++ b/package.json @@ -65,6 +65,7 @@ "colors": "^1.1.2", "commander": "8.2", "css": "^3.0.0", + "css-color-names": "^1.0.1", "deep-freeze-es6": "^1.4.1", "del": "^6.0.0", "dependency-resolver": "^2.0.1", @@ -84,6 +85,7 @@ "should": "^13.2.3", "terser": "^5.7.0", "tiny-worker": "^2.3.0", - "typescript": "^4.4.4" + "typescript": "^4.4.4", + "wcag-contrast": "^3.0.0" } } diff --git a/src/styles/dark.css b/src/styles/dark.css index 34708897f3..052dbc94f1 100644 --- a/src/styles/dark.css +++ b/src/styles/dark.css @@ -6,7 +6,7 @@ Dark style from softwaremaniacs.org (c) Ivan Sagalaev Math.round(x*100)/100; + +class CSSRule { + constructor(rule, body) { + this.rule = rule; + if (rule.declarations) { + this.bg = rule.declarations.find(x => x.property =="background")?.value; + this.fg = rule.declarations.find(x => x.property =="color")?.value; + + if (this.bg) { + this.bg = csscolors[this.bg] || this.bg; + } + if (this.fg) { + this.fg = csscolors[this.fg] || this.fg; + } + + // inherit from body if we're missing fg or bg + if (this.hasColor) { + if (!this.bg) this.bg = body.background; + if (!this.fg) this.fg = body.foreground; + } + } + } + get background() { + return this.bg + } + + get foreground() { + return this.fg + } + get hasColor() { + if (!this.rule.declarations) return false; + return this.fg || this.bg; + } + toString() { + return ` ${this.foreground} on ${this.background}` + } + + contrastRatio() { + if (!this.foreground) return "unknown (no fg)" + if (!this.background) return "unknown (no bg)" + return round2(wcagContrast.hex(this.foreground, this.background)); + } +} + +function contrast_report(rules) { + console.log("Accessibility Report".yellow); + + var hljs = rules.find (x => x.selectors && x.selectors.includes(".hljs")); + var body = new CSSRule(hljs); + const table = new Table({ + chars: {'mid': '', 'left-mid': '', 'mid-mid': '', 'right-mid': ''}, + head: ['ratio', 'selector', 'fg', 'bg'], + colWidths: [7, 40, 10, 10], + style: { + head: ['grey'] + } + }); + + rules.forEach(rule => { + var color = new CSSRule(rule, body); + if (!color.hasColor) return; + table.push([ + color.contrastRatio(), + rule.selectors, + color.foreground, + color.background + ]) + // console.log(r.selectors[0], color.contrastRatio(), color.toString()); + }) + console.log(table.toString()) +} + function validate(data) { const rules = data.stylesheet.rules; @@ -195,6 +271,8 @@ function validate(data) { check_group(CODE, rules); check_group(OTHER, rules); check_group(HIGH_FIDELITY, rules); + + contrast_report(rules); } process.argv.shift(); From 84719c17a51d7bb045f2df441b9c00f871f7c063 Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Thu, 9 Dec 2021 10:53:24 -0500 Subject: [PATCH 30/76] (chore) es6 via CDN (#3412) --- README.md | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 55 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 19a7ae0c88..05d926f528 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,9 @@ detection. - [ES6 Modules / `import`](#es6-modules--import) - [Getting the Library](#getting-the-library) - [Fetch via CDN](#fetch-via-cdn) + - [cdnjs (link)](#cdnjs-link) + - [jsdelivr (link)](#jsdelivr-link) + - [unpkg (link)](#unpkg-link) - [Download prebuilt CDN assets](#download-prebuilt-cdn-assets) - [Download from our website](#download-from-our-website) - [Install via NPM package](#install-via-npm-package) @@ -268,13 +271,16 @@ const highlightedCode = hljs.highlight('Hello World!', {language: ' ### ES6 Modules / `import` +*Note: You can also import directly from fully static URLs, such as our very own pre-built +ES6 Module CDN resources. See [Fetch via CDN](#fetch-via-cdn) for specific examples.* + The default import will register all languages: ```js import hljs from 'highlight.js'; ``` - It is more efficient to import only the library and register the languages you need: +It is more efficient to import only the library and register the languages you need: ```js import hljs from 'highlight.js/lib/core'; @@ -317,7 +323,9 @@ A prebuilt version of Highlight.js bundled with many common languages is hosted When using Highlight.js via CDN you can use Subresource Integrity for additional security. For details see [DIGESTS.md](https://github.com/highlightjs/cdn-release/blob/main/DIGESTS.md). -**cdnjs** ([link](https://cdnjs.com/libraries/highlight.js)) +#### cdnjs ([link](https://cdnjs.com/libraries/highlight.js)) + +##### Common JS ```html @@ -326,7 +334,23 @@ see [DIGESTS.md](https://github.com/highlightjs/cdn-release/blob/main/DIGESTS.md ``` -**jsdelivr** ([link](https://www.jsdelivr.com/package/gh/highlightjs/cdn-release)) +##### ES6 Modules + +````html + + + +```` + + +#### jsdelivr ([link](https://www.jsdelivr.com/package/gh/highlightjs/cdn-release)) + +##### Common JS ```html @@ -335,7 +359,21 @@ see [DIGESTS.md](https://github.com/highlightjs/cdn-release/blob/main/DIGESTS.md ``` -**unpkg** ([link](https://unpkg.com/browse/@highlightjs/cdn-assets/)) +##### ES6 Modules + +```html + + +``` + +#### unpkg ([link](https://unpkg.com/browse/@highlightjs/cdn-assets/)) + +##### Common JS ```html @@ -344,6 +382,19 @@ see [DIGESTS.md](https://github.com/highlightjs/cdn-release/blob/main/DIGESTS.md ``` +##### ES6 Modules + +```html + + +``` + + **Note:** *The CDN-hosted `highlight.min.js` package doesn't bundle every language.* It would be very large. You can find our list of "common" languages that we bundle by default on our [download page][5]. From ba806ed60fb027bd911aad5e2e0d6529099fcd13 Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Thu, 9 Dec 2021 13:26:06 -0500 Subject: [PATCH 31/76] enh(js/ts) improve CLASS_REFERENCE (#3411) --- CHANGES.md | 1 + src/languages/javascript.js | 12 ++++++++---- test/markup/javascript/class.expect.txt | 5 +++++ test/markup/javascript/class.txt | 5 +++++ 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index fc60632dd1..b2294ae731 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -16,6 +16,7 @@ Grammars: - enh(swift) add SE-0290 unavailability condition (#3382) [Bradley Mackey][] - fix(fsharp) Highlight operators, match type names only in type annotations, support quoted identifiers, and other smaller fixes. [Melvyn Laïly][] - enh(java) add `sealed` and `non-sealed` keywords (#3386) [Bradley Mackey][] +- enh(js/ts) improve `CLASS_REFERENCE` (#3411) [Josh Goebel][] - enh(nsis) Update defines pattern to allow `!` (#3417) [idleberg][] - enh(nsis) Update language strings pattern to allow `!` (#3420) [idleberg][] - fix(clojure) Several issues with Clojure highlighting (#3397) [Björn Ebbinghaus][] diff --git a/src/languages/javascript.js b/src/languages/javascript.js index b3282e1725..9b748eb1f7 100644 --- a/src/languages/javascript.js +++ b/src/languages/javascript.js @@ -290,10 +290,14 @@ export default function(hljs) { regex.either( // Hard coded exceptions /\bJSON/, - // Float32Array - /\b[A-Z][a-z]+([A-Z][a-z]+|\d)*/, - // CSSFactory - /\b[A-Z]{2,}([A-Z][a-z]+|\d)+/, + // Float32Array, OutT + /\b[A-Z][a-z]+([A-Z][a-z]*|\d)*/, + // CSSFactory, CSSFactoryT + /\b[A-Z]{2,}([A-Z][a-z]+|\d)+([A-Z][a-z]*|\d)*/, + // FPs, FPsT + /\b[A-Z]{2,}[a-z]+([A-Z][a-z]+|\d)*([A-Z][a-z]*|\d)*/, + // P + // single letters are not highlighted // BLAH // this will be flagged as a UPPER_CASE_CONSTANT instead ), diff --git a/test/markup/javascript/class.expect.txt b/test/markup/javascript/class.expect.txt index 3ef253c364..7e1dd67c80 100644 --- a/test/markup/javascript/class.expect.txt +++ b/test/markup/javascript/class.expect.txt @@ -33,3 +33,8 @@ CSSParser Float32Array BigInt64Array +FPs +OutT +InT +CSSParserT +IResponseTsS diff --git a/test/markup/javascript/class.txt b/test/markup/javascript/class.txt index bebfe77f90..4badef7377 100644 --- a/test/markup/javascript/class.txt +++ b/test/markup/javascript/class.txt @@ -33,3 +33,8 @@ SelfDrivingTruck CSSParser Float32Array BigInt64Array +FPs +OutT +InT +CSSParserT +IResponseTsS From 9e33f830558e77a4938bab661836780761d834d2 Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Thu, 9 Dec 2021 13:31:58 -0500 Subject: [PATCH 32/76] (chore) fix regex backtracking from prior PR --- src/languages/javascript.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/languages/javascript.js b/src/languages/javascript.js index 9b748eb1f7..e3ec15a04c 100644 --- a/src/languages/javascript.js +++ b/src/languages/javascript.js @@ -293,9 +293,9 @@ export default function(hljs) { // Float32Array, OutT /\b[A-Z][a-z]+([A-Z][a-z]*|\d)*/, // CSSFactory, CSSFactoryT - /\b[A-Z]{2,}([A-Z][a-z]+|\d)+([A-Z][a-z]*|\d)*/, + /\b[A-Z]{2,}([A-Z][a-z]+|\d)+([A-Z][a-z]*)*/, // FPs, FPsT - /\b[A-Z]{2,}[a-z]+([A-Z][a-z]+|\d)*([A-Z][a-z]*|\d)*/, + /\b[A-Z]{2,}[a-z]+([A-Z][a-z]+|\d)*([A-Z][a-z]*)*/, // P // single letters are not highlighted // BLAH From c06463af7087f29c1ad5d95c700ad038d3f33613 Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Thu, 9 Dec 2021 18:29:13 -0500 Subject: [PATCH 33/76] chore(php) rewrite keyword lists to arrays --- src/languages/php.js | 204 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 189 insertions(+), 15 deletions(-) diff --git a/src/languages/php.js b/src/languages/php.js index ce0af400a8..b051c266b5 100644 --- a/src/languages/php.js +++ b/src/languages/php.js @@ -71,36 +71,210 @@ export default function(hljs) { ], relevance: 0 }; - const KEYWORDS = { - keyword: + const LITERALS = [ + "false", + "null", + "true" + ]; + const KWS = [ // Magic constants: // - '__CLASS__ __DIR__ __FILE__ __FUNCTION__ __LINE__ __METHOD__ __NAMESPACE__ __TRAIT__ ' + + "__CLASS__", + "__DIR__", + "__FILE__", + "__FUNCTION__", + "__LINE__", + "__METHOD__", + "__NAMESPACE__", + "__TRAIT__", // Function that look like language construct or language construct that look like function: // List of keywords that may not require parenthesis - 'die echo exit include include_once print require require_once ' + + "die", + "echo", + "exit", + "include", + "include_once", + "print", + "require", + "require_once", // These are not language construct (function) but operate on the currently-executing function and can access the current symbol table // 'compact extract func_get_arg func_get_args func_num_args get_called_class get_parent_class ' + // Other keywords: // // - 'array abstract and as binary bool boolean break callable case catch class clone const continue declare ' + - 'default do double else elseif empty enddeclare endfor endforeach endif endswitch endwhile enum eval extends ' + - 'final finally float for foreach from global goto if implements instanceof insteadof int integer interface ' + - 'isset iterable list match|0 mixed new object or private protected public real return string switch throw trait ' + - 'try unset use var void while xor yield', - literal: 'false null true', - built_in: + "array", + "abstract", + "and", + "as", + "binary", + "bool", + "boolean", + "break", + "callable", + "case", + "catch", + "class", + "clone", + "const", + "continue", + "declare", + "default", + "do", + "double", + "else", + "elseif", + "empty", + "enddeclare", + "endfor", + "endforeach", + "endif", + "endswitch", + "endwhile", + "enum", + "eval", + "extends", + "final", + "finally", + "float", + "for", + "foreach", + "from", + "global", + "goto", + "if", + "implements", + "instanceof", + "insteadof", + "int", + "integer", + "interface", + "isset", + "iterable", + "list", + "match|0", + "mixed", + "new", + "object", + "or", + "private", + "protected", + "public", + "real", + "return", + "string", + "switch", + "throw", + "trait", + "try", + "unset", + "use", + "var", + "void", + "while", + "xor", + "yield" + ]; + + const BUILT_INS = [ // Standard PHP library: // - 'Error|0 ' + // error is too common a name esp since PHP is case in-sensitive - 'AppendIterator ArgumentCountError ArithmeticError ArrayIterator ArrayObject AssertionError BadFunctionCallException BadMethodCallException CachingIterator CallbackFilterIterator CompileError Countable DirectoryIterator DivisionByZeroError DomainException EmptyIterator ErrorException Exception FilesystemIterator FilterIterator GlobIterator InfiniteIterator InvalidArgumentException IteratorIterator LengthException LimitIterator LogicException MultipleIterator NoRewindIterator OutOfBoundsException OutOfRangeException OuterIterator OverflowException ParentIterator ParseError RangeException RecursiveArrayIterator RecursiveCachingIterator RecursiveCallbackFilterIterator RecursiveDirectoryIterator RecursiveFilterIterator RecursiveIterator RecursiveIteratorIterator RecursiveRegexIterator RecursiveTreeIterator RegexIterator RuntimeException SeekableIterator SplDoublyLinkedList SplFileInfo SplFileObject SplFixedArray SplHeap SplMaxHeap SplMinHeap SplObjectStorage SplObserver SplObserver SplPriorityQueue SplQueue SplStack SplSubject SplSubject SplTempFileObject TypeError UnderflowException UnexpectedValueException UnhandledMatchError ' + + "Error|0", + "AppendIterator", + "ArgumentCountError", + "ArithmeticError", + "ArrayIterator", + "ArrayObject", + "AssertionError", + "BadFunctionCallException", + "BadMethodCallException", + "CachingIterator", + "CallbackFilterIterator", + "CompileError", + "Countable", + "DirectoryIterator", + "DivisionByZeroError", + "DomainException", + "EmptyIterator", + "ErrorException", + "Exception", + "FilesystemIterator", + "FilterIterator", + "GlobIterator", + "InfiniteIterator", + "InvalidArgumentException", + "IteratorIterator", + "LengthException", + "LimitIterator", + "LogicException", + "MultipleIterator", + "NoRewindIterator", + "OutOfBoundsException", + "OutOfRangeException", + "OuterIterator", + "OverflowException", + "ParentIterator", + "ParseError", + "RangeException", + "RecursiveArrayIterator", + "RecursiveCachingIterator", + "RecursiveCallbackFilterIterator", + "RecursiveDirectoryIterator", + "RecursiveFilterIterator", + "RecursiveIterator", + "RecursiveIteratorIterator", + "RecursiveRegexIterator", + "RecursiveTreeIterator", + "RegexIterator", + "RuntimeException", + "SeekableIterator", + "SplDoublyLinkedList", + "SplFileInfo", + "SplFileObject", + "SplFixedArray", + "SplHeap", + "SplMaxHeap", + "SplMinHeap", + "SplObjectStorage", + "SplObserver", + "SplObserver", + "SplPriorityQueue", + "SplQueue", + "SplStack", + "SplSubject", + "SplSubject", + "SplTempFileObject", + "TypeError", + "UnderflowException", + "UnexpectedValueException", + "UnhandledMatchError", // Reserved interfaces: // - 'ArrayAccess Closure Generator Iterator IteratorAggregate Serializable Stringable Throwable Traversable WeakReference WeakMap ' + + "ArrayAccess", + "Closure", + "Generator", + "Iterator", + "IteratorAggregate", + "Serializable", + "Stringable", + "Throwable", + "Traversable", + "WeakReference", + "WeakMap", // Reserved classes: // - 'Directory __PHP_Incomplete_Class parent php_user_filter self static stdClass' + "Directory", + "__PHP_Incomplete_Class", + "parent", + "php_user_filter", + "self", + "static", + "stdClass" + ]; + + const KEYWORDS = { + keyword: KWS, + literal: LITERALS, + built_in: BUILT_INS }; return { case_insensitive: true, From 8d6265b0406aa4ad6d8808282c75f185371cd63f Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Thu, 9 Dec 2021 18:38:58 -0500 Subject: [PATCH 34/76] enh(php) improve namespace/use highlighting --- src/languages/php.js | 17 +++++++++++++++-- test/markup/php/namespace.expect.txt | 8 ++++++++ test/markup/php/namespace.txt | 8 ++++++++ 3 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 test/markup/php/namespace.expect.txt create mode 100644 test/markup/php/namespace.txt diff --git a/src/languages/php.js b/src/languages/php.js index b051c266b5..2e9c8c318d 100644 --- a/src/languages/php.js +++ b/src/languages/php.js @@ -355,18 +355,31 @@ export default function(hljs) { hljs.UNDERSCORE_TITLE_MODE ] }, + // both use and namespace still use "old style" rules (vs multi-match) + // because the namespace name can include `\` and we still want each + // element to be treated as it's own *individual* title { beginKeywords: 'namespace', relevance: 0, end: ';', illegal: /[.']/, - contains: [hljs.UNDERSCORE_TITLE_MODE] + contains: [ + hljs.inherit(hljs.UNDERSCORE_TITLE_MODE, { scope: "title.class" }) + ] }, { beginKeywords: 'use', relevance: 0, end: ';', - contains: [hljs.UNDERSCORE_TITLE_MODE] + contains: [ + // TODO: title.function vs title.class + { + match: /\b(as|const|function)\b/, + scope: "keyword" + }, + // TODO: could be title.class or title.function + hljs.UNDERSCORE_TITLE_MODE + ] }, STRING, NUMBER diff --git a/test/markup/php/namespace.expect.txt b/test/markup/php/namespace.expect.txt new file mode 100644 index 0000000000..8b907e1873 --- /dev/null +++ b/test/markup/php/namespace.expect.txt @@ -0,0 +1,8 @@ +namespace Location\Web; +namespace foo; +use My\Full\Classname as Another; +use My\Full\NSname; +use ArrayObject; +use function My\Full\functionName; +use function My\Full\functionName as func; +use const My\Full\CONSTANT; diff --git a/test/markup/php/namespace.txt b/test/markup/php/namespace.txt new file mode 100644 index 0000000000..cbb313094b --- /dev/null +++ b/test/markup/php/namespace.txt @@ -0,0 +1,8 @@ +namespace Location\Web; +namespace foo; +use My\Full\Classname as Another; +use My\Full\NSname; +use ArrayObject; +use function My\Full\functionName; +use function My\Full\functionName as func; +use const My\Full\CONSTANT; From 531cbfb70b741840a82136217e7c4748d13090e6 Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Thu, 9 Dec 2021 18:57:05 -0500 Subject: [PATCH 35/76] chore(php) comments should not care about pre-processor - this should be handled by php-template level (not php) --- src/languages/php.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/languages/php.js b/src/languages/php.js index 2e9c8c318d..96e2aec158 100644 --- a/src/languages/php.js +++ b/src/languages/php.js @@ -281,7 +281,7 @@ export default function(hljs) { keywords: KEYWORDS, contains: [ hljs.HASH_COMMENT_MODE, - hljs.COMMENT('//', '$', {contains: [PREPROCESSOR]}), + hljs.COMMENT('//', '$'), hljs.COMMENT( '/\\*', '\\*/', From 8ddadca61d5c70dcdec752a2810eaa5c1b9f5f3b Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Thu, 9 Dec 2021 19:09:08 -0500 Subject: [PATCH 36/76] chore(php) remove dead contains rule This rule wasn't even being used since each of the variants already has it's own contains, so this one would never have a change to be "default". --- src/languages/php.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/languages/php.js b/src/languages/php.js index 96e2aec158..1fd109a844 100644 --- a/src/languages/php.js +++ b/src/languages/php.js @@ -47,13 +47,14 @@ export default function(hljs) { }); const STRING = { className: 'string', - contains: [hljs.BACKSLASH_ESCAPE, PREPROCESSOR], variants: [ hljs.inherit(SINGLE_QUOTED, { - begin: "b'", end: "'", + begin: "b'", + end: "'", }), hljs.inherit(DOUBLE_QUOTED, { - begin: 'b"', end: '"', + begin: 'b"', + end: '"', }), DOUBLE_QUOTED, SINGLE_QUOTED, From 38f58972c19c42398b372de4f6b0ccdf063e851e Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Thu, 9 Dec 2021 19:12:45 -0500 Subject: [PATCH 37/76] enh(php) $this is a variable.language --- src/languages/php.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/languages/php.js b/src/languages/php.js index 1fd109a844..4b04e71acb 100644 --- a/src/languages/php.js +++ b/src/languages/php.js @@ -305,7 +305,8 @@ export default function(hljs) { ), PREPROCESSOR, { - className: 'keyword', begin: /\$this\b/ + className: 'variable.language', + begin: /\$this\b/ }, VARIABLE, { From 417446cb8fe4a3e7bd25e3b28a9d2936d6092480 Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Thu, 9 Dec 2021 19:34:09 -0500 Subject: [PATCH 38/76] chore(php) no binary strings, was a 6.0 only thing --- src/languages/php.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/languages/php.js b/src/languages/php.js index 4b04e71acb..97f8e8d048 100644 --- a/src/languages/php.js +++ b/src/languages/php.js @@ -48,14 +48,6 @@ export default function(hljs) { const STRING = { className: 'string', variants: [ - hljs.inherit(SINGLE_QUOTED, { - begin: "b'", - end: "'", - }), - hljs.inherit(DOUBLE_QUOTED, { - begin: 'b"', - end: '"', - }), DOUBLE_QUOTED, SINGLE_QUOTED, HEREDOC From 6dd5cde9d828f86380118222da64da5a58137279 Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Thu, 9 Dec 2021 19:48:48 -0500 Subject: [PATCH 39/76] enh(php) add __COMPILER_HALT_OFFSET__ --- src/languages/php.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/languages/php.js b/src/languages/php.js index 97f8e8d048..e835d2feec 100644 --- a/src/languages/php.js +++ b/src/languages/php.js @@ -76,6 +76,7 @@ export default function(hljs) { "__DIR__", "__FILE__", "__FUNCTION__", + "__COMPILER_HALT_OFFSET__", "__LINE__", "__METHOD__", "__NAMESPACE__", @@ -289,7 +290,7 @@ export default function(hljs) { ), hljs.COMMENT( '__halt_compiler.+?;', - false, + null, { endsWithParent: true, keywords: '__halt_compiler' From a289f24f4a1b5c4f1f1f987ac7d37de4bdb8f31c Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Thu, 9 Dec 2021 20:23:43 -0500 Subject: [PATCH 40/76] chore(php) more correct __halt_compiler(); --- src/languages/php.js | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/languages/php.js b/src/languages/php.js index e835d2feec..66d1a94f73 100644 --- a/src/languages/php.js +++ b/src/languages/php.js @@ -288,14 +288,21 @@ export default function(hljs) { ] } ), - hljs.COMMENT( - '__halt_compiler.+?;', - null, - { - endsWithParent: true, - keywords: '__halt_compiler' + { + match: /__halt_compiler\(\);/, + keywords: '__halt_compiler', + starts: { + scope: "comment", + end: hljs.MATCH_NOTHING_RE, + contains: [ + { + match: /\?>/, + scope: "meta", + endsParent: true + } + ] } - ), + }, PREPROCESSOR, { className: 'variable.language', From c4d30d1af99a6313714c06d744a61ba7c7f813b9 Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Fri, 10 Dec 2021 12:39:47 -0500 Subject: [PATCH 41/76] chore(php) add changelog for PHP improvements --- CHANGES.md | 3 +++ src/languages/php.js | 2 -- test/markup/php/namespace.expect.txt | 1 + test/markup/php/namespace.txt | 1 + 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index b2294ae731..6bafdafe09 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -9,6 +9,9 @@ These changes should be for the better and should not be super noticeable but if Grammars: +- enh(php) improve `namespace` and `use` highlighting (#3427) [Josh Goebel][] +- enh(php) `$this` is a `variable.language` now (#3427) [Josh Goebel][] +- enh(php) add `__COMPILER_HALT_OFFSET__` (#3427) [Josh Goebel][] - enh(js/ts) fix => async function title highlights (#3405) [Josh Goebel][] - enh(twig) update keywords list (#3415) [Matthieu Lempereur][] - fix(python) def, class keywords detected mid-identifier (#3381) [Josh Goebel][] diff --git a/src/languages/php.js b/src/languages/php.js index 66d1a94f73..b0736a2014 100644 --- a/src/languages/php.js +++ b/src/languages/php.js @@ -230,12 +230,10 @@ export default function(hljs) { "SplMinHeap", "SplObjectStorage", "SplObserver", - "SplObserver", "SplPriorityQueue", "SplQueue", "SplStack", "SplSubject", - "SplSubject", "SplTempFileObject", "TypeError", "UnderflowException", diff --git a/test/markup/php/namespace.expect.txt b/test/markup/php/namespace.expect.txt index 8b907e1873..338c6d38a8 100644 --- a/test/markup/php/namespace.expect.txt +++ b/test/markup/php/namespace.expect.txt @@ -6,3 +6,4 @@ use function My\Full\functionName; use function My\Full\functionName as func; use const My\Full\CONSTANT; +use Example\{ClassA, ClassB, ClassC as C}; diff --git a/test/markup/php/namespace.txt b/test/markup/php/namespace.txt index cbb313094b..c2f16b7f01 100644 --- a/test/markup/php/namespace.txt +++ b/test/markup/php/namespace.txt @@ -6,3 +6,4 @@ use ArrayObject; use function My\Full\functionName; use function My\Full\functionName as func; use const My\Full\CONSTANT; +use Example\{ClassA, ClassB, ClassC as C}; From e1d3a316579640b26565e7d2843e8cc1c67eac0c Mon Sep 17 00:00:00 2001 From: jeyllani <87556224+jeyllani@users.noreply.github.com> Date: Sun, 12 Dec 2021 20:10:33 +0100 Subject: [PATCH 42/76] (enh) New 3rd party Language Grammar: Pine Script (#3428) --- CHANGES.md | 5 +++++ SUPPORTED_LANGUAGES.md | 1 + 2 files changed, 6 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 6bafdafe09..208041d3f8 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,9 @@ ## Version 11.4 (most likely) +New Language: + +- Added 3rd party Pine Script grammar to SUPPORTED_LANGUAGES [Jeylani B][] + Themes: - `Default` is now much closer WCAG AA (contrast) (#3402) [Josh Goebel] @@ -41,6 +45,7 @@ Themes: - Modified background color in css for Gradient Light and Gradient Dark themes [Samia Ali][] +[Jeylani B]: https://github.com/jeyllani [Richard Gibson]: https://github.com/gibson042 [Bradley Mackey]: https://github.com/bradleymackey [Melvyn Laïly]: https://github.com/mlaily diff --git a/SUPPORTED_LANGUAGES.md b/SUPPORTED_LANGUAGES.md index aa6db49636..ed4382692a 100644 --- a/SUPPORTED_LANGUAGES.md +++ b/SUPPORTED_LANGUAGES.md @@ -146,6 +146,7 @@ The table below shows the full list of languages (and corresponding classes/alia | Papyrus | papyrus, psc |[highlightjs-papyrus](https://github.com/Pickysaurus/highlightjs-papyrus) | | Parser3 | parser3 | | | Perl | perl, pl, pm | | +| Pine Script | pine, pinescript | [highlightjs-pine](https://github.com/jeyllani/highlightjs-pine) | | Plaintext | plaintext, txt, text | | | Pony | pony | | | PostgreSQL & PL/pgSQL | pgsql, postgres, postgresql | | From 585be0285137eb93c061ac6257da79ebdc05149c Mon Sep 17 00:00:00 2001 From: Sean Pinkney Date: Tue, 14 Dec 2021 17:28:45 -0500 Subject: [PATCH 43/76] enh(stan) Update Stan for version 2.28 (#3413) Version 2.28 related: * complex and array types * complex numbers * added all new functions and distributions Other Improvements: * highlighting of constants * highlighting for user defined distributions * highlighting for truncation Co-authored-by: Josh Goebel --- CHANGES.md | 3 +- src/languages/stan.js | 392 ++++++++++++---------------- test/detect/stan/default.txt | 63 ++--- test/markup/stan/default.expect.txt | 63 ++--- test/markup/stan/default.txt | 63 ++--- 5 files changed, 263 insertions(+), 321 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 208041d3f8..a15582a946 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -26,6 +26,8 @@ Grammars: - enh(js/ts) improve `CLASS_REFERENCE` (#3411) [Josh Goebel][] - enh(nsis) Update defines pattern to allow `!` (#3417) [idleberg][] - enh(nsis) Update language strings pattern to allow `!` (#3420) [idleberg][] +- fix(stan) Updated for Stan 2.28 and other misc. improvements (#3410) +- enh(nsis) Update variables pattern (#3416) [idleberg][] - fix(clojure) Several issues with Clojure highlighting (#3397) [Björn Ebbinghaus][] - fix(clojure) `comment` macro catches more than it should (#3395) - fix(clojure) `$` in symbol breaks highlighting @@ -35,7 +37,6 @@ Grammars: - enh(clojure) Add `regex` mode to regex literal - fix(clojure) Remove inconsistent/broken highlighting for metadata - enh(clojure) Add `punctuation` mode for commas. - - enh(nsis) Update variables pattern (#3416) [idleberg][] Developer Tools: diff --git a/src/languages/stan.js b/src/languages/stan.js index 3bd657282b..1636359f22 100644 --- a/src/languages/stan.js +++ b/src/languages/stan.js @@ -1,12 +1,13 @@ /* Language: Stan Description: The Stan probabilistic programming language -Author: Jeffrey B. Arnold +Author: Sean Pinkney Website: http://mc-stan.org/ Category: scientific */ export default function(hljs) { + const regex = hljs.regex; // variable names cannot conflict with block identifiers const BLOCKS = [ 'functions', @@ -17,6 +18,7 @@ export default function(hljs) { 'transformed', 'generated' ]; + const STATEMENTS = [ 'for', 'in', @@ -27,16 +29,10 @@ export default function(hljs) { 'continue', 'return' ]; - const SPECIAL_FUNCTIONS = [ - 'print', - 'reject', - 'increment_log_prob|10', - 'integrate_ode|10', - 'integrate_ode_rk45|10', - 'integrate_ode_bdf|10', - 'algebra_solver' - ]; - const VAR_TYPES = [ + + const TYPES = [ + 'array', + 'complex', 'int', 'real', 'vector', @@ -52,13 +48,24 @@ export default function(hljs) { 'cov_matrix|10', 'void' ]; + + // to get the functions list + // clone the [stan-docs repo](https://github.com/stan-dev/docs) + // then cd into it and run this bash script https://gist.github.com/joshgoebel/dcd33f82d4059a907c986049893843cf + // + // the output files are + // distributions_quoted.txt + // functions_quoted.txt + const FUNCTIONS = [ 'Phi', 'Phi_approx', 'abs', 'acos', 'acosh', + 'add_diag', 'algebra_solver', + 'algebra_solver_newton', 'append_array', 'append_col', 'append_row', @@ -67,56 +74,21 @@ export default function(hljs) { 'atan', 'atan2', 'atanh', - 'bernoulli_cdf', - 'bernoulli_lccdf', - 'bernoulli_lcdf', - 'bernoulli_logit_lpmf', - 'bernoulli_logit_rng', - 'bernoulli_lpmf', - 'bernoulli_rng', 'bessel_first_kind', 'bessel_second_kind', - 'beta_binomial_cdf', - 'beta_binomial_lccdf', - 'beta_binomial_lcdf', - 'beta_binomial_lpmf', - 'beta_binomial_rng', - 'beta_cdf', - 'beta_lccdf', - 'beta_lcdf', - 'beta_lpdf', - 'beta_rng', 'binary_log_loss', - 'binomial_cdf', 'binomial_coefficient_log', - 'binomial_lccdf', - 'binomial_lcdf', - 'binomial_logit_lpmf', - 'binomial_lpmf', - 'binomial_rng', 'block', - 'categorical_logit_lpmf', - 'categorical_logit_rng', - 'categorical_lpmf', - 'categorical_rng', - 'cauchy_cdf', - 'cauchy_lccdf', - 'cauchy_lcdf', - 'cauchy_lpdf', - 'cauchy_rng', 'cbrt', 'ceil', - 'chi_square_cdf', - 'chi_square_lccdf', - 'chi_square_lcdf', - 'chi_square_lpdf', - 'chi_square_rng', + 'chol2inv', 'cholesky_decompose', 'choose', 'col', 'cols', 'columns_dot_product', 'columns_dot_self', + 'conj', 'cos', 'cosh', 'cov_exp_quad', @@ -134,34 +106,16 @@ export default function(hljs) { 'diagonal', 'digamma', 'dims', - 'dirichlet_lpdf', - 'dirichlet_rng', 'distance', 'dot_product', 'dot_self', - 'double_exponential_cdf', - 'double_exponential_lccdf', - 'double_exponential_lcdf', - 'double_exponential_lpdf', - 'double_exponential_rng', - 'e', 'eigenvalues_sym', 'eigenvectors_sym', 'erf', 'erfc', 'exp', 'exp2', - 'exp_mod_normal_cdf', - 'exp_mod_normal_lccdf', - 'exp_mod_normal_lcdf', - 'exp_mod_normal_lpdf', - 'exp_mod_normal_rng', 'expm1', - 'exponential_cdf', - 'exponential_lccdf', - 'exponential_lcdf', - 'exponential_lpdf', - 'exponential_rng', 'fabs', 'falling_factorial', 'fdim', @@ -170,94 +124,68 @@ export default function(hljs) { 'fmax', 'fmin', 'fmod', - 'frechet_cdf', - 'frechet_lccdf', - 'frechet_lcdf', - 'frechet_lpdf', - 'frechet_rng', - 'gamma_cdf', - 'gamma_lccdf', - 'gamma_lcdf', - 'gamma_lpdf', 'gamma_p', 'gamma_q', - 'gamma_rng', - 'gaussian_dlm_obs_lpdf', + 'generalized_inverse', + 'get_imag', 'get_lp', - 'gumbel_cdf', - 'gumbel_lccdf', - 'gumbel_lcdf', - 'gumbel_lpdf', - 'gumbel_rng', + 'get_real', 'head', - 'hypergeometric_lpmf', - 'hypergeometric_rng', + 'hmm_hidden_state_prob', + 'hmm_marginal', 'hypot', + 'identity_matrix', 'inc_beta', 'int_step', + 'integrate_1d', 'integrate_ode', + 'integrate_ode_adams', 'integrate_ode_bdf', 'integrate_ode_rk45', 'inv', 'inv_Phi', - 'inv_chi_square_cdf', - 'inv_chi_square_lccdf', - 'inv_chi_square_lcdf', - 'inv_chi_square_lpdf', - 'inv_chi_square_rng', 'inv_cloglog', - 'inv_gamma_cdf', - 'inv_gamma_lccdf', - 'inv_gamma_lcdf', - 'inv_gamma_lpdf', - 'inv_gamma_rng', 'inv_logit', 'inv_sqrt', 'inv_square', - 'inv_wishart_lpdf', - 'inv_wishart_rng', 'inverse', 'inverse_spd', 'is_inf', 'is_nan', + 'lambert_w0', + 'lambert_wm1', 'lbeta', 'lchoose', + 'ldexp', 'lgamma', - 'lkj_corr_cholesky_lpdf', - 'lkj_corr_cholesky_rng', - 'lkj_corr_lpdf', - 'lkj_corr_rng', + 'linspaced_array', + 'linspaced_int_array', + 'linspaced_row_vector', + 'linspaced_vector', 'lmgamma', 'lmultiply', 'log', - 'log10', 'log1m', 'log1m_exp', 'log1m_inv_logit', 'log1p', 'log1p_exp', - 'log2', 'log_determinant', 'log_diff_exp', 'log_falling_factorial', 'log_inv_logit', + 'log_inv_logit_diff', 'log_mix', + 'log_modified_bessel_first_kind', 'log_rising_factorial', 'log_softmax', 'log_sum_exp', - 'logistic_cdf', - 'logistic_lccdf', - 'logistic_lcdf', - 'logistic_lpdf', - 'logistic_rng', 'logit', - 'lognormal_cdf', - 'lognormal_lccdf', - 'lognormal_lcdf', - 'lognormal_lpdf', - 'lognormal_rng', 'machine_precision', + 'map_rect', 'matrix_exp', + 'matrix_exp_multiply', + 'matrix_power', 'max', 'mdivide_left_spd', 'mdivide_left_tri_low', @@ -267,120 +195,80 @@ export default function(hljs) { 'min', 'modified_bessel_first_kind', 'modified_bessel_second_kind', - 'multi_gp_cholesky_lpdf', - 'multi_gp_lpdf', - 'multi_normal_cholesky_lpdf', - 'multi_normal_cholesky_rng', - 'multi_normal_lpdf', - 'multi_normal_prec_lpdf', - 'multi_normal_rng', - 'multi_student_t_lpdf', - 'multi_student_t_rng', - 'multinomial_lpmf', - 'multinomial_rng', 'multiply_log', 'multiply_lower_tri_self_transpose', - 'neg_binomial_2_cdf', - 'neg_binomial_2_lccdf', - 'neg_binomial_2_lcdf', - 'neg_binomial_2_log_lpmf', - 'neg_binomial_2_log_rng', - 'neg_binomial_2_lpmf', - 'neg_binomial_2_rng', - 'neg_binomial_cdf', - 'neg_binomial_lccdf', - 'neg_binomial_lcdf', - 'neg_binomial_lpmf', - 'neg_binomial_rng', 'negative_infinity', - 'normal_cdf', - 'normal_lccdf', - 'normal_lcdf', - 'normal_lpdf', - 'normal_rng', + 'norm', 'not_a_number', 'num_elements', - 'ordered_logistic_lpmf', - 'ordered_logistic_rng', + 'ode_adams', + 'ode_adams_tol', + 'ode_adjoint_tol_ctl', + 'ode_bdf', + 'ode_bdf_tol', + 'ode_ckrk', + 'ode_ckrk_tol', + 'ode_rk45', + 'ode_rk45_tol', + 'one_hot_array', + 'one_hot_int_array', + 'one_hot_row_vector', + 'one_hot_vector', + 'ones_array', + 'ones_int_array', + 'ones_row_vector', + 'ones_vector', 'owens_t', - 'pareto_cdf', - 'pareto_lccdf', - 'pareto_lcdf', - 'pareto_lpdf', - 'pareto_rng', - 'pareto_type_2_cdf', - 'pareto_type_2_lccdf', - 'pareto_type_2_lcdf', - 'pareto_type_2_lpdf', - 'pareto_type_2_rng', - 'pi', - 'poisson_cdf', - 'poisson_lccdf', - 'poisson_lcdf', - 'poisson_log_lpmf', - 'poisson_log_rng', - 'poisson_lpmf', - 'poisson_rng', + 'polar', 'positive_infinity', 'pow', 'print', 'prod', + 'proj', 'qr_Q', 'qr_R', + 'qr_thin_Q', + 'qr_thin_R', 'quad_form', 'quad_form_diag', 'quad_form_sym', + 'quantile', 'rank', - 'rayleigh_cdf', - 'rayleigh_lccdf', - 'rayleigh_lcdf', - 'rayleigh_lpdf', - 'rayleigh_rng', + 'reduce_sum', 'reject', 'rep_array', 'rep_matrix', 'rep_row_vector', 'rep_vector', + 'reverse', 'rising_factorial', 'round', 'row', 'rows', 'rows_dot_product', 'rows_dot_self', - 'scaled_inv_chi_square_cdf', - 'scaled_inv_chi_square_lccdf', - 'scaled_inv_chi_square_lcdf', - 'scaled_inv_chi_square_lpdf', - 'scaled_inv_chi_square_rng', + 'scale_matrix_exp_multiply', 'sd', 'segment', 'sin', 'singular_values', 'sinh', 'size', - 'skew_normal_cdf', - 'skew_normal_lccdf', - 'skew_normal_lcdf', - 'skew_normal_lpdf', - 'skew_normal_rng', 'softmax', 'sort_asc', 'sort_desc', 'sort_indices_asc', 'sort_indices_desc', 'sqrt', - 'sqrt2', 'square', 'squared_distance', 'step', - 'student_t_cdf', - 'student_t_lccdf', - 'student_t_lcdf', - 'student_t_lpdf', - 'student_t_rng', 'sub_col', 'sub_row', 'sum', + 'svd_U', + 'svd_V', + 'symmetrize_from_lower_tri', 'tail', 'tan', 'tanh', @@ -389,6 +277,7 @@ export default function(hljs) { 'tgamma', 'to_array_1d', 'to_array_2d', + 'to_complex', 'to_matrix', 'to_row_vector', 'to_vector', @@ -397,35 +286,29 @@ export default function(hljs) { 'trace_quad_form', 'trigamma', 'trunc', - 'uniform_cdf', - 'uniform_lccdf', - 'uniform_lcdf', - 'uniform_lpdf', - 'uniform_rng', + 'uniform_simplex', 'variance', - 'von_mises_lpdf', - 'von_mises_rng', - 'weibull_cdf', - 'weibull_lccdf', - 'weibull_lcdf', - 'weibull_lpdf', - 'weibull_rng', - 'wiener_lpdf', - 'wishart_lpdf', - 'wishart_rng' + 'zeros_array', + 'zeros_int_array', + 'zeros_row_vector' ]; + const DISTRIBUTIONS = [ 'bernoulli', 'bernoulli_logit', + 'bernoulli_logit_glm', 'beta', 'beta_binomial', + 'beta_proportion', 'binomial', 'binomial_logit', 'categorical', 'categorical_logit', + 'categorical_logit_glm', 'cauchy', 'chi_square', 'dirichlet', + 'discrete_range', 'double_exponential', 'exp_mod_normal', 'exponential', @@ -433,6 +316,7 @@ export default function(hljs) { 'gamma', 'gaussian_dlm_obs', 'gumbel', + 'hmm_latent', 'hypergeometric', 'inv_chi_square', 'inv_gamma', @@ -448,18 +332,26 @@ export default function(hljs) { 'multi_normal_prec', 'multi_student_t', 'multinomial', + 'multinomial_logit', 'neg_binomial', 'neg_binomial_2', 'neg_binomial_2_log', + 'neg_binomial_2_log_glm', 'normal', + 'normal_id_glm', 'ordered_logistic', + 'ordered_logistic_glm', + 'ordered_probit', 'pareto', 'pareto_type_2', 'poisson', 'poisson_log', + 'poisson_log_glm', 'rayleigh', 'scaled_inv_chi_square', + 'skew_double_exponential', 'skew_normal', + 'std_normal', 'student_t', 'uniform', 'von_mises', @@ -475,7 +367,7 @@ export default function(hljs) { relevance: 0, contains: [ { - className: 'doctag', + scope: 'doctag', match: /@(return|param)/ } ] @@ -483,27 +375,33 @@ export default function(hljs) { ); const INCLUDE = { - className: 'meta', - begin: /^#include\b/, + scope: 'meta', + begin: /#include\b/, end: /$/, - relevance: 0, // relevance comes from keywords - keywords: "include", contains: [ { - match: /[a-z][a-z-.]+/, - className: "string" + match: /[a-z][a-z-._]+/, + scope: 'string' }, hljs.C_LINE_COMMENT_MODE ] }; + const RANGE_CONSTRAINTS = [ + "lower", + "upper", + "offset", + "multiplier" + ]; + return { name: 'Stan', aliases: [ 'stanfuncs' ], keywords: { $pattern: hljs.IDENT_RE, title: BLOCKS, - keyword: STATEMENTS.concat(VAR_TYPES).concat(SPECIAL_FUNCTIONS), + type: TYPES, + keyword: STATEMENTS, built_in: FUNCTIONS }, contains: [ @@ -512,41 +410,81 @@ export default function(hljs) { hljs.HASH_COMMENT_MODE, BLOCK_COMMENT, { - // hack: in range constraints, lower must follow "<" - begin: /<\s*lower\s*=/, - keywords: 'lower' + scope: 'built_in', + match: /\s(pi|e|sqrt2|log2|log10)(?=\()/, + relevance: 0 + }, + { + match: regex.concat(/[<,]\s*/, regex.either(...RANGE_CONSTRAINTS), /\s*=/), + keywords: RANGE_CONSTRAINTS }, { - // hack: in range constraints, upper must follow either , or < - // or - begin: /[<,]\s*upper\s*=/, - keywords: 'upper' + scope: 'keyword', + match: /\btarget(?=\s*\+=)/, }, { - className: 'keyword', - begin: /\btarget\s*\+=/ + // highlights the 'T' in T[,] for only Stan language distributrions + match: [ + /~\s*/, + regex.either(...DISTRIBUTIONS), + /(?:\(\))/, + /\s*T(?=\s*\[)/ + ], + scope: { + 2: "built_in", + 4: "keyword" + } }, { - begin: '~\\s*(' + hljs.IDENT_RE + ')\\s*\\(', - keywords: DISTRIBUTIONS + // highlights distributions that end with special endings + scope: 'built_in', + keywords: DISTRIBUTIONS, + begin: regex.concat(/\w*/, regex.either(...DISTRIBUTIONS), /(_lpdf|_lupdf|_lpmf|_cdf|_lcdf|_lccdf|_qf)(?=\s*[\(.*\)])/) }, { - className: 'number', - variants: [ - { - begin: /\b\d+(?:\.\d*)?(?:[eE][+-]?\d+)?/ - }, - { - begin: /\.\d+(?:[eE][+-]?\d+)?\b/ - } + // highlights distributions after ~ + begin: [ + /~/, + /\s*/, + regex.concat(regex.either(...DISTRIBUTIONS), /(?=\s*[\(.*\)])/) ], - relevance: 0 + scope: { 3: "built_in" } + }, + { + // highlights user defined distributions after ~ + begin: [ + /~/, + /\s*\w+(?=\s*[\(.*\)])/, + '(?!.*/\b(' + regex.either(...DISTRIBUTIONS) + ')\b)' + ], + scope: { 2: "title.function" } + }, + { + // highlights user defined distributions with special endings + scope: 'title.function', + begin: /\w*(_lpdf|_lupdf|_lpmf|_cdf|_lcdf|_lccdf|_qf)(?=\s*[\(.*\)])/ }, { - className: 'string', - begin: '"', - end: '"', + scope: 'number', + match: regex.concat( + // Comes from @RunDevelopment accessed 11/29/2021 at + // https://github.com/PrismJS/prism/blob/c53ad2e65b7193ab4f03a1797506a54bbb33d5a2/components/prism-stan.js#L56 + + // start of big noncapture group which + // 1. gets numbers that are by themselves + // 2. numbers that are separated by _ + // 3. numbers that are separted by . + /(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)/, + // grabs scientific notation + // grabs complex numbers with i + /(?:[eE][+-]?\d+(?:_\d+)*)?i?(?!\w)/ + ), relevance: 0 + }, + { + scope: 'string', + begin: /"/, + end: /"/ } ] }; diff --git a/test/detect/stan/default.txt b/test/detect/stan/default.txt index 99e56c45ec..a4b42f332e 100644 --- a/test/detect/stan/default.txt +++ b/test/detect/stan/default.txt @@ -1,39 +1,40 @@ -// Multivariate Regression Example -// Taken from stan-reference-2.8.0.pdf p.66 - +functions { + #include normal_copula.stanfunctions +} data { - int N; // num individuals - int K; // num ind predictors - int J; // num groups - int L; // num group predictors - int jj[N]; // group for individual - matrix[N,K] x; // individual predictors - row_vector[L] u[J]; // group predictors - vector[N] y; // outcomes + int N; + int K; + matrix[N, K] x; } +transformed data { + complex zi = 1+3.14i; + zi = zi * 0i; + complex yi = to_complex(0, 1.1) + to_complex(0.0, 2.2) + to_complex(); + real x = get_real(3i - 40e-3i + 1e10i); +}› parameters { - corr_matrix[K] Omega; // prior correlation - vector[K] tau; // prior scale - matrix[L,K] gamma; // group coeffs - vector[K] beta[J]; // indiv coeffs by group - real sigma; // prediction error scale + array[K - 1] real mu; + array[K + 1] real sigma; + cholesky_factor_corr[K] L; } model { - tau ~ cauchy(0,2.5); - Omega ~ lkj_corr(2); - to_vector(gamma) ~ normal(0, 5); - { - row_vector[K] u_gamma[J]; - for (j in 1:J) - u_gamma[j] <- u[j] * gamma; - beta ~ multi_normal(u_gamma, quad_form_diag(Omega, tau)); - } + target += normal_lpdf(x[ : , 1] | mu[1], sigma[1]); + target += gumbel_lpdf(x[ : , 2] | mu[2], sigma[2]); + target += lognormal_lpdf(x[ : , 3] | mu[3], sigma[3]); + target += weibull_lpdf(x[ : , 4] | sigma[4], sigma[5]); + { - vector[N] x_beta_jj; - for (n in 1:N) - x_beta_jj[n] <- x[n] * beta[jj[n]]; - y ~ normal(x_beta_jj, sigma); + matrix[K, N] y; + for (n in 1 : N) { + y[1, n] = inv_Phi(normal_cdf(x[n, 1] | mu[1], sigma[1])); + y[2, n] = inv_Phi(gumbel_cdf(x[n, 2] | mu[2], sigma[2])); + y[3, n] = inv_Phi(lognormal_cdf(x[n, 3] | mu[3], sigma[3])); + y[4, n] = inv_Phi(weibull_cdf(x[n, 4] | sigma[4], sigma[5])); + } + y ~ multi_normal(L); + } } - -# Note: Octothorpes indicate comments, too! +generated quantities { + matrix[K, K] Sigma = multiply_lower_tri_self_transpose(L); +} \ No newline at end of file diff --git a/test/markup/stan/default.expect.txt b/test/markup/stan/default.expect.txt index 6a32c43433..aeb9552aa5 100644 --- a/test/markup/stan/default.expect.txt +++ b/test/markup/stan/default.expect.txt @@ -1,39 +1,40 @@ -// Multivariate Regression Example -// Taken from stan-reference-2.8.0.pdf p.66 - +functions { + #include normal_copula.stanfunctions +} data { - int<lower=0> N; // num individuals - int<lower=1> K; // num ind predictors - int<lower=1> J; // num groups - int<lower=1> L; // num group predictors - int<lower=1,upper=J> jj[N]; // group for individual - matrix[N,K] x; // individual predictors - row_vector[L] u[J]; // group predictors - vector[N] y; // outcomes + int<lower=0> N; + int K; + matrix[N, K] x; } +transformed data { + complex zi = 1+3.14i; + zi = zi * 0i; + complex yi = to_complex(0, 1.1) + to_complex(0.0, 2.2) + to_complex(); + real x = get_real(3i - 40e-3i + 1e10i); +}› parameters { - corr_matrix[K] Omega; // prior correlation - vector<lower=0>[K] tau; // prior scale - matrix[L,K] gamma; // group coeffs - vector[K] beta[J]; // indiv coeffs by group - real<lower=0> sigma; // prediction error scale + array[K - 1] real mu; + array[K + 1] real<lower=0> sigma; + cholesky_factor_corr[K] L; } model { - tau ~ cauchy(0,2.5); - Omega ~ lkj_corr(2); - to_vector(gamma) ~ normal(0, 5); - { - row_vector[K] u_gamma[J]; - for (j in 1:J) - u_gamma[j] <- u[j] * gamma; - beta ~ multi_normal(u_gamma, quad_form_diag(Omega, tau)); - } + target += normal_lpdf(x[ : , 1] | mu[1], sigma[1]); + target += gumbel_lpdf(x[ : , 2] | mu[2], sigma[2]); + target += lognormal_lpdf(x[ : , 3] | mu[3], sigma[3]); + target += weibull_lpdf(x[ : , 4] | sigma[4], sigma[5]); + { - vector[N] x_beta_jj; - for (n in 1:N) - x_beta_jj[n] <- x[n] * beta[jj[n]]; - y ~ normal(x_beta_jj, sigma); + matrix[K, N] y; + for (n in 1 : N) { + y[1, n] = inv_Phi(normal_cdf(x[n, 1] | mu[1], sigma[1])); + y[2, n] = inv_Phi(gumbel_cdf(x[n, 2] | mu[2], sigma[2])); + y[3, n] = inv_Phi(lognormal_cdf(x[n, 3] | mu[3], sigma[3])); + y[4, n] = inv_Phi(weibull_cdf(x[n, 4] | sigma[4], sigma[5])); + } + y ~ multi_normal(L); + } } - -# Note: Octothorpes indicate comments, too! +generated quantities { + matrix[K, K] Sigma = multiply_lower_tri_self_transpose(L); +} \ No newline at end of file diff --git a/test/markup/stan/default.txt b/test/markup/stan/default.txt index 99e56c45ec..a4b42f332e 100644 --- a/test/markup/stan/default.txt +++ b/test/markup/stan/default.txt @@ -1,39 +1,40 @@ -// Multivariate Regression Example -// Taken from stan-reference-2.8.0.pdf p.66 - +functions { + #include normal_copula.stanfunctions +} data { - int N; // num individuals - int K; // num ind predictors - int J; // num groups - int L; // num group predictors - int jj[N]; // group for individual - matrix[N,K] x; // individual predictors - row_vector[L] u[J]; // group predictors - vector[N] y; // outcomes + int N; + int K; + matrix[N, K] x; } +transformed data { + complex zi = 1+3.14i; + zi = zi * 0i; + complex yi = to_complex(0, 1.1) + to_complex(0.0, 2.2) + to_complex(); + real x = get_real(3i - 40e-3i + 1e10i); +}› parameters { - corr_matrix[K] Omega; // prior correlation - vector[K] tau; // prior scale - matrix[L,K] gamma; // group coeffs - vector[K] beta[J]; // indiv coeffs by group - real sigma; // prediction error scale + array[K - 1] real mu; + array[K + 1] real sigma; + cholesky_factor_corr[K] L; } model { - tau ~ cauchy(0,2.5); - Omega ~ lkj_corr(2); - to_vector(gamma) ~ normal(0, 5); - { - row_vector[K] u_gamma[J]; - for (j in 1:J) - u_gamma[j] <- u[j] * gamma; - beta ~ multi_normal(u_gamma, quad_form_diag(Omega, tau)); - } + target += normal_lpdf(x[ : , 1] | mu[1], sigma[1]); + target += gumbel_lpdf(x[ : , 2] | mu[2], sigma[2]); + target += lognormal_lpdf(x[ : , 3] | mu[3], sigma[3]); + target += weibull_lpdf(x[ : , 4] | sigma[4], sigma[5]); + { - vector[N] x_beta_jj; - for (n in 1:N) - x_beta_jj[n] <- x[n] * beta[jj[n]]; - y ~ normal(x_beta_jj, sigma); + matrix[K, N] y; + for (n in 1 : N) { + y[1, n] = inv_Phi(normal_cdf(x[n, 1] | mu[1], sigma[1])); + y[2, n] = inv_Phi(gumbel_cdf(x[n, 2] | mu[2], sigma[2])); + y[3, n] = inv_Phi(lognormal_cdf(x[n, 3] | mu[3], sigma[3])); + y[4, n] = inv_Phi(weibull_cdf(x[n, 4] | sigma[4], sigma[5])); + } + y ~ multi_normal(L); + } } - -# Note: Octothorpes indicate comments, too! +generated quantities { + matrix[K, K] Sigma = multiply_lower_tri_self_transpose(L); +} \ No newline at end of file From 384cd17098f740f34d6d0bb762527a4b5766b2ad Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Wed, 15 Dec 2021 15:57:03 -0500 Subject: [PATCH 44/76] chore(security) link to wiki security article now --- src/highlight.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/highlight.js b/src/highlight.js index 6f546e6ccc..ed0e187fd5 100644 --- a/src/highlight.js +++ b/src/highlight.js @@ -734,7 +734,8 @@ const HLJS = function(hljs) { if (element.children.length > 0) { if (!options.ignoreUnescapedHTML) { console.warn("One of your code blocks includes unescaped HTML. This is a potentially serious security risk."); - console.warn("https://github.com/highlightjs/highlight.js/issues/2886"); + console.warn("https://github.com/highlightjs/highlight.js/wiki/security"); + console.warn("The element with unescaped HTML:"); console.warn(element); } if (options.throwUnescapedHTML) { From db3f36b8217fcf7164a73cdba2f5f13f6463e033 Mon Sep 17 00:00:00 2001 From: Wojciech Kania Date: Thu, 9 Dec 2021 22:33:04 +0100 Subject: [PATCH 45/76] enh(php) Switch highlighter to partially case-insensitive --- src/languages/php.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/languages/php.js b/src/languages/php.js index b0736a2014..4656a8ef79 100644 --- a/src/languages/php.js +++ b/src/languages/php.js @@ -56,11 +56,11 @@ export default function(hljs) { const NUMBER = { className: 'number', variants: [ - { begin: `\\b0b[01]+(?:_[01]+)*\\b` }, // Binary w/ underscore support - { begin: `\\b0o[0-7]+(?:_[0-7]+)*\\b` }, // Octals w/ underscore support - { begin: `\\b0x[\\da-f]+(?:_[\\da-f]+)*\\b` }, // Hex w/ underscore support + { begin: `\\b0[bB][01]+(?:_[01]+)*\\b` }, // Binary w/ underscore support + { begin: `\\b0[oO][0-7]+(?:_[0-7]+)*\\b` }, // Octals w/ underscore support + { begin: `\\b0[xX][\\da-fA-F]+(?:_[\\da-fA-F]+)*\\b` }, // Hex w/ underscore support // Decimals w/ underscore support, with optional fragments and scientific exponent (e) suffix. - { begin: `(?:\\b\\d+(?:_\\d+)*(\\.(?:\\d+(?:_\\d+)*))?|\\B\\.\\d+)(?:e[+-]?\\d+)?` } + { begin: `(?:\\b\\d+(?:_\\d+)*(\\.(?:\\d+(?:_\\d+)*))?|\\B\\.\\d+)(?:[eE][+-]?\\d+)?` } ], relevance: 0 }; @@ -269,7 +269,7 @@ export default function(hljs) { built_in: BUILT_INS }; return { - case_insensitive: true, + case_insensitive: false, keywords: KEYWORDS, contains: [ hljs.HASH_COMMENT_MODE, From ac9f29431cedaaef8a362425d9450fdb5780d7a2 Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Fri, 10 Dec 2021 13:33:37 -0500 Subject: [PATCH 46/76] chore(php) support dual-cased literals --- src/languages/php.js | 23 ++++++++++++++++++++++- test/markup/php/case.expect.txt | 8 ++++++++ test/markup/php/case.txt | 8 ++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 test/markup/php/case.expect.txt create mode 100644 test/markup/php/case.txt diff --git a/src/languages/php.js b/src/languages/php.js index 4656a8ef79..9d38213f8f 100644 --- a/src/languages/php.js +++ b/src/languages/php.js @@ -263,9 +263,30 @@ export default function(hljs) { "stdClass" ]; + /** Dual-case keywords + * + * ["then","FILE"] => + * ["then", "THEN", "FILE", "file"] + * + * @param {string[]} items */ + const dualCase = (items) => { + /** @type string[] */ + const result = []; + items.forEach(item => { + if (item.toLowerCase() === item) { + result.push(item); + result.push(item.toUpperCase()); + } else { + result.push(item); + result.push(item.toLowerCase()); + } + }); + return result; + }; + const KEYWORDS = { keyword: KWS, - literal: LITERALS, + literal: dualCase(LITERALS), built_in: BUILT_INS }; return { diff --git a/test/markup/php/case.expect.txt b/test/markup/php/case.expect.txt new file mode 100644 index 0000000000..e75606fd72 --- /dev/null +++ b/test/markup/php/case.expect.txt @@ -0,0 +1,8 @@ +$test = true +$test = TRUE + +$a = false +$a = FALSE + +$b = null +$b = NULL diff --git a/test/markup/php/case.txt b/test/markup/php/case.txt new file mode 100644 index 0000000000..079112129e --- /dev/null +++ b/test/markup/php/case.txt @@ -0,0 +1,8 @@ +$test = true +$test = TRUE + +$a = false +$a = FALSE + +$b = null +$b = NULL From 8214035f5cb60f57c3d0156019828e6bf4527383 Mon Sep 17 00:00:00 2001 From: Wojciech Kania Date: Sat, 11 Dec 2021 22:59:35 +0100 Subject: [PATCH 47/76] enh(php) support function invoke --- src/languages/php.js | 33 +++++++++++++++++++++------- test/markup/php/functions.expect.txt | 10 +++++++++ test/markup/php/functions.txt | 10 +++++++++ test/markup/php/strings.expect.txt | 4 ++-- 4 files changed, 47 insertions(+), 10 deletions(-) diff --git a/src/languages/php.js b/src/languages/php.js index 9d38213f8f..baf64f5d9f 100644 --- a/src/languages/php.js +++ b/src/languages/php.js @@ -11,6 +11,7 @@ Category: common * @returns {LanguageDetail} * */ export default function(hljs) { + const regex = hljs.regex; const VARIABLE = { className: 'variable', begin: '\\$+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*' + @@ -145,7 +146,6 @@ export default function(hljs) { "isset", "iterable", "list", - "match|0", "mixed", "new", "object", @@ -172,7 +172,6 @@ export default function(hljs) { const BUILT_INS = [ // Standard PHP library: // - "Error|0", "AppendIterator", "ArgumentCountError", "ArithmeticError", @@ -273,11 +272,10 @@ export default function(hljs) { /** @type string[] */ const result = []; items.forEach(item => { + result.push(item); if (item.toLowerCase() === item) { - result.push(item); result.push(item.toUpperCase()); } else { - result.push(item); result.push(item.toLowerCase()); } }); @@ -285,9 +283,23 @@ export default function(hljs) { }; const KEYWORDS = { - keyword: KWS, + keyword: KWS.concat([ "match|0" ]), literal: dualCase(LITERALS), - built_in: BUILT_INS + built_in: BUILT_INS.concat([ "Error|0" ]), + }; + + const FUNCTION_INVOKE = { + relevance: 0, + match: [ + /(?:->|::|\s|\(|\\)/, + regex.concat("(?!fn\\b|function\\b|match\\b|", KWS.join("\\b|"), "|", BUILT_INS.join("\\b|"), "\\b)"), + /\w+/, + /\s*/, + regex.lookahead(/(?=\()/) + ], + scope: { + 3: "function.title.invoke", + } }; return { case_insensitive: false, @@ -328,9 +340,14 @@ export default function(hljs) { begin: /\$this\b/ }, VARIABLE, + FUNCTION_INVOKE, { // swallow composed identifiers to avoid parsing them as keywords - begin: /(::|->)+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/ + begin: /(::|->)+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(?!\()/ + }, + { + // swallow create object + begin: /new\s\\?[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*\s?\(/ }, { className: 'function', @@ -378,7 +395,7 @@ export default function(hljs) { }, // both use and namespace still use "old style" rules (vs multi-match) // because the namespace name can include `\` and we still want each - // element to be treated as it's own *individual* title + // element to be treated as its own *individual* title { beginKeywords: 'namespace', relevance: 0, diff --git a/test/markup/php/functions.expect.txt b/test/markup/php/functions.expect.txt index d161e753f4..ba14faad0b 100644 --- a/test/markup/php/functions.expect.txt +++ b/test/markup/php/functions.expect.txt @@ -6,3 +6,13 @@ $fn2 = function ($x) use ($y) { return $x + $y; }; + +/** + * Function invoke + */ +$date = new DateTimeImmutable (); +$date->format('Y-m-d'); + +DateTimeImmutable::createFromMutable(new \DateTime()); + +str_contains (\strtoupper(substr('abcdef', -2), 'f')); diff --git a/test/markup/php/functions.txt b/test/markup/php/functions.txt index 2eec171beb..525442d0bf 100644 --- a/test/markup/php/functions.txt +++ b/test/markup/php/functions.txt @@ -6,3 +6,13 @@ $fn1 = fn($x) => $x + $y; $fn2 = function ($x) use ($y) { return $x + $y; }; + +/** + * Function invoke + */ +$date = new DateTimeImmutable (); +$date->format('Y-m-d'); + +DateTimeImmutable::createFromMutable(new \DateTime()); + +str_contains (\strtoupper(substr('abcdef', -2), 'f')); diff --git a/test/markup/php/strings.expect.txt b/test/markup/php/strings.expect.txt index a547757933..56f3428e3b 100644 --- a/test/markup/php/strings.expect.txt +++ b/test/markup/php/strings.expect.txt @@ -12,12 +12,12 @@ MSG); // heredoc syntax -var_dump(<<<SQL +var_dump(<<<SQL SELECT * FROM table SQL); -var_dump(<<<SQL +var_dump(<<<SQL SELECT * FROM table SQL); From 4b1dc30a5b0b828a77cc1fadba77fc6d5f278b64 Mon Sep 17 00:00:00 2001 From: Wojciech Kania Date: Sun, 12 Dec 2021 19:11:43 +0100 Subject: [PATCH 48/76] enh(php) support class constructor call --- CHANGES.md | 3 +++ src/languages/php.js | 30 ++++++++++++++++++++++------ test/markup/php/functions.expect.txt | 23 +++++++++++++++++++-- test/markup/php/functions.txt | 21 ++++++++++++++++++- 4 files changed, 68 insertions(+), 9 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index a15582a946..c0e510146f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -13,6 +13,9 @@ These changes should be for the better and should not be super noticeable but if Grammars: +- enh(php) support class constructor call (#3427) [Wojciech Kania][] +- enh(php) support function invoke (#3427) [Wojciech Kania][] +- enh(php) Switch highlighter to partially case-insensitive (#3427) [Wojciech Kania][] - enh(php) improve `namespace` and `use` highlighting (#3427) [Josh Goebel][] - enh(php) `$this` is a `variable.language` now (#3427) [Josh Goebel][] - enh(php) add `__COMPILER_HALT_OFFSET__` (#3427) [Josh Goebel][] diff --git a/src/languages/php.js b/src/languages/php.js index baf64f5d9f..d37403ff99 100644 --- a/src/languages/php.js +++ b/src/languages/php.js @@ -288,11 +288,31 @@ export default function(hljs) { built_in: BUILT_INS.concat([ "Error|0" ]), }; + const CONSTRUCTOR_CALL = { + variants: [ + { + match: [ + /new/, + /\s+/, + // to prevent built ins from being confused as the class constructor call + regex.concat("(?!", BUILT_INS.join("\\b|"), "\\b)"), + /\\?\w+/, + /\s*\(/, + ], + scope: { + 1: "keyword", + 4: "title.class", + }, + } + ] + }; + const FUNCTION_INVOKE = { relevance: 0, match: [ /(?:->|::|\s|\(|\\)/, - regex.concat("(?!fn\\b|function\\b|match\\b|", KWS.join("\\b|"), "|", BUILT_INS.join("\\b|"), "\\b)"), + // to prevent keywords from being confused as the function title + regex.concat("(?!fn\\b|function\\b|match\\b|Error\\b|", KWS.join("\\b|"), "|", BUILT_INS.join("\\b|"), "\\b)"), /\w+/, /\s*/, regex.lookahead(/(?=\()/) @@ -301,6 +321,7 @@ export default function(hljs) { 3: "function.title.invoke", } }; + return { case_insensitive: false, keywords: KEYWORDS, @@ -343,12 +364,9 @@ export default function(hljs) { FUNCTION_INVOKE, { // swallow composed identifiers to avoid parsing them as keywords - begin: /(::|->)+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(?!\()/ - }, - { - // swallow create object - begin: /new\s\\?[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*\s?\(/ + begin: /(::|->)+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/ }, + CONSTRUCTOR_CALL, { className: 'function', relevance: 0, diff --git a/test/markup/php/functions.expect.txt b/test/markup/php/functions.expect.txt index ba14faad0b..2302fa6297 100644 --- a/test/markup/php/functions.expect.txt +++ b/test/markup/php/functions.expect.txt @@ -10,9 +10,28 @@ /** * Function invoke */ -$date = new DateTimeImmutable (); +$date = new DateTimeImmutable (); $date->format('Y-m-d'); -DateTimeImmutable::createFromMutable(new \DateTime()); +DateTimeImmutable::createFromMutable(new \DateTime('now')); str_contains (\strtoupper(substr('abcdef', -2), 'f')); + +/** + * Function declaration + */ +function testMe(string|int $name): int +{ + if (empty($name)) { + return 0; + } elseif ($name === 1) { + return (int) $name; + } + + switch($name) { + case '2': + return 2; + default: + throw new \Exception('error'); + } +} diff --git a/test/markup/php/functions.txt b/test/markup/php/functions.txt index 525442d0bf..077283afeb 100644 --- a/test/markup/php/functions.txt +++ b/test/markup/php/functions.txt @@ -13,6 +13,25 @@ $fn2 = function ($x) use ($y) { $date = new DateTimeImmutable (); $date->format('Y-m-d'); -DateTimeImmutable::createFromMutable(new \DateTime()); +DateTimeImmutable::createFromMutable(new \DateTime('now')); str_contains (\strtoupper(substr('abcdef', -2), 'f')); + +/** + * Function declaration + */ +function testMe(string|int $name): int +{ + if (empty($name)) { + return 0; + } elseif ($name === 1) { + return (int) $name; + } + + switch($name) { + case '2': + return 2; + default: + throw new \Exception('error'); + } +} From 323652a227549980ef54e0d942bd24a09559669c Mon Sep 17 00:00:00 2001 From: Wojciech Kania Date: Mon, 13 Dec 2021 20:24:40 +0100 Subject: [PATCH 49/76] chore(php) normalize keywords --- src/languages/php.js | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/languages/php.js b/src/languages/php.js index d37403ff99..e5339e0eb1 100644 --- a/src/languages/php.js +++ b/src/languages/php.js @@ -146,6 +146,7 @@ export default function(hljs) { "isset", "iterable", "list", + "match|0", "mixed", "new", "object", @@ -172,6 +173,7 @@ export default function(hljs) { const BUILT_INS = [ // Standard PHP library: // + "Error|0", "AppendIterator", "ArgumentCountError", "ArithmeticError", @@ -283,9 +285,17 @@ export default function(hljs) { }; const KEYWORDS = { - keyword: KWS.concat([ "match|0" ]), + keyword: KWS, literal: dualCase(LITERALS), - built_in: BUILT_INS.concat([ "Error|0" ]), + built_in: BUILT_INS, + }; + + /** + * @param {string[]} items */ + const normalizeKeywords = (items) => { + return items.map(item => { + return item.replace(/\|\d+$/, ""); + }); }; const CONSTRUCTOR_CALL = { @@ -295,7 +305,7 @@ export default function(hljs) { /new/, /\s+/, // to prevent built ins from being confused as the class constructor call - regex.concat("(?!", BUILT_INS.join("\\b|"), "\\b)"), + regex.concat("(?!", normalizeKeywords(BUILT_INS).join("\\b|"), "\\b)"), /\\?\w+/, /\s*\(/, ], @@ -312,7 +322,7 @@ export default function(hljs) { match: [ /(?:->|::|\s|\(|\\)/, // to prevent keywords from being confused as the function title - regex.concat("(?!fn\\b|function\\b|match\\b|Error\\b|", KWS.join("\\b|"), "|", BUILT_INS.join("\\b|"), "\\b)"), + regex.concat("(?!fn\\b|function\\b|", normalizeKeywords(KWS).join("\\b|"), "|", normalizeKeywords(BUILT_INS).join("\\b|"), "\\b)"), /\w+/, /\s*/, regex.lookahead(/(?=\()/) From 622dfd2425e5ee0f5c9e5791d375626dd88ad029 Mon Sep 17 00:00:00 2001 From: Wojciech Kania Date: Tue, 14 Dec 2021 18:26:17 +0100 Subject: [PATCH 50/76] enh(php) support First-class Callable Syntax --- CHANGES.md | 2 ++ src/languages/php.js | 11 ++++++----- test/markup/php/functions.expect.txt | 6 ++++++ test/markup/php/functions.txt | 6 ++++++ 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index c0e510146f..05034fcaea 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -13,6 +13,7 @@ These changes should be for the better and should not be super noticeable but if Grammars: +- enh(php) support First-class Callable Syntax (#3427) [Wojciech Kania][] - enh(php) support class constructor call (#3427) [Wojciech Kania][] - enh(php) support function invoke (#3427) [Wojciech Kania][] - enh(php) Switch highlighter to partially case-insensitive (#3427) [Wojciech Kania][] @@ -49,6 +50,7 @@ Themes: - Modified background color in css for Gradient Light and Gradient Dark themes [Samia Ali][] +[Wojciech Kania]: https://github.com/wkania [Jeylani B]: https://github.com/jeyllani [Richard Gibson]: https://github.com/gibson042 [Bradley Mackey]: https://github.com/bradleymackey diff --git a/src/languages/php.js b/src/languages/php.js index e5339e0eb1..f88609e1b0 100644 --- a/src/languages/php.js +++ b/src/languages/php.js @@ -303,11 +303,11 @@ export default function(hljs) { { match: [ /new/, - /\s+/, + / +/, // to prevent built ins from being confused as the class constructor call regex.concat("(?!", normalizeKeywords(BUILT_INS).join("\\b|"), "\\b)"), /\\?\w+/, - /\s*\(/, + / *\(/, ], scope: { 1: "keyword", @@ -320,11 +320,11 @@ export default function(hljs) { const FUNCTION_INVOKE = { relevance: 0, match: [ - /(?:->|::|\s|\(|\\)/, + /\b/, // to prevent keywords from being confused as the function title regex.concat("(?!fn\\b|function\\b|", normalizeKeywords(KWS).join("\\b|"), "|", normalizeKeywords(BUILT_INS).join("\\b|"), "\\b)"), /\w+/, - /\s*/, + / */, regex.lookahead(/(?=\()/) ], scope: { @@ -374,7 +374,8 @@ export default function(hljs) { FUNCTION_INVOKE, { // swallow composed identifiers to avoid parsing them as keywords - begin: /(::|->)+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/ + begin: /(::|->)+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(?! *\()(?![a-zA-Z0-9_\x7f-\xff])/, + // scope:"wrong" }, CONSTRUCTOR_CALL, { diff --git a/test/markup/php/functions.expect.txt b/test/markup/php/functions.expect.txt index 2302fa6297..946c41bd67 100644 --- a/test/markup/php/functions.expect.txt +++ b/test/markup/php/functions.expect.txt @@ -35,3 +35,9 @@ DateTimeImmutable::createFromMutable throw new \Exception('error'); } } + +/** + * First-class Callable Syntax + */ +$fun = mb_strlen(); +$fun(); diff --git a/test/markup/php/functions.txt b/test/markup/php/functions.txt index 077283afeb..86f7fd48a4 100644 --- a/test/markup/php/functions.txt +++ b/test/markup/php/functions.txt @@ -35,3 +35,9 @@ function testMe(string|int $name): int throw new \Exception('error'); } } + +/** + * First-class Callable Syntax + */ +$fun = mb_strlen(); +$fun(); From ceb070f820a333390f233a6c19772d468e59823c Mon Sep 17 00:00:00 2001 From: Wojciech Kania Date: Wed, 15 Dec 2021 22:38:14 +0100 Subject: [PATCH 51/76] chore(php) add list of valid whitespaces --- src/languages/php.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/languages/php.js b/src/languages/php.js index f88609e1b0..4832f88d71 100644 --- a/src/languages/php.js +++ b/src/languages/php.js @@ -46,6 +46,8 @@ export default function(hljs) { end: /[ \t]*(\w+)\b/, contains: hljs.QUOTE_STRING_MODE.contains.concat(SUBST), }); + // list of valid whitespaces because non-breaking space might be part of a name + const WHITESPACE = '[ \t\n]'; const STRING = { className: 'string', variants: [ @@ -303,11 +305,11 @@ export default function(hljs) { { match: [ /new/, - / +/, + regex.concat(WHITESPACE, "+"), // to prevent built ins from being confused as the class constructor call regex.concat("(?!", normalizeKeywords(BUILT_INS).join("\\b|"), "\\b)"), /\\?\w+/, - / *\(/, + regex.concat(WHITESPACE, "*\\("), ], scope: { 1: "keyword", @@ -324,7 +326,7 @@ export default function(hljs) { // to prevent keywords from being confused as the function title regex.concat("(?!fn\\b|function\\b|", normalizeKeywords(KWS).join("\\b|"), "|", normalizeKeywords(BUILT_INS).join("\\b|"), "\\b)"), /\w+/, - / */, + regex.concat(WHITESPACE, "*"), regex.lookahead(/(?=\()/) ], scope: { @@ -374,7 +376,11 @@ export default function(hljs) { FUNCTION_INVOKE, { // swallow composed identifiers to avoid parsing them as keywords - begin: /(::|->)+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(?! *\()(?![a-zA-Z0-9_\x7f-\xff])/, + match: regex.concat( + /(::|->)+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/, + regex.concat("(?!", WHITESPACE, "*\\()"), + /(?![a-zA-Z0-9_\x7f-\xff])/ + ), // scope:"wrong" }, CONSTRUCTOR_CALL, From 248b109ac477a2a529ba4c8fb65d5063a4deb0f5 Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Wed, 15 Dec 2021 17:43:39 -0500 Subject: [PATCH 52/76] fix: correct parent scope is `title` - also add `title.function.invoke` to the official list (Rust was already using) --- docs/css-classes-reference.rst | 2 ++ src/languages/php.js | 2 +- test/markup/php/functions.expect.txt | 8 ++++---- test/markup/php/strings.expect.txt | 4 ++-- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/docs/css-classes-reference.rst b/docs/css-classes-reference.rst index 70d45e4dc4..9cea743642 100644 --- a/docs/css-classes-reference.rst +++ b/docs/css-classes-reference.rst @@ -70,6 +70,8 @@ in mind so a better choice (for best theme support) might possibly be ``string`` +--------------------------+-------------------------------------------------------------+ | title.function | name of a function | +--------------------------+-------------------------------------------------------------+ +| title.function.invoke | name of a function (when being invoked) | ++--------------------------+-------------------------------------------------------------+ | params | block of function arguments (parameters) at the | | | place of declaration | +--------------------------+-------------------------------------------------------------+ diff --git a/src/languages/php.js b/src/languages/php.js index 4832f88d71..371ef2ae78 100644 --- a/src/languages/php.js +++ b/src/languages/php.js @@ -330,7 +330,7 @@ export default function(hljs) { regex.lookahead(/(?=\()/) ], scope: { - 3: "function.title.invoke", + 3: "title.function.invoke", } }; diff --git a/test/markup/php/functions.expect.txt b/test/markup/php/functions.expect.txt index 946c41bd67..f6bc43f49a 100644 --- a/test/markup/php/functions.expect.txt +++ b/test/markup/php/functions.expect.txt @@ -11,11 +11,11 @@ * Function invoke */ $date = new DateTimeImmutable (); -$date->format('Y-m-d'); +$date->format('Y-m-d'); -DateTimeImmutable::createFromMutable(new \DateTime('now')); +DateTimeImmutable::createFromMutable(new \DateTime('now')); -str_contains (\strtoupper(substr('abcdef', -2), 'f')); +str_contains (\strtoupper(substr('abcdef', -2), 'f')); /** * Function declaration @@ -39,5 +39,5 @@ DateTimeImmutable::createFromMutable /** * First-class Callable Syntax */ -$fun = mb_strlen(); +$fun = mb_strlen(); $fun(); diff --git a/test/markup/php/strings.expect.txt b/test/markup/php/strings.expect.txt index 56f3428e3b..8a9c4dd8f5 100644 --- a/test/markup/php/strings.expect.txt +++ b/test/markup/php/strings.expect.txt @@ -12,12 +12,12 @@ MSG); // heredoc syntax -var_dump(<<<SQL +var_dump(<<<SQL SELECT * FROM table SQL); -var_dump(<<<SQL +var_dump(<<<SQL SELECT * FROM table SQL); From b1d8b85985d1aea0ff2e62333cc26a4953200e5e Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Fri, 3 Dec 2021 13:28:13 -0500 Subject: [PATCH 53/76] (chore) title.class for CoffeeScript --- src/languages/coffeescript.js | 40 ++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/src/languages/coffeescript.js b/src/languages/coffeescript.js index fd333c4c2b..51bf00cd05 100644 --- a/src/languages/coffeescript.js +++ b/src/languages/coffeescript.js @@ -155,6 +155,30 @@ export default function(hljs) { }] }; + const CLASS_DEFINITION = { + variants: [ + { + match: [ + /class\s+/, + JS_IDENT_RE, + /\s+extends\s+/, + JS_IDENT_RE + ] + }, + { + match: [ + /class\s+/, + JS_IDENT_RE + ] + } + ], + scope: { + 2: "title.class", + 4: "title.class.inherited" + }, + keywords: KEYWORDS + }; + return { name: 'CoffeeScript', aliases: [ @@ -190,21 +214,7 @@ export default function(hljs) { contains: [PARAMS] }] }, - { - className: 'class', - beginKeywords: 'class', - end: '$', - illegal: /[:="\[\]]/, - contains: [ - { - beginKeywords: 'extends', - endsWithParent: true, - illegal: /[:="\[\]]/, - contains: [TITLE] - }, - TITLE - ] - }, + CLASS_DEFINITION, { begin: JS_IDENT_RE + ':', end: ':', From d681045da395b32df8a7f3c985a799c74271977b Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Fri, 3 Dec 2021 13:36:10 -0500 Subject: [PATCH 54/76] (chore) title.class for Livescript --- src/languages/livescript.js | 40 ++++++++++++++--------- test/markup/livescript/default.expect.txt | 2 +- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/src/languages/livescript.js b/src/languages/livescript.js index 21efa6f576..f55e004731 100644 --- a/src/languages/livescript.js +++ b/src/languages/livescript.js @@ -176,6 +176,30 @@ export default function(hljs) { begin: '(#=>|=>|\\|>>|-?->|!->)' }; + const CLASS_DEFINITION = { + variants: [ + { + match: [ + /class\s+/, + JS_IDENT_RE, + /\s+extends\s+/, + JS_IDENT_RE + ] + }, + { + match: [ + /class\s+/, + JS_IDENT_RE + ] + } + ], + scope: { + 2: "title.class", + 4: "title.class.inherited" + }, + keywords: KEYWORDS + }; + return { name: 'LiveScript', aliases: ['ls'], @@ -207,21 +231,7 @@ export default function(hljs) { } ] }, - { - className: 'class', - beginKeywords: 'class', - end: '$', - illegal: /[:="\[\]]/, - contains: [ - { - beginKeywords: 'extends', - endsWithParent: true, - illegal: /[:="\[\]]/, - contains: [TITLE] - }, - TITLE - ] - }, + CLASS_DEFINITION, { begin: JS_IDENT_RE + ':', end: ':', diff --git a/test/markup/livescript/default.expect.txt b/test/markup/livescript/default.expect.txt index 253ee2843f..bbf6630265 100644 --- a/test/markup/livescript/default.expect.txt +++ b/test/markup/livescript/default.expect.txt @@ -40,7 +40,7 @@ last-three [1 tofunction add x, y @result = x + y -class A +class A (num) -> @x = num property: 1 From 2b679bc65518236d9caf4cd649c63ca6123b51fe Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Fri, 3 Dec 2021 13:49:09 -0500 Subject: [PATCH 55/76] (chore) title.class for protobuf --- src/languages/protobuf.js | 56 ++++++++++++++----- .../protobuf/message-message.expect.txt | 8 +-- test/markup/protobuf/rpc.expect.txt | 2 +- 3 files changed, 47 insertions(+), 19 deletions(-) diff --git a/src/languages/protobuf.js b/src/languages/protobuf.js index 13c88426ee..7cae0a4a24 100644 --- a/src/languages/protobuf.js +++ b/src/languages/protobuf.js @@ -7,29 +7,57 @@ Category: protocols */ export default function(hljs) { + const KEYWORDS = [ + "package", + "import", + "option", + "optional", + "required", + "repeated", + "group", + "oneof" + ]; + const TYPES = [ + "double", + "float", + "int32", + "int64", + "uint32", + "uint64", + "sint32", + "sint64", + "fixed32", + "fixed64", + "sfixed32", + "sfixed64", + "bool", + "string", + "bytes" + ]; + const CLASS_DEFINITION = { + match: [ + /(message|enum|service)\s+/, + hljs.IDENT_RE + ], + scope: { + 1: "keyword", + 2: "title.class" + } + }; + return { name: 'Protocol Buffers', keywords: { - keyword: 'package import option optional required repeated group oneof', - built_in: 'double float int32 int64 uint32 uint64 sint32 sint64 ' + - 'fixed32 fixed64 sfixed32 sfixed64 bool string bytes', - literal: 'true false' + keyword: KEYWORDS, + type: TYPES, + literal: ['true', 'false'] }, contains: [ hljs.QUOTE_STRING_MODE, hljs.NUMBER_MODE, hljs.C_LINE_COMMENT_MODE, hljs.C_BLOCK_COMMENT_MODE, - { - className: 'class', - beginKeywords: 'message enum service', end: /\{/, - illegal: /\n/, - contains: [ - hljs.inherit(hljs.TITLE_MODE, { - starts: {endsWithParent: true, excludeEnd: true} // hack: eating everything after the first title - }) - ] - }, + CLASS_DEFINITION, { className: 'function', beginKeywords: 'rpc', diff --git a/test/markup/protobuf/message-message.expect.txt b/test/markup/protobuf/message-message.expect.txt index 0243879d38..fcf7712b80 100644 --- a/test/markup/protobuf/message-message.expect.txt +++ b/test/markup/protobuf/message-message.expect.txt @@ -1,10 +1,10 @@ // A Container message -message Container { - message Message { - required int64 id = 1; +message Container { + message Message { + required int64 id = 1; } repeated Message messages = 1; - optional int32 number = 2; + optional int32 number = 2; } /* diff --git a/test/markup/protobuf/rpc.expect.txt b/test/markup/protobuf/rpc.expect.txt index a09ce497c0..6fdb5e5c47 100644 --- a/test/markup/protobuf/rpc.expect.txt +++ b/test/markup/protobuf/rpc.expect.txt @@ -1,4 +1,4 @@ -service Greeter { +service Greeter { // Sends a greeting rpc SayHello (HelloRequest) returns (HelloReply) {} } From 710ab05cc4c73ca72b212cd92f2bd4c0fa8a529e Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Fri, 3 Dec 2021 13:59:04 -0500 Subject: [PATCH 56/76] (chore) title.class and cleanup RSL --- src/languages/rsl.js | 130 +++++++++++++++++++++++++---- test/markup/rsl/default.expect.txt | 6 +- 2 files changed, 118 insertions(+), 18 deletions(-) diff --git a/src/languages/rsl.js b/src/languages/rsl.js index d5de88eab1..01cae371ac 100644 --- a/src/languages/rsl.js +++ b/src/languages/rsl.js @@ -7,19 +7,123 @@ Category: graphics */ export default function(hljs) { + const BUILT_INS = [ + "abs", + "acos", + "ambient", + "area", + "asin", + "atan", + "atmosphere", + "attribute", + "calculatenormal", + "ceil", + "cellnoise", + "clamp", + "comp", + "concat", + "cos", + "degrees", + "depth", + "Deriv", + "diffuse", + "distance", + "Du", + "Dv", + "environment", + "exp", + "faceforward", + "filterstep", + "floor", + "format", + "fresnel", + "incident", + "length", + "lightsource", + "log", + "match", + "max", + "min", + "mod", + "noise", + "normalize", + "ntransform", + "opposite", + "option", + "phong", + "pnoise", + "pow", + "printf", + "ptlined", + "radians", + "random", + "reflect", + "refract", + "renderinfo", + "round", + "setcomp", + "setxcomp", + "setycomp", + "setzcomp", + "shadow", + "sign", + "sin", + "smoothstep", + "specular", + "specularbrdf", + "spline", + "sqrt", + "step", + "tan", + "texture", + "textureinfo", + "trace", + "transform", + "vtransform", + "xcomp", + "ycomp", + "zcomp" + ]; + + const TYPES = [ + "matrix", + "float", + "color", + "point", + "normal", + "vector" + ]; + + const KEYWORDS = [ + "while", + "for", + "if", + "do", + "return", + "else", + "break", + "extern", + "continue" + ]; + + const CLASS_DEFINITION = { + match: [ + /(surface|displacement|light|volume|imager)/, + /\s+/, + hljs.IDENT_RE, + ], + scope: { + 1: "keyword", + 3: "title.class", + } + }; + return { name: 'RenderMan RSL', keywords: { - keyword: - 'float color point normal vector matrix while for if do return else break extern continue', - built_in: - 'abs acos ambient area asin atan atmosphere attribute calculatenormal ceil cellnoise ' + - 'clamp comp concat cos degrees depth Deriv diffuse distance Du Dv environment exp ' + - 'faceforward filterstep floor format fresnel incident length lightsource log match ' + - 'max min mod noise normalize ntransform opposite option phong pnoise pow printf ' + - 'ptlined radians random reflect refract renderinfo round setcomp setxcomp setycomp ' + - 'setzcomp shadow sign sin smoothstep specular specularbrdf spline sqrt step tan ' + - 'texture textureinfo trace transform vtransform xcomp ycomp zcomp' + keyword: KEYWORDS, + built_in: BUILT_INS, + type: TYPES }, illegal: ' -surface plastic (float Ka = 1, Kd = 0.5, Ks = 0.5, roughness = 0.1; - color specularcolor = 1;) { - normal Nf = faceforward (normalize(N),I); +surface plastic (float Ka = 1, Kd = 0.5, Ks = 0.5, roughness = 0.1; + color specularcolor = 1;) { + normal Nf = faceforward (normalize(N),I); Ci = Cs * (Ka*ambient() + Kd*diffuse(Nf)) + specularcolor * Ks * specular(Nf,-normalize(I),roughness); Oi = Os; From 38a6701c6e5423082b7002ff9c37309f32ae963e Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Fri, 3 Dec 2021 14:07:02 -0500 Subject: [PATCH 57/76] (chore) improve oxgene - remove unnecessary `class` scope - add `;` as punctuation - remove deprecated `function` scope - use `title.function` for function names --- src/languages/oxygene.js | 25 +++++------- test/markup/oxygene/default.expect.txt | 56 +++++++++++++------------- 2 files changed, 37 insertions(+), 44 deletions(-) diff --git a/src/languages/oxygene.js b/src/languages/oxygene.js index 6eaef0d295..77c919e585 100644 --- a/src/languages/oxygene.js +++ b/src/languages/oxygene.js @@ -47,12 +47,11 @@ export default function(hljs) { begin: '(#\\d+)+' }; const FUNCTION = { - className: 'function', beginKeywords: 'function constructor destructor procedure method', end: '[:;]', keywords: 'function constructor|10 destructor|10 procedure|10 method|10', contains: [ - hljs.TITLE_MODE, + hljs.inherit(hljs.TITLE_MODE, {scope: "title.function" }), { className: 'params', begin: '\\(', @@ -67,6 +66,13 @@ export default function(hljs) { PAREN_COMMENT ] }; + + const SEMICOLON = { + scope: "punctuation", + match: /;/, + relevance: 0 + }; + return { name: 'Oxygene', case_insensitive: true, @@ -80,20 +86,7 @@ export default function(hljs) { CHAR_STRING, hljs.NUMBER_MODE, FUNCTION, - { - className: 'class', - begin: '=\\bclass\\b', - end: 'end;', - keywords: OXYGENE_KEYWORDS, - contains: [ - STRING, - CHAR_STRING, - CURLY_COMMENT, - PAREN_COMMENT, - hljs.C_LINE_COMMENT_MODE, - FUNCTION - ] - } + SEMICOLON ] }; } diff --git a/test/markup/oxygene/default.expect.txt b/test/markup/oxygene/default.expect.txt index ed31804143..187d068e41 100644 --- a/test/markup/oxygene/default.expect.txt +++ b/test/markup/oxygene/default.expect.txt @@ -1,56 +1,56 @@ -namespace LinkedList; +namespace LinkedList; interface uses - System.Text; + System.Text; type List<T> = public class - where T is Object; + where T is Object; private - method AppendToString(aBuilder: StringBuilder); + method AppendToString(aBuilder: StringBuilder); public - constructor(aData: T); - constructor(aData: T; aNext: List<T>); - property Next: List<T>; - property Data: T; + constructor(aData: T); + constructor(aData: T; aNext: List<T>); + property Next: List<T>; + property Data: T; - method ToString: string; override; - end; + method ToString: string; override; + end; implementation -constructor List<T>(aData: T); +constructor List<T>(aData: T); begin - Data := aData; -end; + Data := aData; +end; -constructor List<T>(aData: T; aNext: List<T>); +constructor List<T>(aData: T; aNext: List<T>); begin - constructor(aData); - Next := aNext; -end; + constructor(aData); + Next := aNext; +end; -method List<T>.ToString: string; +method List<T>.ToString: string; begin with lBuilder := new StringBuilder do begin - AppendToString(lBuilder); - result := lBuilder.ToString(); - end; -end; + AppendToString(lBuilder); + result := lBuilder.ToString(); + end; +end; -method List<T>.AppendToString(aBuilder: StringBuilder); +method List<T>.AppendToString(aBuilder: StringBuilder); begin if assigned(Data) then aBuilder.Append(Data.ToString) else - aBuilder.Append('nil'); + aBuilder.Append('nil'); if assigned(Next) then begin - aBuilder.Append(', '); - Next.AppendToString(aBuilder); - end; -end; + aBuilder.Append(', '); + Next.AppendToString(aBuilder); + end; +end; end. From df3db6b82f1858eebf9b00290d0b18fd844506cd Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Fri, 3 Dec 2021 14:22:49 -0500 Subject: [PATCH 58/76] (chore) title.class for capnproto --- src/languages/capnproto.js | 50 ++++++++++---------- test/markup/capnproto/default.expect.txt | 58 ++++++++++++------------ 2 files changed, 53 insertions(+), 55 deletions(-) diff --git a/src/languages/capnproto.js b/src/languages/capnproto.js index 9986f7292a..5fa4ec5577 100644 --- a/src/languages/capnproto.js +++ b/src/languages/capnproto.js @@ -27,7 +27,7 @@ export default function(hljs) { "from", "fixed" ]; - const BUILT_INS = [ + const TYPES = [ "Void", "Bool", "Int8", @@ -51,12 +51,33 @@ export default function(hljs) { "true", "false" ]; + const CLASS_DEFINITION = { + variants: [ + { + match: [ + /(struct|enum|interface)/, /\s+/, + hljs.IDENT_RE + ] + }, + { + match: [ + /extends/, /\s*\(/, + hljs.IDENT_RE, + /\s*\)/ + ] + } + ], + scope: { + 1: "keyword", + 3: "title.class" + } + }; return { name: 'Cap’n Proto', aliases: ['capnp'], keywords: { keyword: KEYWORDS, - built_in: BUILT_INS, + type: TYPES, literal: LITERALS }, contains: [ @@ -72,30 +93,7 @@ export default function(hljs) { className: 'symbol', begin: /@\d+\b/ }, - { - className: 'class', - beginKeywords: 'struct enum', - end: /\{/, - illegal: /\n/, - contains: [hljs.inherit(hljs.TITLE_MODE, { - starts: { - endsWithParent: true, - excludeEnd: true - } // hack: eating everything after the first title - })] - }, - { - className: 'class', - beginKeywords: 'interface', - end: /\{/, - illegal: /\n/, - contains: [hljs.inherit(hljs.TITLE_MODE, { - starts: { - endsWithParent: true, - excludeEnd: true - } // hack: eating everything after the first title - })] - } + CLASS_DEFINITION ] }; } diff --git a/test/markup/capnproto/default.expect.txt b/test/markup/capnproto/default.expect.txt index b516975696..a62a9928aa 100644 --- a/test/markup/capnproto/default.expect.txt +++ b/test/markup/capnproto/default.expect.txt @@ -1,17 +1,17 @@ @0xdbb9ad1f14bf0b36; # unique file ID, generated by `capnp id` -struct Person { - name @0 :Text; +struct Person { + name @0 :Text; birthdate @3 :Date; - email @1 :Text; - phones @2 :List(PhoneNumber); + email @1 :Text; + phones @2 :List(PhoneNumber); - struct PhoneNumber { - number @0 :Text; + struct PhoneNumber { + number @0 :Text; type @1 :Type; - enum Type { + enum Type { mobile @0; home @1; work @2; @@ -19,37 +19,37 @@ } } -struct Date { - year @0 :Int16; - month @1 :UInt8; - day @2 :UInt8; - flags @3 :List(Bool) = [ true, false, false, true ]; +struct Date { + year @0 :Int16; + month @1 :UInt8; + day @2 :UInt8; + flags @3 :List(Bool) = [ true, false, false, true ]; } -interface Node { - isDirectory @0 () -> (result :Bool); +interface Node { + isDirectory @0 () -> (result :Bool); } -interface Directory extends(Node) { - list @0 () -> (list: List(Entry)); - struct Entry { - name @0 :Text; +interface Directory extends(Node) { + list @0 () -> (list: List(Entry)); + struct Entry { + name @0 :Text; node @1 :Node; } - create @1 (name :Text) -> (file :File); - mkdir @2 (name :Text) -> (directory :Directory) - open @3 (name :Text) -> (node :Node); - delete @4 (name :Text); - link @5 (name :Text, node :Node); + create @1 (name :Text) -> (file :File); + mkdir @2 (name :Text) -> (directory :Directory) + open @3 (name :Text) -> (node :Node); + delete @4 (name :Text); + link @5 (name :Text, node :Node); } -interface File extends(Node) { - size @0 () -> (size: UInt64); - read @1 (startAt :UInt64 = 0, amount :UInt64 = 0xffffffffffffffff) - -> (data: Data); +interface File extends(Node) { + size @0 () -> (size: UInt64); + read @1 (startAt :UInt64 = 0, amount :UInt64 = 0xffffffffffffffff) + -> (data: Data); # Default params = read entire file. - write @2 (startAt :UInt64, data :Data); - truncate @3 (size :UInt64); + write @2 (startAt :UInt64, data :Data); + truncate @3 (size :UInt64); } \ No newline at end of file From e609be9024184d88eefd3cd6a19f9366341f3ccd Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Fri, 3 Dec 2021 14:35:11 -0500 Subject: [PATCH 59/76] (chore) title.class and other groovy cleanups --- src/languages/groovy.js | 90 ++++++++++++++++++++------- test/markup/groovy/default.expect.txt | 14 ++--- 2 files changed, 76 insertions(+), 28 deletions(-) diff --git a/src/languages/groovy.js b/src/languages/groovy.js index 99aefed333..04e3d3f4ed 100644 --- a/src/languages/groovy.js +++ b/src/languages/groovy.js @@ -66,19 +66,78 @@ export default function(hljs) { } ); + const CLASS_DEFINITION = { + match: [ + /(class|interface|trait|enum|extends|implements)/, + /\s+/, + hljs.UNDERSCORE_IDENT_RE + ], + scope: { + 1: "keyword", + 3: "title.class", + } + }; + const TYPES = [ + "byte", + "short", + "char", + "int", + "long", + "boolean", + "float", + "double", + "void" + ]; + const KEYWORDS = [ + // groovy specific keywords + "def", + "as", + "in", + "assert", + "trait", + // common keywords with Java + "abstract", + "static", + "volatile", + "transient", + "public", + "private", + "protected", + "synchronized", + "final", + "class", + "interface", + "enum", + "if", + "else", + "for", + "while", + "switch", + "case", + "break", + "default", + "continue", + "throw", + "throws", + "try", + "catch", + "finally", + "implements", + "extends", + "new", + "import", + "package", + "return", + "instanceof" + ]; + return { name: 'Groovy', keywords: { - built_in: 'this super', + "variable.language": 'this super', literal: 'true false null', - keyword: - 'byte short char int long boolean float double void ' + - // groovy specific keywords - 'def as in assert trait ' + - // common keywords with Java - 'abstract static volatile transient public private protected synchronized final ' + - 'class interface enum if else for while switch case break default continue ' + - 'throw throws try catch finally implements extends new import package return instanceof' + type: TYPES, + keyword: KEYWORDS }, contains: [ hljs.SHEBANG({ @@ -89,18 +148,7 @@ export default function(hljs) { STRING, REGEXP, NUMBER, - { - className: 'class', - beginKeywords: 'class interface trait enum', - end: /\{/, - illegal: ':', - contains: [ - { - beginKeywords: 'extends implements' - }, - hljs.UNDERSCORE_TITLE_MODE - ] - }, + CLASS_DEFINITION, { className: 'meta', begin: '@[A-Za-z]+', diff --git a/test/markup/groovy/default.expect.txt b/test/markup/groovy/default.expect.txt index 5962db4897..acaa4cc323 100644 --- a/test/markup/groovy/default.expect.txt +++ b/test/markup/groovy/default.expect.txt @@ -4,15 +4,15 @@ import groovy.transform.CompileStatic import java.util.List as MyList -trait Distributable { - void distribute(String version) {} +trait Distributable { + void distribute(String version) {} } @CompileStatic -class Distribution implements Distributable { - double number = 1234.234 / 567 +class Distribution implements Distributable { + double number = 1234.234 / 567 def otherNumber = 3 / 4 - boolean archivable = condition ?: true + boolean archivable = condition ?: true def ternary = a ? b : c String name = "Guillaume" Closure description = null @@ -30,9 +30,9 @@ * description method * @param cl the closure */ - void description(Closure cl) { this.description = cl } + void description(Closure cl) { this.description = cl } - void version(String name, Closure versionSpec) { + void version(String name, Closure versionSpec) { def closure = { println "hi" } as Runnable MyList ml = [1, 2, [a: 1, b:2,c :3]] From 1758dcaf0e4ac8df63fbe0ec0289c5e458c676db Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Fri, 3 Dec 2021 15:09:20 -0500 Subject: [PATCH 60/76] (chore) title.class and other monkey cleanup --- src/languages/monkey.js | 168 +++++++++++++++++++++----- test/markup/monkey/default.expect.txt | 10 +- 2 files changed, 141 insertions(+), 37 deletions(-) diff --git a/src/languages/monkey.js b/src/languages/monkey.js index 915fa20c98..2d64a442af 100644 --- a/src/languages/monkey.js +++ b/src/languages/monkey.js @@ -16,20 +16,137 @@ export default function(hljs) { hljs.NUMBER_MODE ] }; + const FUNC_DEFINITION = { + variants: [ + { + match: [ + /(function|method)/, + /\s+/, + hljs.UNDERSCORE_IDENT_RE, + ] + }, + ], + scope: { + 1: "keyword", + 3: "title.function" + } + }; + const CLASS_DEFINITION = { + variants: [ + { + match: [ + /(class|interface|extends|implements)/, + /\s+/, + hljs.UNDERSCORE_IDENT_RE, + ] + }, + ], + scope: { + 1: "keyword", + 3: "title.class" + } + }; + const BUILT_INS = [ + "DebugLog", + "DebugStop", + "Error", + "Print", + "ACos", + "ACosr", + "ASin", + "ASinr", + "ATan", + "ATan2", + "ATan2r", + "ATanr", + "Abs", + "Abs", + "Ceil", + "Clamp", + "Clamp", + "Cos", + "Cosr", + "Exp", + "Floor", + "Log", + "Max", + "Max", + "Min", + "Min", + "Pow", + "Sgn", + "Sgn", + "Sin", + "Sinr", + "Sqrt", + "Tan", + "Tanr", + "Seed", + "PI", + "HALFPI", + "TWOPI" + ]; + const LITERALS = [ + "true", + "false", + "null" + ]; + const KEYWORDS = [ + "public", + "private", + "property", + "continue", + "exit", + "extern", + "new", + "try", + "catch", + "eachin", + "not", + "abstract", + "final", + "select", + "case", + "default", + "const", + "local", + "global", + "field", + "end", + "if", + "then", + "else", + "elseif", + "endif", + "while", + "wend", + "repeat", + "until", + "forever", + "for", + "to", + "step", + "next", + "return", + "module", + "inline", + "throw", + "import", + // not positive, but these are not literals + "and", + "or", + "shl", + "shr", + "mod" + ]; return { name: 'Monkey', case_insensitive: true, keywords: { - keyword: 'public private property continue exit extern new try catch ' + - 'eachin not abstract final select case default const local global field ' + - 'end if then else elseif endif while wend repeat until forever for ' + - 'to step next return module inline throw import', - - built_in: 'DebugLog DebugStop Error Print ACos ACosr ASin ASinr ATan ATan2 ATan2r ATanr Abs Abs Ceil ' + - 'Clamp Clamp Cos Cosr Exp Floor Log Max Max Min Min Pow Sgn Sgn Sin Sinr Sqrt Tan Tanr Seed PI HALFPI TWOPI', - - literal: 'true false null and or shl shr mod' + keyword: KEYWORDS, + built_in: BUILT_INS, + literal: LITERALS }, illegal: /\/\*/, contains: [ @@ -41,39 +158,26 @@ export default function(hljs) { relevance: 0 } ), + FUNC_DEFINITION, + CLASS_DEFINITION, { - className: 'function', - beginKeywords: 'function method', - end: '[(=:]|$', - illegal: /\n/, - contains: [ hljs.UNDERSCORE_TITLE_MODE ] - }, - { - className: 'class', - beginKeywords: 'class interface', - end: '$', - contains: [ - { - beginKeywords: 'extends implements' - }, - hljs.UNDERSCORE_TITLE_MODE - ] - }, - { - className: 'built_in', - begin: '\\b(self|super)\\b' + className: 'variable.language', + begin: /\b(self|super)\b/ }, { className: 'meta', - begin: '\\s*#', + begin: /\s*#/, end: '$', keywords: { keyword: 'if else elseif endif end then' } }, { - className: 'meta', - begin: '^\\s*strict\\b' + match: [ + /^\s*/, + /strict\b/ + ], + scope: { 2: "meta" } }, { beginKeywords: 'alias', diff --git a/test/markup/monkey/default.expect.txt b/test/markup/monkey/default.expect.txt index 8dfd03e961..5228c24cc4 100644 --- a/test/markup/monkey/default.expect.txt +++ b/test/markup/monkey/default.expect.txt @@ -6,18 +6,18 @@ Import mojo ' The main class which expends Mojo's 'App' class: -Class GameApp Extends App +Class GameApp Extends App Field player:Player - Method OnCreate:Int() + Method OnCreate:Int() Local img:Image = LoadImage("player.png") - Self.player = New Player() + Self.player = New Player() SetUpdateRate(60) Return 0 End - Method OnUpdate:Int() + Method OnUpdate:Int() player.x += HALFPI If (player.x > 100) Then @@ -27,7 +27,7 @@ Return 0 End - Method OnRender:Int() + Method OnRender:Int() Cls(32, 64, 128) player.Draw() From 61146b169caca6f8fb4eb70bee90e3c99946874b Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Tue, 7 Dec 2021 13:48:06 -0500 Subject: [PATCH 61/76] (chore) fix checkautodetect, fix elixir autodetect conflict --- src/languages/elixir.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/languages/elixir.js b/src/languages/elixir.js index c43101ad5e..c9b08a9570 100644 --- a/src/languages/elixir.js +++ b/src/languages/elixir.js @@ -262,10 +262,8 @@ export default function(hljs) { { className: 'variable', begin: '(\\$\\W)|((\\$|@@?)(\\w+))' - }, - { - begin: '->' } + // -> has been removed, capnproto always uses this grammar construct ]; SUBST.contains = ELIXIR_DEFAULT_CONTAINS; From 06c57ce3eb0faed01ea4af8f622b7f849e339236 Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Tue, 7 Dec 2021 13:53:58 -0500 Subject: [PATCH 62/76] enh(x++) title.class.inherited for X++ --- src/languages/axapta.js | 39 ++++++++++++++++++--------- test/markup/axapta/default.expect.txt | 2 +- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/src/languages/axapta.js b/src/languages/axapta.js index f5768bddd9..90edecc6f6 100644 --- a/src/languages/axapta.js +++ b/src/languages/axapta.js @@ -8,6 +8,7 @@ Category: enterprise /** @type LanguageFn */ export default function(hljs) { + const IDENT_RE = hljs.UNDERSCORE_IDENT_RE; const BUILT_IN_KEYWORDS = [ 'anytype', 'boolean', @@ -144,6 +145,30 @@ export default function(hljs) { literal: LITERAL_KEYWORDS }; + const CLASS_DEFINITION = { + variants: [ + { + match: [ + /(class|interface)\s+/, + IDENT_RE, + /\s+(extends|implements)\s+/, + IDENT_RE + ] + }, + { + match: [ + /class\s+/, + IDENT_RE + ] + } + ], + scope: { + 2: "title.class", + 4: "title.class.inherited" + }, + keywords: KEYWORDS + }; + return { name: 'X++', aliases: ['x++'], @@ -159,19 +184,7 @@ export default function(hljs) { begin: '#', end: '$' }, - { - className: 'class', - beginKeywords: 'class interface', - end: /\{/, - excludeEnd: true, - illegal: ':', - contains: [ - { - beginKeywords: 'extends implements' - }, - hljs.UNDERSCORE_TITLE_MODE - ] - } + CLASS_DEFINITION ] }; } diff --git a/test/markup/axapta/default.expect.txt b/test/markup/axapta/default.expect.txt index dc645bb496..4ce35197d3 100644 --- a/test/markup/axapta/default.expect.txt +++ b/test/markup/axapta/default.expect.txt @@ -1,4 +1,4 @@ -class ExchRateLoadBatch extends RunBaseBatch { +class ExchRateLoadBatch extends RunBaseBatch { ExchRateLoad rbc; container currencies; boolean actual; From 4284811b743c4515598b41c61f301304125e2d72 Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Tue, 7 Dec 2021 14:21:58 -0500 Subject: [PATCH 63/76] enh(cal) simplify using multi-matchers --- src/languages/cal.js | 97 ++++++++++++++++++++++++------ test/detect/cal/default.txt | 9 ++- test/markup/cal/default.expect.txt | 18 +++--- 3 files changed, 96 insertions(+), 28 deletions(-) diff --git a/src/languages/cal.js b/src/languages/cal.js index 94cee44a0c..bcbbecc822 100644 --- a/src/languages/cal.js +++ b/src/languages/cal.js @@ -7,9 +7,35 @@ Website: https://docs.microsoft.com/en-us/dynamics-nav/programming-in-c-al /** @type LanguageFn */ export default function(hljs) { - const KEYWORDS = - 'div mod in and or not xor asserterror begin case do downto else end exit for if of repeat then to ' + - 'until while with var'; + const regex = hljs.regex; + const KEYWORDS = [ + "div", + "mod", + "in", + "and", + "or", + "not", + "xor", + "asserterror", + "begin", + "case", + "do", + "downto", + "else", + "end", + "exit", + "for", + "local", + "if", + "of", + "repeat", + "then", + "to", + "until", + "while", + "with", + "var" + ]; const LITERALS = 'false true'; const COMMENT_MODES = [ hljs.C_LINE_COMMENT_MODE, @@ -52,12 +78,17 @@ export default function(hljs) { }; const PROCEDURE = { - className: 'function', - beginKeywords: 'procedure', - end: /[:;]/, - keywords: 'procedure|10', + match: [ + /procedure/, + /\s+/, + /[a-zA-Z_][\w@]*/, + /\s*/ + ], + scope: { + 1: "keyword", + 3: "title.function" + }, contains: [ - hljs.TITLE_MODE, { className: 'params', begin: /\(/, @@ -65,20 +96,49 @@ export default function(hljs) { keywords: KEYWORDS, contains: [ STRING, - CHAR_STRING + CHAR_STRING, + hljs.NUMBER_MODE ] - } - ].concat(COMMENT_MODES) + }, + ...COMMENT_MODES + ] }; + const OBJECT_TYPES = [ + "Table", + "Form", + "Report", + "Dataport", + "Codeunit", + "XMLport", + "MenuSuite", + "Page", + "Query" + ]; const OBJECT = { - className: 'class', - begin: 'OBJECT (Table|Form|Report|Dataport|Codeunit|XMLport|MenuSuite|Page|Query) (\\d+) ([^\\r\\n]+)', - returnBegin: true, - contains: [ - hljs.TITLE_MODE, - PROCEDURE - ] + match: [ + /OBJECT/, + /\s+/, + regex.either(...OBJECT_TYPES), + /\s+/, + /\d+/, + /\s+(?=[^\s])/, + /.*/, + /$/ + ], + relevance: 3, + scope: { + 1: "keyword", + 3: "type", + 5: "number", + 7: "title" + } + }; + + const PROPERTY = { + match: /[\w]+(?=\=)/, + scope: "attribute", + relevance: 0 }; return { @@ -90,6 +150,7 @@ export default function(hljs) { }, illegal: /\/\*/, contains: [ + PROPERTY, STRING, CHAR_STRING, DATE, diff --git a/test/detect/cal/default.txt b/test/detect/cal/default.txt index 5eec86caf0..eb65b97364 100644 --- a/test/detect/cal/default.txt +++ b/test/detect/cal/default.txt @@ -1,4 +1,11 @@ -OBJECT Codeunit 11 Gen. Jnl.-Check Line +OBJECT Table 12 something +{ +} +OBJECT XMLport 3000 something.other +{ +} + +OBJECT Codeunit 11 Gen. Jnl.-Chck Line { OBJECT-PROPERTIES { diff --git a/test/markup/cal/default.expect.txt b/test/markup/cal/default.expect.txt index 20f52bece3..6041808c0a 100644 --- a/test/markup/cal/default.expect.txt +++ b/test/markup/cal/default.expect.txt @@ -1,16 +1,16 @@ -OBJECT Codeunit 11 Gen. Jnl.-Check Line +OBJECT Codeunit 11 Gen. Jnl.-Check Line { OBJECT-PROPERTIES { - Date=09-09-14; - Time=12:00:00; - Version List=NAVW18.00; + Date=09-09-14; + Time=12:00:00; + Version List=NAVW18.00; } PROPERTIES { - TableNo=81; - Permissions=TableData 252=rimd; - OnRun=BEGIN + TableNo=81; + Permissions=TableData 252=rimd; + OnRun=BEGIN GLSetup.GET; RunCheck(Rec); END; @@ -22,12 +22,12 @@ Text000@1000 : TextConst 'ENU=can only be a closing date for G/L entries'; Text001@1001 : TextConst 'ENU=is not within your range of allowed posting dates'; - PROCEDURE ErrorIfPositiveAmt@2(GenJnlLine@1000 : Record 81); + PROCEDURE ErrorIfPositiveAmt@2(GenJnlLine@1000 : Record 81); BEGIN IF GenJnlLine.Amount > 0 THEN GenJnlLine.FIELDERROR(Amount,Text008); END; - LOCAL PROCEDURE CheckGenJnlLineDocType@7(GenJnlLine@1001 : Record 81); + LOCAL PROCEDURE CheckGenJnlLineDocType@7(GenJnlLine@1001 : Record 81); } } From bc5a10f1cae3aa725251b2fc5c88bb1492b6fe4a Mon Sep 17 00:00:00 2001 From: Wojciech Kania Date: Thu, 16 Dec 2021 21:32:28 +0100 Subject: [PATCH 64/76] enh(php) add PHP 8.1 keywords --- CHANGES.md | 1 + src/languages/php.js | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 05034fcaea..a463fbb50c 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -13,6 +13,7 @@ These changes should be for the better and should not be super noticeable but if Grammars: +- enh(php) add PHP 8.1 keywords [Wojciech Kania][] - enh(php) support First-class Callable Syntax (#3427) [Wojciech Kania][] - enh(php) support class constructor call (#3427) [Wojciech Kania][] - enh(php) support function invoke (#3427) [Wojciech Kania][] diff --git a/src/languages/php.js b/src/languages/php.js index 371ef2ae78..387abd8adc 100644 --- a/src/languages/php.js +++ b/src/languages/php.js @@ -151,11 +151,13 @@ export default function(hljs) { "match|0", "mixed", "new", + "never", "object", "or", "private", "protected", "public", + "readonly", "real", "return", "string", @@ -245,7 +247,9 @@ export default function(hljs) { // Reserved interfaces: // "ArrayAccess", + "BackedEnum", "Closure", + "Fiber", "Generator", "Iterator", "IteratorAggregate", @@ -253,6 +257,7 @@ export default function(hljs) { "Stringable", "Throwable", "Traversable", + "UnitEnum", "WeakReference", "WeakMap", // Reserved classes: From 093b67f829dc52b387527705ecf3c8990c437e14 Mon Sep 17 00:00:00 2001 From: Wojciech Kania Date: Thu, 16 Dec 2021 21:45:59 +0100 Subject: [PATCH 65/76] (chore) Replace className with scope and use match --- src/languages/php.js | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/languages/php.js b/src/languages/php.js index 387abd8adc..728e744720 100644 --- a/src/languages/php.js +++ b/src/languages/php.js @@ -13,14 +13,14 @@ Category: common export default function(hljs) { const regex = hljs.regex; const VARIABLE = { - className: 'variable', - begin: '\\$+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*' + + scope: 'variable', + match: '\\$+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*' + // negative look-ahead tries to avoid matching patterns that are not // Perl at all like $ident$, @ident@, etc. `(?![A-Za-z0-9])(?![$])` }; const PREPROCESSOR = { - className: 'meta', + scope: 'meta', variants: [ { begin: /<\?php/, relevance: 10 }, // boost for obvious PHP { begin: /<\?[=]?/ }, @@ -28,7 +28,7 @@ export default function(hljs) { ] }; const SUBST = { - className: 'subst', + scope: 'subst', variants: [ { begin: /\$\w+/ }, { begin: /\{\$/, end: /\}/ } @@ -49,7 +49,7 @@ export default function(hljs) { // list of valid whitespaces because non-breaking space might be part of a name const WHITESPACE = '[ \t\n]'; const STRING = { - className: 'string', + scope: 'string', variants: [ DOUBLE_QUOTED, SINGLE_QUOTED, @@ -57,7 +57,7 @@ export default function(hljs) { ] }; const NUMBER = { - className: 'number', + scope: 'number', variants: [ { begin: `\\b0[bB][01]+(?:_[01]+)*\\b` }, // Binary w/ underscore support { begin: `\\b0[oO][0-7]+(?:_[0-7]+)*\\b` }, // Octals w/ underscore support @@ -374,8 +374,8 @@ export default function(hljs) { }, PREPROCESSOR, { - className: 'variable.language', - begin: /\$this\b/ + scope: 'variable.language', + match: /\$this\b/ }, VARIABLE, FUNCTION_INVOKE, @@ -390,7 +390,7 @@ export default function(hljs) { }, CONSTRUCTOR_CALL, { - className: 'function', + scope: 'function', relevance: 0, beginKeywords: 'fn function', end: /[;{]/, excludeEnd: true, illegal: '[$%\\[]', @@ -404,7 +404,7 @@ export default function(hljs) { endsParent: true }, { - className: 'params', + scope: 'params', begin: '\\(', end: '\\)', excludeBegin: true, excludeEnd: true, @@ -420,7 +420,7 @@ export default function(hljs) { ] }, { - className: 'class', + scope: 'class', variants: [ { beginKeywords: "enum", illegal: /[($"]/ }, { beginKeywords: "class interface trait", illegal: /[:($"]/ } From 413425d4c74a272ac841e2870336ccce098fd64e Mon Sep 17 00:00:00 2001 From: Angelo Verlain <37999241+vixalien@users.noreply.github.com> Date: Sat, 18 Dec 2021 15:23:11 +0200 Subject: [PATCH 66/76] (chore) Fix typo in README on "good first issue" badge (#3431) When you clicked the badge it took you to "beginner friendly" instead of "good first issue" --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 05d926f528..e1fcf0656f 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ [![discord](https://badgen.net/badge/icon/discord?icon=discord&label&color=pink)](https://discord.gg/M24EbU7ja9) [![open issues](https://badgen.net/github/open-issues/highlightjs/highlight.js?label=issues)](https://github.com/highlightjs/highlight.js/issues) [![help welcome issues](https://badgen.net/github/label-issues/highlightjs/highlight.js/help%20welcome/open)](https://github.com/highlightjs/highlight.js/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+welcome%22) -[![good first issue](https://badgen.net/github/label-issues/highlightjs/highlight.js/good%20first%20issue/open)](https://github.com/highlightjs/highlight.js/issues?q=is%3Aopen+is%3Aissue+label%3A%22beginner+friendly%22) +[![good first issue](https://badgen.net/github/label-issues/highlightjs/highlight.js/good%20first%20issue/open)](https://github.com/highlightjs/highlight.js/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) From c5ff49e7cf2b975a0f63500a6f647b0ff57f74ab Mon Sep 17 00:00:00 2001 From: Fons van der Plas Date: Wed, 22 Dec 2021 14:32:27 +0100 Subject: [PATCH 67/76] fix(julia-repl) `aliases` was not in correct object (#3432) --- CHANGES.md | 2 ++ src/languages/julia-repl.js | 16 ++++++++-------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index a463fbb50c..ade99dd748 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -42,6 +42,7 @@ Grammars: - enh(clojure) Add `regex` mode to regex literal - fix(clojure) Remove inconsistent/broken highlighting for metadata - enh(clojure) Add `punctuation` mode for commas. +- fix(julia) Enable the `jldoctest` alias (#3432) [Fons van der Plas][] Developer Tools: @@ -61,6 +62,7 @@ Themes: [Samia Ali]: https://github.com/samiaab1990 [Matthieu Lempereur]: https://github.com/MrYamous [idleberg]: https://github.com/idleberg +[Fons van der Plas]: https://github.com/fonsp ## Version 11.3.1 diff --git a/src/languages/julia-repl.js b/src/languages/julia-repl.js index 6772b86641..8094c4fa9f 100644 --- a/src/languages/julia-repl.js +++ b/src/languages/julia-repl.js @@ -35,14 +35,14 @@ export default function(hljs) { // least six spaces in the beginning end: /^(?![ ]{6})/, subLanguage: 'julia' + }, }, - // jldoctest Markdown blocks are used in the Julia manual and package docs indicate - // code snippets that should be verified when the documentation is built. They can be - // either REPL-like or script-like, but are usually REPL-like and therefore we apply - // julia-repl highlighting to them. More information can be found in Documenter's - // manual: https://juliadocs.github.io/Documenter.jl/latest/man/doctests.html - aliases: ['jldoctest'] - } - ] + ], + // jldoctest Markdown blocks are used in the Julia manual and package docs indicate + // code snippets that should be verified when the documentation is built. They can be + // either REPL-like or script-like, but are usually REPL-like and therefore we apply + // julia-repl highlighting to them. More information can be found in Documenter's + // manual: https://juliadocs.github.io/Documenter.jl/latest/man/doctests.html + aliases: ['jldoctest'], } } From c0138d99b476933eb105e9c7eff4b2cd006d70bb Mon Sep 17 00:00:00 2001 From: Pegasis Date: Mon, 27 Dec 2021 09:16:40 -0500 Subject: [PATCH 68/76] (themes) Add new `intellij-light` theme (#3433) --- CHANGES.md | 2 + src/styles/intellij-light.css | 119 ++++++++++++++++++++++++++++++++++ tools/developer.html | 1 + 3 files changed, 122 insertions(+) create mode 100644 src/styles/intellij-light.css diff --git a/CHANGES.md b/CHANGES.md index ade99dd748..b5c98322d9 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,6 +8,7 @@ Themes: - `Default` is now much closer WCAG AA (contrast) (#3402) [Josh Goebel] - `Dark` now meets WCAG AA (contrast) (#3402) [Josh Goebel] +- Added `intellij-light` theme [Pegasis] These changes should be for the better and should not be super noticeable but if you're super picky about your colors you may want to intervene here or copy over the older themes from 11.3 or prior. @@ -52,6 +53,7 @@ Themes: - Modified background color in css for Gradient Light and Gradient Dark themes [Samia Ali][] +[Pegasis]: https://github.com/PegasisForever [Wojciech Kania]: https://github.com/wkania [Jeylani B]: https://github.com/jeyllani [Richard Gibson]: https://github.com/gibson042 diff --git a/src/styles/intellij-light.css b/src/styles/intellij-light.css new file mode 100644 index 0000000000..4ab3f230bb --- /dev/null +++ b/src/styles/intellij-light.css @@ -0,0 +1,119 @@ +/* + +Intellij-light style (c) Pegasis + +*/ + +.hljs { + color: #000; + background: #fff; +} + +.hljs-subst, +.hljs-title { + font-weight: normal; + color: #000; +} + +.hljs-title.function_ { + color: #7A7A43; +} + +.hljs-code, +.hljs-comment, +.hljs-quote { + color: #8C8C8C; + font-style: italic; +} + +.hljs-meta { + color: #9E880D; +} + +.hljs-section { + color: #871094; +} + +.hljs-variable.language_, +.hljs-symbol, +.hljs-selector-class, +.hljs-selector-id, +.hljs-selector-tag, +.hljs-template-tag, +.hljs-selector-attr, +.hljs-selector-pseudo, +.hljs-keyword, +.hljs-meta .hljs-keyword, +.hljs-literal, +.hljs-name, +.hljs-built_in, +.hljs-type { + color: #0033B3; +} + +.hljs-property, +.hljs-attr { + color: #871094; +} + +.hljs-attribute { + color: #174AD4; +} + +.hljs-number { + color: #1750EB; +} + +.hljs-regexp { + color: #264EFF; +} + +.hljs-link { + text-decoration: underline; + color: #006DCC; +} + +.hljs-meta .hljs-string, +.hljs-string { + color: #067D17; +} + +.hljs-char.escape_ { + color: #0037A6; +} + +.hljs-doctag { + text-decoration: underline; +} + +.hljs-template-variable { + color: #248F8F; +} + +.hljs-addition { + background: #BEE6BE; +} + +.hljs-deletion { + background: #D6D6D6; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} + +.hljs-variable, +.hljs-operator, +.hljs-punctuation, +.hljs-title.class_.inherited__, +.hljs-title.class_, +.hljs-params, +.hljs-bullet, +.hljs-formula, +.hljs-tag { + /* purposely ignored */ +} diff --git a/tools/developer.html b/tools/developer.html index 0690702bfa..5707b0600b 100644 --- a/tools/developer.html +++ b/tools/developer.html @@ -107,6 +107,7 @@

Code

+ From 7355c13512374e14b93f7124f67e71d300924f4c Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Wed, 29 Dec 2021 07:01:45 -0500 Subject: [PATCH 69/76] fix(cpp) `vector<<` false positive as template begin (#3438) --- CHANGES.md | 1 + src/languages/cpp.js | 2 +- test/markup/cpp/bugs.expect.txt | 6 ++++++ test/markup/cpp/bugs.txt | 6 ++++++ 4 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 test/markup/cpp/bugs.expect.txt create mode 100644 test/markup/cpp/bugs.txt diff --git a/CHANGES.md b/CHANGES.md index b5c98322d9..071402f28d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -15,6 +15,7 @@ These changes should be for the better and should not be super noticeable but if Grammars: - enh(php) add PHP 8.1 keywords [Wojciech Kania][] +- fix(cpp) fix `vector<<` template false positive (#3437) [Josh Goebel][] - enh(php) support First-class Callable Syntax (#3427) [Wojciech Kania][] - enh(php) support class constructor call (#3427) [Wojciech Kania][] - enh(php) support function invoke (#3427) [Wojciech Kania][] diff --git a/src/languages/cpp.js b/src/languages/cpp.js index e2cf5a9d28..54e3bced7d 100644 --- a/src/languages/cpp.js +++ b/src/languages/cpp.js @@ -558,7 +558,7 @@ export default function(hljs) { [ PREPROCESSOR, { // containers: ie, `vector rooms (9);` - begin: '\\b(deque|list|queue|priority_queue|pair|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array|tuple|optional|variant|function)\\s*<', + begin: '\\b(deque|list|queue|priority_queue|pair|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array|tuple|optional|variant|function)\\s*<(?!<)', end: '>', keywords: CPP_KEYWORDS, contains: [ diff --git a/test/markup/cpp/bugs.expect.txt b/test/markup/cpp/bugs.expect.txt new file mode 100644 index 0000000000..08e8689dfc --- /dev/null +++ b/test/markup/cpp/bugs.expect.txt @@ -0,0 +1,6 @@ +//4. 对角矩阵 +//4.1 构造对角矩阵 +Eigen::VectorXd vector(5); //构建5维向量 +vector<<1,2,3,4,5; //向量赋值 +Eigen::MatrixXd C(vector.asDiagonal()); //使用向量生成对角阵 +std::cout << "\nC= \n" << C << std::endl; diff --git a/test/markup/cpp/bugs.txt b/test/markup/cpp/bugs.txt new file mode 100644 index 0000000000..00c4281821 --- /dev/null +++ b/test/markup/cpp/bugs.txt @@ -0,0 +1,6 @@ +//4. 对角矩阵 +//4.1 构造对角矩阵 +Eigen::VectorXd vector(5); //构建5维向量 +vector<<1,2,3,4,5; //向量赋值 +Eigen::MatrixXd C(vector.asDiagonal()); //使用向量生成对角阵 +std::cout << "\nC= \n" << C << std::endl; From 360f5c42c2d26ac51f90fb56d351a745e3cb1e66 Mon Sep 17 00:00:00 2001 From: John Foster Date: Thu, 30 Dec 2021 14:35:33 -0800 Subject: [PATCH 70/76] Add curl to supported languages (#3445) --- CHANGES.md | 1 + SUPPORTED_LANGUAGES.md | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 071402f28d..4fe1fdbdbf 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,6 +3,7 @@ New Language: - Added 3rd party Pine Script grammar to SUPPORTED_LANGUAGES [Jeylani B][] +- Added 3rd party cURL grammar to SUPPORTED_LANGUAGES [highlightjs-curl][https://github.com/highlightjs/highlightjs-curl] Themes: diff --git a/SUPPORTED_LANGUAGES.md b/SUPPORTED_LANGUAGES.md index ed4382692a..c73a294af5 100644 --- a/SUPPORTED_LANGUAGES.md +++ b/SUPPORTED_LANGUAGES.md @@ -52,6 +52,7 @@ The table below shows the full list of languages (and corresponding classes/alia | CpcdosC+ | cpc | [highlightjs-cpcdos](https://github.com/SPinti-Software/highlightjs-cpcdos) | | Crmsh | crmsh, crm, pcmk | | | Crystal | crystal, cr | | +| cURL | curl | [highlightjs-curl](https://github.com/highlightjs/highlightjs-curl) | | Cypher (Neo4j) | cypher | [highlightjs-cypher](https://github.com/highlightjs/highlightjs-cypher) | | D | d | | | Dafny | dafny | [highlightjs-dafny](https://github.com/ConsenSys/highlightjs-dafny)| From 2e344f51c305dabc06005f1a17c439e934600727 Mon Sep 17 00:00:00 2001 From: John Foster Date: Thu, 30 Dec 2021 15:12:41 -0800 Subject: [PATCH 71/76] Update CHANGES.md (#3447) --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 4fe1fdbdbf..0e6f4b1bdf 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,7 +3,7 @@ New Language: - Added 3rd party Pine Script grammar to SUPPORTED_LANGUAGES [Jeylani B][] -- Added 3rd party cURL grammar to SUPPORTED_LANGUAGES [highlightjs-curl][https://github.com/highlightjs/highlightjs-curl] +- Added 3rd party cURL grammar to SUPPORTED_LANGUAGES [highlightjs-curl](https://github.com/highlightjs/highlightjs-curl) Themes: From 0e3735ac62a35b7296b7e92bc39f73d587c738f5 Mon Sep 17 00:00:00 2001 From: Felipe Contreras Date: Sat, 1 Jan 2022 17:17:26 -0600 Subject: [PATCH 72/76] tools: check-theme: consider background-color too (#3449) * tools: check-theme: consider `background-color` too This is the precise property we want to check. --- tools/checkTheme.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/checkTheme.js b/tools/checkTheme.js index bd2587e6d0..45ae7d9157 100755 --- a/tools/checkTheme.js +++ b/tools/checkTheme.js @@ -193,7 +193,10 @@ class CSSRule { constructor(rule, body) { this.rule = rule; if (rule.declarations) { - this.bg = rule.declarations.find(x => x.property =="background")?.value; + this.bg = rule.declarations.find(x => x.property == "background-color")?.value; + if (!this.bg) { + this.bg = rule.declarations.find(x => x.property == "background")?.value; + } this.fg = rule.declarations.find(x => x.property =="color")?.value; if (this.bg) { From e828d694b4dc8cc7f9c1aae8a2cab806178cb446 Mon Sep 17 00:00:00 2001 From: wkania Date: Tue, 4 Jan 2022 23:50:39 +0100 Subject: [PATCH 73/76] enh(php) Left and right-side of double colon (#3422) - declare and use `IDENT_RE` for valid labels instead of `w+` - declaration of PHP [constants](https://www.php.net/manual/en/language.oop5.constants.php) were not highlighted. Now they use the same class as variables. - enum and constant reference were not highlighted. Now they use the same class as variables. - Class name references are highlighted as `variable.language`. [class](https://wiki.php.net/rfc/class_name_literal_on_object) is a special case of the constant, it's also a reserved keyword. - left-side class name highlighting --- CHANGES.md | 2 + src/languages/php.js | 94 +++++++++++++++++++++++----- test/markup/php/functions.expect.txt | 2 +- test/markup/php/titles.expect.txt | 26 ++++++++ test/markup/php/titles.txt | 26 ++++++++ 5 files changed, 132 insertions(+), 18 deletions(-) create mode 100644 test/markup/php/titles.expect.txt create mode 100644 test/markup/php/titles.txt diff --git a/CHANGES.md b/CHANGES.md index 0e6f4b1bdf..92f6d7b2f5 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -15,6 +15,8 @@ These changes should be for the better and should not be super noticeable but if Grammars: +- enh(php) Left and right-side of double colon [Wojciech Kania][] +- enh(php) add PHP constants [Wojciech Kania][] - enh(php) add PHP 8.1 keywords [Wojciech Kania][] - fix(cpp) fix `vector<<` template false positive (#3437) [Josh Goebel][] - enh(php) support First-class Callable Syntax (#3427) [Wojciech Kania][] diff --git a/src/languages/php.js b/src/languages/php.js index 728e744720..7f0be203ae 100644 --- a/src/languages/php.js +++ b/src/languages/php.js @@ -12,12 +12,16 @@ Category: common * */ export default function(hljs) { const regex = hljs.regex; + const IDENT_RE_CORE = '[a-zA-Z0-9_\x7f-\xff]*' + + // negative look-ahead tries to avoid matching patterns that are not + // Perl at all like $ident$, @ident@, etc. + '(?![A-Za-z0-9])(?![$]))'; + const IDENT_RE = regex.concat("([a-zA-Z_\\x7f-\\xff]", IDENT_RE_CORE); + // Will not detect camelCase classes + const PASCAL_CASE_CLASS_NAME_RE = regex.concat("([A-Z]", IDENT_RE_CORE); const VARIABLE = { scope: 'variable', - match: '\\$+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*' + - // negative look-ahead tries to avoid matching patterns that are not - // Perl at all like $ident$, @ident@, etc. - `(?![A-Za-z0-9])(?![$])` + match: '\\$+' + IDENT_RE, }; const PREPROCESSOR = { scope: 'meta', @@ -46,7 +50,7 @@ export default function(hljs) { end: /[ \t]*(\w+)\b/, contains: hljs.QUOTE_STRING_MODE.contains.concat(SUBST), }); - // list of valid whitespaces because non-breaking space might be part of a name + // list of valid whitespaces because non-breaking space might be part of a IDENT_RE const WHITESPACE = '[ \t\n]'; const STRING = { scope: 'string', @@ -313,8 +317,8 @@ export default function(hljs) { regex.concat(WHITESPACE, "+"), // to prevent built ins from being confused as the class constructor call regex.concat("(?!", normalizeKeywords(BUILT_INS).join("\\b|"), "\\b)"), - /\\?\w+/, - regex.concat(WHITESPACE, "*\\("), + regex.concat(/\\?/, IDENT_RE), + regex.concat(WHITESPACE, "*", /\(/), ], scope: { 1: "keyword", @@ -330,7 +334,7 @@ export default function(hljs) { /\b/, // to prevent keywords from being confused as the function title regex.concat("(?!fn\\b|function\\b|", normalizeKeywords(KWS).join("\\b|"), "|", normalizeKeywords(BUILT_INS).join("\\b|"), "\\b)"), - /\w+/, + IDENT_RE, regex.concat(WHITESPACE, "*"), regex.lookahead(/(?=\()/) ], @@ -339,6 +343,57 @@ export default function(hljs) { } }; + const CONSTANT_REFERENCE = regex.concat(IDENT_RE, "\\b(?!\\()"); + + const LEFT_AND_RIGHT_SIDE_OF_DOUBLE_COLON = { + variants: [ + { + match: [ + regex.concat( + /::/, + regex.lookahead(/(?!class\b)/) + ), + CONSTANT_REFERENCE, + ], + scope: { + 2: "variable.constant", + }, + }, + { + match: [ + /::/, + /class/, + ], + scope: { + 2: "variable.language", + }, + }, + { + match: [ + PASCAL_CASE_CLASS_NAME_RE, + regex.concat( + "::", + regex.lookahead(/(?!class\b)/) + ), + ], + scope: { + 1: "title.class", + }, + }, + { + match: [ + PASCAL_CASE_CLASS_NAME_RE, + /::/, + /class/, + ], + scope: { + 1: "title.class", + 3: "variable.language", + }, + } + ] + }; + return { case_insensitive: false, keywords: KEYWORDS, @@ -351,8 +406,8 @@ export default function(hljs) { { contains: [ { - className: 'doctag', - begin: '@[A-Za-z]+' + scope: 'doctag', + match: '@[A-Za-z]+' } ] } @@ -379,14 +434,18 @@ export default function(hljs) { }, VARIABLE, FUNCTION_INVOKE, + LEFT_AND_RIGHT_SIDE_OF_DOUBLE_COLON, { - // swallow composed identifiers to avoid parsing them as keywords - match: regex.concat( - /(::|->)+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/, - regex.concat("(?!", WHITESPACE, "*\\()"), - /(?![a-zA-Z0-9_\x7f-\xff])/ - ), - // scope:"wrong" + match: [ + /const/, + /\s/, + IDENT_RE, + /\s*=/, + ], + scope: { + 1: "keyword", + 3: "variable.constant", + }, }, CONSTRUCTOR_CALL, { @@ -412,6 +471,7 @@ export default function(hljs) { contains: [ 'self', VARIABLE, + LEFT_AND_RIGHT_SIDE_OF_DOUBLE_COLON, hljs.C_BLOCK_COMMENT_MODE, STRING, NUMBER diff --git a/test/markup/php/functions.expect.txt b/test/markup/php/functions.expect.txt index f6bc43f49a..88c5d94ebe 100644 --- a/test/markup/php/functions.expect.txt +++ b/test/markup/php/functions.expect.txt @@ -13,7 +13,7 @@ $date = new DateTimeImmutable (); $date->format('Y-m-d'); -DateTimeImmutable::createFromMutable(new \DateTime('now')); +DateTimeImmutable::createFromMutable(new \DateTime('now')); str_contains (\strtoupper(substr('abcdef', -2), 'f')); diff --git a/test/markup/php/titles.expect.txt b/test/markup/php/titles.expect.txt new file mode 100644 index 0000000000..05763d78a2 --- /dev/null +++ b/test/markup/php/titles.expect.txt @@ -0,0 +1,26 @@ +final class Example extends Foo { + const FOO='foo'; + + public function __construct( + public readonly string $name = self::FOO + ) {} + + public function getClass(): string { + return DateTimeImmutable::class; + } + + public function getClassFromSelf(): string { + return self::class; + } + + public static function getClassFromStatic(): string { + return static::class; + } + + public static function getParentClass(): string { + return parent::class; + } +} + +$date = DateTimeImmutable::createFromMutable(new \DateTime()); +echo $date::class; diff --git a/test/markup/php/titles.txt b/test/markup/php/titles.txt new file mode 100644 index 0000000000..6ff19f2fc6 --- /dev/null +++ b/test/markup/php/titles.txt @@ -0,0 +1,26 @@ +final class Example extends Foo { + const FOO='foo'; + + public function __construct( + public readonly string $name = self::FOO + ) {} + + public function getClass(): string { + return DateTimeImmutable::class; + } + + public function getClassFromSelf(): string { + return self::class; + } + + public static function getClassFromStatic(): string { + return static::class; + } + + public static function getParentClass(): string { + return parent::class; + } +} + +$date = DateTimeImmutable::createFromMutable(new \DateTime()); +echo $date::class; From c88890c57ce8c286366172fe18c565baa5ddbfad Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Tue, 4 Jan 2022 18:54:36 -0500 Subject: [PATCH 74/76] chore(arcade) eslint --fix, explode keywords --- src/languages/arcade.js | 242 ++++++++++++++++++++++++++++++---------- 1 file changed, 185 insertions(+), 57 deletions(-) diff --git a/src/languages/arcade.js b/src/languages/arcade.js index 45abb1ea18..579d5b475a 100644 --- a/src/languages/arcade.js +++ b/src/languages/arcade.js @@ -10,22 +10,156 @@ export default function(hljs) { const IDENT_RE = '[A-Za-z_][0-9A-Za-z_]*'; const KEYWORDS = { - keyword: - 'if for while var new function do return void else break', - literal: - 'BackSlash DoubleQuote false ForwardSlash Infinity NaN NewLine null PI SingleQuote Tab TextFormatting true undefined', - built_in: - 'Abs Acos Angle Attachments Area AreaGeodetic Asin Atan Atan2 Average Bearing Boolean Buffer BufferGeodetic ' + - 'Ceil Centroid Clip Console Constrain Contains Cos Count Crosses Cut Date DateAdd ' + - 'DateDiff Day Decode DefaultValue Dictionary Difference Disjoint Distance DistanceGeodetic Distinct ' + - 'DomainCode DomainName Equals Exp Extent Feature FeatureSet FeatureSetByAssociation FeatureSetById FeatureSetByPortalItem ' + - 'FeatureSetByRelationshipName FeatureSetByTitle FeatureSetByUrl Filter First Floor Geometry GroupBy Guid HasKey Hour IIf IndexOf ' + - 'Intersection Intersects IsEmpty IsNan IsSelfIntersecting Length LengthGeodetic Log Max Mean Millisecond Min Minute Month ' + - 'MultiPartToSinglePart Multipoint NextSequenceValue Now Number OrderBy Overlaps Point Polygon ' + - 'Polyline Portal Pow Random Relate Reverse RingIsClockWise Round Second SetGeometry Sin Sort Sqrt Stdev Sum ' + - 'SymmetricDifference Tan Text Timestamp Today ToLocal Top Touches ToUTC TrackCurrentTime ' + - 'TrackGeometryWindow TrackIndex TrackStartTime TrackWindow TypeOf Union UrlEncode Variance ' + - 'Weekday When Within Year ' + keyword: [ + "if", + "for", + "while", + "var", + "new", + "function", + "do", + "return", + "void", + "else", + "break" + ], + literal: [ + "BackSlash", + "DoubleQuote", + "false", + "ForwardSlash", + "Infinity", + "NaN", + "NewLine", + "null", + "PI", + "SingleQuote", + "Tab", + "TextFormatting", + "true", + "undefined" + ], + built_in: [ + "Abs", + "Acos", + "Angle", + "Attachments", + "Area", + "AreaGeodetic", + "Asin", + "Atan", + "Atan2", + "Average", + "Bearing", + "Boolean", + "Buffer", + "BufferGeodetic", + "Ceil", + "Centroid", + "Clip", + "Console", + "Constrain", + "Contains", + "Cos", + "Count", + "Crosses", + "Cut", + "Date", + "DateAdd", + "DateDiff", + "Day", + "Decode", + "DefaultValue", + "Dictionary", + "Difference", + "Disjoint", + "Distance", + "DistanceGeodetic", + "Distinct", + "DomainCode", + "DomainName", + "Equals", + "Exp", + "Extent", + "Feature", + "FeatureSet", + "FeatureSetByAssociation", + "FeatureSetById", + "FeatureSetByPortalItem", + "FeatureSetByRelationshipName", + "FeatureSetByTitle", + "FeatureSetByUrl", + "Filter", + "First", + "Floor", + "Geometry", + "GroupBy", + "Guid", + "HasKey", + "Hour", + "IIf", + "IndexOf", + "Intersection", + "Intersects", + "IsEmpty", + "IsNan", + "IsSelfIntersecting", + "Length", + "LengthGeodetic", + "Log", + "Max", + "Mean", + "Millisecond", + "Min", + "Minute", + "Month", + "MultiPartToSinglePart", + "Multipoint", + "NextSequenceValue", + "Now", + "Number", + "OrderBy", + "Overlaps", + "Point", + "Polygon", + "Polyline", + "Portal", + "Pow", + "Random", + "Relate", + "Reverse", + "RingIsClockWise", + "Round", + "Second", + "SetGeometry", + "Sin", + "Sort", + "Sqrt", + "Stdev", + "Sum", + "SymmetricDifference", + "Tan", + "Text", + "Timestamp", + "Today", + "ToLocal", + "Top", + "Touches", + "ToUTC", + "TrackCurrentTime", + "TrackGeometryWindow", + "TrackIndex", + "TrackStartTime", + "TrackWindow", + "TypeOf", + "Union", + "UrlEncode", + "Variance", + "Weekday", + "When", + "Within", + "Year" + ] }; const SYMBOL = { className: 'symbol', @@ -34,15 +168,9 @@ export default function(hljs) { const NUMBER = { className: 'number', variants: [ - { - begin: '\\b(0[bB][01]+)' - }, - { - begin: '\\b(0[oO][0-7]+)' - }, - { - begin: hljs.C_NUMBER_RE - } + { begin: '\\b(0[bB][01]+)' }, + { begin: '\\b(0[oO][0-7]+)' }, + { begin: hljs.C_NUMBER_RE } ], relevance: 0 }; @@ -88,16 +216,20 @@ export default function(hljs) { { // object attr container begin: /[{,]\s*/, relevance: 0, - contains: [{ - begin: IDENT_RE + '\\s*:', - returnBegin: true, - relevance: 0, - contains: [{ - className: 'attr', - begin: IDENT_RE, - relevance: 0 - }] - }] + contains: [ + { + begin: IDENT_RE + '\\s*:', + returnBegin: true, + relevance: 0, + contains: [ + { + className: 'attr', + begin: IDENT_RE, + relevance: 0 + } + ] + } + ] }, { // "value" container begin: '(' + hljs.RE_STARTERS_RE + '|\\b(return)\\b)\\s*', @@ -111,25 +243,23 @@ export default function(hljs) { begin: '(\\(.*?\\)|' + IDENT_RE + ')\\s*=>', returnBegin: true, end: '\\s*=>', - contains: [{ - className: 'params', - variants: [ - { - begin: IDENT_RE - }, - { - begin: /\(\s*\)/ - }, - { - begin: /\(/, - end: /\)/, - excludeBegin: true, - excludeEnd: true, - keywords: KEYWORDS, - contains: PARAMS_CONTAINS - } - ] - }] + contains: [ + { + className: 'params', + variants: [ + { begin: IDENT_RE }, + { begin: /\(\s*\)/ }, + { + begin: /\(/, + end: /\)/, + excludeBegin: true, + excludeEnd: true, + keywords: KEYWORDS, + contains: PARAMS_CONTAINS + } + ] + } + ] } ], relevance: 0 @@ -154,9 +284,7 @@ export default function(hljs) { ], illegal: /\[|%/ }, - { - begin: /\$[(.]/ - } + { begin: /\$[(.]/ } ], illegal: /#(?!!)/ }; From 9598caafafbeab8db23dc5ba8cea9793fb7a25e8 Mon Sep 17 00:00:00 2001 From: John Foster Date: Tue, 4 Jan 2022 18:56:10 -0500 Subject: [PATCH 75/76] enh(arcade) Add missing keywords for Arcade v1.16 Signed-off-by: Josh Goebel --- CHANGES.md | 2 + src/languages/arcade.js | 78 +++++++++++++++++++++++++-- test/markup/arcade/profile.expect.txt | 2 +- 3 files changed, 76 insertions(+), 6 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 92f6d7b2f5..82d853a84e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -15,6 +15,7 @@ These changes should be for the better and should not be super noticeable but if Grammars: +- enh(arcade) updated to ArcGIS Arcade version 1.16 [John Foster][] - enh(php) Left and right-side of double colon [Wojciech Kania][] - enh(php) add PHP constants [Wojciech Kania][] - enh(php) add PHP 8.1 keywords [Wojciech Kania][] @@ -57,6 +58,7 @@ Themes: - Modified background color in css for Gradient Light and Gradient Dark themes [Samia Ali][] +[John Foster]: https://github.com/jf990 [Pegasis]: https://github.com/PegasisForever [Wojciech Kania]: https://github.com/wkania [Jeylani B]: https://github.com/jeyllani diff --git a/src/languages/arcade.js b/src/languages/arcade.js index 579d5b475a..6de745189d 100644 --- a/src/languages/arcade.js +++ b/src/languages/arcade.js @@ -42,14 +42,18 @@ export default function(hljs) { built_in: [ "Abs", "Acos", + "All", "Angle", - "Attachments", + "Any", "Area", "AreaGeodetic", + "Array", "Asin", "Atan", "Atan2", + "Attachments", "Average", + "Back", "Bearing", "Boolean", "Buffer", @@ -57,9 +61,11 @@ export default function(hljs) { "Ceil", "Centroid", "Clip", + "Concatenate", "Console", "Constrain", "Contains", + "ConvertDirection", "Cos", "Count", "Crosses", @@ -70,45 +76,71 @@ export default function(hljs) { "Day", "Decode", "DefaultValue", + "Densify", + "DensifyGeodetic", "Dictionary", "Difference", "Disjoint", "Distance", "DistanceGeodetic", "Distinct", + "Domain", "DomainCode", "DomainName", + "EnvelopeIntersects", "Equals", + "Erase", "Exp", + "Expects", "Extent", "Feature", "FeatureSet", "FeatureSetByAssociation", "FeatureSetById", + "FeatureSetByName", "FeatureSetByPortalItem", "FeatureSetByRelationshipName", - "FeatureSetByTitle", - "FeatureSetByUrl", "Filter", + "Find", "First", "Floor", + "FromCharCode", + "FromCodePoint", + "FromJSON", + "GdbVersion", + "Generalize", "Geometry", + "GetFeatureSet", + "GetUser", "GroupBy", "Guid", + "Hash", "HasKey", "Hour", "IIf", + "Includes", "IndexOf", + "Insert", "Intersection", "Intersects", "IsEmpty", "IsNan", + "ISOMonth", + "ISOWeek", + "ISOWeekday", + "ISOYear", "IsSelfIntersecting", + "IsSimple", + "Left|0", "Length", + "Length3D", "LengthGeodetic", "Log", + "Lower", + "Map", "Max", "Mean", + "Mid", "Millisecond", "Min", "Minute", @@ -116,45 +148,80 @@ export default function(hljs) { "MultiPartToSinglePart", "Multipoint", "NextSequenceValue", + "None", "Now", "Number", + "Offset|0", "OrderBy", "Overlaps", "Point", "Polygon", "Polyline", + "Pop", "Portal", "Pow", + "Proper", + "Push", "Random", + "Reduce", "Relate", + "Replace", + "Resize", "Reverse", - "RingIsClockWise", + "Right|0", + "RingIsClockwise", + "Rotate", "Round", + "Schema", "Second", "SetGeometry", + "Simplify", "Sin", + "Slice", "Sort", + "Splice", + "Split", "Sqrt", "Stdev", + "SubtypeCode", + "SubtypeName", + "Subtypes", "Sum", "SymmetricDifference", "Tan", "Text", "Timestamp", + "ToCharCode", + "ToCodePoint", "Today", + "ToHex", "ToLocal", - "Top", + "Top|0", "Touches", "ToUTC", + "TrackAccelerationAt", + "TrackAccelerationWindow", + "TrackCurrentAcceleration", + "TrackCurrentDistance", + "TrackCurrentSpeed", "TrackCurrentTime", + "TrackDistanceAt", + "TrackDistanceWindow", + "TrackDuration", + "TrackFieldWindow", "TrackGeometryWindow", "TrackIndex", + "TrackSpeedAt", + "TrackSpeedWindow", "TrackStartTime", "TrackWindow", + "Trim", "TypeOf", "Union", + "Upper", "UrlEncode", "Variance", + "Week", "Weekday", "When", "Within", @@ -204,6 +271,7 @@ export default function(hljs) { return { name: 'ArcGIS Arcade', + case_insensitive: true, keywords: KEYWORDS, contains: [ hljs.APOS_STRING_MODE, diff --git a/test/markup/arcade/profile.expect.txt b/test/markup/arcade/profile.expect.txt index d4a9dce5f2..f30c09e4b6 100644 --- a/test/markup/arcade/profile.expect.txt +++ b/test/markup/arcade/profile.expect.txt @@ -3,7 +3,7 @@ */
function offsetPopulation(offset){ var popDensity = Round( $feature.POPULATION / AreaGeodetic(Geometry($feature), "square-kilometers") ); - var geom = Geometry({ 'x': offset.x, 'y': offset.y, 'spatialReference':{'wkid':102100} }); + var geom = Geometry({ 'x': offset.x, 'y': offset.y, 'spatialReference':{'wkid':102100} }); var myLayer = FeatureSet($map, ["POPULATION", "ELECTION-DATA"]); return popDensity; } From 2d0e7c1094a3c867bd65c8d2655cfcaa5f9dfa79 Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Thu, 6 Jan 2022 09:56:23 -0500 Subject: [PATCH 76/76] (chore) release 10.4.0 --- CHANGES.md | 2 +- README.md | 36 ++++++++++++++++++------------------ docs/conf.py | 4 ++-- package-lock.json | 4 ++-- package.json | 2 +- 5 files changed, 24 insertions(+), 24 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 82d853a84e..7973fa6ff6 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,4 +1,4 @@ -## Version 11.4 (most likely) +## Version 11.4.0 New Language: diff --git a/README.md b/README.md index e1fcf0656f..e4f00a20e3 100644 --- a/README.md +++ b/README.md @@ -328,20 +328,20 @@ see [DIGESTS.md](https://github.com/highlightjs/cdn-release/blob/main/DIGESTS.md ##### Common JS ```html - - + + - + ``` ##### ES6 Modules ````html - + @@ -353,20 +353,20 @@ hljs.registerLanguage('go', go); ##### Common JS ```html - - + + - + ``` ##### ES6 Modules ```html - + ``` @@ -376,20 +376,20 @@ hljs.registerLanguage('go', go); ##### Common JS ```html - - + + - + ``` ##### ES6 Modules ```html - + ``` diff --git a/docs/conf.py b/docs/conf.py index 3fd4634487..95fb287478 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -46,14 +46,14 @@ # General information about the project. project = u'highlight.js' -copyright = u'2012–2021, Ivan Sagalaev' +copyright = u'2012–2022, Ivan Sagalaev' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # The full version, including alpha/beta/rc tags. -release = '11.3.1' +release = '11.4.0' # The short X.Y version. version = ".".join(release.split(".")[:2]) diff --git a/package-lock.json b/package-lock.json index 55b90dec9d..349ec60b07 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { "name": "highlight.js", - "version": "11.3.1", + "version": "11.4.0", "lockfileVersion": 2, "requires": true, "packages": { "": { - "version": "11.3.1", + "version": "11.4.0", "license": "BSD-3-Clause", "devDependencies": { "@rollup/plugin-commonjs": "^21.0.0", diff --git a/package.json b/package.json index 985b47fdd6..0687273b47 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "syntax" ], "homepage": "https://highlightjs.org/", - "version": "11.3.1", + "version": "11.4.0", "author": { "name": "Ivan Sagalaev", "email": "maniac@softwaremaniacs.org"