aboutsummaryrefslogtreecommitdiffstats
path: root/public/prism/prism-cshtml.js
diff options
context:
space:
mode:
authorArmand Philippot <git@armandphilippot.com>2021-12-30 19:47:21 +0100
committerArmand Philippot <git@armandphilippot.com>2021-12-30 19:47:21 +0100
commita98b5ea6fe8e8cc98a55e0fd793e6e8660ea31c1 (patch)
tree542810ab5aef99150db228bb54fd58303dcb31c7 /public/prism/prism-cshtml.js
parentab355897a12b7bda1089a44de326d41455a0f7a3 (diff)
chore: add prismjs for syntax highlighting
Diffstat (limited to 'public/prism/prism-cshtml.js')
-rw-r--r--public/prism/prism-cshtml.js234
1 files changed, 234 insertions, 0 deletions
diff --git a/public/prism/prism-cshtml.js b/public/prism/prism-cshtml.js
new file mode 100644
index 0000000..df73bac
--- /dev/null
+++ b/public/prism/prism-cshtml.js
@@ -0,0 +1,234 @@
+// Docs:
+// https://docs.microsoft.com/en-us/aspnet/core/razor-pages/?view=aspnetcore-5.0&tabs=visual-studio
+// https://docs.microsoft.com/en-us/aspnet/core/mvc/views/razor?view=aspnetcore-5.0
+
+(function (Prism) {
+ var commentLike = /\/(?![/*])|\/\/.*[\r\n]|\/\*[^*]*(?:\*(?!\/)[^*]*)*\*\//
+ .source;
+ var stringLike =
+ /@(?!")|"(?:[^\r\n\\"]|\\.)*"|@"(?:[^\\"]|""|\\[\s\S])*"(?!")/.source +
+ '|' +
+ /'(?:(?:[^\r\n'\\]|\\.|\\[Uux][\da-fA-F]{1,8})'|(?=[^\\](?!')))/.source;
+
+ /**
+ * Creates a nested pattern where all occurrences of the string `<<self>>` are replaced with the pattern itself.
+ *
+ * @param {string} pattern
+ * @param {number} depthLog2
+ * @returns {string}
+ */
+ function nested(pattern, depthLog2) {
+ for (var i = 0; i < depthLog2; i++) {
+ pattern = pattern.replace(/<self>/g, function () {
+ return '(?:' + pattern + ')';
+ });
+ }
+ return pattern
+ .replace(/<self>/g, '[^\\s\\S]')
+ .replace(/<str>/g, '(?:' + stringLike + ')')
+ .replace(/<comment>/g, '(?:' + commentLike + ')');
+ }
+
+ var round = nested(/\((?:[^()'"@/]|<str>|<comment>|<self>)*\)/.source, 2);
+ var square = nested(/\[(?:[^\[\]'"@/]|<str>|<comment>|<self>)*\]/.source, 2);
+ var curly = nested(/\{(?:[^{}'"@/]|<str>|<comment>|<self>)*\}/.source, 2);
+ var angle = nested(/<(?:[^<>'"@/]|<str>|<comment>|<self>)*>/.source, 2);
+
+ // Note about the above bracket patterns:
+ // They all ignore HTML expressions that might be in the C# code. This is a problem because HTML (like strings and
+ // comments) is parsed differently. This is a huge problem because HTML might contain brackets and quotes which
+ // messes up the bracket and string counting implemented by the above patterns.
+ //
+ // This problem is not fixable because 1) HTML expression are highly context sensitive and very difficult to detect
+ // and 2) they require one capturing group at every nested level. See the `tagRegion` pattern to admire the
+ // complexity of an HTML expression.
+ //
+ // To somewhat alleviate the problem a bit, the patterns for characters (e.g. 'a') is very permissive, it also
+ // allows invalid characters to support HTML expressions like this: <p>That's it!</p>.
+
+ var tagAttrs =
+ /(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?/
+ .source;
+ var tagContent = /(?!\d)[^\s>\/=$<%]+/.source + tagAttrs + /\s*\/?>/.source;
+ var tagRegion =
+ /\B@?/.source +
+ '(?:' +
+ /<([a-zA-Z][\w:]*)/.source +
+ tagAttrs +
+ /\s*>/.source +
+ '(?:' +
+ (/[^<]/.source +
+ '|' +
+ // all tags that are not the start tag
+ // eslint-disable-next-line regexp/strict
+ /<\/?(?!\1\b)/.source +
+ tagContent +
+ '|' +
+ // nested start tag
+ nested(
+ // eslint-disable-next-line regexp/strict
+ /<\1/.source +
+ tagAttrs +
+ /\s*>/.source +
+ '(?:' +
+ (/[^<]/.source +
+ '|' +
+ // all tags that are not the start tag
+ // eslint-disable-next-line regexp/strict
+ /<\/?(?!\1\b)/.source +
+ tagContent +
+ '|' +
+ '<self>') +
+ ')*' +
+ // eslint-disable-next-line regexp/strict
+ /<\/\1\s*>/.source,
+ 2
+ )) +
+ ')*' +
+ // eslint-disable-next-line regexp/strict
+ /<\/\1\s*>/.source +
+ '|' +
+ /</.source +
+ tagContent +
+ ')';
+
+ // Now for the actual language definition(s):
+ //
+ // Razor as a language has 2 parts:
+ // 1) CSHTML: A markup-like language that has been extended with inline C# code expressions and blocks.
+ // 2) C#+HTML: A variant of C# that can contain CSHTML tags as expressions.
+ //
+ // In the below code, both CSHTML and C#+HTML will be create as separate language definitions that reference each
+ // other. However, only CSHTML will be exported via `Prism.languages`.
+
+ Prism.languages.cshtml = Prism.languages.extend('markup', {});
+
+ var csharpWithHtml = Prism.languages.insertBefore(
+ 'csharp',
+ 'string',
+ {
+ html: {
+ pattern: RegExp(tagRegion),
+ greedy: true,
+ inside: Prism.languages.cshtml,
+ },
+ },
+ { csharp: Prism.languages.extend('csharp', {}) }
+ );
+
+ var cs = {
+ pattern: /\S[\s\S]*/,
+ alias: 'language-csharp',
+ inside: csharpWithHtml,
+ };
+
+ Prism.languages.insertBefore('cshtml', 'prolog', {
+ 'razor-comment': {
+ pattern: /@\*[\s\S]*?\*@/,
+ greedy: true,
+ alias: 'comment',
+ },
+
+ block: {
+ pattern: RegExp(
+ /(^|[^@])@/.source +
+ '(?:' +
+ [
+ // @{ ... }
+ curly,
+ // @code{ ... }
+ /(?:code|functions)\s*/.source + curly,
+ // @for (...) { ... }
+ /(?:for|foreach|lock|switch|using|while)\s*/.source +
+ round +
+ /\s*/.source +
+ curly,
+ // @do { ... } while (...);
+ /do\s*/.source +
+ curly +
+ /\s*while\s*/.source +
+ round +
+ /(?:\s*;)?/.source,
+ // @try { ... } catch (...) { ... } finally { ... }
+ /try\s*/.source +
+ curly +
+ /\s*catch\s*/.source +
+ round +
+ /\s*/.source +
+ curly +
+ /\s*finally\s*/.source +
+ curly,
+ // @if (...) {...} else if (...) {...} else {...}
+ /if\s*/.source +
+ round +
+ /\s*/.source +
+ curly +
+ '(?:' +
+ /\s*else/.source +
+ '(?:' +
+ /\s+if\s*/.source +
+ round +
+ ')?' +
+ /\s*/.source +
+ curly +
+ ')*',
+ ].join('|') +
+ ')'
+ ),
+ lookbehind: true,
+ greedy: true,
+ inside: {
+ keyword: /^@\w*/,
+ csharp: cs,
+ },
+ },
+
+ directive: {
+ pattern:
+ /^([ \t]*)@(?:addTagHelper|attribute|implements|inherits|inject|layout|model|namespace|page|preservewhitespace|removeTagHelper|section|tagHelperPrefix|using)(?=\s).*/m,
+ lookbehind: true,
+ greedy: true,
+ inside: {
+ keyword: /^@\w+/,
+ csharp: cs,
+ },
+ },
+
+ value: {
+ pattern: RegExp(
+ /(^|[^@])@/.source +
+ /(?:await\b\s*)?/.source +
+ '(?:' +
+ /\w+\b/.source +
+ '|' +
+ round +
+ ')' +
+ '(?:' +
+ /[?!]?\.\w+\b/.source +
+ '|' +
+ round +
+ '|' +
+ square +
+ '|' +
+ angle +
+ round +
+ ')*'
+ ),
+ lookbehind: true,
+ greedy: true,
+ alias: 'variable',
+ inside: {
+ keyword: /^@/,
+ csharp: cs,
+ },
+ },
+
+ 'delegate-operator': {
+ pattern: /(^|[^@])@(?=<)/,
+ lookbehind: true,
+ alias: 'operator',
+ },
+ });
+
+ Prism.languages.razor = Prism.languages.cshtml;
+})(Prism);