From 11f4a8a797816cfa8272718cc05baaf7be345d75 Mon Sep 17 00:00:00 2001 From: Darius Roberts <darius.roberts@gmail.com> Date: Wed, 25 Sep 2013 09:25:50 -0400 Subject: [PATCH] adding gherkin mode --- AUTHORS | 1 + doc/compress.html | 1 + mode/gherkin/gherkin.js | 170 ++++++++++++++++++++++++++++++++++++++++ mode/gherkin/index.html | 48 ++++++++++++ mode/index.html | 1 + mode/meta.js | 3 +- 6 files changed, 223 insertions(+), 1 deletion(-) create mode 100644 mode/gherkin/gherkin.js create mode 100644 mode/gherkin/index.html diff --git a/AUTHORS b/AUTHORS index ad2ec9957..260c13a86 100644 --- a/AUTHORS +++ b/AUTHORS @@ -84,6 +84,7 @@ Ford_Lawnmower Gabriel Nahmias galambalazs Gautam Mehta +Glenn Jorde Glenn Ruehle Golevka Gordon Smith diff --git a/doc/compress.html b/doc/compress.html index 5ae53c483..567c68f45 100644 --- a/doc/compress.html +++ b/doc/compress.html @@ -93,6 +93,7 @@ <option value="http://codemirror.net/mode/fortran/fortran.js">fortran.js</option> <option value="http://codemirror.net/mode/gfm/gfm.js">gfm.js</option> <option value="http://codemirror.net/mode/gas/gas.js">gas.js</option> + <option value="http://codemirror.net/mode/gherkin/gherkin.js">gherkin.js</option> <option value="http://codemirror.net/mode/go/go.js">go.js</option> <option value="http://codemirror.net/mode/groovy/groovy.js">groovy.js</option> <option value="http://codemirror.net/mode/haml/haml.js">haml.js</option> diff --git a/mode/gherkin/gherkin.js b/mode/gherkin/gherkin.js new file mode 100644 index 000000000..580587a02 --- /dev/null +++ b/mode/gherkin/gherkin.js @@ -0,0 +1,170 @@ +/* +Gherkin mode - http://www.cukes.info/ +Report bugs/issues here: https://github.com/marijnh/CodeMirror/issues +*/ + +// Following Objs from Brackets implementation: https://github.com/tregusti/brackets-gherkin/blob/master/main.js +//var Quotes = { +// SINGLE: 1, +// DOUBLE: 2 +//}; + +//var regex = { +// keywords: /(Feature| {2}(Scenario|In order to|As|I)| {4}(Given|When|Then|And))/ +//}; + +CodeMirror.defineMode("gherkin", function () { + return { + startState: function () { + return { + lineNumber: 0, + tableHeaderLine: null, + allowFeature: true, + allowBackground: false, + allowScenario: false, + allowSteps: false, + allowPlaceholders: false, + inMultilineArgument: false, + inMultilineString: false, + inMultilineTable: false + }; + }, + token: function (stream, state) { + if (stream.sol()) { + state.lineNumber++; + } + stream.eatSpace(); + + // INSIDE OF MULTILINE ARGUMENTS + if (state.inMultilineArgument) { + + // STRING + if (state.inMultilineString) { + if (stream.match('"""')) { + state.inMultilineString = false; + state.inMultilineArgument = false; + } else { + stream.match(/.*/); + } + return "string"; + } + + // TABLE + if (state.inMultilineTable) { + // New table, assume first row is headers + if (state.tableHeaderLine === null) { + state.tableHeaderLine = state.lineNumber; + } + + if (stream.match(/\|\s*/)) { + if (stream.eol()) { + state.inMultilineTable = false; + } + return "bracket"; + } else { + stream.match(/[^\|]*/); + return state.tableHeaderLine === state.lineNumber ? "property" : "string"; + } + } + + // DETECT START + if (stream.match('"""')) { + // String + state.inMultilineString = true; + return "string"; + } else if (stream.match("|")) { + // Table + state.inMultilineTable = true; + return "bracket"; + } else { + // Or abort + state.inMultilineArgument = false; + state.tableHeaderLine = null; + } + + + return null; + } + + // LINE COMMENT + if (stream.match(/#.*/)) { + return "comment"; + + // TAG + } else if (stream.match(/@\S+/)) { + return "def"; + + // FEATURE + } else if (state.allowFeature && stream.match(/Feature:/)) { + state.allowScenario = true; + state.allowBackground = true; + state.allowPlaceholders = false; + state.allowSteps = false; + return "keyword"; + + // BACKGROUND + } else if (state.allowBackground && stream.match("Background:")) { + state.allowPlaceholders = false; + state.allowSteps = true; + state.allowBackground = false; + return "keyword"; + + // SCENARIO OUTLINE + } else if (state.allowScenario && stream.match("Scenario Outline:")) { + state.allowPlaceholders = true; + state.allowSteps = true; + return "keyword"; + + // EXAMPLES + } else if (state.allowScenario && stream.match("Examples:")) { + state.allowPlaceholders = false; + state.allowSteps = true; + state.allowBackground = false; + state.inMultilineArgument = true; + return "keyword"; + + // SCENARIO + } else if (state.allowScenario && stream.match(/Scenario:/)) { + state.allowPlaceholders = false; + state.allowSteps = true; + state.allowBackground = false; + return "keyword"; + + // STEPS + } else if (state.allowSteps && stream.match(/(Given|When|Then|And|But)/)) { + return "keyword"; + + // INLINE STRING + } else if (!state.inMultilineArgument && stream.match(/"/)) { + stream.match(/.*?"/); + return "string"; + + // MULTILINE ARGUMENTS + } else if (state.allowSteps && stream.eat(":")) { + if (stream.match(/\s*$/)) { + state.inMultilineArgument = true; + return "keyword"; + } else { + return null; + } + + } else if (state.allowSteps && stream.match("<")) { + if (stream.match(/.*?>/)) { + return "property"; + } else { + return null; + } + + // Fall through + } else { + stream.eatWhile(/[^":<]/); + } + + return null; + } + }; +}); + +CodeMirror.defineMIME("text/x-feature", "gherkin"); +if (!CodeMirror.mimeModes.hasOwnProperty("text/x-feature")) + CodeMirror.defineMIME("text/x-feature", "gherkin"); diff --git a/mode/gherkin/index.html b/mode/gherkin/index.html new file mode 100644 index 000000000..b76877acd --- /dev/null +++ b/mode/gherkin/index.html @@ -0,0 +1,48 @@ +<!doctype html> + +<title>CodeMirror: Gherkin mode</title> +<meta charset="utf-8"/> +<link rel=stylesheet href="../../doc/docs.css"> + +<link rel="stylesheet" href="../../lib/codemirror.css"> +<script src="../../lib/codemirror.js"></script> +<script src="gherkin.js"></script> +<style>.CodeMirror { border-top: 1px solid #ddd; border-bottom: 1px solid #ddd; }</style> +<div id=nav> + <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a> + + <ul> + <li><a href="../../index.html">Home</a> + <li><a href="../../doc/manual.html">Manual</a> + <li><a href="https://github.com/marijnh/codemirror">Code</a> + </ul> + <ul> + <li><a href="../index.html">Language modes</a> + <li><a class=active href="#">Gherkin</a> + </ul> +</div> + +<article> +<h2>Gherkin mode</h2> +<form><textarea id="code" name="code"> +Feature: Using Google + Background: + Something something + Something else + Scenario: Has a homepage + When I navigate to the google home page + Then the home page should contain the menu and the search form + Scenario: Searching for a term + When I navigate to the google home page + When I search for Tofu + Then the search results page is displayed + Then the search results page contains 10 individual search results + Then the search results contain a link to the wikipedia tofu page +</textarea></form> + <script> + var editor = CodeMirror.fromTextArea(document.getElementById("code"), {}); + </script> + + <p><strong>MIME types defined:</strong> <code>text/x-feature</code>.</p> + + </article> diff --git a/mode/index.html b/mode/index.html index 063e69b6c..f72b1f062 100644 --- a/mode/index.html +++ b/mode/index.html @@ -46,6 +46,7 @@ option.</p> <li><a href="erlang/index.html">Erlang</a></li> <li><a href="fortran/index.html">Fortran</a></li> <li><a href="gas/index.html">Gas</a> (AT&T-style assembly)</li> + <li><a href="gherkin/index.html">Gherkin</a></li> <li><a href="go/index.html">Go</a></li> <li><a href="groovy/index.html">Groovy</a></li> <li><a href="haml/index.html">HAML</a></li> diff --git a/mode/meta.js b/mode/meta.js index ce51c8ae1..fe5cd848a 100644 --- a/mode/meta.js +++ b/mode/meta.js @@ -18,8 +18,9 @@ CodeMirror.modeInfo = [ {name: 'Erlang', mime: 'text/x-erlang', mode: 'erlang'}, {name: 'Fortran', mime: 'text/x-fortran', mode: 'fortran'}, {name: 'Gas', mime: 'text/x-gas', mode: 'gas'}, + {name: 'Gherkin', mime: 'text/x-feature', mode: 'gherkin'}, {name: 'GitHub Flavored Markdown', mime: 'text/x-gfm', mode: 'gfm'}, - {name: 'GO', mime: 'text/x-go', mode: 'go'}, + {name: 'Go', mime: 'text/x-go', mode: 'go'}, {name: 'Groovy', mime: 'text/x-groovy', mode: 'groovy'}, {name: 'HAML', mime: 'text/x-haml', mode: 'haml'}, {name: 'Haskell', mime: 'text/x-haskell', mode: 'haskell'}, -- GitLab