diff --git a/lib/ace/mode/php_highlight_rules.js b/lib/ace/mode/php_highlight_rules.js index b772f759..b9492560 100644 --- a/lib/ace/mode/php_highlight_rules.js +++ b/lib/ace/mode/php_highlight_rules.js @@ -1058,8 +1058,8 @@ var PhpHighlightRules = function() { for (var i in this.$rules) { this.$rules[i].unshift({ token : "support.php_tag", // php open tag - regex : "<\\?(?:php|\\=)?", - next : "php-start" + regex : "<\\?(?:php|=)?", + next : {push: "php-start"} }); } @@ -1068,8 +1068,9 @@ var PhpHighlightRules = function() { this.$rules["php-start"].unshift({ token : "support.php_tag", // php close tag regex : "\\?>", - next : "start" + next : "pop" }); + this.normalizeRules(); }; oop.inherits(PhpHighlightRules, HtmlHighlightRules); diff --git a/lib/ace/mode/text_highlight_rules.js b/lib/ace/mode/text_highlight_rules.js index 2d11602c..c411e751 100644 --- a/lib/ace/mode/text_highlight_rules.js +++ b/lib/ace/mode/text_highlight_rules.js @@ -43,8 +43,7 @@ var TextHighlightRules = function() { token : "empty_line", regex : '^$' }, { - token : "text", - regex : ".+" + defaultToken : "text" }] }; }; @@ -96,35 +95,80 @@ var TextHighlightRules = function() { return this.$embeds; }; + var pushState = function(currentState, stack) { + if (currentState != "start") + stack.unshift(this.nextState, currentState); + return this.nextState; + }; + var popState = function(currentState, stack) { + if (stack[0] !== currentState) + return "start"; + stack.shift(); + return stack.shift(); + }; + this.normalizeRules = function() { var id = 0; - for (var key in this.$rules) { - var state = this.$rules[key]; + var rules = this.$rules; + function processState(key) { + var state = rules[key]; + state.processed = true; for (var i = 0; i < state.length; i++) { var rule = state[i]; + if (!rule.regex && rule.start) { + rule.regex = rule.start; + if (!rule.next) + rule.next = []; + rule.next.push({ + defaultToken: rule.token + }, { + token: rule.token + ".end", + regex: rule.end || rule.start, + next: key + }); + rule.token = rule.token + ".start"; + } if (rule.next && Array.isArray(rule.next)) { - var stateName = rule.stateName || ("state" + id++); - this.$rules[stateName] = rule.next; + var stateName = rule.stateName || (rule.token + id++); + rules[stateName] = rule.next; rule.next = stateName; + processState(stateName); + } else if (rule.next && typeof rule.next == "object") { + var next = rule.next; + rule.nextState = next.push; + rule.next = pushState; + } else if (rule.next == "pop") { + rule.next = popState; } if (rule.rules) { - for (var r in rule.rules) { - if (this.$rules[r]) { - if (this.$rules[r].push) - this.$rules[r].push.apply(this.$rules[r], rule.rules[r]); + for (var r in rule.rules) { + if (rules[r]) { + if (rules[r].push) + rules[r].push.apply(rules[r], rule.rules[r]); } else { - this.$rules[r] = rule.rules[r]; + rules[r] = rule.rules[r]; } } } if (rule.include || typeof rule == "string") { - var args = [i, 1].concat(this.$rules[rule.include || rule]); + var includeName = rule.include || rule; + var toInsert = rules[includeName]; + } else if (Array.isArray(rule)) + toInsert = rule; + + if (toInsert) { + var args = [i, 1].concat(toInsert); if (rule.noEscape) args = args.filter(function(x) {return !x.next;}); state.splice.apply(state, args); + // skip included rules since they are already processed + //i += args.length - 3; + i--; + toInsert = null } } - } + }; + Object.keys(rules).forEach(processState); }; this.createKeywordMapper = function(map, defaultToken, ignoreCase, splitChar) { diff --git a/lib/ace/tokenizer.js b/lib/ace/tokenizer.js index b94b53fe..3835e535 100644 --- a/lib/ace/tokenizer.js +++ b/lib/ace/tokenizer.js @@ -194,7 +194,11 @@ var Tokenizer = function(rules) { : rule.token; if (rule.next) { - currentState = rule.next; + if (typeof rule.next == "string") + currentState = rule.next; + else + currentState = rule.next(currentState, stack); + state = this.states[currentState]; if (!state) { window.console && console.error && console.error(currentState, "doesn't exist");