From 08de8b4aa1a0acf56fba18a82cc955cd4a4a00ca Mon Sep 17 00:00:00 2001 From: Fabian Jakobs Date: Thu, 13 Oct 2011 12:38:34 +0200 Subject: [PATCH] add static highlighter demos --- demo/static-highlighter/client.html | 48 ++++++++++ demo/static-highlighter/server.js | 36 +++++++ lib/ace/ext/static.css | 19 ++++ lib/ace/ext/static_highlight.js | 94 +++++++++++++++++++ .../static_highlight_test.js} | 53 +++-------- lib/ace/serversidehighlighter.js | 91 ------------------ 6 files changed, 210 insertions(+), 131 deletions(-) create mode 100644 demo/static-highlighter/client.html create mode 100644 demo/static-highlighter/server.js create mode 100644 lib/ace/ext/static.css create mode 100644 lib/ace/ext/static_highlight.js rename lib/ace/{serversidehighlighter_test.js => ext/static_highlight_test.js} (54%) delete mode 100644 lib/ace/serversidehighlighter.js diff --git a/demo/static-highlighter/client.html b/demo/static-highlighter/client.html new file mode 100644 index 00000000..561add80 --- /dev/null +++ b/demo/static-highlighter/client.html @@ -0,0 +1,48 @@ + + + + + + Static Code highlighter using Ace + + + + +

Client Side Syntax Highlighting

+ +

Syntax highlighting using Ace language modes and themes.

