Skip to content

Commit be36e3e

Browse files
grzegorzmazurmarijnh
authored andcommitted
[yacas mode] Add
1 parent 6fa5752 commit be36e3e

File tree

4 files changed

+227
-0
lines changed

4 files changed

+227
-0
lines changed

mode/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ <h2>Language modes</h2>
151151
<li><a href="vue/index.html">Vue.js app</a></li>
152152
<li><a href="xml/index.html">XML/HTML</a></li>
153153
<li><a href="xquery/index.html">XQuery</a></li>
154+
<li><a href="yacas/index.html">Yacas</a></li>
154155
<li><a href="yaml/index.html">YAML</a></li>
155156
<li><a href="yaml-frontmatter/index.html">YAML frontmatter</a></li>
156157
<li><a href="z80/index.html">Z80</a></li>

mode/meta.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@
152152
{name: "VHDL", mime: "text/x-vhdl", mode: "vhdl", ext: ["vhd", "vhdl"]},
153153
{name: "XML", mimes: ["application/xml", "text/xml"], mode: "xml", ext: ["xml", "xsl", "xsd"], alias: ["rss", "wsdl", "xsd"]},
154154
{name: "XQuery", mime: "application/xquery", mode: "xquery", ext: ["xy", "xquery"]},
155+
{name: "Yacas", mime: "text/x-yacas", mode: "yacas", ext: ["ys"]},
155156
{name: "YAML", mime: "text/x-yaml", mode: "yaml", ext: ["yaml", "yml"], alias: ["yml"]},
156157
{name: "Z80", mime: "text/x-z80", mode: "z80", ext: ["z80"]},
157158
{name: "mscgen", mime: "text/x-mscgen", mode: "mscgen", ext: ["mscgen", "mscin", "msc"]},

