highlightjs-cshtml-razor
Advanced tools
Comparing version
# Changelog | ||
All notable changes to this project will be documented in this file. | ||
## [2.1.2] - 2025-06-25 | ||
- Fix incorrect processing '>' symbols inside strings in code blocks | ||
- Split tests to simplify its running | ||
## [2.1.0] - 2021-04-14 | ||
@@ -5,0 +9,0 @@ - Add the dist directory, and a minified version of the script |
{ | ||
"name": "highlightjs-cshtml-razor", | ||
"version": "2.1.1", | ||
"version": "2.1.2", | ||
"description": "highlight.js syntax definition for ASP.NET Razor CSHTML language", | ||
@@ -5,0 +5,0 @@ "main": "src/languages/cshtml-razor.js", |
@@ -41,4 +41,4 @@ # CSHTML Razor - a language grammar for [highlight.js](https://highlightjs.org/) | ||
hljs.registerLanguage("highlightjs-cshtml-razor", hljsRazor); | ||
hljs.initHighlightingOnLoad(); | ||
hljs.registerLanguage("cshtml-razor", hljsRazor); | ||
hljs.highlightAll(); | ||
``` | ||
@@ -48,2 +48,2 @@ | ||
[](http://creativecommons.org/publicdomain/zero/1.0/) | ||
[](http://creativecommons.org/publicdomain/zero/1.0/) |
@@ -8,5 +8,5 @@ /* | ||
module.exports = function (hljs) { | ||
var SPECIAL_SYMBOL_CLASSNAME = "built_in"; | ||
var CONTENT_REPLACER = {}; | ||
var closed_brace = { | ||
const SPECIAL_SYMBOL_CLASSNAME = "built_in"; | ||
const CONTENT_REPLACER = {}; | ||
const closed_brace = { | ||
begin: "}", | ||
@@ -16,3 +16,3 @@ className: SPECIAL_SYMBOL_CLASSNAME, | ||
}; | ||
var braces = { | ||
const braces = { | ||
begin: "{", | ||
@@ -22,3 +22,3 @@ end: "}", | ||
}; | ||
var csbraces = { | ||
const csbraces = { // allows to find exactly last closing brace in code blocks (to process codeblock content with "csharp" sub language) | ||
begin: "{", | ||
@@ -29,3 +29,10 @@ end: "}", | ||
}; | ||
var razor_comment = hljs.COMMENT( | ||
const quotes = { // allows to skip razor symbols/tags inside CS strings | ||
variants: [ | ||
{ begin: /"/, end: /"/, skip: true }, | ||
{ begin: /'/, end: /'/, skip: true } | ||
], | ||
skip: true | ||
}; | ||
const razor_comment = hljs.COMMENT( | ||
'@\\*', | ||
@@ -37,3 +44,3 @@ '\\*@', | ||
); | ||
var razor_inline_expresion = { | ||
const razor_inline_expresion = { | ||
begin: '@[A-Za-z0-9\\._:-]+', | ||
@@ -62,3 +69,3 @@ returnBegin: true, | ||
}; | ||
var razor_text_block = { | ||
const razor_text_block = { | ||
begin: "[@]{0,1}<text>", | ||
@@ -81,3 +88,3 @@ returnBegin: true, | ||
}; | ||
var razor_escape_at = { | ||
const razor_escape_at = { | ||
variants: [ | ||
@@ -90,3 +97,3 @@ { begin: "@@" }, | ||
var razor_parentheses_block = { | ||
const razor_parentheses_block = { | ||
begin: "@\\(", | ||
@@ -116,5 +123,5 @@ end: "\\)", | ||
}; | ||
var xml_blocks = getXmlBlocks(hljs, [razor_inline_expresion, razor_parentheses_block]); | ||
var razor_directives_prefix = "^\\s*@(page|model|using|inherits|inject|layout)"; | ||
var razor_directives = { | ||
const xml_blocks = getXmlBlocks(hljs, [razor_inline_expresion, razor_parentheses_block]); | ||
const razor_directives_prefix = "^\\s*@(page|model|using|inherits|inject|layout)"; | ||
const razor_directives = { | ||
begin: razor_directives_prefix + "[^\\r\\n{\\(]*$", | ||
@@ -140,7 +147,7 @@ end: "$", | ||
}; | ||
var cs_code_block_variants = [ | ||
const cs_code_block_variants = [ | ||
{ begin: "@\\{", end: "}" }, | ||
{ begin: "@code\\s*\\{", end: "}" } | ||
]; | ||
var razor_block = { | ||
const razor_block = { | ||
variants: cs_code_block_variants, | ||
@@ -157,6 +164,7 @@ returnBegin: true, | ||
csbraces, | ||
quotes, | ||
closed_brace | ||
] | ||
}; | ||
var razor_helper_block = { | ||
const razor_helper_block = { | ||
begin: "^\\s*@helper[\\s]*[^{]+[\\s]*{", | ||
@@ -173,3 +181,3 @@ returnBegin: true, | ||
}; | ||
var razor_code_block_variants = [ | ||
const razor_code_block_variants = [ | ||
{ begin: "@for[\\s]*\\([^{]+[\\s]*{", end: "}" }, | ||
@@ -183,3 +191,3 @@ { begin: "@if[\\s]*\\([^{]+[\\s]*{", end: "}" }, | ||
]; | ||
var razor_code_block = { | ||
const razor_code_block = { | ||
variants: razor_code_block_variants, | ||
@@ -228,3 +236,3 @@ returnBegin: true, | ||
}; | ||
var razor_try_block = { | ||
const razor_try_block = { | ||
begin: "@try[\\s]*{", | ||
@@ -261,4 +269,4 @@ end: "}", | ||
}; | ||
var section_begin = "@section[\\s]+[a-zA-Z0-9]+[\\s]*{"; | ||
var razor_section_block = { | ||
const section_begin = "@section[\\s]+[a-zA-Z0-9]+[\\s]*{"; | ||
const razor_section_block = { | ||
begin: section_begin, | ||
@@ -278,3 +286,3 @@ returnBegin: true, | ||
}; | ||
var rasor_await = { | ||
const rasor_await = { | ||
begin: "@await ", | ||
@@ -296,3 +304,3 @@ returnBegin: true, | ||
var contains = [ | ||
const contains = [ | ||
razor_directives, | ||
@@ -322,4 +330,4 @@ razor_helper_block, | ||
.forEach(function (mode) { | ||
var razorModes = contains.filter(function (c) { return c !== mode; }); | ||
var replacerIndex = mode.contains.indexOf(CONTENT_REPLACER); | ||
const razorModes = contains.filter(function (c) { return c !== mode; }); | ||
const replacerIndex = mode.contains.indexOf(CONTENT_REPLACER); | ||
mode.contains.splice.apply(mode.contains, [replacerIndex, 1].concat(razorModes)); | ||
@@ -335,3 +343,3 @@ }); | ||
function getXmlBlocks(hljs, additional_blocks) { | ||
var xml_comment = hljs.COMMENT( | ||
const xml_comment = hljs.COMMENT( | ||
'<!--', | ||
@@ -343,3 +351,3 @@ '-->', | ||
); | ||
var string = { | ||
const string = { | ||
className: 'string', | ||
@@ -352,3 +360,3 @@ variants: [ | ||
}; | ||
var xml_tag_internal = { | ||
const xml_tag_internal = { | ||
endsWithParent: true, | ||
@@ -355,0 +363,0 @@ illegal: /</, |
@@ -13,16 +13,41 @@ var should = require('should'); | ||
beforeEach(() => { | ||
hljsDefineCshtmlRazor(hljs); | ||
hljs.registerLanguage('cshtml-razor', hljsDefineCshtmlRazor); | ||
}); | ||
it("should generate correct markup", async () => { | ||
var files = await readdir(path.join(__dirname, "markup", "cshtml-razor")); | ||
files = files.filter(f => !f.includes(".expect.")); | ||
for(var f of files) { | ||
let fn = path.join(__dirname, "markup", "cshtml-razor", f); | ||
let expectFn = fn.replace(".txt", ".expect.txt"); | ||
var code = await readFile(fn, "utf-8"); | ||
var exp = await readFile(expectFn, "utf-8"); | ||
var actual = hljs.highlight("cshtml-razor", code).value; | ||
actual.trim().should.eql(exp.trim(), f); | ||
} | ||
async function testMarkupGeneration(fileName) { | ||
const codeFn = path.join(__dirname, "markup", "cshtml-razor", `${fileName}.txt`); | ||
const expectedFn = path.join(__dirname, "markup", "cshtml-razor", `${fileName}.expect.txt`); | ||
const code = (await readFile(codeFn, "utf-8")).trim(); | ||
const expectedMarkup = (await readFile(expectedFn, "utf-8")).trim(); | ||
const actualMarkup = hljs.highlight("cshtml-razor", code).value.trim(); | ||
actualMarkup.should.eql(expectedMarkup, ` | ||
Markup for ${fileName} does not match expected output. | ||
📄 Source code: | ||
${code} | ||
📄 Expected generated markup: | ||
${expectedMarkup} | ||
📄 Actual generated markup: | ||
${actualMarkup} | ||
`); | ||
} | ||
it("should generate correct markup - code-block-multiline", async () => { | ||
await testMarkupGeneration("code-block-multiline"); | ||
}); | ||
it("should generate correct markup - if-else-block", async () => { | ||
await testMarkupGeneration("if-else-block"); | ||
}); | ||
it("should generate correct markup - inline", async () => { | ||
await testMarkupGeneration("inline"); | ||
}); | ||
it("should generate correct markup - razor-in-razor", async () => { | ||
await testMarkupGeneration("razor-in-razor"); | ||
}); | ||
it("should generate correct markup - triangle-bracket-in-cs", async () => { | ||
await testMarkupGeneration("triangle-bracket-in-cs"); | ||
}); | ||
it("should be detected correctly", async () => { | ||
@@ -29,0 +54,0 @@ var code = await readFile(path.join(__dirname, 'detect', "cshtml-razor", "default.txt"), "utf-8"); |
42071
4.87%22
10%534
5.33%48
2.13%