Skip to content

Commit e9d562d

Browse files
author
Christophe Gragnic
committed
Add clubexpr mode
1 parent 7ae9e75 commit e9d562d

File tree

3 files changed

+176
-0
lines changed

3 files changed

+176
-0
lines changed

mode/clubexpr/clubexpr.css

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
.CodeMirror {
2+
font-size: 100%;
3+
height: 5em;
4+
border: 1px solid #999;
5+
}
6+
7+
.cm-bracket-1 {background: #fab;}
8+
.cm-bracket-2 {background: #fdb;}
9+
.cm-bracket-3 {background: #ffd;}
10+
.cm-bracket-4 {background: #dfb;}
11+
.cm-bracket-5 {background: #cef;}
12+
.cm-bracket-6 {background: #dcf;}
13+
.cm-bracket-0 {background: #bbe;}
14+
15+
.cm-error {
16+
color: black !important;
17+
border-bottom: solid 3px red;
18+
}
19+
20+
.CodeMirror-cursor {
21+
width: 0.6em;
22+
background-color: #ffff0070;
23+
}
24+
25+
.CodeMirror-matchingbracket {
26+
background-color: #00ffff;
27+
color: black !important;
28+
}

mode/clubexpr/clubexpr.js

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
// CodeMirror, copyright (c) by Marijn Haverbeke and others
2+
// Distributed under an MIT license: http://codemirror.net/LICENSE
3+
4+
// Copy-pasted from the Common Lisp mode, then tweaked for rainbow parens.
5+
6+
(function(mod) {
7+
if (typeof exports == "object" && typeof module == "object") // CommonJS
8+
mod(require("../../lib/codemirror"));
9+
else if (typeof define == "function" && define.amd) // AMD
10+
define(["../../lib/codemirror"], mod);
11+
else // Plain browser env
12+
mod(CodeMirror);
13+
})(function(CodeMirror) {
14+
"use strict";
15+
16+
CodeMirror.defineMode("clubexpr", function (config) {
17+
var command = /^Somme$|^Diff$|^Produit$|^Quotient$|^Opposé$|^Inverse$|^Carré$|^Puissance$|^Racine$/;
18+
var letter = /^[a-zA-Z]$/;
19+
var greek = /^alpha$|^beta$|^gamma$|^delta$|^epsilon$|^zeta$|^eta$|^theta$|^iota$|^kappa$|^lambda$|^mu$|^nu$|^xi$|^omicron$|^pi$|^rho$|^sigmaf$|^sigma$|^tau$|^upsilon$|^phi$|^chi$|^psi$|^omega$/;
20+
var numLiteral = /^[-]?[0-9]+[^a-zA-Z]|^[+-]?[0-9]+[.,]?[0-9]+[^a-zA-Z]/;
21+
var symbol = /[^\s'`,@()\[\]";]/;
22+
var type;
23+
24+
function readSym(stream) {
25+
var ch;
26+
while (ch = stream.next()) {
27+
if (ch == "\\") stream.next();
28+
else if (!symbol.test(ch)) { stream.backUp(1); break; }
29+
}
30+
return stream.current();
31+
}
32+
33+
function base(stream, state) {
34+
if (stream.eatSpace()) {
35+
type = "ws";
36+
return null;
37+
}
38+
if (stream.match(numLiteral)) {
39+
return "number";
40+
}
41+
var ch = stream.next();
42+
if (ch == "\\") {
43+
ch = stream.next();
44+
}
45+
if (ch == "(") {
46+
type = "open";
47+
return "bracket-" + state.parenDepth;
48+
} else if (ch == ")") {
49+
type = "close";
50+
return "bracket-" + (state.parenDepth + 6)%7;
51+
} else {
52+
var name = readSym(stream);
53+
if (state.lastType == "open") {
54+
if (command.test(name)) return "keyword";
55+
} else if (letter.test(name)) {
56+
return "variable";
57+
} else if (greek.test(name)) {
58+
return "variable-2";
59+
}
60+
return "error";
61+
}
62+
}
63+
64+
return {
65+
startState: function () {
66+
return {ctx: {prev: null, start: 0, indentTo: 0},
67+
lastType: null, tokenize: base, parenDepth: 1};
68+
},
69+
70+
token: function (stream, state) {
71+
if (stream.sol() && typeof state.ctx.indentTo != "number")
72+
state.ctx.indentTo = state.ctx.start + 1;
73+
74+
type = null;
75+
var style = state.tokenize(stream, state);
76+
if (type != "ws") {
77+
if (state.ctx.indentTo == null) {
78+
if (type == "symbol" && command.test(stream.current()))
79+
state.ctx.indentTo = state.ctx.start + config.indentUnit;
80+
else
81+
state.ctx.indentTo = "next";
82+
} else if (state.ctx.indentTo == "next") {
83+
state.ctx.indentTo = stream.column();
84+
}
85+
state.lastType = type;
86+
}
87+
if (type == "open") {
88+
state.ctx = {prev: state.ctx, start: stream.column(), indentTo: null};
89+
state.parenDepth = (state.parenDepth + 1)%7;
90+
} else if (type == "close") {
91+
state.ctx = state.ctx.prev || state.ctx;
92+
// +6 instead of -1 to avoid negative depth
93+
state.parenDepth = (state.parenDepth + 6)%7;
94+
}
95+
return style;
96+
},
97+
98+
indent: function (state, _textAfter) {
99+
var i = state.ctx.indentTo;
100+
return typeof i == "number" ? i : state.ctx.start + 1;
101+
},
102+
103+
closeBrackets: {pairs: "()"}
104+
};
105+
});
106+
107+
CodeMirror.defineMIME("text/x-clubexpr", "clubexpr");
108+
109+
});

mode/clubexpr/index.html

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<!doctype html>
2+
3+
<title>CodeMirror: ClubExpr mode</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/edit/matchbrackets.js"></script>
10+
<script src="clubexpr.js"></script>
11+
<style>.CodeMirror {background: #f8f8f8;}</style>
12+
<link rel="stylesheet" href="clubexpr.css">
13+
<div id=nav>
14+
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
15+
16+
<ul>
17+
<li><a href="../../index.html">Home</a>
18+
<li><a href="../../doc/manual.html">Manual</a>
19+
<li><a href="https://github.com/codemirror/codemirror">Code</a>
20+
</ul>
21+
<ul>
22+
<li><a href="../index.html">Language modes</a>
23+
<li><a class=active href="#">ClubExpr</a>
24+
</ul>
25+
</div>
26+
27+
<article>
28+
<h2>ClubExpr mode</h2>
29+
<form><textarea id="code" name="code">(Somme 1 (Produit x phi))
30+
(Somm 2x ph)
31+
(Somme 1 (Somme 2 (Somme 3 (Somme 4 (Somme 5 (Somme 6 (Somme 7)))))))
32+
</textarea></form>
33+
<script>
34+
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {lineNumbers: true, matchBrackets: true});
35+
</script>
36+
37+
<p><strong>MIME types defined:</strong> <code>text/x-clubexpr</code>.</p>
38+
39+
</article>

0 commit comments

Comments
 (0)