scripts/CodeMirror/mode/mscgen/mscgen.js (view raw)
1// CodeMirror, copyright (c) by Marijn Haverbeke and others
2// Distributed under an MIT license: https://codemirror.net/LICENSE
3
4// mode(s) for the sequence chart dsl's mscgen, xù and msgenny
5// For more information on mscgen, see the site of the original author:
6// http://www.mcternan.me.uk/mscgen
7//
8// This mode for mscgen and the two derivative languages were
9// originally made for use in the mscgen_js interpreter
10// (https://sverweij.github.io/mscgen_js)
11
12(function(mod) {
13 if ( typeof exports == "object" && typeof module == "object")// CommonJS
14 mod(require("../../lib/codemirror"));
15 else if ( typeof define == "function" && define.amd)// AMD
16 define(["../../lib/codemirror"], mod);
17 else// Plain browser env
18 mod(CodeMirror);
19})(function(CodeMirror) {
20 "use strict";
21
22 var languages = {
23 mscgen: {
24 "keywords" : ["msc"],
25 "options" : ["hscale", "width", "arcgradient", "wordwraparcs"],
26 "constants" : ["true", "false", "on", "off"],
27 "attributes" : ["label", "idurl", "id", "url", "linecolor", "linecolour", "textcolor", "textcolour", "textbgcolor", "textbgcolour", "arclinecolor", "arclinecolour", "arctextcolor", "arctextcolour", "arctextbgcolor", "arctextbgcolour", "arcskip"],
28 "brackets" : ["\\{", "\\}"], // [ and ] are brackets too, but these get handled in with lists
29 "arcsWords" : ["note", "abox", "rbox", "box"],
30 "arcsOthers" : ["\\|\\|\\|", "\\.\\.\\.", "---", "--", "<->", "==", "<<=>>", "<=>", "\\.\\.", "<<>>", "::", "<:>", "->", "=>>", "=>", ">>", ":>", "<-", "<<=", "<=", "<<", "<:", "x-", "-x"],
31 "singlecomment" : ["//", "#"],
32 "operators" : ["="]
33 },
34 xu: {
35 "keywords" : ["msc", "xu"],
36 "options" : ["hscale", "width", "arcgradient", "wordwraparcs", "wordwrapentities", "watermark"],
37 "constants" : ["true", "false", "on", "off", "auto"],
38 "attributes" : ["label", "idurl", "id", "url", "linecolor", "linecolour", "textcolor", "textcolour", "textbgcolor", "textbgcolour", "arclinecolor", "arclinecolour", "arctextcolor", "arctextcolour", "arctextbgcolor", "arctextbgcolour", "arcskip", "title", "deactivate", "activate", "activation"],
39 "brackets" : ["\\{", "\\}"], // [ and ] are brackets too, but these get handled in with lists
40 "arcsWords" : ["note", "abox", "rbox", "box", "alt", "else", "opt", "break", "par", "seq", "strict", "neg", "critical", "ignore", "consider", "assert", "loop", "ref", "exc"],
41 "arcsOthers" : ["\\|\\|\\|", "\\.\\.\\.", "---", "--", "<->", "==", "<<=>>", "<=>", "\\.\\.", "<<>>", "::", "<:>", "->", "=>>", "=>", ">>", ":>", "<-", "<<=", "<=", "<<", "<:", "x-", "-x"],
42 "singlecomment" : ["//", "#"],
43 "operators" : ["="]
44 },
45 msgenny: {
46 "keywords" : null,
47 "options" : ["hscale", "width", "arcgradient", "wordwraparcs", "wordwrapentities", "watermark"],
48 "constants" : ["true", "false", "on", "off", "auto"],
49 "attributes" : null,
50 "brackets" : ["\\{", "\\}"],
51 "arcsWords" : ["note", "abox", "rbox", "box", "alt", "else", "opt", "break", "par", "seq", "strict", "neg", "critical", "ignore", "consider", "assert", "loop", "ref", "exc"],
52 "arcsOthers" : ["\\|\\|\\|", "\\.\\.\\.", "---", "--", "<->", "==", "<<=>>", "<=>", "\\.\\.", "<<>>", "::", "<:>", "->", "=>>", "=>", ">>", ":>", "<-", "<<=", "<=", "<<", "<:", "x-", "-x"],
53 "singlecomment" : ["//", "#"],
54 "operators" : ["="]
55 }
56 }
57
58 CodeMirror.defineMode("mscgen", function(_, modeConfig) {
59 var language = languages[modeConfig && modeConfig.language || "mscgen"]
60 return {
61 startState: startStateFn,
62 copyState: copyStateFn,
63 token: produceTokenFunction(language),
64 lineComment : "#",
65 blockCommentStart : "/*",
66 blockCommentEnd : "*/"
67 };
68 });
69
70 CodeMirror.defineMIME("text/x-mscgen", "mscgen");
71 CodeMirror.defineMIME("text/x-xu", {name: "mscgen", language: "xu"});
72 CodeMirror.defineMIME("text/x-msgenny", {name: "mscgen", language: "msgenny"});
73
74 function wordRegexpBoundary(pWords) {
75 return new RegExp("\\b(" + pWords.join("|") + ")\\b", "i");
76 }
77
78 function wordRegexp(pWords) {
79 return new RegExp("(" + pWords.join("|") + ")", "i");
80 }
81
82 function startStateFn() {
83 return {
84 inComment : false,
85 inString : false,
86 inAttributeList : false,
87 inScript : false
88 };
89 }
90
91 function copyStateFn(pState) {
92 return {
93 inComment : pState.inComment,
94 inString : pState.inString,
95 inAttributeList : pState.inAttributeList,
96 inScript : pState.inScript
97 };
98 }
99
100 function produceTokenFunction(pConfig) {
101
102 return function(pStream, pState) {
103 if (pStream.match(wordRegexp(pConfig.brackets), true, true)) {
104 return "bracket";
105 }
106 /* comments */
107 if (!pState.inComment) {
108 if (pStream.match(/\/\*[^\*\/]*/, true, true)) {
109 pState.inComment = true;
110 return "comment";
111 }
112 if (pStream.match(wordRegexp(pConfig.singlecomment), true, true)) {
113 pStream.skipToEnd();
114 return "comment";
115 }
116 }
117 if (pState.inComment) {
118 if (pStream.match(/[^\*\/]*\*\//, true, true))
119 pState.inComment = false;
120 else
121 pStream.skipToEnd();
122 return "comment";
123 }
124 /* strings */
125 if (!pState.inString && pStream.match(/\"(\\\"|[^\"])*/, true, true)) {
126 pState.inString = true;
127 return "string";
128 }
129 if (pState.inString) {
130 if (pStream.match(/[^\"]*\"/, true, true))
131 pState.inString = false;
132 else
133 pStream.skipToEnd();
134 return "string";
135 }
136 /* keywords & operators */
137 if (!!pConfig.keywords && pStream.match(wordRegexpBoundary(pConfig.keywords), true, true))
138 return "keyword";
139
140 if (pStream.match(wordRegexpBoundary(pConfig.options), true, true))
141 return "keyword";
142
143 if (pStream.match(wordRegexpBoundary(pConfig.arcsWords), true, true))
144 return "keyword";
145
146 if (pStream.match(wordRegexp(pConfig.arcsOthers), true, true))
147 return "keyword";
148
149 if (!!pConfig.operators && pStream.match(wordRegexp(pConfig.operators), true, true))
150 return "operator";
151
152 if (!!pConfig.constants && pStream.match(wordRegexp(pConfig.constants), true, true))
153 return "variable";
154
155 /* attribute lists */
156 if (!pConfig.inAttributeList && !!pConfig.attributes && pStream.match(/\[/, true, true)) {
157 pConfig.inAttributeList = true;
158 return "bracket";
159 }
160 if (pConfig.inAttributeList) {
161 if (pConfig.attributes !== null && pStream.match(wordRegexpBoundary(pConfig.attributes), true, true)) {
162 return "attribute";
163 }
164 if (pStream.match(/]/, true, true)) {
165 pConfig.inAttributeList = false;
166 return "bracket";
167 }
168 }
169
170 pStream.next();
171 return "base";
172 };
173 }
174
175});