asterisk.js 6.9 KB

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