+ +
+ + + + + + diff --git a/demo/static-highlighter/server.js b/demo/static-highlighter/server.js new file mode 100644 index 00000000..a58b00b6 --- /dev/null +++ b/demo/static-highlighter/server.js @@ -0,0 +1,36 @@ +/** + * Simple node.js server, which generates the synax highlighted version of itself + * using the Ace modes and themes on the server and serving a static web page. + */ + +// include ace search path and modules +require("../../support/paths"); + +// load jsdom, which is required by Ace +require("ace/test/mockdom"); + +var http = require("http"); +var fs = require("fs"); + +// load the highlighter and the desired mode and theme +var highlighter = require("ace/ext/static_highlight"); +var JavaScriptMode = require("ace/mode/javascript").Mode; +var theme = require("ace/theme/twilight"); + +var port = process.env.PORT || 2222; + +http.createServer(function(req, res) { + res.writeHead(200, {"Content-Type": "text/html"}); + + fs.readFile(__filename, "utf8", function(err, data) { + var highlighted = highlighter.render(data, new JavaScriptMode(), theme); + res.end('\n\ +\n\ +:html:\n\ +'.replace(":css:", highlighted.css).replace(":html:", highlighted.html)); + }); +}).listen(port); + +console.log("Listening on port " + port); \ No newline at end of file diff --git a/lib/ace/ext/static.css b/lib/ace/ext/static.css new file mode 100644 index 00000000..c2842bf4 --- /dev/null +++ b/lib/ace/ext/static.css @@ -0,0 +1,19 @@ +.ace_editor { + font-family: 'Monaco', 'Menlo', 'Droid Sans Mono', 'Courier New', monospace; + font-size: 12px; +} + +.ace_editor .ace_gutter { + width: 20px; + display: inline-block; + text-align: right; + padding: 0 3px 0 0; + margin-right: 3px; +} + +*.ace_gutter-cell { + -moz-user-select: -moz-none; + -khtml-user-select: none; + -webkit-user-select: none; + user-select: none; +} \ No newline at end of file diff --git a/lib/ace/ext/static_highlight.js b/lib/ace/ext/static_highlight.js new file mode 100644 index 00000000..cec33bf4 --- /dev/null +++ b/lib/ace/ext/static_highlight.js @@ -0,0 +1,94 @@ +/* vim:ts=4:sts=4:sw=4: + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ajax.org Code Editor (ACE). + * + * The Initial Developer of the Original Code is + * Ajax.org B.V. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Jan Jongboom + * Fabian Jakobs + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +var EditSession = require("ace/edit_session").EditSession; +var TextLayer = require("ace/layer/text").Text; +var baseStyles = require("ace/requirejs/text!ace/ext/static.css"); + +/** Transforms a given input code snippet into HTML using the given mode +* +* @param {string} input Code snippet +* @param {mode} mode Mode loaded from /ace/mode (use 'ServerSideHiglighter.getMode') +* @param {string} r Code snippet +* @returns {object} An object containing: html, css +*/ + +exports.render = function(input, mode, theme) { + var session = new EditSession(""); + session.setMode(mode); + session.setUseWorker(false); + + var textLayer = new TextLayer(document.createElement("div")); + textLayer.setSession(session); + textLayer.config = { + characterWidth: 10, + lineHeight: 20 + }; + + session.setValue(input); + + var stringBuilder = []; + var length = session.getLength(); + var tokens = session.getTokens(0, length - 1); + + for(var ix = 0; ix < length; ix++) { + var lineTokens = tokens[ix].tokens; + stringBuilder.push("" + (ix+1) + ""); + textLayer.$renderLine(stringBuilder, 0, lineTokens, true); + stringBuilder.push("
"); + } + + // let's prepare the whole html + var html = "
\ +
\ + :code\ +
\ +
".replace(/:cssClass/, theme.cssClass).replace(/:code/, stringBuilder.join("")); + + textLayer.destroy(); + + return { + css: baseStyles + theme.cssText, + html: html + }; +}; + +}); \ No newline at end of file diff --git a/lib/ace/serversidehighlighter_test.js b/lib/ace/ext/static_highlight_test.js similarity index 54% rename from lib/ace/serversidehighlighter_test.js rename to lib/ace/ext/static_highlight_test.js index cf461bfb..e2658073 100644 --- a/lib/ace/serversidehighlighter_test.js +++ b/lib/ace/ext/static_highlight_test.js @@ -1,42 +1,16 @@ -require("../../support/paths"); +if (typeof process !== "undefined") { + require("../../../support/paths"); + require("ace/test/mockdom"); +} var assert = require("assert"); -var ServerSideHighlighter = require("./serversidehighlighter"); +var highlighter = require("./static_highlight"); +var JavaScriptMode = require("ace/mode/javascript").Mode; // Execution ORDER: test.setUpSuite, setUp, testFn, tearDown, test.tearDownSuite module.exports = { timeout: 10000, - dispatcher: null, - req: null, - res: null, - highlighter: null, - - setUpSuite: function (next) { - this.highlighter = new ServerSideHighlighter(); - next(); - }, - - setUp: function(next) { - next(); - }, - - tearDown: function(next) { - next(); - }, - - "test extension js": function(next) { - var JavascriptMode = require("ace/mode/javascript").Mode - assert.equal(this.highlighter.getMode("jan.js") instanceof JavascriptMode, true); - next(); - }, - - "test extension unknown": function(next) { - var TextMode = require("ace/mode/text").Mode - assert.equal(this.highlighter.getMode("jan.unknown") instanceof TextMode, true); - next(); - }, - "test simple snippet": function(next) { var theme = require("ace/theme/tomorrow"); var snippet = "/** this is a function\n\ @@ -45,11 +19,11 @@ module.exports = { function hello (a, b, c) {\n\ console.log(a * b + c + 'sup?');\n\ }"; - var mode = this.highlighter.getMode("some.js"); + var mode = new JavaScriptMode(); var isError = false, result; try { - result = this.highlighter.render(snippet, mode, theme); + result = highlighter.render(snippet, mode, theme); } catch (e) { console.log(e); @@ -69,10 +43,10 @@ function hello (a, b, c) {\n\ function hello (a, b, c) {\n\ console.log(a * b + c + 'sup?');\n\ }"; - var mode = this.highlighter.getMode("some.js"); + var mode = new JavaScriptMode(); var isError = false, result; - result = this.highlighter.render(snippet, mode, theme); + result = highlighter.render(snippet, mode, theme); assert.equal(result.css, theme.cssText); @@ -87,15 +61,14 @@ function hello (a, b, c) {\n\ function hello (a, b, c) {\n\ console.log(a * b + c + 'sup?');\n\ }"; - var mode = this.highlighter.getMode("some.js"); + var mode = new JavaScriptMode(); var isError = false, result; - result = this.highlighter.render(snippet, mode, theme); - + result = highlighter.render(snippet, mode, theme); assert.equal(!!result.html.match(/
/), true); next(); } }; -!module.parent && require("asyncjs").test.testcase(module.exports, "ServerSideHighlighter").exec(); +!module.parent && require("asyncjs").test.testcase(module.exports).exec(); diff --git a/lib/ace/serversidehighlighter.js b/lib/ace/serversidehighlighter.js deleted file mode 100644 index c1ef873a..00000000 --- a/lib/ace/serversidehighlighter.js +++ /dev/null @@ -1,91 +0,0 @@ -if (typeof process !== "undefined") { - require("../../support/paths"); - require("ace/test/mockdom"); -} - -var theme = require("ace/theme/tomorrow"); -var EditSession = require("ace/edit_session").EditSession; -var Editor = require("ace/editor").Editor; -var MockRenderer = require("ace/test/mockrenderer").MockRenderer; -var TextLayer = require("ace/layer/text").Text; - -/** Ace highlighting but server side - */ -var ServerSideHighlighter = module.exports = function() { -}; - -(function () { - - /** Returns a mode from /ace/mode based on a filename - * - * @param {string} fileName name of the file without directory information - * @returns {mode} A mode that can highlight the given file, or TextMode if nothing matched - */ - function getMode (fileName) { - var extension = fileName.match(/\.(\w+)$/)[1]; - - switch (extension) { - case "js": - var JavascriptMode = require("ace/mode/javascript").Mode; - return new JavascriptMode(); - default: - var TextMode = require("ace/mode/text").Mode; - return new TextMode(); - } - } - - /** Transforms a given input code snippet into HTML using the given mode - * - * @param {string} input Code snippet - * @param {mode} mode Mode loaded from /ace/mode (use 'ServerSideHiglighter.getMode') - * @param {string} r Code snippet - * @returns {object} An object containing: html, css - */ - function render (input, mode, theme) { - var session = new EditSession(""); - session.setMode(mode);// || new JavaScriptMode()); - - var editor = new Editor(new MockRenderer(), session); - var textLayer = new TextLayer(document.createElement("div")); - textLayer.setSession(session); - textLayer.config = { - characterWidth: 10, - lineHeight: 20 - }; - - session.setValue(input); - - var stringBuilder = [], length = session.getLength(); - var tokens = session.getTokens(0, length - 1); - - for(var ix = 0; ix < length; ix++) { - var lineTokens = tokens[ix].tokens; - stringBuilder.push("" + (ix+1) + ""); - textLayer.$renderLine(stringBuilder, 0, lineTokens, true); - stringBuilder.push("
"); - } - - // let's prepare the whole html - var html = "
\ -
\ - :code\ -
\ -
".replace(/:cssClass/, theme.cssClass).replace(/:code/, stringBuilder.join("")); - - return { - css: theme.cssText, - html: html - }; - } - - this.getMode = getMode; - this.render = render; -}).call(ServerSideHighlighter.prototype); - -//"/**\n\ -// * juhu\n\ -// * kinner \n\ -// */\n\ -// function a(b) {\n\ -// return b;\n\ -// }" \ No newline at end of file