diff .cms/lib/codemirror/mode/ebnf/ebnf.js @ 0:78edf6b517a0 draft

24.10
author Coffee CMS <info@coffee-cms.ru>
date Fri, 11 Oct 2024 22:40:23 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.cms/lib/codemirror/mode/ebnf/ebnf.js	Fri Oct 11 22:40:23 2024 +0000
@@ -0,0 +1,195 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/5/LICENSE
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  "use strict";
+
+  CodeMirror.defineMode("ebnf", function (config) {
+    var commentType = {slash: 0, parenthesis: 1};
+    var stateType = {comment: 0, _string: 1, characterClass: 2};
+    var bracesMode = null;
+
+    if (config.bracesMode)
+      bracesMode = CodeMirror.getMode(config, config.bracesMode);
+
+    return {
+      startState: function () {
+        return {
+          stringType: null,
+          commentType: null,
+          braced: 0,
+          lhs: true,
+          localState: null,
+          stack: [],
+          inDefinition: false
+        };
+      },
+      token: function (stream, state) {
+        if (!stream) return;
+
+        //check for state changes
+        if (state.stack.length === 0) {
+          //strings
+          if ((stream.peek() == '"') || (stream.peek() == "'")) {
+            state.stringType = stream.peek();
+            stream.next(); // Skip quote
+            state.stack.unshift(stateType._string);
+          } else if (stream.match('/*')) { //comments starting with /*
+            state.stack.unshift(stateType.comment);
+            state.commentType = commentType.slash;
+          } else if (stream.match('(*')) { //comments starting with (*
+            state.stack.unshift(stateType.comment);
+            state.commentType = commentType.parenthesis;
+          }
+        }
+
+        //return state
+        //stack has
+        switch (state.stack[0]) {
+        case stateType._string:
+          while (state.stack[0] === stateType._string && !stream.eol()) {
+            if (stream.peek() === state.stringType) {
+              stream.next(); // Skip quote
+              state.stack.shift(); // Clear flag
+            } else if (stream.peek() === "\\") {
+              stream.next();
+              stream.next();
+            } else {
+              stream.match(/^.[^\\\"\']*/);
+            }
+          }
+          return state.lhs ? "property string" : "string"; // Token style
+
+        case stateType.comment:
+          while (state.stack[0] === stateType.comment && !stream.eol()) {
+            if (state.commentType === commentType.slash && stream.match('*/')) {
+              state.stack.shift(); // Clear flag
+              state.commentType = null;
+            } else if (state.commentType === commentType.parenthesis && stream.match('*)')) {
+              state.stack.shift(); // Clear flag
+              state.commentType = null;
+            } else {
+              stream.match(/^.[^\*]*/);
+            }
+          }
+          return "comment";
+
+        case stateType.characterClass:
+          while (state.stack[0] === stateType.characterClass && !stream.eol()) {
+            if (!(stream.match(/^[^\]\\]+/) || stream.match('.'))) {
+              state.stack.shift();
+            }
+          }
+          return "operator";
+        }
+
+        var peek = stream.peek();
+
+        if (bracesMode !== null && (state.braced || peek === "{")) {
+          if (state.localState === null)
+            state.localState = CodeMirror.startState(bracesMode);
+
+          var token = bracesMode.token(stream, state.localState),
+          text = stream.current();
+
+          if (!token) {
+            for (var i = 0; i < text.length; i++) {
+              if (text[i] === "{") {
+                if (state.braced === 0) {
+                  token = "matchingbracket";
+                }
+                state.braced++;
+              } else if (text[i] === "}") {
+                state.braced--;
+                if (state.braced === 0) {
+                  token = "matchingbracket";
+                }
+              }
+            }
+          }
+          return token;
+        }
+
+        //no stack
+        switch (peek) {
+        case "[":
+          stream.next();
+          state.stack.unshift(stateType.characterClass);
+          return "bracket";
+        case ":":
+        case "|":
+        case ";":
+          stream.next();
+          return "operator";
+        case "%":
+          if (stream.match("%%")) {
+            return "header";
+          } else if (stream.match(/[%][A-Za-z]+/)) {
+            return "keyword";
+          } else if (stream.match(/[%][}]/)) {
+            return "matchingbracket";
+          }
+          break;
+        case "/":
+          if (stream.match(/[\/][A-Za-z]+/)) {
+          return "keyword";
+        }
+        case "\\":
+          if (stream.match(/[\][a-z]+/)) {
+            return "string-2";
+          }
+        case ".":
+          if (stream.match(".")) {
+            return "atom";
+          }
+        case "*":
+        case "-":
+        case "+":
+        case "^":
+          if (stream.match(peek)) {
+            return "atom";
+          }
+        case "$":
+          if (stream.match("$$")) {
+            return "builtin";
+          } else if (stream.match(/[$][0-9]+/)) {
+            return "variable-3";
+          }
+        case "<":
+          if (stream.match(/<<[a-zA-Z_]+>>/)) {
+            return "builtin";
+          }
+        }
+
+        if (stream.match('//')) {
+          stream.skipToEnd();
+          return "comment";
+        } else if (stream.match('return')) {
+          return "operator";
+        } else if (stream.match(/^[a-zA-Z_][a-zA-Z0-9_]*/)) {
+          if (stream.match(/(?=[\(.])/)) {
+            return "variable";
+          } else if (stream.match(/(?=[\s\n]*[:=])/)) {
+            return "def";
+          }
+          return "variable-2";
+        } else if (["[", "]", "(", ")"].indexOf(stream.peek()) != -1) {
+          stream.next();
+          return "bracket";
+        } else if (!stream.eatSpace()) {
+          stream.next();
+        }
+        return null;
+      }
+    };
+  });
+
+  CodeMirror.defineMIME("text/x-ebnf", "ebnf");
+});