|
| 1 | +<!doctype html> |
| 2 | + |
| 3 | +<title>CodeMirror: Simple Mode Demo</title> |
| 4 | +<meta charset="utf-8"/> |
| 5 | +<link rel=stylesheet href="../doc/docs.css"> |
| 6 | + |
| 7 | +<link rel="stylesheet" href="../lib/codemirror.css"> |
| 8 | +<script src="../lib/codemirror.js"></script> |
| 9 | +<script src="../addon/mode/simple.js"></script> |
| 10 | +<script src="../mode/xml/xml.js"></script> |
| 11 | +<style type="text/css"> |
| 12 | + .CodeMirror {border: 1px solid silver; margin-bottom: 1em; } |
| 13 | + dt { text-indent: -2em; padding-left: 2em; margin-top: 1em; } |
| 14 | + dd { margin-left: 1.5em; margin-bottom: 1em; } |
| 15 | + dt {margin-top: 1em;} |
| 16 | +</style> |
| 17 | + |
| 18 | +<div id=nav> |
| 19 | + <a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a> |
| 20 | + |
| 21 | + <ul> |
| 22 | + <li><a href="../index.html">Home</a> |
| 23 | + <li><a href="../doc/manual.html">Manual</a> |
| 24 | + <li><a href="https://github.com/codemirror/codemirror">Code</a> |
| 25 | + </ul> |
| 26 | + <ul> |
| 27 | + <li><a class=active href="#">Simple Mode</a> |
| 28 | + </ul> |
| 29 | +</div> |
| 30 | + |
| 31 | +<article> |
| 32 | +<h2>Simple Mode Demo</h2> |
| 33 | + |
| 34 | +<p>The <a href="../addon/mode/simple.js"><code>mode/simple</code></a> |
| 35 | +addon allows CodeMirror modes to be specified with a relatively simple |
| 36 | +declarative format. This format is not as powerful as writing code |
| 37 | +directly against the <a href="../doc/manual.html#modeapi">mode |
| 38 | +interface</a>, but is a lot easier to get started with, and |
| 39 | +sufficiently expressive for many simple language modes.</p> |
| 40 | + |
| 41 | +<p>This interface is still in flux. It is unlikely to be scrapped or |
| 42 | +overhauled completely, so do start writing code against it, but |
| 43 | +details might change as it stabilizes, and you might have to tweak |
| 44 | +your code when upgrading.</p> |
| 45 | + |
| 46 | +<p>Simple modes (loosely based on |
| 47 | +the <a href="https://github.com/mozilla/skywriter/wiki/Common-JavaScript-Syntax-Highlighting-Specification">Common |
| 48 | +JavaScript Syntax Highlighting Specification</a>, which never took |
| 49 | +off), are state machines, where each state has a number of rules that |
| 50 | +match tokens. A rule describes a type of token that may occur in the |
| 51 | +current state, and possibly a transition to another state caused by |
| 52 | +that token.</p> |
| 53 | + |
| 54 | +<p>The <code>CodeMirror.defineSimpleMode(name, states)</code> method |
| 55 | +takes a mode name and an object that describes the mode's states. The |
| 56 | +editor below shows an example of such a mode (and is itself |
| 57 | +highlighted by the mode shown in it).</p> |
| 58 | + |
| 59 | +<div id="code"></div> |
| 60 | + |
| 61 | +<p>Each state is an array of rules. A rule may have the following properties:</p> |
| 62 | + |
| 63 | +<dl> |
| 64 | + <dt><code>regex</code></dt> |
| 65 | + <dd>The regular expression that matches the token. May be a string |
| 66 | + or a regex object. When a regex, the <code>ignoreCase</code> flag |
| 67 | + will be taken into account when matching the token. This regex |
| 68 | + should only capture groups when the <code>token</code> property is |
| 69 | + an array.</dd> |
| 70 | + <dt><code>token</code></dt> |
| 71 | + <dd>An optional token style. Multiple styles can be specified by |
| 72 | + separating them with dots or spaces. When the <code>regex</code> for |
| 73 | + this rule captures groups, it must capture <em>all</em> of the |
| 74 | + string (since JS provides no way to find out where a group matched), |
| 75 | + and this property must hold an array of token styles that has one |
| 76 | + style for each matched group.</dd> |
| 77 | + <dt><code>next</code></dt> |
| 78 | + <dd>When a <code>next</code> property is present, the mode will |
| 79 | + transfer to another state when the token is encountered.</dd> |
| 80 | + <dt><code>mode</code></dt> |
| 81 | + <dd>Can be used to embed another mode inside a mode. When present, |
| 82 | + must hold an object with a <code>spec</code> property that describes |
| 83 | + the embedded mode, and an optional <code>end</code> end property |
| 84 | + that specifies the regexp that will end the extent of the mode. When |
| 85 | + a <code>persistent</code> property is set (and true), the nested |
| 86 | + mode's state will be preserved between occurrences of the mode.</dd> |
| 87 | + <dt><code>indent</code></dt> |
| 88 | + <dd>When true, this token changes the indentation to be one unit |
| 89 | + more than the current line's indentation.</dd> |
| 90 | + <dt><code>dedent</code></dt> |
| 91 | + <dd>When true, this token will pop one scope off the indentation |
| 92 | + stack.</dd> |
| 93 | + <dt><code>dedentIfLineStart</code></dt> |
| 94 | + <dd>If a token has its <code>dedent</code> property set, it will, by |
| 95 | + default, cause lines where it appears at the start to be dedented. |
| 96 | + Set this property to false to prevent that behavior.</dd> |
| 97 | +</dl> |
| 98 | + |
| 99 | +<p>The <code>meta</code> property of the states object is special, and |
| 100 | +will not be interpreted as a state. Instead, properties set on it will |
| 101 | +be set on the mode, which is useful for properties |
| 102 | +like <a href="../doc/manual.html#addon_comment"><code>lineComment</code></a>, |
| 103 | +which sets the comment style for a mode. The simple mode addon also |
| 104 | +recognizes a few such properties:</p> |
| 105 | + |
| 106 | +<dl> |
| 107 | + <dt><code>dontIndentStates</code></dt> |
| 108 | + <dd>An array of states in which the mode's auto-indentation should |
| 109 | + not take effect. Usually used for multi-line comment and string |
| 110 | + states.</dd> |
| 111 | +</dl> |
| 112 | + |
| 113 | +<script id="modecode">/* Example definition of a simple mode that understands a subset of |
| 114 | + * JavaScript: |
| 115 | + */ |
| 116 | + |
| 117 | +CodeMirror.defineSimpleMode("simplemode", { |
| 118 | + // The start state contains the rules that are intially used |
| 119 | + start: [ |
| 120 | + // The regex matches the token, the token property contains the type |
| 121 | + {regex: /"(?:[^\\]|\\.)*?"/, token: "string"}, |
| 122 | + // You can match multiple tokens at once. Note that the captured |
| 123 | + // groups must span the whole string in this case |
| 124 | + {regex: /(function)(\s+)([a-z$][\w$]*)/, |
| 125 | + token: ["keyword", null, "variable-2"]}, |
| 126 | + // Rules are matched in the order in which they appear, so there is |
| 127 | + // no ambiguity between this one and the one above |
| 128 | + {regex: /(?:function|var|return|if|for|while|else|do|this)\b/, |
| 129 | + token: "keyword"}, |
| 130 | + {regex: /true|false|null|undefined/, token: "atom"}, |
| 131 | + {regex: /0x[a-f\d]+|[-+]?(?:\.\d+|\d+\.?\d*)(?:e[-+]?\d+)?/i, |
| 132 | + token: "number"}, |
| 133 | + {regex: /\/\/.*/, token: "comment"}, |
| 134 | + {regex: /\/(?:[^\\]|\\.)*?\//, token: "variable-3"}, |
| 135 | + // A next property will cause the mode to move to a different state |
| 136 | + {regex: /\/\*/, token: "comment", next: "comment"}, |
| 137 | + {regex: /[-+\/*=<>!]+/, token: "operator"}, |
| 138 | + // indent and dedent properties guide autoindentation |
| 139 | + {regex: /[\{\[\(]/, indent: true}, |
| 140 | + {regex: /[\}\]\)]/, dedent: true}, |
| 141 | + {regex: /[a-z$][\w$]*/, token: "variable"}, |
| 142 | + // You can embed other modes with the mode property. This rule |
| 143 | + // causes all code between << and >> to be highlighted with the XML |
| 144 | + // mode. |
| 145 | + {regex: /<</, token: "meta", mode: {spec: "xml", end: />>/}} |
| 146 | + ], |
| 147 | + // The multi-line comment state. |
| 148 | + comment: [ |
| 149 | + {regex: /.*?\*\//, token: "comment", next: "start"}, |
| 150 | + {regex: /.*/, token: "comment"} |
| 151 | + ], |
| 152 | + // The meta property contains global information about the mode. It |
| 153 | + // can contain properties like lineComment, which are supported by |
| 154 | + // all modes, and also directives like dontIndentStates, which are |
| 155 | + // specific to simple modes. |
| 156 | + meta: { |
| 157 | + dontIndentStates: ["comment"], |
| 158 | + lineComment: "//" |
| 159 | + } |
| 160 | +}); |
| 161 | +</script> |
| 162 | + |
| 163 | +<script> |
| 164 | +var sc = document.getElementById("modecode"); |
| 165 | +var code = document.getElementById("code"); |
| 166 | +var editor = CodeMirror(code, { |
| 167 | + value: (sc.textContent || sc.innerText || sc.innerHTML), |
| 168 | + mode: "simplemode" |
| 169 | +}); |
| 170 | +</script> |
| 171 | + |
| 172 | +</article> |
0 commit comments