var type;
function ret(t, n) {
  return type = n, t;
}
function tokenBase(e, n) {
  var o = e.next();
  if (o == "<" && e.eat("!")) {
    if (e.eatWhile(/[\-]/)) return n.tokenize = tokenSGMLComment, tokenSGMLComment(e, n);
    if (e.eatWhile(/[\w]/)) return ret("keyword", "doindent");
  } else if (o == "<" && e.eat("?")) return n.tokenize = inBlock("meta", "?>"), ret("meta", o);
  else if (o == "#" && e.eatWhile(/[\w]/)) return ret("atom", "tag");
  else if (o == "|") return ret("keyword", "separator");
  else if (o.match(/[\(\)\[\]\-\.,\+\?>]/)) return ret(null, o);
  else if (o.match(/[\[\]]/)) return ret("rule", o);
  else if (o == '"' || o == "'") return n.tokenize = tokenString(o), n.tokenize(e, n);
  else if (e.eatWhile(/[a-zA-Z\?\+\d]/)) {
    var s = e.current();
    return s.substr(s.length - 1, s.length).match(/\?|\+/) !== null && e.backUp(1), ret("tag", "tag");
  } else if (o == "%" || o == "*") return ret("number", "number");
  else return e.eatWhile(/[\w\\\-_%.{,]/), ret(null, null);
}
function tokenSGMLComment(e, r) {
  for (var i = 0, a; (a = e.next()) != null; ) {
    if (i >= 2 && a == ">") {
      r.tokenize = tokenBase;
      break;
    }
    i = a == "-" ? i + 1 : 0;
  }
  return ret("comment", "comment");
}
function tokenString(e) {
  return function(r, i) {
    for (var a = false, o; (o = r.next()) != null; ) {
      if (o == e && !a) {
        i.tokenize = tokenBase;
        break;
      }
      a = !a && o == "\\";
    }
    return ret("string", "tag");
  };
}
function inBlock(e, t) {
  return function(r, i) {
    for (; !r.eol(); ) {
      if (r.match(t)) {
        i.tokenize = tokenBase;
        break;
      }
      r.next();
    }
    return e;
  };
}
const dtd = {
  name: "dtd",
  startState: function() {
    return {
      tokenize: tokenBase,
      baseIndent: 0,
      stack: []
    };
  },
  token: function(t, n) {
    if (t.eatSpace()) return null;
    var r = n.tokenize(t, n), i = n.stack[n.stack.length - 1];
    return t.current() == "[" || type === "doindent" || type == "[" ? n.stack.push("rule") : type === "endtag" ? n.stack[n.stack.length - 1] = "endtag" : t.current() == "]" || type == "]" || type == ">" && i == "rule" ? n.stack.pop() : type == "[" && n.stack.push("["), r;
  },
  indent: function(t, n, r) {
    var i = t.stack.length;
    return n.charAt(0) === "]" ? i-- : n.substr(n.length - 1, n.length) === ">" && (n.substr(0, 1) === "<" || type == "doindent" && n.length > 1 || (type == "doindent" ? i-- : type == ">" && n.length > 1 || type == "tag" && n !== ">" || (type == "tag" && t.stack[t.stack.length - 1] == "rule" ? i-- : type == "tag" ? i++ : n === ">" && t.stack[t.stack.length - 1] == "rule" && type === ">" ? i-- : n === ">" && t.stack[t.stack.length - 1] == "rule" || (n.substr(0, 1) !== "<" && n.substr(0, 1) === ">" ? --i : n === ">" || --i))), (type == null || type == "]") && i--), t.baseIndent + i * r.unit;
  },
  languageData: { indentOnInput: /^\s*[\]>]$/ }
};
export {
  dtd as t
};
