ink-docstrap
Version:
[](https://nodei.co/npm/ink-docstrap/)
149 lines (119 loc) • 4.62 kB
JavaScript
(function(sunlight, undefined){
if (sunlight === undefined || sunlight["registerLanguage"] === undefined) {
throw "Include sunlight.js before including language files";
}
sunlight.registerLanguage("batch", {
caseInsensitive: true,
scopes: {
string: [ ["\"", "\"", ["\\\"", "\\\\"]] ],
comment: [ ["REM", "\n", null, true], ["::", "\n", null, true] ],
variable: [["%", { regex: /[^\w%]/, length: 1}, null, true]]
},
customParseRules: [
//labels
function(context) {
var colon,
peek,
value = "",
line,
column;
if (!context.reader.isSolWs() || context.reader.current() !== ":" || context.reader.peek() === ":") {
return null;
}
colon = context.createToken("operator", ":", context.reader.getLine(), context.reader.getColumn());
//label, read until whitespace
while (peek = context.reader.peek()) {
if (/\s/.test(peek)) {
break;
}
value += context.reader.read();
if (!line) {
line = context.reader.getLine();
column = context.reader.getColumn();
}
}
if (value === "") {
return null;
}
return [colon, context.createToken("label", value, line, column)];
},
//label after goto statements
function(context) {
var matches = sunlight.util.createProceduralRule(context.count() - 1, -1, [{ token: "keyword", values: ["goto"] }, { token: "operator", values: [":"], optional: true }], true),
peek,
value,
line = context.reader.getLine(),
column = context.reader.getColumn();
if (!matches(context.getAllTokens())) {
return null;
}
value = context.reader.current();
while (peek = context.reader.peek()) {
if (/[\W]/.test(peek)) {
break;
}
value += context.reader.read();
}
return context.createToken("label", value, line, column);
},
//keywords have to be handled manually because strings don't have to be quoted
//e.g. we don't want to highlight "do" in "echo do you have the time?"
function() {
var keywords = sunlight.util.createHashMap([
//commands
"assoc","attrib","break","bcdedit","cacls","call","cd","chcp","chdir","chkdsk","chkntfs","cls","cmd",
"color","comp","compact","convertfcopy","date","del","dir","diskcomp","diskcopy","diskpart","doskey",
"driverquery","echo","endlocal","erase","exit","fc","findstr","find","format","for","fsutil","ftype",
"goto","gpresult","graftabl","help","icacls","if","label","md","mkdir","mklink","mode","more","move",
"openfiles","path","pause","popd","print","prompt","pushd","rd","recover",/*"rem",*/"rename","ren",
"replace","rmdir","robocopy","setlocal","set","schtasks","sc","shift","shutdown","sort","start",
"subst","systeminfo","tasklist","taskkill","time","title","tree","type","verify","ver","vol","xcopy",
"wmic",
"lfnfor",
//keywords
"do", "else", "errorlevel", "exist", "in", "not",
"choice",
"com1", "con", "prn", "aux", "nul", "lpt1",
"exit", "eof", "off", "on",
"equ","neq","lss","leq","gtr","geq"
], "\\b", true);
return function(context) {
var token = sunlight.util.matchWord(context, keywords, "keyword", true),
prevToken,
index;
if (!token) {
return null;
}
//look backward for "echo" or "title" or "set" or "|" or beginning of line
//if we find "echo" or "set" or "title" or "=" before "|" or sol then it's a fail
if (!context.reader.isSolWs()) {
index = context.count();
while (prevToken = context.token(--index)) {
if (prevToken.name === "keyword" && sunlight.util.contains(["echo", "title", "set"], prevToken.value)) {
return null;
}
if (prevToken.name === "operator" && prevToken.value === "=") {
return null;
}
//pipe
if (prevToken.name === "operator" && prevToken.value === "|") {
break;
}
//sol
if (prevToken.name === "default" && prevToken.value.indexOf("\n") >= 0) {
break;
}
}
}
context.reader.read(token.value.length - 1);
return token;
};
}()
],
identFirstLetter: /[A-Za-z_\.]/,
identAfterFirstLetter: /[\w-]/,
operators: [
"&&", "||", "&", ":", "/", "==", "|", "@", "*", ">>", ">", "<", "==!", "!", "=", "+"
]
});
}(this["Sunlight"]));