diff --git a/demo/kitchen-sink/demo.js b/demo/kitchen-sink/demo.js index 4e5da13e..f3a163e5 100644 --- a/demo/kitchen-sink/demo.js +++ b/demo/kitchen-sink/demo.js @@ -3,7 +3,7 @@ * * Copyright (c) 2010, Ajax.org B.V. * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright @@ -14,7 +14,7 @@ * * Neither the name of Ajax.org B.V. nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE @@ -83,48 +83,49 @@ Mode.prototype.supportsFile = function(filename) { }; var modesByName = { - c9search: ["C9Search" , "c9search_results"], - coffee: ["CoffeeScript" , "coffee|^Cakefile"], - coldfusion: ["ColdFusion" , "cfm"], - csharp: ["C#" , "cs"], - css: ["CSS" , "css"], - diff: ["Diff" , "diff|patch"], - glsl: ["Glsl" , "glsl|frag|vert"], - golang: ["Go" , "go"], - groovy: ["Groovy" , "groovy"], - haxe: ["haXe" , "hx"], - html: ["HTML" , "htm|html|xhtml"], - c_cpp: ["C/C++" , "c|cc|cpp|cxx|h|hh|hpp"], - clojure: ["Clojure" , "clj"], - java: ["Java" , "java"], - javascript: ["JavaScript" , "js"], - json: ["JSON" , "json"], - jsx: ["JSX" , "jsx"], - latex: ["LaTeX" , "latex|tex|ltx|bib"], - less: ["LESS" , "less"], - liquid: ["Liquid" , "liquid"], - lua: ["Lua" , "lua"], - luapage: ["LuaPage" , "lp"], // http://keplerproject.github.com/cgilua/manual.html#templates - markdown: ["Markdown" , "md|markdown"], - ocaml: ["OCaml" , "ml|mli"], - perl: ["Perl" , "pl|pm"], - pgsql: ["pgSQL" , "pgsql"], - php: ["PHP" , "php|phtml"], - powershell: ["Powershell" , "ps1"], - python: ["Python" , "py"], - ruby: ["Ruby" , "ru|gemspec|rake|rb"], - scad: ["OpenSCAD" , "scad"], - scala: ["Scala" , "scala"], - scss: ["SCSS" , "scss|sass"], - sh: ["SH" , "sh|bash|bat"], - sql: ["SQL" , "sql"], - svg: ["SVG" , "svg"], - tcl: ["Tcl" , "tcl"], - text: ["Text" , "txt"], - textile: ["Textile" , "textile"], - xml: ["XML" , "xml|rdf|rss|wsdl|xslt|atom|mathml|mml|xul|xbl"], - xquery: ["XQuery" , "xq"], - yaml: ["YAML" , "yaml"] + c9search: ["C9Search" , "c9search_results"], + coffee: ["CoffeeScript" , "coffee|^Cakefile"], + coldfusion: ["ColdFusion" , "cfm"], + csharp: ["C#" , "cs"], + css: ["CSS" , "css"], + diff: ["Diff" , "diff|patch"], + glsl: ["Glsl" , "glsl|frag|vert"], + golang: ["Go" , "go"], + groovy: ["Groovy" , "groovy"], + haxe: ["haXe" , "hx"], + html: ["HTML" , "htm|html|xhtml"], + c_cpp: ["C/C++" , "c|cc|cpp|cxx|h|hh|hpp"], + clojure: ["Clojure" , "clj"], + jade: ["Jade" , "jade"], + java: ["Java" , "java"], + javascript: ["JavaScript" , "js"], + json: ["JSON" , "json"], + jsx: ["JSX" , "jsx"], + latex: ["LaTeX" , "latex|tex|ltx|bib"], + less: ["LESS" , "less"], + liquid: ["Liquid" , "liquid"], + lua: ["Lua" , "lua"], + luapage: ["LuaPage" , "lp"], // http://keplerproject.github.com/cgilua/manual.html#templates + markdown: ["Markdown" , "md|markdown"], + ocaml: ["OCaml" , "ml|mli"], + perl: ["Perl" , "pl|pm"], + pgsql: ["pgSQL" , "pgsql"], + php: ["PHP" , "php|phtml"], + powershell: ["Powershell" , "ps1"], + python: ["Python" , "py"], + ruby: ["Ruby" , "ru|gemspec|rake|rb"], + scad: ["OpenSCAD" , "scad"], + scala: ["Scala" , "scala"], + scss: ["SCSS" , "scss|sass"], + sh: ["SH" , "sh|bash|bat"], + sql: ["SQL" , "sql"], + svg: ["SVG" , "svg"], + tcl: ["Tcl" , "tcl"], + text: ["Text" , "txt"], + textile: ["Textile" , "textile"], + xml: ["XML" , "xml|rdf|rss|wsdl|xslt|atom|mathml|mml|xul|xbl"], + xquery: ["XQuery" , "xq"], + yaml: ["YAML" , "yaml"] }; for (var name in modesByName) { @@ -176,6 +177,7 @@ var docs = { "docs/groovy.groovy": "Groovy", "docs/Haxe.hx": "haXe", "docs/html.html": "HTML", + "docs/jade.jade": "Jade", "docs/java.java": "Java", "docs/json.json": "JSON", "docs/jsx.jsx": "JSX", diff --git a/demo/kitchen-sink/docs/jade.jade b/demo/kitchen-sink/docs/jade.jade new file mode 100644 index 00000000..d9fb7e30 --- /dev/null +++ b/demo/kitchen-sink/docs/jade.jade @@ -0,0 +1,45 @@ +!!!doctype +!!!5 +!!! + +include something + + include another_thing + + // let's talk about it + +// + here it is. a block comment! + and another row! +but not here. + + // + a far spaced + should be lack of block + + // also not a comment + div.attemptAtBlock + + span#myName + + #{implicit} + !{more_explicit} + + #idDiv + + .idDiv + + test(id="tag") + header(id="tag", blah="foo", meh="aads") +mixin article(obj, parents) + + mixin bleh() + + mixin clever-name + + -var x = "0"; + - y each z + + - var items = ["one", "two", "three"] + each item in items + li= item \ No newline at end of file diff --git a/lib/ace/mode/c_cpp_highlight_rules.js b/lib/ace/mode/c_cpp_highlight_rules.js index 8f3d9b34..8e700938 100644 --- a/lib/ace/mode/c_cpp_highlight_rules.js +++ b/lib/ace/mode/c_cpp_highlight_rules.js @@ -35,29 +35,47 @@ var oop = require("../lib/oop"); var DocCommentHighlightRules = require("./doc_comment_highlight_rules").DocCommentHighlightRules; var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; +// used by objective-c +var cFunctions = exports.cFunctions = "\\s*\\bhypot(?:f|l)?|s(?:scanf|ystem|nprintf|ca(?:nf|lb(?:n(?:f|l)?|ln(?:f|l)?))|i(?:n(?:h(?:f|l)?|f|l)?|gn(?:al|bit))|tr(?:s(?:tr|pn)|nc(?:py|at|mp)|c(?:spn|hr|oll|py|at|mp)|to(?:imax|d|u(?:l(?:l)?|max)|k|f|l(?:d|l)?)|error|pbrk|ftime|len|rchr|xfrm)|printf|et(?:jmp|vbuf|locale|buf)|qrt(?:f|l)?|w(?:scanf|printf)|rand)|n(?:e(?:arbyint(?:f|l)?|xt(?:toward(?:f|l)?|after(?:f|l)?))|an(?:f|l)?)|c(?:s(?:in(?:h(?:f|l)?|f|l)?|qrt(?:f|l)?)|cos(?:h(?:f)?|f|l)?|imag(?:f|l)?|t(?:ime|an(?:h(?:f|l)?|f|l)?)|o(?:s(?:h(?:f|l)?|f|l)?|nj(?:f|l)?|pysign(?:f|l)?)|p(?:ow(?:f|l)?|roj(?:f|l)?)|e(?:il(?:f|l)?|xp(?:f|l)?)|l(?:o(?:ck|g(?:f|l)?)|earerr)|a(?:sin(?:h(?:f|l)?|f|l)?|cos(?:h(?:f|l)?|f|l)?|tan(?:h(?:f|l)?|f|l)?|lloc|rg(?:f|l)?|bs(?:f|l)?)|real(?:f|l)?|brt(?:f|l)?)|t(?:ime|o(?:upper|lower)|an(?:h(?:f|l)?|f|l)?|runc(?:f|l)?|gamma(?:f|l)?|mp(?:nam|file))|i(?:s(?:space|n(?:ormal|an)|cntrl|inf|digit|u(?:nordered|pper)|p(?:unct|rint)|finite|w(?:space|c(?:ntrl|type)|digit|upper|p(?:unct|rint)|lower|al(?:num|pha)|graph|xdigit|blank)|l(?:ower|ess(?:equal|greater)?)|al(?:num|pha)|gr(?:eater(?:equal)?|aph)|xdigit|blank)|logb(?:f|l)?|max(?:div|abs))|di(?:v|fftime)|_Exit|unget(?:c|wc)|p(?:ow(?:f|l)?|ut(?:s|c(?:har)?|wc(?:har)?)|error|rintf)|e(?:rf(?:c(?:f|l)?|f|l)?|x(?:it|p(?:2(?:f|l)?|f|l|m1(?:f|l)?)?))|v(?:s(?:scanf|nprintf|canf|printf|w(?:scanf|printf))|printf|f(?:scanf|printf|w(?:scanf|printf))|w(?:scanf|printf)|a_(?:start|copy|end|arg))|qsort|f(?:s(?:canf|e(?:tpos|ek))|close|tell|open|dim(?:f|l)?|p(?:classify|ut(?:s|c|w(?:s|c))|rintf)|e(?:holdexcept|set(?:e(?:nv|xceptflag)|round)|clearexcept|testexcept|of|updateenv|r(?:aiseexcept|ror)|get(?:e(?:nv|xceptflag)|round))|flush|w(?:scanf|ide|printf|rite)|loor(?:f|l)?|abs(?:f|l)?|get(?:s|c|pos|w(?:s|c))|re(?:open|e|ad|xp(?:f|l)?)|m(?:in(?:f|l)?|od(?:f|l)?|a(?:f|l|x(?:f|l)?)?))|l(?:d(?:iv|exp(?:f|l)?)|o(?:ngjmp|cal(?:time|econv)|g(?:1(?:p(?:f|l)?|0(?:f|l)?)|2(?:f|l)?|f|l|b(?:f|l)?)?)|abs|l(?:div|abs|r(?:int(?:f|l)?|ound(?:f|l)?))|r(?:int(?:f|l)?|ound(?:f|l)?)|gamma(?:f|l)?)|w(?:scanf|c(?:s(?:s(?:tr|pn)|nc(?:py|at|mp)|c(?:spn|hr|oll|py|at|mp)|to(?:imax|d|u(?:l(?:l)?|max)|k|f|l(?:d|l)?|mbs)|pbrk|ftime|len|r(?:chr|tombs)|xfrm)|to(?:b|mb)|rtomb)|printf|mem(?:set|c(?:hr|py|mp)|move))|a(?:s(?:sert|ctime|in(?:h(?:f|l)?|f|l)?)|cos(?:h(?:f|l)?|f|l)?|t(?:o(?:i|f|l(?:l)?)|exit|an(?:h(?:f|l)?|2(?:f|l)?|f|l)?)|b(?:s|ort))|g(?:et(?:s|c(?:har)?|env|wc(?:har)?)|mtime)|r(?:int(?:f|l)?|ound(?:f|l)?|e(?:name|alloc|wind|m(?:ove|quo(?:f|l)?|ainder(?:f|l)?))|a(?:nd|ise))|b(?:search|towc)|m(?:odf(?:f|l)?|em(?:set|c(?:hr|py|mp)|move)|ktime|alloc|b(?:s(?:init|towcs|rtowcs)|towc|len|r(?:towc|len)))\\b" + var c_cppHighlightRules = function() { - var keywords = ( - "and|double|not_eq|throw|and_eq|dynamic_cast|operator|true|" + - "asm|else|or|try|auto|enum|or_eq|typedef|bitand|explicit|private|" + - "typeid|bitor|extern|protected|typename|bool|false|public|union|" + - "break|float|register|unsigned|case|fro|reinterpret-cast|using|catch|" + - "friend|return|virtual|char|goto|short|void|class|if|signed|volatile|" + - "compl|inline|sizeof|wchar_t|const|int|static|while|const-cast|long|" + - "static_cast|xor|continue|mutable|struct|xor_eq|default|namespace|" + - "switch|delete|new|template|do|not|this|for" + var keywordControls = ( + "break|case|continue|default|do|else|for|goto|if|_Pragma|" + + "return|switch|while|catch|operator|try|throw|using" + ); + + var storageType = ( + "asm|__asm__|auto|bool|_Bool|char|_Complex|double|enum|float|" + + "_Imaginary|int|long|short|signed|struct|typedef|union|unsigned|void" + + "class|wchar_t|template" ); - var buildinConstants = ( - "NULL" + var storageModifiers = ( + "const|extern|register|restrict|static|volatile|inline|private:|" + + "protected:|public:|friend|explicit|virtual|export|mutable|typename" + ); + + var keywordOperators = ( + "and|and_eq|bitand|bitor|compl|not|not_eq|or|or_eq|typeid|xor|xor_eq" + + "const_cast|dynamic_cast|reinterpret_cast|static_cast|sizeof|namespace" + ); + + var builtinConstants = ( + "NULL|true|false|TRUE|FALSE" ); var keywordMapper = this.createKeywordMapper({ + "keyword.control" : keywordControls, + "storage.type" : storageType, + "storage.modifier" : storageModifiers, + "keyword.operator" : keywordOperators, "variable.language": "this", - "keyword": keywords, - "constant.language": buildinConstants + "constant.language": builtinConstants }, "identifier"); + var identifierRe = "[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\d\\$_\u00a1-\uffff]*\\b"; + // regexp must not have capturing parentheses. Use (?:) instead. // regexps are ordered -> the first match is used @@ -101,7 +119,16 @@ var c_cppHighlightRules = function() { }, { token : "keyword", // pre-compiler directivs regex : "(?:#include|#pragma|#line|#define|#undef|#ifdef|#else|#elif|#endif|#ifndef)" - }, { + }, { + token : "support.function.C99.c", + regex : cFunctions + }, { + // function myFunc(arg) { } + token : [ + "text", "entity.name.function", "text", "paren.lparen" + ], + regex : "(\\s+)(" + identifierRe + ")(\\s*)(\\()" + }, { token : keywordMapper, regex : "[a-zA-Z_$][a-zA-Z0-9_$]*\\b" }, { diff --git a/lib/ace/mode/jade.js b/lib/ace/mode/jade.js new file mode 100644 index 00000000..03b54306 --- /dev/null +++ b/lib/ace/mode/jade.js @@ -0,0 +1,58 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2012, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * Contributor(s): + * + * Garen J. Torikian + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextMode = require("./text").Mode; +var Tokenizer = require("../tokenizer").Tokenizer; +var JadeHighlightRules = require("./jade_highlight_rules").JadeHighlightRules; +// var JavascriptMode = require("ace/mode/javascript").Mode; +// var CssMode = require("ace/mode/css").Mode; + +var Mode = function() { + var highlighter = new JadeHighlightRules(); + + this.$tokenizer = new Tokenizer(highlighter.getRules()); +}; +oop.inherits(Mode, TextMode); + +(function() { + // Extra logic goes here. +}).call(Mode.prototype); + +exports.Mode = Mode; +}); \ No newline at end of file diff --git a/lib/ace/mode/jade_highlight_rules.js b/lib/ace/mode/jade_highlight_rules.js new file mode 100644 index 00000000..41042038 --- /dev/null +++ b/lib/ace/mode/jade_highlight_rules.js @@ -0,0 +1,327 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2012, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * Contributor(s): + * + * Garen J. Torikian + * + * ***** END LICENSE BLOCK ***** */ + +/* + THIS FILE WAS AUTOGENERATED BY mode_highlight_rules.tmpl.js (UUID: C5B73B98-5F2A-42E3-9F0E-028A74A9FE4B) +*/ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; +var MarkdownHighlightRules = require("./markdown_highlight_rules").MarkdownHighlightRules; +var SassHighlightRules = require("./scss_highlight_rules").ScssHighlightRules; +var LessHighlightRules = require("./less_highlight_rules").LessHighlightRules; +var CoffeeHighlightRules = require("./coffee_highlight_rules").CoffeeHighlightRules; +var JavaScriptHighlightRules = require("./javascript_highlight_rules").JavaScriptHighlightRules; + +function mixin_embed(tag, prefix) { + return { + token : "entity.name.function.jade", + regex : "^\\s*\\:" + tag, + next : prefix + "start" + }; +} + +var JadeHighlightRules = function() { + + var escapedRe = "\\\\(?:x[0-9a-fA-F]{2}|" + // hex + "u[0-9a-fA-F]{4}|" + // unicode + "[0-2][0-7]{0,2}|" + // oct + "3[0-6][0-7]?|" + // oct + "37[0-7]?|" + // oct + "[4-7][0-7]?|" + //oct + ".)"; + + // regexp must not have capturing parentheses. Use (?:) instead. + // regexps are ordered -> the first match is used + + this.$rules = + { + "start": [ + { + "token": "keyword.control.import.include.jade", + "regex": "\\s*\\binclude\\b" + }, + { + "token": "keyword.other.doctype.jade", + "regex": "^!!!\\s*(?:[a-zA-Z0-9-_]+)?" + }, + { + "token" : "punctuation.section.comment", + "regex" : "^\\s*\/\/(?:\\s*[^-\\s]|\\s+\\S)(?:.*$)", + }, + { + "token" : function(space, text) { + return "punctuation.section.comment"; + }, + "regex" : "^((\\s*)\/\/)(?:\\s*$)", + "next": "comment_block" + }, + mixin_embed("markdown", "markdown-"), + mixin_embed("sass", "sass-"), + mixin_embed("less", "less-"), + mixin_embed("coffee", "coffee-"), + /* + { + "token": { + "2": { + "name": "entity.name.function.jade" + } + }, + "regex": "^(\\s*)(\\:cdata)", + "next": "state_9" + },*/ + // match stuff like: mixin dialog-title-desc(title, desc) + { + "token": [ "storage.type.function.jade", + "entity.name.function.jade", + "punctuation.definition.parameters.begin.jade", + "variable.parameter.function.jade", + "punctuation.definition.parameters.end.jade" + ], + "regex": "^(\\s*mixin)( [\\w\\-]+)(\\s*\\()(.*?)(\\))" + }, + // match stuff like: mixin dialog-title-desc + { + "token": [ "storage.type.function.jade", "entity.name.function.jade"], + "regex": "^(\\s*mixin)( [\\w\\-]+)" + }, + /* { + "token": "source.js.embedded.jade", + "regex": "^\\s*-|=|!=", + "next": "js_code" + },*/ + /*{ + "token": "entity.name.tag.script.jade", + "regex": "^\\s*script", + "next": "js_code_tag" + },*/ + { + "token": "string.interpolated.jade", + "regex": "[#!]\\{[^\\}]+\\}" + }, + // Match any tag, id or class. skip AST filters + { + "token": ["meta.tag.any.jade", "entity.variable.tag.jade"], + "regex": /^\s*(?!\w+\:)(?:[\w]+|(?=\.|#)])/, + "next": "tag_single" + }, + { + "token": "suport.type.attribute.id.jade", + "regex": "#\\w+" + }, + { + "token": "suport.type.attribute.class.jade", + "regex": "\\.\\w+" + }, + { + "token": "punctuation", + "regex": "\\s*(?:\\()", + "next": "tag_attributes" + } + ], + "comment_block": [ + { + "token": function(text) { + return "text"; + }, + "regex": "^(\\1\\S|$)", + "captures": "1", + "next": "start" + }, + { + "token": "comment.block.jade", + "merge" : true, + "regex" : ".+" + } + ], + /* + + "state_9": [ + { + "token": "TODO", + "regex": "^(?!\\1\\s+)", + "next": "start" + }, + { + "token": "TODO", + "regex": ".+", + "next": "state_9" + } + ],*/ + /*"js_code": [ + { + "token": "keyword.control.js", + "regex": "\\beach\\b" + }, + { + "token": "text", + "regex": "$", + "next": "start" + } + ],*/ + /*"js_code_tag": [ + { + "include": "source.js" + }, + { + "token": "TODO", + "regex": "^((?=(\\1)([\\w#\\.]|$\\n?))|^$\\n?)", + "next": "start" + } + ],*/ + "tag_single": [ + { + "token": "suport.type.attribute.class.jade", + "regex": "\\.[\\w-]+" + }, + { + "token": "suport.type.attribute.id.jade", + "regex": "#[\\w-]+" + }, + { + "token": ["text", "punctuation"], + "regex": "($)|((?!\\.|#|=|-))", + "next": "start" + } + ], + "tag_attributes": [ + { + "token": ["entity.other.attribute-name.jade", "punctuation"], + "regex": "\\b([a-zA-Z:\\.-]+)(=)", + "next": "attribute_strings" + }, + { + "token": "punctuation", + "regex": "\\)", + "next": "start" + } + ], + "attribute_strings": [ + { + "token" : "string", + "regex" : "'(?=.)", + "next" : "qstring" + }, + { + "token" : "string", + "regex" : '"(?=.)', + "next" : "qqstring" + } + ], + "qqstring" : [ + { + token : "constant.language.escape", + regex : escapedRe + }, { + token : "string", + regex : '[^"\\\\]+', + merge : true + }, { + token : "string", + regex : "\\\\$", + next : "qqstring", + merge : true + }, { + token : "string", + regex : '"|$', + next : "tag_attributes", + merge : true + } + ], + "qstring" : [ + { + token : "constant.language.escape", + regex : escapedRe + }, { + token : "string", + regex : "[^'\\\\]+", + merge : true + }, { + token : "string", + regex : "\\\\$", + next : "qstring", + merge : true + }, { + token : "string", + regex : "'|$", + next : "tag_attributes", + merge : true + } + ] +}; +/* + this.embedRules(MarkdownHighlightRules, "markdown-", [{ + token : "support.function", + regex : "^\\1\\s+", + captures: "1", + next : "start" + }]); + + this.embedRules(SassHighlightRules, "sass-", [{ + token : "support.function", + regex : "^(?!\\1\\s+)", + captures: "1", + next : "start" + }]); + + this.embedRules(LessHighlightRules, "less-", [{ + token : "support.function", + regex : "^(?!\\1\\s+)", + captures: "1", + next : "start" + }]); + + this.embedRules(CoffeeHighlightRules, "coffee-", [{ + token : "support.function", + regex : "^(?!\\1\\s+)", + captures: "1", + next : "start" + }]); + + this.embedRules(JavaScriptHighlightRules, "js-", [{ + token : "support.function", + regex : "$", + captures: "1", + next : "start" + }]); */ +}; + +oop.inherits(JadeHighlightRules, TextHighlightRules); + +exports.JadeHighlightRules = JadeHighlightRules; +}); \ No newline at end of file diff --git a/lib/ace/theme/chrome.css b/lib/ace/theme/chrome.css index 000c4e53..8a50d17f 100644 --- a/lib/ace/theme/chrome.css +++ b/lib/ace/theme/chrome.css @@ -62,7 +62,8 @@ } .ace-chrome .ace_line .ace_support.ace_type, -.ace-chrome .ace_line .ace_support.ace_class { +.ace-chrome .ace_line .ace_support.ace_class +.ace-chrome .ace_line .ace_support.ace_other, { color: rgb(109, 121, 222); } diff --git a/lib/ace/theme/chrome.js b/lib/ace/theme/chrome.js index 4f26b06c..b0d02480 100644 --- a/lib/ace/theme/chrome.js +++ b/lib/ace/theme/chrome.js @@ -30,10 +30,10 @@ define(function(require, exports, module) { +exports.isDark = false; exports.cssClass = "ace-chrome"; exports.cssText = require('ace/requirejs/text!./chrome.css'); var dom = require("../lib/dom"); dom.importCssString(exports.cssText, exports.cssClass); - }); diff --git a/lib/ace/theme/clouds.css b/lib/ace/theme/clouds.css index 80364f41..3f33a7d7 100644 --- a/lib/ace/theme/clouds.css +++ b/lib/ace/theme/clouds.css @@ -1,4 +1,3 @@ - .ace-clouds .ace_editor { border: 2px solid rgb(159, 159, 159); } @@ -93,7 +92,10 @@ border-color: #000000; } -.ace-clouds .ace_support.ace_function { +.ace-clouds .ace_support.ace_function, +.ace-clouds .ace_support.ace_class, +.ace-clouds .ace_support.ace_type, +.ace-clouds .ace_support.ace_other { color:#C52727; } diff --git a/lib/ace/theme/clouds_midnight.css b/lib/ace/theme/clouds_midnight.css index 22b52c99..ba8abd68 100644 --- a/lib/ace/theme/clouds_midnight.css +++ b/lib/ace/theme/clouds_midnight.css @@ -94,7 +94,10 @@ background-color:#E92E2E; border-color: #929292; } -.ace-clouds-midnight .ace_support.ace_function { +.ace-clouds-midnight .ace_support.ace_function, +.ace-clouds-midnight .ace_support.ace_class, +.ace-clouds-midnight .ace_support.ace_type, +.ace-clouds-midnight .ace_support.ace_other { color:#E92E2E; } diff --git a/lib/ace/theme/cobalt.css b/lib/ace/theme/cobalt.css index 60fda700..f20de018 100644 --- a/lib/ace/theme/cobalt.css +++ b/lib/ace/theme/cobalt.css @@ -1,4 +1,3 @@ - .ace-cobalt .ace_editor { border: 2px solid rgb(159, 159, 159); } @@ -57,7 +56,7 @@ } .ace-cobalt .ace_gutter_active_line { - background-color : rgba(0, 0, 0, 0.35); + background-color: rgba(0, 0, 0, 0.35); } .ace-cobalt .ace_marker-layer .ace_selected_word { @@ -143,7 +142,6 @@ background-color:#001221; .ace-cobalt .ace_markup.ace_list { background-color:#130D26; } - .ace-cobalt .ace_indent-guide { background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgUHL4zzBz5sz/AA80BCzv+WXhAAAAAElFTkSuQmCC) right repeat-y; } \ No newline at end of file diff --git a/lib/ace/theme/merbivore.css b/lib/ace/theme/merbivore.css index 9b110778..19a74801 100644 --- a/lib/ace/theme/merbivore.css +++ b/lib/ace/theme/merbivore.css @@ -57,7 +57,7 @@ } .ace-merbivore .ace_gutter_active_line { - background-color : #333435; + background-color: #333435; } .ace-merbivore .ace_marker-layer .ace_selected_word { @@ -114,6 +114,10 @@ background-color:#990000; color:#FC6F09; } +.ace-merbivore .ace_support.ace_type { + color:#1EDAFB; +} + .ace-merbivore .ace_storage { color:#FC6F09; } diff --git a/lib/ace/theme/merbivore_soft.css b/lib/ace/theme/merbivore_soft.css index 55e401b1..591bd3a9 100644 --- a/lib/ace/theme/merbivore_soft.css +++ b/lib/ace/theme/merbivore_soft.css @@ -115,6 +115,10 @@ background-color:#FE3838; border-color: #E6E1DC; } +.ace-merbivore-soft .ace_support.ace_type { + color:#68C1D8; +} + .ace-merbivore-soft .ace_storage { color:#FC803A; } diff --git a/lib/ace/theme/mono_industrial.css b/lib/ace/theme/mono_industrial.css index 5d282e83..e8c79c76 100644 --- a/lib/ace/theme/mono_industrial.css +++ b/lib/ace/theme/mono_industrial.css @@ -110,6 +110,14 @@ background-color:rgba(153, 0, 0, 0.68); color:#588E60; } +.ace-mono-industrial .ace_support.ace_type { + color:#5778B6; +} + +.ace-mono-industrial .ace_support.ace_class { + color:#5778B6; +} + .ace-mono-industrial .ace_storage { color:#C23B00; } diff --git a/lib/ace/theme/monokai.css b/lib/ace/theme/monokai.css index 02d4fa9d..be54ca9b 100644 --- a/lib/ace/theme/monokai.css +++ b/lib/ace/theme/monokai.css @@ -55,6 +55,7 @@ .ace-monokai .ace_marker-layer .ace_active_line { background: #49483E; } + .ace-monokai .ace_gutter_active_line { background-color: #191916; } @@ -71,6 +72,10 @@ color:#F92672; } +.ace-monokai .ace_constant.ace_character { + color:#AE81FF; +} + .ace-monokai .ace_constant.ace_language { color:#AE81FF; } @@ -106,6 +111,16 @@ background-color:#AE81FF; color:#66D9EF; } +.ace-monokai .ace_support.ace_type { + font-style:italic; +color:#66D9EF; +} + +.ace-monokai .ace_support.ace_class { + font-style:italic; +color:#66D9EF; +} + .ace-monokai .ace_storage { color:#F92672; } diff --git a/lib/ace/theme/solarized_dark.css b/lib/ace/theme/solarized_dark.css index 11eaba93..d67fa827 100644 --- a/lib/ace/theme/solarized_dark.css +++ b/lib/ace/theme/solarized_dark.css @@ -72,6 +72,10 @@ color:#859900; } +.ace-solarized-dark .ace_constant.ace_character { + color:#CB4B16; +} + .ace-solarized-dark .ace_constant.ace_language { color:#B58900; } @@ -93,6 +97,14 @@ color:#268BD2; } +.ace-solarized-dark .ace_support.ace_type { + color:#859900; +} + +.ace-solarized-dark .ace_support.ace_class { + color:#859900; +} + .ace-solarized-dark .ace_storage { color:#93A1A1; } diff --git a/lib/ace/theme/solarized_light.css b/lib/ace/theme/solarized_light.css index d269ecc8..5f8cea3b 100644 --- a/lib/ace/theme/solarized_light.css +++ b/lib/ace/theme/solarized_light.css @@ -72,6 +72,10 @@ color:#859900; } +.ace-solarized-light .ace_constant.ace_character { + color:#CB4B16; +} + .ace-solarized-light .ace_constant.ace_language { color:#B58900; } @@ -93,6 +97,14 @@ color:#268BD2; } +.ace-solarized-light .ace_support.ace_type { + color:#859900; +} + +.ace-solarized-light .ace_support.ace_class { + color:#859900; +} + .ace-solarized-light .ace_storage { color:#073642; } diff --git a/lib/ace/theme/tomorrow.css b/lib/ace/theme/tomorrow.css index a9c04182..90ea2b72 100644 --- a/lib/ace/theme/tomorrow.css +++ b/lib/ace/theme/tomorrow.css @@ -76,6 +76,10 @@ color:#3E999F; } +.ace-tomorrow .ace_constant.ace_character { + color:#F5871F; +} + .ace-tomorrow .ace_constant.ace_language { color:#F5871F; } @@ -111,6 +115,14 @@ background-color:#8959A8; color:#4271AE; } +.ace-tomorrow .ace_support.ace_type { + color:#C99E00; +} + +.ace-tomorrow .ace_support.ace_class { + color:#C99E00; +} + .ace-tomorrow .ace_storage { color:#8959A8; } diff --git a/lib/ace/theme/tomorrow_night.css b/lib/ace/theme/tomorrow_night.css index 137e35d8..baf95470 100644 --- a/lib/ace/theme/tomorrow_night.css +++ b/lib/ace/theme/tomorrow_night.css @@ -76,6 +76,10 @@ color:#8ABEB7; } +.ace-tomorrow-night .ace_constant.ace_character { + color:#DE935F; +} + .ace-tomorrow-night .ace_constant.ace_language { color:#DE935F; } @@ -111,6 +115,14 @@ background-color:#B798BF; color:#81A2BE; } +.ace-tomorrow-night .ace_support.ace_type { + color:#F0C674; +} + +.ace-tomorrow-night .ace_support.ace_class { + color:#F0C674; +} + .ace-tomorrow-night .ace_storage { color:#B294BB; } diff --git a/lib/ace/theme/tomorrow_night_blue.css b/lib/ace/theme/tomorrow_night_blue.css index 7a8354bb..2efb818d 100644 --- a/lib/ace/theme/tomorrow_night_blue.css +++ b/lib/ace/theme/tomorrow_night_blue.css @@ -76,6 +76,10 @@ color:#99FFFF; } +.ace-tomorrow-night-blue .ace_constant.ace_character { + color:#FFC58F; +} + .ace-tomorrow-night-blue .ace_constant.ace_language { color:#FFC58F; } @@ -111,6 +115,14 @@ background-color:#EBBBFF; color:#BBDAFF; } +.ace-tomorrow-night-blue .ace_support.ace_type { + color:#FFEEAD; +} + +.ace-tomorrow-night-blue .ace_support.ace_class { + color:#FFEEAD; +} + .ace-tomorrow-night-blue .ace_storage { color:#EBBBFF; } diff --git a/lib/ace/theme/tomorrow_night_bright.css b/lib/ace/theme/tomorrow_night_bright.css index 44d944a5..3702017d 100644 --- a/lib/ace/theme/tomorrow_night_bright.css +++ b/lib/ace/theme/tomorrow_night_bright.css @@ -76,6 +76,10 @@ color:#70C0B1; } +.ace-tomorrow-night-bright .ace_constant.ace_character { + color:#E78C45; +} + .ace-tomorrow-night-bright .ace_constant.ace_language { color:#E78C45; } @@ -111,6 +115,14 @@ background-color:#B798BF; color:#7AA6DA; } +.ace-tomorrow-night-bright .ace_support.ace_type { + color:#E7C547; +} + +.ace-tomorrow-night-bright .ace_support.ace_class { + color:#E7C547; +} + .ace-tomorrow-night-bright .ace_storage { color:#C397D8; } diff --git a/lib/ace/theme/tomorrow_night_eighties.css b/lib/ace/theme/tomorrow_night_eighties.css index 1dfd9ead..714320e0 100644 --- a/lib/ace/theme/tomorrow_night_eighties.css +++ b/lib/ace/theme/tomorrow_night_eighties.css @@ -76,6 +76,10 @@ color:#66CCCC; } +.ace-tomorrow-night-eighties .ace_constant.ace_character { + color:#F99157; +} + .ace-tomorrow-night-eighties .ace_constant.ace_language { color:#F99157; } @@ -111,6 +115,14 @@ background-color:#CC99CC; color:#6699CC; } +.ace-tomorrow-night-eighties .ace_support.ace_type { + color:#FFCC66; +} + +.ace-tomorrow-night-eighties .ace_support.ace_class { + color:#FFCC66; +} + .ace-tomorrow-night-eighties .ace_storage { color:#CC99CC; } diff --git a/lib/ace/tokenizer.js b/lib/ace/tokenizer.js index ec4c973b..955e8772 100644 --- a/lib/ace/tokenizer.js +++ b/lib/ace/tokenizer.js @@ -74,7 +74,7 @@ var Tokenizer = function(rules, flag) { }); if (matchcount > 1 && state[i].token.length !== matchcount-1) - throw new Error("Matching groups and length of the token array don't match in rule #" + i + " of state " + key); + throw new Error("For " + state[i].regex + " the matching groups and length of the token array don't match (rule #" + i + " of state " + key + ")"); mapping[matchTotal] = { rule: i, @@ -139,6 +139,11 @@ var Tokenizer = function(rules, flag) { lastIndex = re.lastIndex; re = this.regExps[currentState]; + + if (re === undefined) { + throw new Error("You indicated a state of " + rule.next + " to go to, but it doesn't exist!"); + } + re.lastIndex = lastIndex; } break; diff --git a/tool/Theme.tmpl.css b/tool/Theme.tmpl.css index f1579b60..8b52ef83 100644 --- a/tool/Theme.tmpl.css +++ b/tool/Theme.tmpl.css @@ -1,3 +1,4 @@ +/* THIS THEME WAS AUTOGENERATED BY Theme.tmpl.css (UUID: %uuid%) */ .%cssClass% .ace_editor { border: 2px solid rgb(159, 159, 159); @@ -80,12 +81,12 @@ %constant% } -.%cssClass% .ace_constant.ace_character, { - %constant% +.%cssClass% .ace_constant.ace_character { + %constant.character% } -.%cssClass% .ace_constant.ace_character.ace_escape, { - %constant% +.%cssClass% .ace_constant.ace_character.ace_escape { + %constant.character.escape% } .%cssClass% .ace_constant.ace_language { @@ -133,6 +134,18 @@ %support.function% } +.%cssClass% .ace_support.ace_type { + %support.type% +} + +.%cssClass% .ace_support.ace_class { + %support.class% +} + +.%cssClass% .ace_support.ace_other { + %support.other% +} + .%cssClass% .ace_storage { %storage% } diff --git a/tool/mode.tmpl.js b/tool/mode.tmpl.js new file mode 100644 index 00000000..3a3e4c60 --- /dev/null +++ b/tool/mode.tmpl.js @@ -0,0 +1,60 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2012, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * Contributor(s): + * + * + * + * ***** END LICENSE BLOCK ***** */ + +/* + THIS FILE WAS AUTOGENERATED BY mode.tmpl.js +*/ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextMode = require("./text").Mode; +var Tokenizer = require("../tokenizer").Tokenizer; +var %language%HighlightRules = require("./%languageHighlightFilename%_highlight_rules").%language%HighlightRules; + +var Mode = function() { + var highlighter = new %language%HighlightRules(); + + this.$tokenizer = new Tokenizer(highlighter.getRules()); +}; +oop.inherits(Mode, TextMode); + +(function() { + // Extra logic goes here. +}).call(Mode.prototype); + +exports.Mode = Mode; +}); \ No newline at end of file diff --git a/tool/mode_highlight_rules.tmpl.js b/tool/mode_highlight_rules.tmpl.js new file mode 100644 index 00000000..e6d99137 --- /dev/null +++ b/tool/mode_highlight_rules.tmpl.js @@ -0,0 +1,79 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2012, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * Contributor(s): + * + * + * + * ***** END LICENSE BLOCK ***** */ + +/* + THIS FILE WAS AUTOGENERATED BY mode_highlight_rules.tmpl.js (UUID: %uuid%) */ + +/******* + + THIS FILE MIGHT NOT BE PERFECT, PARTICULARLY: + + IN DECIDING STATES TO TRANSITION TO, + + IGNORING WHITESPACE, + + IGNORING GROUPS WITH ?:, + + EXTENDING EXISTING MODES, + + GATHERING KEYWORDS, OR + + RULE PREFERENCE ORDER. + + ...But it's a good start from an existing *.tmlanguage file. + +*******/ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; + +var %language%HighlightRules = function() { + + // regexp must not have capturing parentheses. Use (?:) instead. + // regexps are ordered -> the first match is used + + this.$rules = + %languageTokens% + + %respositoryRules% +}; + +oop.inherits(%language%HighlightRules, TextHighlightRules); + +exports.%language%HighlightRules = %language%HighlightRules; +}); \ No newline at end of file diff --git a/tool/theme.tmpl.js b/tool/theme.tmpl.js index 0d980a3a..dfaf0bf5 100644 --- a/tool/theme.tmpl.js +++ b/tool/theme.tmpl.js @@ -34,6 +34,6 @@ exports.isDark = %isDark%; exports.cssClass = "%cssClass%"; exports.cssText = %css%; - var dom = require("../lib/dom"); - dom.importCssString(exports.cssText, exports.cssClass); +var dom = require("../lib/dom"); +dom.importCssString(exports.cssText, exports.cssClass); }); diff --git a/tool/tmlanguage.js b/tool/tmlanguage.js new file mode 100644 index 00000000..6a6fcb03 --- /dev/null +++ b/tool/tmlanguage.js @@ -0,0 +1,287 @@ +var fs = require("fs"); +var util = require("util"); + +// for tracking token states +var startState = { start: [] }, statesObj = { }; + + +var args = process.argv.splice(2); +var tmLanguageFile = args[0]; +var devMode = args[1]; + +var parseString = require("plist").parseString; +function parseLanguage(languageXml, callback) { + parseString(languageXml, function(_, language) { + callback(language[0]) + }); +} + +function logDebug(string, obj) { + console.log(string, obj); +} + +String.prototype.splice = function( idx, rem, s ) { + return (this.slice(0,idx) + s + this.slice(idx + Math.abs(rem))); +}; + +String.prototype.replaceAt = function (index, char) { + return this.substr(0, index) + char + this.substr(index + 1); +} + +function keyCount(obj) { + return Object.keys(obj).length; +} + +/** + +Scrubbing is sometimes necessary, but there appears to be no +automated way to do it... + + +function cleanSingleCapture(match) { + // if there's a single "( )", screw that and make it "(?: )" + return match.replace("(", "(?:"); +} + +function cleanMultiCapture(match) { + // regexp will be a quoted string, so turn "\" into "\\" + var spaceFinderRegExp = new RegExp("\\\\s.| .", "g"); + var m; + /* + essentially turns things like + + \\s*(mixin) ([\\w\\-]+)\\s*(\\() + + into + + (\\s*mixin)( [\\w\\-]+)(\\s*\\() + + so that mode parser stops complaining + + while ((m = spaceFinderRegExp.exec(match)) != null) { + var idx = m.index; + var nextParenIdx = match.indexOf("(", idx); + + if (nextParenIdx > idx) { + match = match.splice(idx, 0, "(").replaceAt(nextParenIdx + 1, ''); + } + } + + //console.log("match", match); + return match; +} +*/ + +// stupid yet necessary function, to transform JSON id comments into real comments +function restoreComments(objStr) { + return objStr.replace(/"\s+(\/\/.+)",/g, "\$1").replace(/ \/\/ ERROR/g, '", // ERROR'); +} + +function checkForLookBehind(str) { + var lookbehindRegExp = new RegExp("\\?<[=|!]", "g"); + return lookbehindRegExp.test(str) ? str + " // ERROR: This contains a lookbehind, which JS does not support :(" : str; +} + +function removeXFlag(str) { + if (str.slice(0,4) == "(?x)") { + str = str.substr(4).replace(/\\[\s#]|\s+|(?:#[^\n]*)/g, function(s) { + return s[0] == "\\" ? s[1] : ""; + }); + } + return str; +} + +function transformRegExp(str) { + str = removeXFlag(str); + str = checkForLookBehind(str); + return str; +} + +function assembleStateObjs(strState, pattern) { + var patterns = pattern.patterns; + var stateObj = {}; + var tokenElem = []; + + if (patterns) { + for (var p in patterns) { + stateObj = {}; // this is apparently necessary + + if (patterns[p].include) { + stateObj.include = patterns[p].include; + } + else { + stateObj.token = patterns[p].name; + stateObj.regex = transformRegExp(patterns[p].match); + } + statesObj[strState].push(stateObj); + } + + stateObj = {}; + stateObj.token = "TODO"; + stateObj.regex = transformRegExp(pattern.end); + stateObj.next = "start"; + } + else { + stateObj.token = "TODO"; + stateObj.regex = transformRegExp(pattern.end); + stateObj.next = "start"; + + statesObj[strState].push(stateObj); + + stateObj = {}; + stateObj.token = "TODO"; + stateObj.regex = ".+"; + stateObj.next = strState; + } + + return stateObj; +} + +function extractPatterns(patterns) { + var state = 0; + patterns.forEach(function(pattern) { + state++; + var i = 1; + var tokenArray = []; + var tokenObj = { token: [] }; + var stateObj = {}; + + if (pattern.comment) { + startState.start.push(" // " + pattern.comment.trim()); + } + + // it needs a state transition + if (pattern.begin && pattern.end) { + var strState = "state_" + state; + if ( pattern.beginCaptures === undefined && pattern.endCaptures === undefined) { + tokenObj.token.push(pattern.captures); + } + else if (pattern.beginCaptures) { + tokenObj.token.push(pattern.beginCaptures); + } + else if (pattern.endCaptures) { + tokenObj.token.push(pattern.endCaptures); + } + + if (tokenObj.token === undefined) { + if (pattern.name) + tokenObj.token.push(pattern.name); + else + logDebug("There's no token name for this state transition", pattern) + } + + if (tokenObj.token === undefined) { + tokenObj.token.push(pattern.name); + } + + statesObj[strState] = [ ]; + statesObj[strState].push(assembleStateObjs(strState, pattern)); + + tokenObj.regex = transformRegExp(pattern.begin); + tokenObj.next = strState; + } + else if( ( pattern.begin || pattern.end ) && !( pattern.begin && pattern.end ) ) { + logDebug("Somehow, there's pattern.begin or pattern.end--but not both?", pattern); + } + + else if (pattern.captures) { + tokenObj.token.push([]); + tokenObj.token.push(pattern.captures); + tokenObj.regex = transformRegExp(pattern.match); + } + + else if (pattern.match) { + tokenObj.token.push(pattern.name); + tokenObj.regex = transformRegExp(pattern.match); + } + + else if (pattern.include) { + tokenObj.token.push(pattern.include); + tokenObj.regex = ""; + } + + else { + tokenObj.token.push(""); + tokenObj.regex = ""; + logDebug("I've gone through every choice, and have no clue what this is:", pattern); + } + + // sometimes captures have names--not sure when or why + if (pattern.name) { + tokenObj.token.push(pattern.name); + } + + startState.start.push(tokenObj); + }); + + var resultingObj = startState; + + for (var state in statesObj) { + resultingObj[state] = statesObj[state]; + } + + return restoreComments(JSON.stringify(resultingObj, null, " ")); +} + +function fillTemplate(template, replacements) { + return template.replace(/%(.+?)%/g, function(str, m) { + return replacements[m] || ""; + }); +} + +var modeTemplate = fs.readFileSync(__dirname + "/mode.tmpl.js", "utf8"); +var modeHighlightTemplate = fs.readFileSync(__dirname + "/mode_highlight_rules.tmpl.js", "utf8"); + +function convertLanguage(name) { + var tmLanguage = fs.readFileSync(__dirname + "/" + name, "utf8"); + parseLanguage(tmLanguage, function(language) { + var languageHighlightFilename = language.name.replace(/[-_]/g, "").toLowerCase(); + var languageNameSanitized = language.name.replace(/-/g, ""); + + var languageHighlightFile = __dirname + "/../lib/ace/mode/" + languageHighlightFilename + "_highlight_rules.js"; + var languageModeFile = __dirname + "/../lib/ace/mode/" + languageHighlightFilename + ".js"; + + console.log("Converting " + name + " to " + languageHighlightFile); + + if (devMode) { + console.log(util.inspect(language.patterns, false, 4)); + console.log(util.inspect(language.repository, false, 4)); + } + + var languageMode = fillTemplate(modeTemplate, { + language: languageNameSanitized, + languageHighlightFilename: languageHighlightFilename + }); + + var patterns = extractPatterns(language.patterns); + var repository = {}; + + if (language.repository) { + for (var r in language.repository) { + repository[r] = language.repository[r]; + } + repository = restoreComments(JSON.stringify(repository, null, " ")); + } + + var languageHighlightRules = fillTemplate(modeHighlightTemplate, { + language: languageNameSanitized, + languageTokens: patterns, + respositoryRules: "/*** START REPOSITORY RULES\n" + repository + "\nEND REPOSITORY RULES ***/", + uuid: language.uuid + }); + + if (devMode) { + console.log("Not writing, 'cause we're in dev mode, baby."); + } + else { + fs.writeFileSync(languageHighlightFile, languageHighlightRules); + fs.writeFileSync(languageModeFile, languageMode); + } + }); +} + +if (tmLanguageFile === undefined) { + console.error("Please pass in a language file via the command line."); + process.exit(1); +} +convertLanguage(tmLanguageFile); \ No newline at end of file diff --git a/tool/tmtheme.js b/tool/tmtheme.js index d56cf766..fca5453b 100755 --- a/tool/tmtheme.js +++ b/tool/tmtheme.js @@ -2,14 +2,11 @@ var fs = require("fs"); var parseString = require("plist").parseString; function parseTheme(themeXml, callback) { - parseString(themeXml, function(_, theme) { - console.log(theme) - callback(theme[0]) - }); + parseString(themeXml, function(_, theme) { + callback(theme[0]) + }); } - - var supportedScopes = { "keyword": "keyword", "keyword.operator": "keyword.operator", @@ -28,6 +25,9 @@ var supportedScopes = { "support.function.firebug": "support.firebug", "support.function.constant": "support.function.constant", "support.constant": "support.constant", + "support.class": "support.class", + "support.type": "support.type", + "support.other": "support.other", "function": "function", "function.buildin": "function.buildin", @@ -178,10 +178,15 @@ var cssTemplate = fs.readFileSync(__dirname + "/Theme.tmpl.css", "utf8"); var jsTemplate = fs.readFileSync(__dirname + "/Theme.tmpl.js", "utf8"); var themes = { + //"chrome": "Chrome", "clouds": "Clouds", "clouds_midnight": "Clouds Midnight", "cobalt": "Cobalt", + //"crimson_editor": "Crimson Editor", "dawn": "Dawn", + //"dreamweaver": "Dreamweaver", + //"eclipse": "Eclipse", + //"github": "GitHub", "idle_fingers": "idleFingers", "kr_theme": "krTheme", "merbivore": "Merbivore", @@ -191,6 +196,7 @@ var themes = { "pastel_on_dark": "Pastels on Dark", "solarized_dark": "Solarized-dark", "solarized_light": "Solarized-light", + //"textmate": "Textmate", "tomorrow": "Tomorrow", "tomorrow_night": "Tomorrow-Night", "tomorrow_night_blue": "Tomorrow-Night-Blue", @@ -203,24 +209,25 @@ var themes = { function convertTheme(name) { console.log("Converting " + name); var tmTheme = fs.readFileSync(__dirname + "/tmthemes/" + themes[name] + ".tmTheme", "utf8"); - parseTheme(tmTheme, function(theme) { - var styles = extractStyles(theme); + parseTheme(tmTheme, function(theme) { + var styles = extractStyles(theme); - styles.cssClass = "ace-" + hyphenate(name); - var css = fillTemplate(cssTemplate, styles); - css = css.replace(/[^\{\}]+{\s*}/g, ""); + styles.cssClass = "ace-" + hyphenate(name); + styles.uuid = theme.uuid; + var css = fillTemplate(cssTemplate, styles); + css = css.replace(/[^\{\}]+{\s*}/g, ""); - var js = fillTemplate(jsTemplate, { - name: name, - css: "require('ace/requirejs/text!./" + name + ".css')", // quoteString(css), // - cssClass: "ace-" + hyphenate(name), - isDark: styles.isDark - }); + var js = fillTemplate(jsTemplate, { + name: name, + css: "require('ace/requirejs/text!./" + name + ".css')", // quoteString(css), // + cssClass: "ace-" + hyphenate(name), + isDark: styles.isDark + }); - fs.writeFileSync(__dirname + "/../lib/ace/theme/" + name + ".js", js); - fs.writeFileSync(__dirname + "/../lib/ace/theme/" + name + ".css", css); - }) + fs.writeFileSync(__dirname + "/../lib/ace/theme/" + name + ".js", js); + fs.writeFileSync(__dirname + "/../lib/ace/theme/" + name + ".css", css); + }) } for (var name in themes) - convertTheme(name); \ No newline at end of file + convertTheme(name); \ No newline at end of file