Skip to content
Snippets Groups Projects
Commit e1a1e131 authored by Marijn Haverbeke's avatar Marijn Haverbeke
Browse files

Add a mode multiplexer utility script

parent c497aa6c
No related branches found
No related tags found
No related merge requests found
<!doctype html>
<html>
<head>
<title>CodeMirror: Multiplexing Parser Demo</title>
<link rel="stylesheet" href="../lib/codemirror.css">
<script src="../lib/codemirror.js"></script>
<script src="../lib/util/multiplex.js"></script>
<script src="../mode/xml/xml.js"></script>
<link rel="stylesheet" href="../doc/docs.css">
<style type="text/css">
.CodeMirror {border: 1px solid black;}
.cm-delimit {color: #fa4;}
</style>
</head>
<body>
<h1>CodeMirror: Multiplexing Parser Demo</h1>
<form><textarea id="code" name="code">
<html>
<body>
<h1><< this is not <html >></h1>
<<
multiline
not html
at all : &amp;amp; <link/>
>>
<p>this is html again</p>
</body>
</html>
</textarea></form>
<script>
CodeMirror.defineMode("demo", function(config) {
return CodeMirror.multiplexingMode(
CodeMirror.getMode(config, "text/html"),
{open: "<<", close: ">>",
mode: CodeMirror.getMode(config, "text/plain"),
delimStyle: "delimit"}
// .. more multiplexed styles can follow here
);
});
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
mode: "demo",
lineNumbers: true,
lineWrapping: true
});
</script>
<p>Demonstration of a mode that parses HTML, highlighting
the <a href="http://mustache.github.com/">Mustache</a> templating
directives inside of it by using the code
in <a href="../lib/util/overlay.js"><code>overlay.js</code></a>. View
source to see the 15 lines of code needed to accomplish this.</p>
</body>
</html>
......@@ -42,7 +42,7 @@ CodeMirror.defineMode("mustache", function(config, parserConfig) {
return null;
}
};
return CodeMirror.overlayParser(CodeMirror.getMode(config, parserConfig.backdrop || "text/html"), mustacheOverlay);
return CodeMirror.overlayMode(CodeMirror.getMode(config, parserConfig.backdrop || "text/html"), mustacheOverlay);
});
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {mode: "mustache"});
</script>
......
......@@ -820,6 +820,31 @@
actually opening an editor instance.
See <a href="../demo/runmode.html">the demo</a> for an
example.</dd>
<dt id="util_overlay"><a href="../lib/util/overlay.js"><code>overlay.js</code></a></dt>
<dd>Mode combinator that can be used to extend a mode with an
'overlay' — a secondary mode is run over the stream, along with
the base mode, and can color specific pieces of text without
interfering with the base mode.
Defines <code>CodeMirror.overlayMode</code>, which is used to
create such a mode. See <a href="../demo/mustache.html">this
demo</a> for a detailed example.</dd>
<dt id="util_multiple"><a href="../lib/util/multiplex.js"><code>multiplex.js</code></a></dt>
<dd>Mode combinator that can be used to easily 'multiplex'
between several modes.
Defines <code>CodeMirror.multiplexingMode</code> which, when
given as first argument a mode object, and as other arguments
any number of <code>{open, close, mode [, delimStyle]}</code>
objects, will return a mode object that starts parsing using the
mode passed as first argument, but will switch to another mode
as soon as it encounters a string that occurs in one of
the <code>open</code> fields of the passed objects. When in a
sub-mode, it will go back to the top mode again when
the <code>close</code> string is encountered.
When <code>delimStyle</code> is specified, it will be the token
style returned for the delimiter tokens. The outer mode will not
see the content between the delimiters.
See <a href="../demo/multiplex.html">this demo</a> for an
example.</dd>
<dt id="util_simple-hint"><a href="../lib/util/simple-hint.js"><code>simple-hint.js</code></a></dt>
<dd>Provides a framework for showing autocompletion hints.
Defines <code>CodeMirror.simpleHint</code>, which takes a
......
CodeMirror.multiplexingMode = function(outer /*, others */) {
// Others should be {open, close, mode [, delimStyle]} objects
var others = Array.prototype.slice.call(arguments, 1);
var n_others = others.length;
return {
startState: function() {
return {
outer: CodeMirror.startState(outer),
innerActive: null,
inner: null
};
},
copyState: function(state) {
return {
outer: CodeMirror.copyState(outer, state.outer),
innerActive: state.innerActive,
inner: state.innerActive && CodeMirror.copyState(state.innerActive.mode, state.inner)
};
},
token: function(stream, state) {
if (!state.innerActive) {
for (var i = 0; i < n_others; ++i) {
var other = others[i];
if (stream.match(other.open)) {
state.innerActive = other;
state.inner = CodeMirror.startState(other.mode);
return other.delimStyle;
}
}
var outerToken = outer.token(stream, state.outer);
var cur = stream.current();
for (var i = 0; i < n_others; ++i) {
var other = others[i], found = cur.indexOf(other.open);
if (found > -1) {
stream.backUp(cur.length - found);
cur = cur.slice(0, found);
}
}
return outerToken;
} else {
var curInner = state.innerActive;
if (stream.match(curInner.close)) {
state.innerActive = state.inner = null;
return curInner.delimStyle;
}
var innerToken = curInner.mode.token(stream, state.inner);
var cur = stream.current(), found = cur.indexOf(curInner.close);
if (found > -1) stream.backUp(cur.length - found);
return innerToken;
}
},
indent: function(state, textAfter) {
var mode = state.innerActive || outer;
if (!mode.indent) return CodeMirror.Pass;
return mode.indent(state.innerActive ? state.inner : state.outer, textAfter);
},
compareStates: function(a, b) {
if (a.innerActive != b.innerActive) return false;
var mode = a.innerActive || outer;
if (!mode.compareStates) return CodeMirror.Pass;
return mode.compareStates(a.innerActive ? a.inner : a.outer,
b.innerActive ? b.inner : b.outer);
},
electricChars: outer.electricChars
};
};
......@@ -6,7 +6,8 @@
// overlay wins, unless the combine argument was true, in which case
// the styles are combined.
CodeMirror.overlayParser = function(base, overlay, combine) {
// overlayParser is the old, deprecated name
CodeMirror.overlayMode = CodeMirror.overlayParser = function(base, overlay, combine) {
return {
startState: function() {
return {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment