From 5d907f60f3439c301876fa37aa3dda4f48df0cf7 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Sun, 18 Sep 2016 11:40:14 +0300 Subject: [PATCH] Add razor --- README.md | 1 + gulpfile.js | 1 + package.json | 2 +- src/monaco.contribution.ts | 7 + src/razor.ts | 329 +++++++++++++++++++++++++++++++++++++ test/all.js | 1 + test/razor.test.ts | 156 ++++++++++++++++++ tsconfig.json | 2 + 8 files changed, 498 insertions(+), 1 deletion(-) create mode 100644 src/razor.ts create mode 100644 test/razor.test.ts diff --git a/README.md b/README.md index 7cf3072c..a47c487d 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ Colorization and configuration supports for multiple languages for the Monaco Ed * powershell * python * r +* razor * ruby * sql * swift diff --git a/gulpfile.js b/gulpfile.js index 2d0f8869..d24f74c0 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -67,6 +67,7 @@ gulp.task('release', ['clean-release','compile'], function() { bundleOne('src/postiats'), bundleOne('src/python'), bundleOne('src/r'), + bundleOne('src/razor'), bundleOne('src/ruby'), bundleOne('src/scss'), bundleOne('src/sql'), diff --git a/package.json b/package.json index a7f41cb4..98e5741f 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "jsdom-no-contextify": "^3.1.0", "merge-stream": "^1.0.0", "mocha": "^2.5.3", - "monaco-editor-core": "0.7.0-next.3", + "monaco-editor-core": "0.7.0-next.4", "object-assign": "^4.1.0", "rimraf": "^2.5.2", "typescript": "^1.8.10", diff --git a/src/monaco.contribution.ts b/src/monaco.contribution.ts index b36c67e8..539d79b7 100644 --- a/src/monaco.contribution.ts +++ b/src/monaco.contribution.ts @@ -185,6 +185,13 @@ registerLanguage({ aliases: [ 'R', 'r' ], module: './r' }); +registerLanguage({ + id: 'razor', + extensions: ['.cshtml'], + aliases: ['Razor', 'razor'], + mimetypes: ['text/x-cshtml'], + module: './razor' +}); registerLanguage({ id: 'ruby', extensions: [ '.rb', '.rbx', '.rjs', '.gemspec', '.pp' ], diff --git a/src/razor.ts b/src/razor.ts new file mode 100644 index 00000000..4ed7e132 --- /dev/null +++ b/src/razor.ts @@ -0,0 +1,329 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import IRichLanguageConfiguration = monaco.languages.LanguageConfiguration; +import ILanguage = monaco.languages.IMonarchLanguage; + +// Allow for running under nodejs/requirejs in tests +var _monaco: typeof monaco = (typeof monaco === 'undefined' ? (self).monaco : monaco); + +const EMPTY_ELEMENTS:string[] = ['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'menuitem', 'meta', 'param', 'source', 'track', 'wbr']; + +export var conf:IRichLanguageConfiguration = { + wordPattern: /(-?\d*\.\d\w*)|([^\`\~\!\@\$\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\s]+)/g, + + comments: { + blockComment: [''] + }, + + brackets: [ + [''], + ['{', '}'], + ['(', ')'] + ], + + __electricCharacterSupport: { + embeddedElectricCharacters: ['*', '}', ']', ')'] + }, + + autoClosingPairs: [ + { open: '{', close: '}' }, + { open: '[', close: ']' }, + { open: '(', close: ')' }, + { open: '"', close: '"' }, + { open: '\'', close: '\'' } + ], + surroundingPairs: [ + { open: '"', close: '"' }, + { open: '\'', close: '\'' } + ], + + onEnterRules: [ + { + beforeText: new RegExp(`<(?!(?:${EMPTY_ELEMENTS.join('|')}))(\\w[\\w\\d]*)([^/>]*(?!/)>)[^<]*$`, 'i'), + afterText: /^<\/(\w[\w\d]*)\s*>$/i, + action: { indentAction: _monaco.languages.IndentAction.IndentOutdent } + }, + { + beforeText: new RegExp(`<(?!(?:${EMPTY_ELEMENTS.join('|')}))(\\w[\\w\\d]*)([^/>]*(?!/)>)[^<]*$`, 'i'), + action: { indentAction: _monaco.languages.IndentAction.Indent } + } + ], +}; + +export const htmlTokenTypes = { + DELIM_START: 'start.delimiter.tag.html', + DELIM_END: 'end.delimiter.tag.html', + DELIM_COMMENT: 'comment.html', + COMMENT: 'comment.content.html', + getTag: (name: string) => { + return 'tag.html'; + } +}; + +export var language = { + defaultToken: '', + tokenPostfix: '', + // ignoreCase: true, + + // The main tokenizer for our languages + tokenizer: { + root: [ + [/@@/], // text + [/@[^@]/, { token: '@rematch', switchTo: '@razorInSimpleState.root' }], + [/)/, [htmlTokenTypes.DELIM_START, 'tag.html', htmlTokenTypes.DELIM_END]], + [/(<)(script)/, [htmlTokenTypes.DELIM_START, { token: 'tag.html', next: '@script'} ]], + [/(<)(style)/, [htmlTokenTypes.DELIM_START, { token: 'tag.html', next: '@style'} ]], + [/(<)([:\w]+)/, [htmlTokenTypes.DELIM_START, { token: 'tag.html', next: '@otherTag'} ]], + [/(<\/)(\w+)/, [htmlTokenTypes.DELIM_START, { token: 'tag.html', next: '@otherTag' }]], + [/]+/, 'metatag.content.html' ], + [/>/, 'metatag.html', '@pop' ], + ], + + comment: [ + [/@[^@]/, { token: '@rematch', switchTo: '@razorInSimpleState.comment' }], + [/-->/, 'comment.html', '@pop'], + [/[^-]+/, 'comment.content.html'], + [/./, 'comment.content.html'] + ], + + otherTag: [ + [/@[^@]/, { token: '@rematch', switchTo: '@razorInSimpleState.otherTag' }], + [/\/?>/, htmlTokenTypes.DELIM_END, '@pop'], + [/"([^"]*)"/, 'attribute.value'], + [/'([^']*)'/, 'attribute.value'], + [/[\w\-]+/, 'attribute.name'], + [/=/, 'delimiter'], + [/[ \t\r\n]+/], // whitespace + ], + + // -- BEGIN