diff --git a/.gitignore b/.gitignore index c6a7ecc9975..604e1a96a19 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,16 @@ jam/ .git-ref npm-debug.log deps/ + +# themedump-generated files +plotdevice/editor +plotdevice/autocomplete.css +plotdevice/themes.json + +# plotdevice-specific syntax & themes +lib/ace/mode/plotdevice.js +lib/ace/mode/plotdevice_highlight_rules.js +lib/ace/snippets/plotdevice.js +lib/ace/snippets/plotdevice.snippets +lib/ace/theme/blackboard.css +lib/ace/theme/blackboard.js \ No newline at end of file diff --git a/Makefile b/Makefile index 95dcf964cb7..c2500425349 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ pre_build: mkdir -p build/src mkdir -p build/demo/kitchen-sink mkdir -p build/textarea/src - + cp -r demo/kitchen-sink/styles.css build/demo/kitchen-sink/styles.css cp demo/kitchen-sink/logo.png build/demo/kitchen-sink/logo.png cp -r doc/site/images build/textarea @@ -18,14 +18,27 @@ build: pre_build # Minimal build: call Makefile.dryice.js only if our sources changed basic: build/src/ace.js -build/src/ace.js : ${wildcard lib/*} \ - ${wildcard lib/*/*} \ - ${wildcard lib/*/*/*} \ - ${wildcard lib/*/*/*/*} \ - ${wildcard lib/*/*/*/*/*} \ - ${wildcard lib/*/*/*/*/*/*} +build/src/ace.js: ${wildcard lib/*} \ + ${wildcard lib/*/*} \ + ${wildcard lib/*/*/*} \ + ${wildcard lib/*/*/*/*} \ + ${wildcard lib/*/*/*/*/*} \ + ${wildcard lib/*/*/*/*/*/*} ./Makefile.dryice.js +plotdevice/editor/ace-min.js: ${wildcard lib/*} \ + ${wildcard lib/*/*} \ + ${wildcard lib/*/*/*} \ + ${wildcard lib/*/*/*/*} \ + ${wildcard lib/*/*/*/*/*} \ + ${wildcard lib/*/*/*/*/*/*} + /usr/local/bin/node ./Makefile-plod.dryice.js minimal --s --target plotdevice/editor + +install: plotdevice/editor/ace-min.js + @yui plotdevice/editor/ace-min.js > ../plotdevice/app/Resources/ui/js/ace.js + @cp plotdevice/themes.json ../plotdevice/app/Resources/ui/themes.json + @cp plotdevice/autocomplete.css ../plotdevice/app/Resources/ui/autocomplete.css + doc: cd doc;\ (test -d node_modules && npm update) || npm install;\ diff --git a/Makefile-plod.dryice.js b/Makefile-plod.dryice.js new file mode 100755 index 00000000000..139e205ed27 --- /dev/null +++ b/Makefile-plod.dryice.js @@ -0,0 +1,730 @@ +#!/usr/bin/env node +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * 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 + * 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. + * + * ***** END LICENSE BLOCK ***** */ + +var fs = require("fs"); +var path = require("path"); +if (!fs.existsSync) + fs.existsSync = path.existsSync; +else + path.existsSync = fs.existsSync; +var copy = require('dryice').copy; + +var ACE_HOME = __dirname; +var BUILD_DIR = ACE_HOME + "/build"; + +function main(args) { + if (args.indexOf("updateModes") !== -1) { + return updateModes(); + } + var type = "minimal"; + args = args.map(function(x) { + if (x[0] == "-" && x[1] != "-") + return "-" + x; + return x; + }); + + if (args[2] && (args[2][0] != "-" || args[2].indexOf("h") != -1)) + type = args[2]; + + var i = args.indexOf("--target"); + if (i != -1 && args[i+1]) + BUILD_DIR = args[i+1]; + + if (args.indexOf("--h") == -1) { + if (type == "minimal") { + buildAce({ + compress: args.indexOf("--m") != -1, + noconflict: args.indexOf("--nc") != -1, + shrinkwrap: args.indexOf("--s") != -1 + }); + } else if (type == "normal") { + ace(); + } else if (type == "demo") { + demo(); + } else if (type == "bm") { + bookmarklet(); + } else if (type == "full") { + demo(ace()); + bookmarklet(); + } else if (type == "highlighter") { + var project = buildAce({ + coreOnly: true, + exportModule: "ace/ext/static_highlight", + requires: ["ace/ext/static_highlight", "ace/theme/textmate"], + readFilters: [copy.filter.moduleDefines, function(a) { + console.log(a.substring(0, 2500)) + return a + }] + }) + copy({ + source: project.result, + filter: getWriteFilters(project.options, "main"), + dest: BUILD_DIR + "/static_highlight.js" + }); + } + } + + console.log("--- Ace Dryice Build Tool ---"); + console.log(""); + console.log("Options:"); + console.log(" minimal Places necessary Ace files out in build dir; uses configuration flags below [default]"); + console.log(" normal Runs four Ace builds--minimal, minimal-noconflict, minimal-min, and minimal-noconflict-min"); + console.log(" demo Runs demo build of Ace"); + console.log(" bm Runs bookmarklet build of Ace"); + console.log(" full all of above"); + console.log(" highlighter "); + console.log("args:"); + console.log(" --target ./path path to build folder"); + console.log("flags:"); + console.log(" --h print this help"); + console.log(" --m minify"); + console.log(" --nc namespace require"); + console.log(" --s shrinkwrap (combines all output files into one)"); + console.log(""); + if (BUILD_DIR) + console.log(" output generated in " + type + __dirname + "/" + BUILD_DIR) +} + +function bookmarklet() { + var targetDir = BUILD_DIR + "/textarea"; + copy({ + source: "build_support/editor_textarea.html", + dest: targetDir + '/editor.html' + }); + copy({ + source: "build_support/style.css", + dest: targetDir + '/style.css' + }); + + buildAce({ + targetDir: targetDir + "/src", + ns: "__ace_shadowed__", + exportModule: "ace/ext/textarea", + compress: false, + noconflict: true, + suffix: "", + name: "ace-bookmarklet", + workers: [], + keybindings: [] + }); +} + +function ace() { + console.log('# ace ---------'); + + // uncompressed + var project = buildAce({ + compress: false, + noconflict: false + }); + buildAce({ + compress: false, + noconflict: true + }); + + // compressed + buildAce({ + compress: true, + noconflict: false + }); + buildAce({ + compress: true, + noconflict: true + }); + + console.log('# ace License | Readme | Changelog ---------'); + + copy({ + source: ACE_HOME + "/build_support/editor.html", + dest: BUILD_DIR + "/editor.html" + }); + copy({ + source: ACE_HOME + "/LICENSE", + dest: BUILD_DIR + "/LICENSE" + }); + copy({ + source: ACE_HOME + "/ChangeLog.txt", + dest: BUILD_DIR + "/ChangeLog.txt" + }); + + return project; +} + +function demo(project) { + project = project || buildAce({ + compress: false, + noconflict: false, + coreOnly: true + }); + console.log('# kitchen sink ---------'); + + var version, ref; + try { + version = JSON.parse(fs.readFileSync(ACE_HOME + "/package.json")).version; + ref = fs.readFileSync(ACE_HOME + "/.git-ref").toString(); + } catch(e) { + ref = ""; + version = ""; + } + + function changeComments(data) { + return (data + .replace(//g, "") + .replace(/PACKAGE\-\->|=0;){ + if (!results[i]) continue + if (results[i].meta=='local' && keywords.indexOf(results[i].caption)!=-1){ + results.splice(i,1) + } + } + return results; }; }).call(FilteredList.prototype); diff --git a/lib/ace/document.js b/lib/ace/document.js index a2ca72104ac..b35b6673208 100644 --- a/lib/ace/document.js +++ b/lib/ace/document.js @@ -69,6 +69,10 @@ var Document = function(text) { oop.implement(this, EventEmitter); + this.initialize = function(text) { + this.refresh(text); + }; + /** * Replaces all the lines in the current `Document` with the value of `text`. * @@ -78,6 +82,7 @@ var Document = function(text) { var len = this.getLength(); this.remove(new Range(0, 0, len, this.getLine(len-1).length)); this.insert({row: 0, column:0}, text); + // this.refresh(text); // patch in a version of _insertLines that emits a separate event }; /** @@ -265,6 +270,31 @@ var Document = function(text) { return position; }; + this.refresh = function(text, row){ + var row = row || 0 + var lines = this.$split(text); + + // apply doesn't work for big arrays (smallest threshold is on safari 0xFFFF) + // to circumvent that we have to break huge inserts into smaller chunks here + if (lines.length > 0xFFFF) { + var end = this.refresh(row, lines.slice(0xFFFF)); + lines = lines.slice(0, 0xFFFF); + } + + var args = [row, 0]; + args.push.apply(args, lines); + this.$lines.splice.apply(this.$lines, args); + var range = new Range(row, 0, row + lines.length, 0); + var delta = { + action: "insertLines", + context: 'refresh', + range: range, + lines: lines + }; + this._emit("change", { data: delta }); + return {row:0, column:0}; + } + /** * Fires whenever the document changes. * diff --git a/lib/ace/mouse/default_gutter_handler.js b/lib/ace/mouse/default_gutter_handler.js index 1b5cb98607c..d8cdfd2ac18 100644 --- a/lib/ace/mouse/default_gutter_handler.js +++ b/lib/ace/mouse/default_gutter_handler.js @@ -87,7 +87,9 @@ function GutterHandler(mouseHandler) { tooltipAnnotation = annotation.text.join("
"); tooltip.setHtml(tooltipAnnotation); - tooltip.show(); + if (tooltipAnnotation.length){ + tooltip.show(); + } editor.on("mousewheel", hideTooltip); if (mouseHandler.$tooltipFollowsMouse) { diff --git a/plotdevice/mode/plotdevice.js b/plotdevice/mode/plotdevice.js new file mode 100644 index 00000000000..d1520d968b2 --- /dev/null +++ b/plotdevice/mode/plotdevice.js @@ -0,0 +1,117 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * 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 + * 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. + * + * ***** 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 PlotDeviceHighlightRules = require("./plotdevice_highlight_rules").PlotDeviceHighlightRules; +var PythonFoldMode = require("./folding/pythonic").FoldMode; +var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour; +var Range = require("../range").Range; + +var Mode = function() { + this.HighlightRules = PlotDeviceHighlightRules; + this.foldingRules = new PythonFoldMode("\\:"); + this.$behaviour = new CstyleBehaviour(); + +}; +oop.inherits(Mode, TextMode); + +(function() { + + this.lineCommentStart = "#"; + + this.getNextLineIndent = function(state, line, tab) { + var indent = this.$getIndent(line); + + var tokenizedLine = this.getTokenizer().getLineTokens(line, state); + var tokens = tokenizedLine.tokens; + + if (tokens.length && tokens[tokens.length-1].type == "comment") { + return indent; + } + + if (state == "start") { + var match = line.match(/^.*[\{\(\[\:]\s*$/); + if (match) { + indent += tab; + } + } + + return indent; + }; + + var outdents = { + "pass": 1, + "return": 1, + "raise": 1, + "break": 1, + "continue": 1 + }; + + this.checkOutdent = function(state, line, input) { + if (input !== "\r\n" && input !== "\r" && input !== "\n") + return false; + + var tokens = this.getTokenizer().getLineTokens(line.trim(), state).tokens; + + if (!tokens) + return false; + + // ignore trailing comments + do { + var last = tokens.pop(); + } while (last && (last.type == "comment" || (last.type == "text" && last.value.match(/^\s+$/)))); + + if (!last) + return false; + + return (last.type == "keyword" && outdents[last.value]); + }; + + this.autoOutdent = function(state, doc, row) { + // outdenting in python is slightly different because it always applies + // to the next line and only of a new line is inserted + + row += 1; + var indent = this.$getIndent(doc.getLine(row)); + var tab = doc.getTabString(); + if (indent.slice(-tab.length) == tab) + doc.remove(new Range(row, indent.length-tab.length, row, indent.length)); + }; + + this.$id = "ace/mode/plotdevice"; +}).call(Mode.prototype); + +exports.Mode = Mode; +}); diff --git a/plotdevice/mode/plotdevice_highlight_rules.js b/plotdevice/mode/plotdevice_highlight_rules.js new file mode 100644 index 00000000000..b43764e86f5 --- /dev/null +++ b/plotdevice/mode/plotdevice_highlight_rules.js @@ -0,0 +1,250 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * 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 + * 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. + * + * ***** END LICENSE BLOCK ***** */ +/* + * TODO: python delimiters + */ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; + +var PlotDeviceHighlightRules = function() { + + var builtinKeywords = [ + "and", "as", "assert", "break", "class", "continue", "def", "del", "elif", "else", "except", + "exec", "finally", "for", "from", "global", "if", "import", "in", "is", "lambda", "not", "or", + "pass", "print", "raise", "return", "try", "while", "with", "yield" + ] + + var plodClasses = [ + 'Bezier', 'BezierPath', 'Color', 'Curve', 'Effect', 'Family', 'Font', + 'Gradient', 'Grob', 'Image', 'Mask', 'PathElement', 'Pattern', 'Point', + 'Region', 'Shadow', 'Size', 'Stylesheet', 'Text', 'Transform', 'Variable', + 'adict', 'ddict', 'odict' + ] + + var builtinConstants = ["True", "False", "None", "NotImplemented", "Ellipsis", "__debug__"] + var plodInteractive = ["MOUSEX", "MOUSEY", "KEY_UP", "KEY_DOWN", "KEY_LEFT", "KEY_RIGHT", "keydown", "mousedown", "keycode", "key"] + + var plodNumeric = [ + 'BEVEL', 'BOOLEAN', 'BUTT', 'BUTTON', 'CENTER', 'CLOSE', 'CMYK', 'CORNER', + 'CURVETO', 'DEFAULT', 'DEGREES', 'FORTYFIVE', 'FRAME', 'GREY', 'HEIGHT', 'HSV', + 'JUSTIFY', 'KEY_BACKSPACE', 'KEY_DOWN', 'KEY_ESC', 'KEY_LEFT', 'KEY_RIGHT', + 'KEY_TAB', 'KEY_UP', 'LEFT', 'LINETO', 'MITER', 'MOVETO', 'NORMAL', 'NUMBER', + 'PAGE', 'PERCENT', 'RADIANS', 'RGB', 'RIGHT', 'ROUND', 'SQUARE', 'TEXT', 'WIDTH', + 'cm', 'inch', 'mm', 'pi', 'pica', 'px', 'tau' + ] + + var builtinFunctions = [ + "abs", "divmod", "input", "open", "staticmethod", "all", "enumerate", "int", "ord", "str", "any", + "eval", "isinstance", "pow", "sum", "basestring", "execfile", "issubclass", "print", "super", + "binfile", "iter", "property", "tuple", "bool", "filter", "len", "range", "type", "bytearray", + "float", "list", "raw_input", "unichr", "callable", "format", "locals", "reduce", "unicode", + "chr", "frozenset", "long", "reload", "vars", "classmethod", "getattr", "map", "repr", "xrange", + "cmp", "globals", "max", "reversed", "zip", "compile", "hasattr", "memoryview", "round", + "__import__", "complex", "hash", "min", "set", "apply", "delattr", "help", "next", "setattr", + "buffer", "dict", "hex", "object", "slice", "coerce", "dir", "id", "oct", "sorted", "intern" + ] + + var plodFunctions = [ + 'align', 'alpha', 'arc', 'arcto', 'arrow', 'autoclosepath', 'autotext', + 'background', 'beginclip', 'beginpath', 'bezier', 'blend', 'canvas', + 'capstyle', 'choice', 'clear', 'clip', 'closepath', 'color', 'colormode', + 'colorrange', 'curveto', 'drawpath', 'ellipse', 'endclip', 'endpath', + 'export', 'files', 'fill', 'findpath', 'font', 'fonts', 'fontsize', + 'geometry', 'grid', 'image', 'imagesize', 'joinstyle', 'line', 'lineheight', + 'lineto', 'mask', 'measure', 'moveto', 'nofill', 'noshadow', 'nostroke', + 'order', 'ordered', 'outputmode', 'oval', 'pen', 'plot', 'poly', 'pop', + 'push', 'random', 'read', 'rect', 'reset', 'rotate', 'scale', 'shadow', + 'shuffled', 'size', 'skew', 'speed', 'star', 'stroke', 'strokewidth', + 'stylesheet', 'text', 'textheight', 'textmetrics', 'textpath', 'textwidth', + 'transform', 'translate', "var", 'ximport' + ] + + var colorEntities = ('aliceblue|antiquewhite|aqua|aquamarine|azure|bark|beige|bisque|black|blanchedalmond|blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|gray|green|greenyellow|grey|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightsteelblue|lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|purple|red|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|snow|springgreen|steelblue|tan|teal|thistle|tomato|transparent|turquoise|violet|wheat|white|whitesmoke|yellow|yellowgreen'); + var colorCodes = '(#?[a-f0-9]{3}([a-f0-9]{3}([a-f0-9]{2})?)?\\b)' + + var keywordMapper = this.createKeywordMapper({ + "invalid.deprecated": "debugger", + "support.function": builtinFunctions.concat(plodFunctions).join("|"), + "constant.language": builtinConstants.concat(plodInteractive).join("|"), + "constant.numeric": plodNumeric.join("|"), + "keyword": builtinKeywords.concat(plodClasses).join("|") + }, "identifier"); + + var strPre = "(?:r|u|ur|R|U|UR|Ur|uR)?"; + + var decimalInteger = "(?:(?:[1-9]\\d*)|(?:0))"; + var octInteger = "(?:0[oO]?[0-7]+)"; + var hexInteger = "(?:0[xX][\\dA-Fa-f]+)"; + var binInteger = "(?:0[bB][01]+)"; + var integer = "(?:" + decimalInteger + "|" + octInteger + "|" + hexInteger + "|" + binInteger + ")"; + + var exponent = "(?:[eE][+-]?\\d+)"; + var fraction = "(?:\\.\\d+)"; + var intPart = "(?:\\d+)"; + var pointFloat = "(?:(?:" + intPart + "?" + fraction + ")|(?:" + intPart + "\\.))"; + var exponentFloat = "(?:(?:" + pointFloat + "|" + intPart + ")" + exponent + ")"; + var floatNumber = "(?:" + exponentFloat + "|" + pointFloat + ")"; + var colorString = "'(" + colorCodes + "|" + colorEntities + ")'" + var qcolorString = '"(' + colorCodes + '|' + colorEntities + ')"' + + var stringEscape = "\\\\(x[0-9A-Fa-f]{2}|[0-7]{3}|[\\\\abfnrtv'\"]|U[0-9A-Fa-f]{8}|u[0-9A-Fa-f]{4})"; + + this.$rules = { + "start" : [ { + token : "comment", + regex : "#.*$" + }, { + token : "keyword", + regex : '\\bdef\\b|\\bclass\\b', + next : "define" + }, { + token : "constant.numeric", // string containing a hex or named color + regex : colorString + }, { + token : "constant.numeric", // string containing a hex or named color + regex : qcolorString + }, { + token : "string", // multi line """ string start + regex : strPre + '"{3}', + next : "qqstring3" + }, { + token : "string", // " string + regex : strPre + '"(?=.)', + next : "qqstring" + }, { + token : "string", // multi line ''' string start + regex : strPre + "'{3}", + next : "qstring3" + }, { + token : "string", // ' string + regex : strPre + "'(?=.)", + next : "qstring" + }, { + token : "constant.numeric", // imaginary + regex : "(?:" + floatNumber + "|\\d+)[jJ]\\b" + }, { + token : "constant.numeric", // float + regex : floatNumber + }, { + token : "constant.numeric", // long integer + regex : integer + "[lL]\\b" + }, { + token : "constant.numeric", // integer + regex : integer + "\\b" + }, { + token : keywordMapper, + regex : "[a-zA-Z_$][a-zA-Z0-9_$]*\\b" + }, { + token : "keyword.operator", + regex : "\\+|\\-|\\*|\\*\\*|\\/|\\/\\/|%|<<|>>|&|\\||\\^|~|<|>|<=|=>|==|!=|<>|=" + }, { + token : "paren.lparen", + regex : "[\\[\\(\\{]" + }, { + token : "paren.rparen", + regex : "[\\]\\)\\}]" + }, { + token : "text", + regex : "\\s+" + } ], + "define":[ + { + token : "constant.language", + regex : "def|class" + }, + { + token : "variable.language", + regex : "[A-Za-z_][A-Za-z0-9_]*", + next : "start" + }, + { + token : "text", + regex : "\\s+" + } + ], + "qqstring3" : [ { + token : "constant.language.escape", + regex : stringEscape + }, { + token : "string", // multi line """ string end + regex : '"{3}', + next : "start" + }, { + defaultToken : "string" + } ], + "qstring3" : [ { + token : "constant.language.escape", + regex : stringEscape + }, { + token : "string", // multi line ''' string end + regex : "'{3}", + next : "start" + }, { + defaultToken : "string" + } ], + "qqstring" : [{ + token : "constant.language.escape", + regex : stringEscape + }, { + token : "string", + regex : "\\\\$", + next : "qqstring" + }, { + token : "string", + regex : '"|$', + next : "start" + }, { + defaultToken: "string" + }], + "qstring" : [{ + token : "constant.language.escape", + regex : stringEscape + }, { + token : "string", + regex : "\\\\$", + next : "qstring" + }, { + token : "string", + regex : "'|$", + next : "start" + }, { + defaultToken: "string" + }] + }; +}; + +oop.inherits(PlotDeviceHighlightRules, TextHighlightRules); + +exports.PlotDeviceHighlightRules = PlotDeviceHighlightRules; +}); diff --git a/plotdevice/snippets/plotdevice.js b/plotdevice/snippets/plotdevice.js new file mode 100644 index 00000000000..39ec6a52ae8 --- /dev/null +++ b/plotdevice/snippets/plotdevice.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./plotdevice.snippets"); +exports.scope = "plotdevice"; + +}); diff --git a/plotdevice/snippets/plotdevice.snippets b/plotdevice/snippets/plotdevice.snippets new file mode 100644 index 00000000000..1fd5352f09a --- /dev/null +++ b/plotdevice/snippets/plotdevice.snippets @@ -0,0 +1,254 @@ +### general purpose + +snippet { + {"${1:k}":${2:v}, kw$3} +snippet kw + "${1:k}":${2:v}, kw$3 +snippet dict + dict(${1:k}=${2:v}, dkw$3) +snippet dkw + ${1:k}=${2:v}, dkw$3 +snippet t + True +snippet f + False +snippet lorem + "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." +snippet draw + def draw(state): + print FRAME$1 +snippet setup + def setup(state): + $1 +snippet stop + def stop(state): + $1 +snippet anim + speed(${1:30})$2 + def setup(state): + pass + def draw(state): + print FRAME + def stop(state): + pass + + +### Some handy abbreviations borrowed from python.snippets + +snippet imp + import ${1:module} +snippet xi + ${1:library} = ximport("$1") +snippet from + from ${1:package} import ${2:module} +snippet wh + while ${1:condition}: + $2 +snippet with + with ${1:expr} as ${2:var}: + $3 +# New Class +snippet cl + class ${1:ClassName}(${2:object}): + """${3:docstring for $1}""" + def __init__(self, ${4:arg}): + ${5:super($1, self).__init__()} + $6 +# New Function +snippet def + def ${1:fname}($2): + $3 +# New Method +snippet defs + def ${1:mname}(self, ${2:arg}): + $3 +# Ifs +snippet if + if ${1:condition}: + $2 +snippet el + else: + $1 +snippet ei + elif ${1:condition}: + $2 +# For +snippet for + for ${1:item} in ${2:items}: + $3 +snippet try + try: + ${1:# TODO: write code...} + except ${2:Exception}, ${3:e}: + ${4:raise $3} +# if __name__ == '__main__': +snippet ifmain + if __name__ == '__main__': + ${1:main()} +# __magic__ +snippet _ + __${1:init}__${2} + + + + + +### signatures for the plotdevice api + +snippet align + align(${1:LEFT/RIGHT/CENTER/JUSTIFY}) +snippet alpha + alpha(${1:1.0}) +snippet arc + arc(${1:x}, ${2:y}, ${3:radius}${4:, range=${5:None}, ccw=${6:False}, close=${7:False}}) +snippet arcto + arcto(${1:x}, ${2:y}${3:, cx=${4:None}, cy=${5:None}, radius=${6:None}, ccw=${7:False}, close=${8:False}}) +snippet arrow + arrow(${1:x}, ${2:y}${3:, width=${4:100}, type=${5:NORMAL/FORTYFIVE}, plot=${6:True}}) +snippet autoclosepath + autoclosepath(${1:close=${2:True}}) +snippet autotext + autotext(${1:sourceFile}) +snippet background + background() +snippet beginclip + beginclip(${1:stencil}${2:, mask=${3:False}, channel=${4:None}}) +snippet beginpath + beginpath(${1:${2:x}, ${3:y}}) +snippet bezier + bezier(${1:${2:x}, ${3:y}}, close=${4:True}, plot=${5:True}) +snippet blend + blend("${1:normal}") +snippet capstyle + capstyle(${1:style=${2:BUTT/ROUND/SQUARE}}) +snippet choice + choice(${1:seq}) +snippet clear + clear(${1:all}) +snippet clip + clip(${1:stencil}${2:, channel="${3:black/white/alpha/red/green/blue}"}) +snippet mask + mask(${1:stencil}${2:, channel="${3:black/white/alpha/red/green/blue}"}) +snippet closepath + closepath() +snippet color + color("${1:black}") +snippet colormode + colormode(${1:mode=${2:RGB/HSB/CMYK}, range=${3:None}}) +snippet colorrange + colorrange(${1:maxval}) +snippet curveto + curveto(${1:x1}, ${2:y1}, ${3:x2}, ${4:y2}, ${5:x}, ${6:y}${7:, close=${8:False}}) +snippet drawpath + drawpath(${1:path}) +snippet ellipse + ellipse(${1:x}, ${2:y}, ${3:width}, ${4:height}${5:, range=${6:None}, ccw=${7:False}, close=${8:False}, plot=${9:True}}) +snippet endclip + endclip() +snippet endpath + endpath(${1:plot=${2:True}}) +snippet export + export("${1:${2:document}.${3:mov}}"${4:, fps=${5:None}, loop=${6:None}, bitrate=${7:1.0}}) +snippet files + files("${1:${2:*}.${3:json}}", case=${4:True}}) +snippet fill + fill(${1:"#${2:000}"}) +snippet findpath + findpath(${1:points}${2:, curvature=${3:1.0}}) +snippet findvar + findvar(${1:name}) +snippet font + font("${1:HelveticaNeue-Medium}", ${2:12}}) +snippet fonts + fonts(${1:like="${2:akzidenz}", western=${3:True}}) +snippet fontsize + fontsize(${1:12}) +snippet geometry + geometry(${1:DEGREES/RADIANS/PERCENT}) +snippet grid + grid(${1:cols}, ${2:rows}${3:, colSize=${4:1}, rowSize=${5:1}, shuffled=${6:False}}) +snippet image + image("${1:image.png}", ${2:x}, ${3:y}${4:, width=${5:None}, height=${6:None}, plot=${7:True}}) +snippet imagesize + imagesize("${1:image.png}"${2:, data=${3:None}}) +snippet joinstyle + joinstyle(${1:MITER/ROUND/BEVEL}) +snippet line + line(${1:x1}, ${2:y1}, ${3:x2}, ${4:y2}${5:, plot=${6:True}}) +snippet lineheight + lineheight(${1:None}) +snippet lineto + lineto(${1:x}, ${2:y}${3:, close=${4:False}}) +snippet measure + measure(${1:obj}) +snippet moveto + moveto(${1:x}, ${2:y}) +snippet nofill + nofill() +snippet nostroke + nostroke() +snippet noshadow + noshadow() +snippet ordered + ordered(${1:seq}) +snippet outputmode + outputmode(${1:RGB/HSB/CMYK}) +snippet oval + oval(${1:x}, ${2:y}, ${3:width}, ${4:height}${5:, range=${6:None}, ccw=${7:False}, close=${8:False}, plot=${9:True}}) +snippet pen + pen(${1:nib}) +snippet plot + plot(${1:obj}) +snippet poly + poly(${1:x}, ${2:y}, ${3:radius}, ${4:sides}${5:, plot=${6:True}}) +snippet pop + pop() +snippet push + push() +snippet random + random(${1:v1=${2:None}, v2=${3:None}}) +snippet read + read(${1:pth}${2:, format=${3:None}, encoding=${4:utf-8}, cols=${5:None}}) +snippet rect + rect(${1:x}, ${2:y}, ${3:width}, ${4:height}${5:, roundness=${6:0.0}, plot=${7:True}}) +snippet reset + reset() +snippet rotate + rotate(${1:theta}) +snippet scale + scale(${1:x=${2:1}, y=${3:None}}) +snippet shadow + shadow(${1:"black"}, blur=${2:10}, offset=${3:10}))) +snippet shuffled + shuffled(${2:seq}) +snippet size + size(${1:width}, ${2:height}, unit=${4:px}}) +snippet skew + skew(${1:horizontal}, ${2:vertical}) +snippet speed + speed(${1:fps}) +snippet star + star(${1:x}, ${2:y}${3:, points=${4:20}, outer=${5:100}, inner=${6:None}, plot=${7:True}}}) +snippet stroke + stroke() +snippet strokewidth + strokewidth(${1:width}) +snippet text + text("${1:txt}", ${2:x}, ${3:y}${4:, width=${5:None}, height=${6:None}, outline=${7:False}, plot=${8:True}}) +snippet textheight + textheight("${1:txt}"${2:, width=${3:None}}) +snippet textmetrics + textmetrics("${1:txt}"${2:, width=${3:None}, height=${4:None}}) +snippet textpath + textpath("${1:txt}", ${2:x}, ${3:y}${4:, width=${5:None}, height=${6:None}}) +snippet textwidth + textwidth("${1:txt}"${2:, width=${3:None}}) +snippet transform + transform() +snippet transform() + with transform(${1:${2:CENTER/CORNER, }${3:...}}): + $4 +snippet translate + translate(${1:x}, ${2:y}) +snippet ximport + ${1:libName} = ximport("$1") diff --git a/plotdevice/theme/blackboard.css b/plotdevice/theme/blackboard.css new file mode 100644 index 00000000000..8f9c797af1b --- /dev/null +++ b/plotdevice/theme/blackboard.css @@ -0,0 +1,98 @@ +/* THIS THEME WAS AUTOGENERATED BY Theme.tmpl.css (UUID: A2C6BAA7-90D0-4147-BBF5-96B0CD92D109) */ + +.ace-blackboard .ace_gutter { + background: #0c1021; + color: #AEAEAE; +} + +.ace-blackboard .ace_print-margin { + width: 1px; + background: #e8e8e8; +} + +.ace-blackboard { + background-color: #0C1021; + color: #F8F8F8; +} + +.ace-blackboard .ace_cursor { + color: rgba(255, 255, 255, 0.65); +} + +.ace-blackboard .ace_marker-layer .ace_selection { + background: #325087; +} + +.ace-blackboard.ace_multiselect .ace_selection.ace_start { + box-shadow: 0 0 3px 0px #0C1021; + border-radius: 2px; +} + +.ace-blackboard .ace_marker-layer .ace_step { + background: rgb(198, 219, 174); +} + +.ace-blackboard .ace_marker-layer .ace_bracket { + margin: -1px 0 0 -1px; + border: 1px solid rgba(255, 255, 255, 0.25); +} + +.ace-blackboard .ace_marker-layer .ace_active-line { + background: rgba(255, 255, 255, 0.059); +} + +.ace-blackboard .ace_gutter-active-line { + background-color: rgba(255, 255, 255, 0.059); +} + +.ace-blackboard .ace_marker-layer .ace_selected-word { + border: 1px solid #253B76; +} + +.ace-blackboard .ace_fold { + background-color: #FBDE2D; + border-color: #F8F8F8; +} + +.ace-blackboard .ace_keyword, +.ace-blackboard .ace_storage { + color: #FBDE2D; +} + +.ace-blackboard .ace_constant { + color: #D8FA3C; +} + +.ace-blackboard .ace_support { + color: #8DA6CE; +} + +.ace-blackboard .ace_invalid.ace_illegal { + color: #F8F8F8; + background-color: #9D1E15; +} + +.ace-blackboard .ace_invalid.ace_deprecated { + font-style: italic; + color: #AB2A1D; +} + +.ace-blackboard .ace_string { + color: #61CE3C; +} + +.ace-blackboard .ace_invisible{ + color:rgba(174, 174, 174, 0.5); +} +.ace-blackboard .ace_comment { + color: #AEAEAE; +} + +.ace-blackboard .ace_meta.ace_tag { + color: #7F90AA; +} + +.ace-blackboard .ace_variable, +.ace-blackboard .ace_variable.ace_language { + color:rgba(255, 100, 0, 1.0); +} \ No newline at end of file diff --git a/plotdevice/theme/blackboard.js b/plotdevice/theme/blackboard.js new file mode 100644 index 00000000000..3252a02784e --- /dev/null +++ b/plotdevice/theme/blackboard.js @@ -0,0 +1,39 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * 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 + * 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. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +exports.isDark = true; +exports.cssClass = "ace-blackboard"; +exports.cssText = require("../requirejs/text!./blackboard.css"); + +var dom = require("../lib/dom"); +dom.importCssString(exports.cssText, exports.cssClass); +}); diff --git a/plotdevice/themedump/digest.py b/plotdevice/themedump/digest.py new file mode 100644 index 00000000000..8b6cbdb9b27 --- /dev/null +++ b/plotdevice/themedump/digest.py @@ -0,0 +1,134 @@ +#!/usr/bin/env python +# encoding: utf-8 +""" +digest.py + +Created by Christian Swinehart on 2014/02/04. +Copyright (c) 2014 Samizdat Drafting Co All rights reserved. +""" + +from __future__ import with_statement, division +import sys +import os +import re +from glob import glob +from os.path import basename +from collections import defaultdict +from pprint import pprint +import tinycss +from tinycss.color3 import parse_color +import json +py_root = os.path.dirname(os.path.abspath(__file__)) +_mkdir = lambda pth: os.path.exists(pth) or os.makedirs(pth) + +from jinja2 import Environment, FileSystemLoader +tmpls = Environment(loader=FileSystemLoader(py_root)) + +def redness(rgba): + return rgba.alpha * (rgba.red + (rgba.red-rgba.blue) + (rgba.red-rgba.green)) + +def hexcolor(rgba): + return '#%02x%02x%02x%02x'%(rgba.red*255,rgba.green*255,rgba.blue*255,rgba.alpha*255) + +def rgbacolor(hexclr, alpha=None): + hexclr = hexclr.lstrip('#') + r, g, b, a = [int(n, 16)/255.0 for n in (hexclr[0:2], hexclr[2:4], hexclr[4:6], hexclr[6:8])] + if alpha is not None: + # a = min(a, alpha) + a *= alpha + return 'rgba(%i, %i, %i, %0.1f)'%(r*255,g*255,b*255,a) + +def main(): + themes = defaultdict(lambda:defaultdict(defaultdict)) + + css_themes = {} + for theme_js in glob('../../lib/ace/theme/*.js'): + fname_stub = theme_js.replace('.js','') + theme_css = fname_stub + '.css' + theme_name = basename(fname_stub).replace('_',' ').replace('-',' ').title() + src = file(theme_js).read().decode('utf-8') + m = re.search(r'isDark.*(true|false)', src) + darkness = 'dark' if m.group(1)=='true' else 'light' + isdark = darkness=='dark' + + m = re.search(r'cssClass.*"(.*?)"', src) + theme_class = m.group(1) + # print theme_name, theme_class, darkness + css_themes[theme_name] = theme_class + + parser = tinycss.make_parser('page3') + stylesheet = parser.parse_stylesheet_file(theme_css) + textcolors = set() + for rule in stylesheet.rules: + selectors = rule.selector.as_css().split(',\n') + # print selectors + if selectors[0] == '.'+theme_class: + colors = {} + for d in rule.declarations: + fgbg = d.name.split('-')[0] + for v in d.value: + themes[theme_name]['colors'][fgbg] = hexcolor(parse_color(v)) + themes[theme_name].update(dict(dark=isdark, theme=theme_name, + module='ace/theme/'+basename(fname_stub))) + + # find all the text colors + for d in rule.declarations: + if d.name == 'color': + for v in d.value: + textcolors.add(parse_color(v)) + + + if any([s.endswith('.ace_selection') for s in selectors]): + for d in rule.declarations: + if d.name == 'background': + for v in d.value: + themes[theme_name]['colors']['selection'] = hexcolor(parse_color(v)) + + if any([s.endswith('.ace_comment') for s in selectors]): + for d in rule.declarations: + if d.name == 'color': + # themes[theme_name]['comment'] = d.value.as_css() + for v in d.value: + themes[theme_name]['colors']['comment'] = hexcolor(parse_color(v)) + + reddest = [hexcolor(c) for c in sorted(textcolors, key=redness, reverse=True)] + while reddest[0] in themes[theme_name]['colors'].values(): + reddest.pop(0) + themes[theme_name]['colors']['error'] = reddest[0] + + # pprint(json.loads(json.dumps(themes[theme_name]))) + # t = themes[theme_name] + # colors = dict(color=t['color'], background=t['background'], error=t['error'], comment=t['comment']) + # repack = dict(theme=t['theme'], dark=t['dark'], css=t['css'], colors=colors) + # themes[theme_name]['json'] = repack + # 1/0 + + + with file('../themes.json','w') as f: + # json.dump({t:themes[t]['json'] for t in themes}, f, indent=2) + json.dump(themes, f, indent=2) + + # rows = [dict(theme=n, module=t['theme'], background=t['background'], plain=t['color'], err=t['error'], comment=t['comment']) for n,t in themes.items()] + # # pprint(rows) + # html = tmpls.get_template('tmpl.html') + # info = {"rows":rows} + # with file('themes.html','w') as f: + # f.write(html.render(info).encode('utf-8')) + + + css = [] + tmpl = tmpls.get_template('tmpl.css') + for theme, clazz in css_themes.items(): + # colors = {c:rgbacolor(v) for c,v in themes[theme]['colors'].items()} + info = dict(clazz=clazz) + info.update({c:rgbacolor(v) for c,v in themes[theme]['colors'].items()}) + info['halfselection'] = rgbacolor(themes[theme]['colors']['selection'], .7) + print theme, clazz + css.append(tmpl.render(info)) + + with file('../autocomplete.css','w') as f: + f.write("\n".join(css)) + + +if __name__ == "__main__": + main() diff --git a/plotdevice/themedump/requirements.txt b/plotdevice/themedump/requirements.txt new file mode 100644 index 00000000000..b4aea016a40 --- /dev/null +++ b/plotdevice/themedump/requirements.txt @@ -0,0 +1,2 @@ +tinycss +jinja2 \ No newline at end of file diff --git a/plotdevice/themedump/tmpl.css b/plotdevice/themedump/tmpl.css new file mode 100644 index 00000000000..7eed363d006 --- /dev/null +++ b/plotdevice/themedump/tmpl.css @@ -0,0 +1,6 @@ +#editor.{{clazz}} ~ div.ace_autocomplete.ace-tm .ace_marker-layer .ace_active-line {border:1px solid {{selection}}; background-color:{{halfselection}};} +#editor.{{clazz}} ~ div.ace_autocomplete.ace-tm .ace_line{color:{{color}};} +#editor.{{clazz}} ~ div.ace_autocomplete.ace-tm .ace_line-hover {border-color:{{selection}}; background-color:{{halfselection}};} +#editor.{{clazz}} ~ div.ace_rightAlignedText {color:{{comment}};} +#editor.{{clazz}} ~ div.ace_autocomplete .ace_completion-highlight{color:{{error}};} +#editor.{{clazz}} ~ div.ace_autocomplete {background-color:{{background}}; color:{{color}}; border-color:{{color}};} diff --git a/plotdevice/themedump/tmpl.html b/plotdevice/themedump/tmpl.html new file mode 100644 index 00000000000..c03c1a5274c --- /dev/null +++ b/plotdevice/themedump/tmpl.html @@ -0,0 +1,24 @@ + + + + + + themedump + + + + + + + + +
+{% for row in rows %} +
+ {{row.theme}} Traceback (most recent call last): # Lorem ipsum dolor module +
+{% endfor %} +
+ + + diff --git a/plotdevice/unpack.sh b/plotdevice/unpack.sh new file mode 100755 index 00000000000..4d76452bb1d --- /dev/null +++ b/plotdevice/unpack.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +ln -f mode/plotdevice.js ../lib/ace/mode/plotdevice.js +ln -f mode/plotdevice_highlight_rules.js ../lib/ace/mode/plotdevice_highlight_rules.js +ln -f snippets/plotdevice.js ../lib/ace/snippets/plotdevice.js +ln -f snippets/plotdevice.snippets ../lib/ace/snippets/plotdevice.snippets +ln -f theme/blackboard.css ../lib/ace/theme/blackboard.css +ln -f theme/blackboard.js ../lib/ace/theme/blackboard.js diff --git a/plotdevice/wipe.sh b/plotdevice/wipe.sh new file mode 100755 index 00000000000..01ca5fda876 --- /dev/null +++ b/plotdevice/wipe.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +rm ../lib/ace/mode/plotdevice.js +rm ../lib/ace/mode/plotdevice_highlight_rules.js +rm ../lib/ace/snippets/plotdevice.js +rm ../lib/ace/snippets/plotdevice.snippets +rm ../lib/ace/theme/blackboard.css +rm ../lib/ace/theme/blackboard.js