mode/yacas/index.html

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
<!doctype html>
2+
3+
<title>CodeMirror: yacas 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=yacas.js></script>
11+
<style type=text/css>
12+
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
13+
</style>
14+
<div id=nav>
15+
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
16+
17+
<ul>
18+
<li><a href="../../index.html">Home</a>
19+
<li><a href="../../doc/manual.html">Manual</a>
20+
<li><a href="https://github.com/codemirror/codemirror">Code</a>
21+
</ul>
22+
<ul>
23+
<li><a href="../index.html">Language modes</a>
24+
<li><a class=active href="#">yacas</a>
25+
</ul>
26+
</div>
27+
28+
<article>
29+
<h2>yacas mode</h2>
30+
31+
32+
<textarea id="yacasCode">
33+
// example yacas code
34+
Graph(edges_IsList) <-- [
35+
Local(v, e, f, t);
36+
37+
vertices := {};
38+
39+
ForEach (e, edges) [
40+
If (IsList(e), e := Head(e));
41+
{f, t} := Tail(Listify(e));
42+
43+
DestructiveAppend(vertices, f);
44+
DestructiveAppend(vertices, t);
45+
];
46+
47+
Graph(RemoveDuplicates(vertices), edges);
48+
];
49+
50+
10 # IsGraph(Graph(vertices_IsList, edges_IsList)) <-- True;
51+
20 # IsGraph(_x) <-- False;
52+
53+
Edges(Graph(vertices_IsList, edges_IsList)) <-- edges;
54+
Vertices(Graph(vertices_IsList, edges_IsList)) <-- vertices;
55+
56+
AdjacencyList(g_IsGraph) <-- [
57+
Local(l, vertices, edges, e, op, f, t);
58+
59+
l := Association'Create();
60+
61+
vertices := Vertices(g);
62+
ForEach (v, vertices)
63+
Association'Set(l, v, {});
64+
65+
edges := Edges(g);
66+
67+
ForEach(e, edges) [
68+
If (IsList(e), e := Head(e));
69+
{op, f, t} := Listify(e);
70+
DestructiveAppend(Association'Get(l, f), t);
71+
If (String(op) = "<->", DestructiveAppend(Association'Get(l, t), f));
72+
];
73+
74+
l;
75+
];
76+
</textarea>
77+
78+
<script>
79+
var yacasEditor = CodeMirror.fromTextArea(document.getElementById('yacasCode'), {
80+
mode: 'text/x-yacas',
81+
lineNumbers: true,
82+
matchBrackets: true
83+
});
84+
</script>
85+
86+
<p><strong>MIME types defined:</strong> <code>text/x-yacas</code> (yacas).</p>
87+
</article>

mode/yacas/yacas.js

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
// CodeMirror, copyright (c) by Marijn Haverbeke and others
2+
// Distributed under an MIT license: http://codemirror.net/LICENSE
3+
4+
// Yacas mode copyright (c) 2015 by Grzegorz Mazur
5+
// Loosely based on mathematica mode by Calin Barbat
6+
7+
(function(mod) {
8+
if (typeof exports == "object" && typeof module == "object") // CommonJS
9+
mod(require("../../lib/codemirror"));
10+
else if (typeof define == "function" && define.amd) // AMD
11+
define(["../../lib/codemirror"], mod);
12+
else // Plain browser env
13+
mod(CodeMirror);
14+
})(function(CodeMirror) {
15+
"use strict";
16+
17+
CodeMirror.defineMode('yacas', function(_config, _parserConfig) {
18+
19+
// patterns
20+
var pFloatForm = "(?:(?:\\.\\d+|\\d+\\.\\d*|\\d+)(?:[eE][+-]?\\d+)?)";
21+
var pIdentifier = "(?:[a-zA-Z\\$'][a-zA-Z0-9\\$']*)";
22+
23+
// regular expressions
24+
var reFloatForm = new RegExp(pFloatForm);
25+
var reIdentifier = new RegExp(pIdentifier);
26+
var rePattern = new RegExp(pIdentifier + "?_" + pIdentifier);
27+
var reFunctionLike = new RegExp(pIdentifier + "\\s*\\(");
28+
29+
function tokenBase(stream, state) {
30+
var ch;
31+
32+
// get next character
33+
ch = stream.next();
34+
35+
// string
36+
if (ch === '"') {
37+
state.tokenize = tokenString;
38+
return state.tokenize(stream, state);
39+
}
40+
41+
// comment
42+
if (ch === '/') {
43+
if (stream.eat('*')) {
44+
state.tokenize = tokenComment;
45+
return state.tokenize(stream, state);
46+
}
47+
if (stream.eat("/")) {
48+
stream.skipToEnd();
49+
return "comment";
50+
}
51+
}
52+
53+
// go back one character
54+
stream.backUp(1);
55+
56+
// look for ordered rules
57+
if (stream.match(/\d+ *#/, true, false)) {
58+
return 'qualifier';
59+
}
60+
61+
// look for numbers
62+
if (stream.match(reFloatForm, true, false)) {
63+
return 'number';
64+
}
65+
66+
// look for placeholders
67+
if (stream.match(rePattern, true, false)) {
68+
return 'variable-3';
69+
}
70+
71+
// match all braces separately
72+
if (stream.match(/(?:\[|\]|{|}|\(|\))/, true, false)) {
73+
return 'bracket';
74+
}
75+
76+
// literals looking like function calls
77+
if (stream.match(reFunctionLike, true, false)) {
78+
stream.backUp(1);
79+
return 'variable';
80+
}
81+
82+
// all other identifiers
83+
if (stream.match(reIdentifier, true, false)) {
84+
return 'variable-2';
85+
}
86+
87+
// operators; note that operators like @@ or /; are matched separately for each symbol.
88+
if (stream.match(/(?:\\|\+|\-|\*|\/|,|;|\.|:|@|~|=|>|<|&|\||_|`|'|\^|\?|!|%)/, true, false)) {
89+
return 'operator';
90+
}
91+
92+
// everything else is an error
93+
return 'error';
94+
}
95+
96+
function tokenString(stream, state) {
97+
var next, end = false, escaped = false;
98+
while ((next = stream.next()) != null) {
99+
if (next === '"' && !escaped) {
100+
end = true;
101+
break;
102+
}
103+
escaped = !escaped && next === '\\';
104+
}
105+
if (end && !escaped) {
106+
state.tokenize = tokenBase;
107+
}
108+
return 'string';
109+
};
110+
111+
function tokenComment(stream, state) {
112+
var prev, next;
113+
while((next = stream.next()) != null) {
114+
if (prev === '*' && next === '/')
115+
break;
116+
prev = next;
117+
}
118+
state.tokenize = tokenBase;
119+
return 'comment';
120+
}
121+
122+
return {
123+
startState: function() {return {tokenize: tokenBase, commentLevel: 0};},
124+
token: function(stream, state) {
125+
if (stream.eatSpace()) return null;
126+
return state.tokenize(stream, state);
127+
},
128+
blockCommentStart: "/*",
129+
blockCommentEnd: "*/",
130+
lineComment: "//"
131+
};
132+
});
133+
134+
CodeMirror.defineMIME('text/x-yacas', {
135+
name: 'yacas'
136+
});
137+
138+
});

0 commit comments

Comments
 (0)