github.com/jancarloviray/community@v0.41.1-0.20170124221257-33a66c87cf2f/app/public/codemirror/mode/dtd/dtd.js (about)

     1  // CodeMirror, copyright (c) by Marijn Haverbeke and others
     2  // Distributed under an MIT license: http://codemirror.net/LICENSE
     3  
     4  /*
     5    DTD mode
     6    Ported to CodeMirror by Peter Kroon <plakroon@gmail.com>
     7    Report bugs/issues here: https://github.com/codemirror/CodeMirror/issues
     8    GitHub: @peterkroon
     9  */
    10  
    11  (function(mod) {
    12    if (typeof exports == "object" && typeof module == "object") // CommonJS
    13      mod(require("../../lib/codemirror"));
    14    else if (typeof define == "function" && define.amd) // AMD
    15      define(["../../lib/codemirror"], mod);
    16    else // Plain browser env
    17      mod(CodeMirror);
    18  })(function(CodeMirror) {
    19  "use strict";
    20  
    21  CodeMirror.defineMode("dtd", function(config) {
    22    var indentUnit = config.indentUnit, type;
    23    function ret(style, tp) {type = tp; return style;}
    24  
    25    function tokenBase(stream, state) {
    26      var ch = stream.next();
    27  
    28      if (ch == "<" && stream.eat("!") ) {
    29        if (stream.eatWhile(/[\-]/)) {
    30          state.tokenize = tokenSGMLComment;
    31          return tokenSGMLComment(stream, state);
    32        } else if (stream.eatWhile(/[\w]/)) return ret("keyword", "doindent");
    33      } else if (ch == "<" && stream.eat("?")) { //xml declaration
    34        state.tokenize = inBlock("meta", "?>");
    35        return ret("meta", ch);
    36      } else if (ch == "#" && stream.eatWhile(/[\w]/)) return ret("atom", "tag");
    37      else if (ch == "|") return ret("keyword", "seperator");
    38      else if (ch.match(/[\(\)\[\]\-\.,\+\?>]/)) return ret(null, ch);//if(ch === ">") return ret(null, "endtag"); else
    39      else if (ch.match(/[\[\]]/)) return ret("rule", ch);
    40      else if (ch == "\"" || ch == "'") {
    41        state.tokenize = tokenString(ch);
    42        return state.tokenize(stream, state);
    43      } else if (stream.eatWhile(/[a-zA-Z\?\+\d]/)) {
    44        var sc = stream.current();
    45        if( sc.substr(sc.length-1,sc.length).match(/\?|\+/) !== null )stream.backUp(1);
    46        return ret("tag", "tag");
    47      } else if (ch == "%" || ch == "*" ) return ret("number", "number");
    48      else {
    49        stream.eatWhile(/[\w\\\-_%.{,]/);
    50        return ret(null, null);
    51      }
    52    }
    53  
    54    function tokenSGMLComment(stream, state) {
    55      var dashes = 0, ch;
    56      while ((ch = stream.next()) != null) {
    57        if (dashes >= 2 && ch == ">") {
    58          state.tokenize = tokenBase;
    59          break;
    60        }
    61        dashes = (ch == "-") ? dashes + 1 : 0;
    62      }
    63      return ret("comment", "comment");
    64    }
    65  
    66    function tokenString(quote) {
    67      return function(stream, state) {
    68        var escaped = false, ch;
    69        while ((ch = stream.next()) != null) {
    70          if (ch == quote && !escaped) {
    71            state.tokenize = tokenBase;
    72            break;
    73          }
    74          escaped = !escaped && ch == "\\";
    75        }
    76        return ret("string", "tag");
    77      };
    78    }
    79  
    80    function inBlock(style, terminator) {
    81      return function(stream, state) {
    82        while (!stream.eol()) {
    83          if (stream.match(terminator)) {
    84            state.tokenize = tokenBase;
    85            break;
    86          }
    87          stream.next();
    88        }
    89        return style;
    90      };
    91    }
    92  
    93    return {
    94      startState: function(base) {
    95        return {tokenize: tokenBase,
    96                baseIndent: base || 0,
    97                stack: []};
    98      },
    99  
   100      token: function(stream, state) {
   101        if (stream.eatSpace()) return null;
   102        var style = state.tokenize(stream, state);
   103  
   104        var context = state.stack[state.stack.length-1];
   105        if (stream.current() == "[" || type === "doindent" || type == "[") state.stack.push("rule");
   106        else if (type === "endtag") state.stack[state.stack.length-1] = "endtag";
   107        else if (stream.current() == "]" || type == "]" || (type == ">" && context == "rule")) state.stack.pop();
   108        else if (type == "[") state.stack.push("[");
   109        return style;
   110      },
   111  
   112      indent: function(state, textAfter) {
   113        var n = state.stack.length;
   114  
   115        if( textAfter.match(/\]\s+|\]/) )n=n-1;
   116        else if(textAfter.substr(textAfter.length-1, textAfter.length) === ">"){
   117          if(textAfter.substr(0,1) === "<")n;
   118          else if( type == "doindent" && textAfter.length > 1 )n;
   119          else if( type == "doindent")n--;
   120          else if( type == ">" && textAfter.length > 1)n;
   121          else if( type == "tag" && textAfter !== ">")n;
   122          else if( type == "tag" && state.stack[state.stack.length-1] == "rule")n--;
   123          else if( type == "tag")n++;
   124          else if( textAfter === ">" && state.stack[state.stack.length-1] == "rule" && type === ">")n--;
   125          else if( textAfter === ">" && state.stack[state.stack.length-1] == "rule")n;
   126          else if( textAfter.substr(0,1) !== "<" && textAfter.substr(0,1) === ">" )n=n-1;
   127          else if( textAfter === ">")n;
   128          else n=n-1;
   129          //over rule them all
   130          if(type == null || type == "]")n--;
   131        }
   132  
   133        return state.baseIndent + n * indentUnit;
   134      },
   135  
   136      electricChars: "]>"
   137    };
   138  });
   139  
   140  CodeMirror.defineMIME("application/xml-dtd", "dtd");
   141  
   142  });