From 7ab31f2f87a23d3e250c86344916c8c79484b4ec Mon Sep 17 00:00:00 2001 From: James Allen Date: Thu, 11 Aug 2011 01:21:35 +0100 Subject: [PATCH] Add LaTeX highlighting Added a new highlighting mode from LaTeX which understands commands, inline math and comments. It's a very simple parser, but it doesn't understand comments inside inline math and it doesn't do anything complicated with command arguments. --- demo/demo.js | 10 ++++- kitchen-sink.html | 25 ++++++++++++ lib/ace/mode/latex.js | 58 +++++++++++++++++++++++++++ lib/ace/mode/latex_highlight_rules.js | 39 ++++++++++++++++++ 4 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 lib/ace/mode/latex.js create mode 100644 lib/ace/mode/latex_highlight_rules.js diff --git a/demo/demo.js b/demo/demo.js index 3a1fc37e..87721de8 100644 --- a/demo/demo.js +++ b/demo/demo.js @@ -70,6 +70,7 @@ exports.launch = function(env) { var TextMode = require("ace/mode/text").Mode; var GroovyMode = require("ace/mode/groovy").Mode; var ScalaMode = require("ace/mode/scala").Mode; + var LatexMode = require("ace/mode/latex").Mode; var UndoManager = require("ace/undomanager").UndoManager; @@ -182,6 +183,9 @@ exports.launch = function(env) { docs.scala.setMode(new ScalaMode()); docs.scala.setUndoManager(new UndoManager()); + docs.latex = new EditSession(document.getElementById("latex").innerHTML); + docs.latex.setMode(new LatexMode()); + docs.latex.setUndoManager(new UndoManager()); @@ -226,7 +230,8 @@ exports.launch = function(env) { ocaml: new OcamlMode(), csharp: new CSharpMode(), groovy: new GroovyMode(), - scala: new ScalaMode() + scala: new ScalaMode(), + latex: new LatexMode() }; function getMode() { @@ -324,6 +329,9 @@ exports.launch = function(env) { else if (mode instanceof ScalaMode) { modeEl.value = "scala"; } + else if (mode instanceof LatexMode) { + modeEl.value = "latex"; + } else { modeEl.value = "text"; } diff --git a/kitchen-sink.html b/kitchen-sink.html index 941cf169..2f7dade6 100644 --- a/kitchen-sink.html +++ b/kitchen-sink.html @@ -36,6 +36,7 @@ + @@ -65,6 +66,7 @@ + @@ -683,6 +685,29 @@ object implicits extends Application { val x = Array(2, 3, 1, 4) println("x = "+ x.sort((x: Int, y: Int) => x < y)) } + diff --git a/lib/ace/mode/latex.js b/lib/ace/mode/latex.js new file mode 100644 index 00000000..0b603236 --- /dev/null +++ b/lib/ace/mode/latex.js @@ -0,0 +1,58 @@ +define(function(require, exports, module) { + +var oop = require("pilot/oop"); +var TextMode = require("ace/mode/text").Mode; +var Tokenizer = require("ace/tokenizer").Tokenizer; +var LatexHighlightRules = require("ace/mode/latex_highlight_rules").LatexHighlightRules; +var Range = require("ace/range").Range; + +var Mode = function() +{ + this.$tokenizer = new Tokenizer(new LatexHighlightRules().getRules()); +}; +oop.inherits(Mode, TextMode); + +(function() +{ + this.toggleCommentLines = function(state, doc, startRow, endRow) { + // This code is adapted from ruby.js + var outdent = true; + var outentedRows = []; + + // LaTeX comments begin with % and go to the end of the line + var commentRegEx = /^(\s*)\%/; + + for (var i = startRow; i <= endRow; i++) { + if (!commentRegEx.test(doc.getLine(i))) { + outdent = false; + break; + } + } + + if (outdent) { + var deleteRange = new Range(0, 0, 0, 0); + for (var i = startRow; i <= endRow; i++) { + var line = doc.getLine(i); + var m = line.match(commentRegEx); + deleteRange.start.row = i; + deleteRange.end.row = i; + deleteRange.end.column = m[0].length; + doc.replace(deleteRange, m[1]); + } + } + else { + doc.indentRows(startRow, endRow, "%"); + } + }; + + // There is no universally accepted way of indenting a tex document + // so just maintain the indentation of the previous line + this.getNextLineIndent = function(state, line, tab) { + return this.$getIndent(line); + }; + +}).call(Mode.prototype); + +exports.Mode = Mode; + +}); diff --git a/lib/ace/mode/latex_highlight_rules.js b/lib/ace/mode/latex_highlight_rules.js new file mode 100644 index 00000000..76a6ca90 --- /dev/null +++ b/lib/ace/mode/latex_highlight_rules.js @@ -0,0 +1,39 @@ +define(function(require, exports, module) { + +var oop = require("pilot/oop"); +var TextHighlightRules = require("ace/mode/text_highlight_rules").TextHighlightRules; + +var LatexHighlightRules = function() +{ + this.$rules = { + "start" : [ + { + // A tex command e.g. \foo + token : "keyword", + regex : "\\\\(?:[^a-zA-Z]|[a-zA-Z]+)", + }, + { + // Curly and square braces + token : "keyword", + regex : "[\\{\\}\\]\\[]" + }, + { + // Inline math between two $ symbols + token : "string", + regex : "\\$(?:(?:\\\\.)|(?:[^\\$\\\\]))*?\\$" + }, + { + // A comment. Tex comments start with % and go to + // the end of the line + token : "comment", + regex : "%.*$" + } + ] + }; +}; + +oop.inherits(LatexHighlightRules, TextHighlightRules); + +exports.LatexHighlightRules = LatexHighlightRules; + +});