ink-docstrap
Version:
[](https://nodei.co/npm/ink-docstrap/)
168 lines (140 loc) • 5.46 kB
JavaScript
(function(sunlight, undefined){
if (sunlight === undefined || sunlight["registerLanguage"] === undefined) {
throw "Include sunlight.js before including language files";
}
sunlight.registerLanguage("powershell", {
scopes: {
string: [ ["\"", "\"", ["\\\"", "\\\\"]], ["'", "'", ["\\'", "\\\\"]] ],
comment: [ ["#", "\n", null, true] ]
},
customParseRules: [
//idents and special operators
//we need a custom rule to differentiate between the "-" operator and idents that start with "-"
function() {
var specialOperators = [
"-not", "-band", "-bor", "bnot", "-replace", "-ireplace", "-creplace", "-and",
"-or", "-isnot", "-is", "-as", "-F", "-lt", "-le", "-gt", "-ge", "-eq", "-ne",
"-contains", "-notcontains", "-like", "-notlike", "-match", "-notmatch"
],
keywords = [
//[type]::gettype("System.Management.Automation.KeywordTokenReader")|%{$_.InvokeMember("_keywordTokens", "NonPublic,Static,GetField", $null, $_,@())}
"elseif","begin","function","for","foreach","return","else","trap","while","using","do","data",
"dynamicparam","class","define","until","end","break","if","throw","param","continue","finally",
"in","switch","exit","filter","from","try","process","var","catch"
];
return function(context) {
var peek,
ident = context.reader.current(),
line = context.reader.getLine(),
column = context.reader.getColumn(),
tokenType;
if (!/[A-Za-z_-]/.test(context.reader.current()) || !/[\w-]/.test(context.reader.peek())) {
return null;
}
while (peek = context.reader.peek()) {
if (!/[\w-]/.test(peek)) {
break;
}
ident += context.reader.read();
}
//lol at the utter confusion i know this statement creates
//BUT I DONT'T CARE
tokenType = sunlight.util.contains(specialOperators, ident)
? "specialOperator"
: (sunlight.util.contains(keywords, ident)
? "keyword"
: (ident.charAt(0) === "-"
? "switch"
: "ident"
)
);
return context.createToken(tokenType, ident, line, column);
};
}(),
//variables
function() {
//Get-Help about_automatic_variables
//all uppercase because they're not case sensitive
var invalidVariableCharRegex = /[!@#%&,\.\s]/,
specialVariables = [
"$$", "$?", "$^", "$_", "$ARGS", "$CONSOLEFILENAME", "$ERROR", "$EVENT", "$EVENTSUBSCRIBER",
"$EXECUTIONCONTEXT", "$FALSE", "$FOREACH", "$HOME", "$HOST", "$INPUT", "$LASTEXITCODE",
"$MATCHES", "$MYINVOCATION", "$NESTEDPROMPTLEVEL", "$NULL", "$PID", "$PROFILE", "$PSBOUNDPARAMETERS",
"$PSCMDLET", "$PSCULTURE", "$PSDEBUGCONTEXT", "$PSHOME", "$PSSCRIPTROOT", "$PSUICULTURE",
"$PSVERSIONTABLE", "$PWD", "$SENDER", "$SHELLID", "$SOURCEARGS", "$SOURCEEVENTARGS", "$THIS", "$TRUE"
];
return function(context) {
var peek,
value = "$",
line = context.reader.getLine(),
column = context.reader.getColumn();
//illegal characters in a variable: ! @ # % & , . whitespace
if (context.reader.current() !== "$" || invalidVariableCharRegex.test(context.reader.peek())) {
return null;
}
while (peek = context.reader.peek()) {
if (invalidVariableCharRegex.test(peek)) {
break;
}
value += context.reader.read();
}
return context.createToken(sunlight.util.contains(specialVariables, value.toUpperCase()) ? "specialVariable" : "variable", value, line, column);
}
}()
],
namedIdentRules: {
custom: [
function(context) {
var prevToken = context.tokens[context.index - 1];
if (!prevToken) {
return true;
}
//must be first thing on the line that's not a continuation (preceded by "`" operator)
if (prevToken.name === "default" && prevToken.value.indexOf(sunlight.util.eol) >= 0) {
prevToken = context.tokens[context.index - 2];
if (prevToken && prevToken.name === "operator" && prevToken.value === "`") {
return false;
}
return true;
}
//if it follows an equals sign, that's cool, too
prevToken = sunlight.util.getPreviousNonWsToken(context.tokens, context.index);
if (prevToken && ((prevToken.name === "operator" && prevToken.value === "=") || (prevToken.name === "punctuation" && prevToken.value === "{"))) {
return true;
}
return false;
},
//type coercion
function(context) {
var nextToken = sunlight.util.getNextNonWsToken(context.tokens, context.index),
isBetween;
if (nextToken && nextToken.name === "operator" && nextToken.value === ".") {
return false;
}
isBetween = sunlight.util.createBetweenRule(context.index, { token: "punctuation", values: ["["] }, { token: "punctuation", values: ["]"] });
if (!isBetween(context.tokens)) {
return false;
}
return true;
}
]
},
operators: [
"@(",
"::",
"..", ".",
"=",
"!=", "!",
"|",
">>", ">",
"++", "+=", "+",
"`",
"*=", "*",
"/=", "/",
"--", "-=", "-",
"%{", "%=", "%",
"${",
"&"
]
});
}(this["Sunlight"]));