diff --git a/components.js b/components.js index 51ee723bec..f35bd076b6 100644 --- a/components.js +++ b/components.js @@ -97,6 +97,10 @@ var components = { "title": "BASIC", "owner": "Golmote" }, + "batch": { + "title": "Batch", + "owner": "Golmote" + }, "bison": { "title": "Bison", "require": "c", diff --git a/components/prism-batch.js b/components/prism-batch.js new file mode 100644 index 0000000000..c7ca9ca60d --- /dev/null +++ b/components/prism-batch.js @@ -0,0 +1,99 @@ +(function (Prism) { + var variable = /%%?[~:\w]+%?|!\S+!/; + var parameter = { + pattern: /\/[a-z?]+(?=[ :]|$):?|-[a-z]\b|--[a-z-]+\b/im, + alias: 'attr-name', + inside: { + 'punctuation': /:/ + } + }; + var string = /"[^"]*"/; + var number = /(?:\b|-)\d+\b/; + + Prism.languages.batch = { + 'comment': [ + /^::.*/m, + { + pattern: /((?:^|[&(])[ \t]*)rem\b(?:[^^&)\r\n]|\^(?:\r\n|[\s\S]))*/im, + lookbehind: true + } + ], + 'label': { + pattern: /^:.*/m, + alias: 'property' + }, + 'command': [ + { + // FOR command + pattern: /((?:^|[&(])[ \t]*)for(?: ?\/[a-z?](?:[ :](?:"[^"]*"|\S+))?)* \S+ in \([^)]+\) do/im, + lookbehind: true, + inside: { + 'keyword': /^for\b|\b(?:in|do)\b/i, + 'string': string, + 'parameter': parameter, + 'variable': variable, + 'number': number, + 'punctuation': /[()',]/ + } + }, + { + // IF command + pattern: /((?:^|[&(])[ \t]*)if(?: ?\/[a-z?](?:[ :](?:"[^"]*"|\S+))?)* (?:not )?(?:cmdextversion \d+|defined \w+|errorlevel \d+|exist \S+|(?:"[^"]*"|\S+)?(?:==| (?:equ|neq|lss|leq|gtr|geq) )(?:"[^"]*"|\S+))/im, + lookbehind: true, + inside: { + 'keyword': /^if\b|\b(?:not|cmdextversion|defined|errorlevel|exist)\b/i, + 'string': string, + 'parameter': parameter, + 'variable': variable, + 'number': number, + 'operator': /\^|==|\b(?:equ|neq|lss|leq|gtr|geq)\b/i + } + }, + { + // ELSE command + pattern: /((?:^|[&()])[ \t]*)else\b/im, + lookbehind: true, + inside: { + 'keyword': /^else\b/i + } + }, + { + // SET command + pattern: /((?:^|[&(])[ \t]*)set(?: ?\/[a-z](?:[ :](?:"[^"]*"|\S+))?)* (?:[^^&)\r\n]|\^(?:\r\n|[\s\S]))*/im, + lookbehind: true, + inside: { + 'keyword': /^set\b/i, + 'string': string, + 'parameter': parameter, + 'variable': [ + variable, + /\w+(?=(?:[*\/%+\-&^|]|<<|>>)?=)/ + ], + 'number': number, + 'operator': /[*\/%+\-&^|]=?|<<=?|>>=?|[!~_=]/, + 'punctuation': /[()',]/ + } + }, + { + // Other commands + pattern: /((?:^|[&(])[ \t]*@?)\w+\b(?:[^^&)\r\n]|\^(?:\r\n|[\s\S]))*/im, + lookbehind: true, + inside: { + 'keyword': /^\w+\b/i, + 'string': string, + 'parameter': parameter, + 'label': { + pattern: /(^\s*):\S+/m, + lookbehind: true, + alias: 'property' + }, + 'variable': variable, + 'number': number, + 'operator': /\^/ + } + } + ], + 'operator': /[&@]/, + 'punctuation': /[()']/ + }; +}(Prism)); \ No newline at end of file diff --git a/components/prism-batch.min.js b/components/prism-batch.min.js new file mode 100644 index 0000000000..6ce5085710 --- /dev/null +++ b/components/prism-batch.min.js @@ -0,0 +1 @@ +!function(e){var r=/%%?[~:\w]+%?|!\S+!/,t={pattern:/\/[a-z?]+(?=[ :]|$):?|-[a-z]\b|--[a-z-]+\b/im,alias:"attr-name",inside:{punctuation:/:/}},n=/"[^"]*"/,i=/(?:\b|-)\d+\b/;e.languages.batch={comment:[/^::.*/m,{pattern:/((?:^|[&(])[ \t]*)rem\b(?:[^^&)\r\n]|\^(?:\r\n|[\s\S]))*/im,lookbehind:!0}],label:{pattern:/^:.*/m,alias:"property"},command:[{pattern:/((?:^|[&(])[ \t]*)for(?: ?\/[a-z?](?:[ :](?:"[^"]*"|\S+))?)* \S+ in \([^)]+\) do/im,lookbehind:!0,inside:{keyword:/^for\b|\b(?:in|do)\b/i,string:n,parameter:t,variable:r,number:i,punctuation:/[()',]/}},{pattern:/((?:^|[&(])[ \t]*)if(?: ?\/[a-z?](?:[ :](?:"[^"]*"|\S+))?)* (?:not )?(?:cmdextversion \d+|defined \w+|errorlevel \d+|exist \S+|(?:"[^"]*"|\S+)?(?:==| (?:equ|neq|lss|leq|gtr|geq) )(?:"[^"]*"|\S+))/im,lookbehind:!0,inside:{keyword:/^if\b|\b(?:not|cmdextversion|defined|errorlevel|exist)\b/i,string:n,parameter:t,variable:r,number:i,operator:/\^|==|\b(?:equ|neq|lss|leq|gtr|geq)\b/i}},{pattern:/((?:^|[&()])[ \t]*)else\b/im,lookbehind:!0,inside:{keyword:/^else\b/i}},{pattern:/((?:^|[&(])[ \t]*)set(?: ?\/[a-z](?:[ :](?:"[^"]*"|\S+))?)* (?:[^^&)\r\n]|\^(?:\r\n|[\s\S]))*/im,lookbehind:!0,inside:{keyword:/^set\b/i,string:n,parameter:t,variable:[r,/\w+(?=(?:[*\/%+\-&^|]|<<|>>)?=)/],number:i,operator:/[*\/%+\-&^|]=?|<<=?|>>=?|[!~_=]/,punctuation:/[()',]/}},{pattern:/((?:^|[&(])[ \t]*@?)\w+\b(?:[^^&)\r\n]|\^(?:\r\n|[\s\S]))*/im,lookbehind:!0,inside:{keyword:/^\w+\b/i,string:n,parameter:t,label:{pattern:/(^\s*):\S+/m,lookbehind:!0,alias:"property"},variable:r,number:i,operator:/\^/}}],operator:/[&@]/,punctuation:/[()']/}}(Prism); \ No newline at end of file diff --git a/examples/prism-batch.html b/examples/prism-batch.html new file mode 100644 index 0000000000..5a3ba7e9df --- /dev/null +++ b/examples/prism-batch.html @@ -0,0 +1,20 @@ +

Batch

+

To use this language, use the class "language-batch".

+ +

Comments

+
::
+:: Foo bar
+REM This is a comment too
+REM Multi-line ^
+comment
+ +

Labels

+
:foobar
+GOTO :EOF
+ +

Commands

+
@ECHO OFF
+FOR /l %%a in (5,-1,1) do (TITLE %title% -- closing in %%as)
+SET title=%~n0
+if /i "%InstSize:~0,1%"=="M" set maxcnt=3
+ping -n 2 -w 1 127.0.0.1
\ No newline at end of file diff --git a/tests/languages/batch/command_feature.test b/tests/languages/batch/command_feature.test new file mode 100644 index 0000000000..350788a8bd --- /dev/null +++ b/tests/languages/batch/command_feature.test @@ -0,0 +1,103 @@ +FOR /l %%a in (5,-1,1) do (TITLE %title% -- closing in %%as) +SET title=%~n0 +echo.Hello World +@ECHO OFF +if not defined ProgressFormat set "ProgressFormat=[PPPP]" +EXIT /b +set /a ProgressCnt+=1 +IF "%~1" NEQ "" (SET %~1=%new%) ELSE (echo.%new%) + +---------------------------------------------------- + +[ + ["command", [ + ["keyword", "FOR"], + ["parameter", ["/l"]], + ["variable", "%%a"], + ["keyword", "in"], + ["punctuation", "("], + ["number", "5"], ["punctuation", ","], + ["number", "-1"], ["punctuation", ","], + ["number", "1"], ["punctuation", ")"], + ["keyword", "do"] + ]], + ["punctuation", "("], + ["command", [ + ["keyword", "TITLE"], + ["variable", "%title%"], + " -- closing in ", + ["variable", "%%as"] + ]], + ["punctuation", ")"], + + ["command", [ + ["keyword", "SET"], + ["variable", "title"], + ["operator", "="], + ["variable", "%~n0"] + ]], + + ["command", [ + ["keyword", "echo"], + ".Hello World" + ]], + + ["operator", "@"], + ["command", [ + ["keyword", "ECHO"], + " OFF" + ]], + + ["command", [ + ["keyword", "if"], + ["keyword", "not"], + ["keyword", "defined"], + " ProgressFormat" + ]], + ["command", [ + ["keyword", "set"], + ["string", "\"ProgressFormat=[PPPP]\""] + ]], + + ["command", [ + ["keyword", "EXIT"], + ["parameter", ["/b"]] + ]], + + ["command", [ + ["keyword", "set"], + ["parameter", ["/a"]], + ["variable", "ProgressCnt"], + ["operator", "+="], + ["number", "1"] + ]], + + ["command", [ + ["keyword", "IF"], + ["string", "\"%~1\""], + ["operator", "NEQ"], + ["string", "\"\""] + ]], + ["punctuation", "("], + ["command", [ + ["keyword", "SET"], + ["variable", "%~1"], + ["operator", "="], + ["variable", "%new%"] + ]], + ["punctuation", ")"], + ["command", [ + ["keyword", "ELSE"] + ]], + ["punctuation", "("], + ["command", [ + ["keyword", "echo"], + ".", + ["variable", "%new%"] + ]], + ["punctuation", ")"] +] + +---------------------------------------------------- + +Checks for commands. \ No newline at end of file diff --git a/tests/languages/batch/comment_feature.test b/tests/languages/batch/comment_feature.test new file mode 100644 index 0000000000..83759d8e86 --- /dev/null +++ b/tests/languages/batch/comment_feature.test @@ -0,0 +1,18 @@ +:: +:: Foobar +REM Foobar +rem foo^ +bar + +---------------------------------------------------- + +[ + ["comment", "::"], + ["comment", ":: Foobar"], + ["comment", "REM Foobar"], + ["comment", "rem foo^\r\nbar"] +] + +---------------------------------------------------- + +Checks for comments. \ No newline at end of file diff --git a/tests/languages/batch/label_feature.test b/tests/languages/batch/label_feature.test new file mode 100644 index 0000000000..a672ba0cc3 --- /dev/null +++ b/tests/languages/batch/label_feature.test @@ -0,0 +1,13 @@ +:foo +:Foo_Bar + +---------------------------------------------------- + +[ + ["label", ":foo"], + ["label", ":Foo_Bar"] +] + +---------------------------------------------------- + +Checks for labels. \ No newline at end of file