+++ /dev/null
-/**
-* @file smartymixed.js
-* @brief Smarty Mixed Codemirror mode (Smarty + Mixed HTML)
-* @author Ruslan Osmanov <rrosmanov at gmail dot com>
-* @version 3.0
-* @date 05.07.2013
-*/
-CodeMirror.defineMode("smartymixed", function(config) {
- var settings, regs, helpers, parsers,
- htmlMixedMode = CodeMirror.getMode(config, "htmlmixed"),
- smartyMode = CodeMirror.getMode(config, "smarty"),
-
- settings = {
- rightDelimiter: '}',
- leftDelimiter: '{'
- };
-
- if (config.hasOwnProperty("leftDelimiter")) {
- settings.leftDelimiter = config.leftDelimiter;
- }
- if (config.hasOwnProperty("rightDelimiter")) {
- settings.rightDelimiter = config.rightDelimiter;
- }
-
- regs = {
- smartyComment: new RegExp("^" + settings.leftDelimiter + "\\*"),
- literalOpen: new RegExp(settings.leftDelimiter + "literal" + settings.rightDelimiter),
- literalClose: new RegExp(settings.leftDelimiter + "\/literal" + settings.rightDelimiter),
- hasLeftDelimeter: new RegExp(".*" + settings.leftDelimiter),
- htmlHasLeftDelimeter: new RegExp("[^<>]*" + settings.leftDelimiter)
- };
-
- helpers = {
- chain: function(stream, state, parser) {
- state.tokenize = parser;
- return parser(stream, state);
- },
-
- cleanChain: function(stream, state, parser) {
- state.tokenize = null;
- state.localState = null;
- state.localMode = null;
- return (typeof parser == "string") ? (parser ? parser : null) : parser(stream, state);
- },
-
- maybeBackup: function(stream, pat, style) {
- var cur = stream.current();
- var close = cur.search(pat),
- m;
- if (close > - 1) stream.backUp(cur.length - close);
- else if (m = cur.match(/<\/?$/)) {
- stream.backUp(cur.length);
- if (!stream.match(pat, false)) stream.match(cur[0]);
- }
- return style;
- }
- };
-
- parsers = {
- html: function(stream, state) {
- if (!state.inLiteral && stream.match(regs.htmlHasLeftDelimeter, false)) {
- state.tokenize = parsers.smarty;
- state.localMode = smartyMode;
- state.localState = smartyMode.startState(htmlMixedMode.indent(state.htmlMixedState, ""));
- return helpers.maybeBackup(stream, settings.leftDelimiter, smartyMode.token(stream, state.localState));
- }
- return htmlMixedMode.token(stream, state.htmlMixedState);
- },
-
- smarty: function(stream, state) {
- if (stream.match(settings.leftDelimiter, false)) {
- if (stream.match(regs.smartyComment, false)) {
- return helpers.chain(stream, state, parsers.inBlock("comment", "*" + settings.rightDelimiter));
- }
- } else if (stream.match(settings.rightDelimiter, false)) {
- stream.eat(settings.rightDelimiter);
- state.tokenize = parsers.html;
- state.localMode = htmlMixedMode;
- state.localState = state.htmlMixedState;
- return "tag";
- }
-
- return helpers.maybeBackup(stream, settings.rightDelimiter, smartyMode.token(stream, state.localState));
- },
-
- inBlock: function(style, terminator) {
- return function(stream, state) {
- while (!stream.eol()) {
- if (stream.match(terminator)) {
- helpers.cleanChain(stream, state, "");
- break;
- }
- stream.next();
- }
- return style;
- };
- }
- };
-
- return {
- startState: function() {
- var state = htmlMixedMode.startState();
- return {
- token: parsers.html,
- localMode: null,
- localState: null,
- htmlMixedState: state,
- tokenize: null,
- inLiteral: false
- };
- },
-
- copyState: function(state) {
- var local = null, tok = (state.tokenize || state.token);
- if (state.localState) {
- local = CodeMirror.copyState((tok != parsers.html ? smartyMode : htmlMixedMode), state.localState);
- }
- return {
- token: state.token,
- tokenize: state.tokenize,
- localMode: state.localMode,
- localState: local,
- htmlMixedState: CodeMirror.copyState(htmlMixedMode, state.htmlMixedState),
- inLiteral: state.inLiteral
- };
- },
-
- token: function(stream, state) {
- if (stream.match(settings.leftDelimiter, false)) {
- if (!state.inLiteral && stream.match(regs.literalOpen, true)) {
- state.inLiteral = true;
- return "keyword";
- } else if (state.inLiteral && stream.match(regs.literalClose, true)) {
- state.inLiteral = false;
- return "keyword";
- }
- }
- if (state.inLiteral && state.localState != state.htmlMixedState) {
- state.tokenize = parsers.html;
- state.localMode = htmlMixedMode;
- state.localState = state.htmlMixedState;
- }
-
- var style = (state.tokenize || state.token)(stream, state);
- return style;
- },
-
- indent: function(state, textAfter) {
- if (state.localMode == smartyMode
- || (state.inLiteral && !state.localMode)
- || regs.hasLeftDelimeter.test(textAfter)) {
- return CodeMirror.Pass;
- }
- return htmlMixedMode.indent(state.htmlMixedState, textAfter);
- },
-
- electricChars: "/{}:",
-
- innerMode: function(state) {
- return {
- state: state.localState || state.htmlMixedState,
- mode: state.localMode || htmlMixedMode
- };
- }
- };
-},
-"htmlmixed");
-
-CodeMirror.defineMIME("text/x-smarty", "smartymixed");
-// vim: et ts=2 sts=2 sw=2