// CodeMirror, copyright (c) by Marijn Haverbeke and others // Distributed under an MIT license: https://codemirror.net/LICENSE ;(function (mod) { if (typeof exports == 'object' && typeof module == 'object') // CommonJS mod(require('../../lib/codemirror'), require('../../addon/mode/multiplex')) else if (typeof define == 'function' && define.amd) // AMD define(['../../lib/codemirror', '../../addon/mode/multiplex'], mod) // Plain browser env else mod(CodeMirror) })(function (CodeMirror) { 'use strict' CodeMirror.defineMode('twig:inner', function () { var keywords = [ 'and', 'as', 'autoescape', 'endautoescape', 'block', 'do', 'endblock', 'else', 'elseif', 'extends', 'for', 'endfor', 'embed', 'endembed', 'filter', 'endfilter', 'flush', 'from', 'if', 'endif', 'in', 'is', 'include', 'import', 'not', 'or', 'set', 'spaceless', 'endspaceless', 'with', 'endwith', 'trans', 'endtrans', 'blocktrans', 'endblocktrans', 'macro', 'endmacro', 'use', 'verbatim', 'endverbatim', ], operator = /^[+\-*&%=<>!?|~^]/, sign = /^[:\[\(\{]/, atom = ['true', 'false', 'null', 'empty', 'defined', 'divisibleby', 'divisible by', 'even', 'odd', 'iterable', 'sameas', 'same as'], number = /^(\d[+\-\*\/])?\d+(\.\d+)?/ keywords = new RegExp('((' + keywords.join(')|(') + '))\\b') atom = new RegExp('((' + atom.join(')|(') + '))\\b') function tokenBase(stream, state) { var ch = stream.peek() //Comment if (state.incomment) { if (!stream.skipTo('#}')) { stream.skipToEnd() } else { stream.eatWhile(/\#|}/) state.incomment = false } return 'comment' //Tag } else if (state.intag) { //After operator if (state.operator) { state.operator = false if (stream.match(atom)) { return 'atom' } if (stream.match(number)) { return 'number' } } //After sign if (state.sign) { state.sign = false if (stream.match(atom)) { return 'atom' } if (stream.match(number)) { return 'number' } } if (state.instring) { if (ch == state.instring) { state.instring = false } stream.next() return 'string' } else if (ch == "'" || ch == '"') { state.instring = ch stream.next() return 'string' } else if (stream.match(state.intag + '}') || (stream.eat('-') && stream.match(state.intag + '}'))) { state.intag = false return 'tag' } else if (stream.match(operator)) { state.operator = true return 'operator' } else if (stream.match(sign)) { state.sign = true } else { if (stream.eat(' ') || stream.sol()) { if (stream.match(keywords)) { return 'keyword' } if (stream.match(atom)) { return 'atom' } if (stream.match(number)) { return 'number' } if (stream.sol()) { stream.next() } } else { stream.next() } } return 'variable' } else if (stream.eat('{')) { if (stream.eat('#')) { state.incomment = true if (!stream.skipTo('#}')) { stream.skipToEnd() } else { stream.eatWhile(/\#|}/) state.incomment = false } return 'comment' //Open tag } else if ((ch = stream.eat(/\{|%/))) { //Cache close tag state.intag = ch if (ch == '{') { state.intag = '}' } stream.eat('-') return 'tag' } } stream.next() } return { startState: function () { return {} }, token: function (stream, state) { return tokenBase(stream, state) }, } }) CodeMirror.defineMode('twig', function (config, parserConfig) { var twigInner = CodeMirror.getMode(config, 'twig:inner') if (!parserConfig || !parserConfig.base) return twigInner return CodeMirror.multiplexingMode(CodeMirror.getMode(config, parserConfig.base), { open: /\{[{#%]/, close: /[}#%]\}/, mode: twigInner, parseDelimiters: true, }) }) CodeMirror.defineMIME('text/x-twig', 'twig') })