asterisk.js 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. /*
  2. * =====================================================================================
  3. *
  4. * Filename: mode/asterisk/asterisk.js
  5. *
  6. * Description: CodeMirror mode for Asterisk dialplan
  7. *
  8. * Created: 05/17/2012 09:20:25 PM
  9. * Revision: none
  10. *
  11. * Author: Stas Kobzar (stas@modulis.ca),
  12. * Company: Modulis.ca Inc.
  13. *
  14. * =====================================================================================
  15. */
  16. (function(mod) {
  17. if (typeof exports == "object" && typeof module == "object") // CommonJS
  18. mod(require("../../lib/codemirror"));
  19. else if (typeof define == "function" && define.amd) // AMD
  20. define(["../../lib/codemirror"], mod);
  21. else // Plain browser env
  22. mod(CodeMirror);
  23. })(function(CodeMirror) {
  24. "use strict";
  25. CodeMirror.defineMode("asterisk", function() {
  26. var atoms = ["exten", "same", "include","ignorepat","switch"],
  27. dpcmd = ["#include","#exec"],
  28. apps = [
  29. "addqueuemember","adsiprog","aelsub","agentlogin","agentmonitoroutgoing","agi",
  30. "alarmreceiver","amd","answer","authenticate","background","backgrounddetect",
  31. "bridge","busy","callcompletioncancel","callcompletionrequest","celgenuserevent",
  32. "changemonitor","chanisavail","channelredirect","chanspy","clearhash","confbridge",
  33. "congestion","continuewhile","controlplayback","dahdiacceptr2call","dahdibarge",
  34. "dahdiras","dahdiscan","dahdisendcallreroutingfacility","dahdisendkeypadfacility",
  35. "datetime","dbdel","dbdeltree","deadagi","dial","dictate","directory","disa",
  36. "dumpchan","eagi","echo","endwhile","exec","execif","execiftime","exitwhile","extenspy",
  37. "externalivr","festival","flash","followme","forkcdr","getcpeid","gosub","gosubif",
  38. "goto","gotoif","gotoiftime","hangup","iax2provision","ices","importvar","incomplete",
  39. "ivrdemo","jabberjoin","jabberleave","jabbersend","jabbersendgroup","jabberstatus",
  40. "jack","log","macro","macroexclusive","macroexit","macroif","mailboxexists","meetme",
  41. "meetmeadmin","meetmechanneladmin","meetmecount","milliwatt","minivmaccmess","minivmdelete",
  42. "minivmgreet","minivmmwi","minivmnotify","minivmrecord","mixmonitor","monitor","morsecode",
  43. "mp3player","mset","musiconhold","nbscat","nocdr","noop","odbc","odbc","odbcfinish",
  44. "originate","ospauth","ospfinish","osplookup","ospnext","page","park","parkandannounce",
  45. "parkedcall","pausemonitor","pausequeuemember","pickup","pickupchan","playback","playtones",
  46. "privacymanager","proceeding","progress","queue","queuelog","raiseexception","read","readexten",
  47. "readfile","receivefax","receivefax","receivefax","record","removequeuemember",
  48. "resetcdr","retrydial","return","ringing","sayalpha","saycountedadj","saycountednoun",
  49. "saycountpl","saydigits","saynumber","sayphonetic","sayunixtime","senddtmf","sendfax",
  50. "sendfax","sendfax","sendimage","sendtext","sendurl","set","setamaflags",
  51. "setcallerpres","setmusiconhold","sipaddheader","sipdtmfmode","sipremoveheader","skel",
  52. "slastation","slatrunk","sms","softhangup","speechactivategrammar","speechbackground",
  53. "speechcreate","speechdeactivategrammar","speechdestroy","speechloadgrammar","speechprocessingsound",
  54. "speechstart","speechunloadgrammar","stackpop","startmusiconhold","stopmixmonitor","stopmonitor",
  55. "stopmusiconhold","stopplaytones","system","testclient","testserver","transfer","tryexec",
  56. "trysystem","unpausemonitor","unpausequeuemember","userevent","verbose","vmauthenticate",
  57. "vmsayname","voicemail","voicemailmain","wait","waitexten","waitfornoise","waitforring",
  58. "waitforsilence","waitmusiconhold","waituntil","while","zapateller"
  59. ];
  60. function basicToken(stream,state){
  61. var cur = '';
  62. var ch = '';
  63. ch = stream.next();
  64. // comment
  65. if(ch == ";") {
  66. stream.skipToEnd();
  67. return "comment";
  68. }
  69. // context
  70. if(ch == '[') {
  71. stream.skipTo(']');
  72. stream.eat(']');
  73. return "header";
  74. }
  75. // string
  76. if(ch == '"') {
  77. stream.skipTo('"');
  78. return "string";
  79. }
  80. if(ch == "'") {
  81. stream.skipTo("'");
  82. return "string-2";
  83. }
  84. // dialplan commands
  85. if(ch == '#') {
  86. stream.eatWhile(/\w/);
  87. cur = stream.current();
  88. if(dpcmd.indexOf(cur) !== -1) {
  89. stream.skipToEnd();
  90. return "strong";
  91. }
  92. }
  93. // application args
  94. if(ch == '$'){
  95. var ch1 = stream.peek();
  96. if(ch1 == '{'){
  97. stream.skipTo('}');
  98. stream.eat('}');
  99. return "variable-3";
  100. }
  101. }
  102. // extension
  103. stream.eatWhile(/\w/);
  104. cur = stream.current();
  105. if(atoms.indexOf(cur) !== -1) {
  106. state.extenStart = true;
  107. switch(cur) {
  108. case 'same': state.extenSame = true; break;
  109. case 'include':
  110. case 'switch':
  111. case 'ignorepat':
  112. state.extenInclude = true;break;
  113. default:break;
  114. }
  115. return "atom";
  116. }
  117. }
  118. return {
  119. startState: function() {
  120. return {
  121. extenStart: false,
  122. extenSame: false,
  123. extenInclude: false,
  124. extenExten: false,
  125. extenPriority: false,
  126. extenApplication: false
  127. };
  128. },
  129. token: function(stream, state) {
  130. var cur = '';
  131. var ch = '';
  132. if(stream.eatSpace()) return null;
  133. // extension started
  134. if(state.extenStart){
  135. stream.eatWhile(/[^\s]/);
  136. cur = stream.current();
  137. if(/^=>?$/.test(cur)){
  138. state.extenExten = true;
  139. state.extenStart = false;
  140. return "strong";
  141. } else {
  142. state.extenStart = false;
  143. stream.skipToEnd();
  144. return "error";
  145. }
  146. } else if(state.extenExten) {
  147. // set exten and priority
  148. state.extenExten = false;
  149. state.extenPriority = true;
  150. stream.eatWhile(/[^,]/);
  151. if(state.extenInclude) {
  152. stream.skipToEnd();
  153. state.extenPriority = false;
  154. state.extenInclude = false;
  155. }
  156. if(state.extenSame) {
  157. state.extenPriority = false;
  158. state.extenSame = false;
  159. state.extenApplication = true;
  160. }
  161. return "tag";
  162. } else if(state.extenPriority) {
  163. state.extenPriority = false;
  164. state.extenApplication = true;
  165. ch = stream.next(); // get comma
  166. if(state.extenSame) return null;
  167. stream.eatWhile(/[^,]/);
  168. return "number";
  169. } else if(state.extenApplication) {
  170. stream.eatWhile(/,/);
  171. cur = stream.current();
  172. if(cur === ',') return null;
  173. stream.eatWhile(/\w/);
  174. cur = stream.current().toLowerCase();
  175. state.extenApplication = false;
  176. if(apps.indexOf(cur) !== -1){
  177. return "def strong";
  178. }
  179. } else{
  180. return basicToken(stream,state);
  181. }
  182. return null;
  183. }
  184. };
  185. });
  186. CodeMirror.defineMIME("text/x-asterisk", "asterisk");
  187. });