How can I highlight code with ACE editor?
Asked Answered
P

5

16

I'd like to syntax highlight more than a dozen small snippets of code and then make them editable with ACE Editor by clicking on them, since I think it would be much faster than setting up the full editor for each. I see there's a simple command for setting up an ACE editor:

<div id="editor">some text</div>
<script src="src/ace.js" type="text/javascript" charset="utf-8"></script>
<script>
window.onload = function() {
    var editor = ace.edit("editor");
};
</script>

Is there a simple way to call into the API to just highlight the text without setting up the editor? The ideal API would take in some text and return HTML with tags that could be used for highlighting. I'm aware there are specialized highlighting libraries for JavaScript, but I would like to try using the same highlighter both for text that's being displayed and text that's being edited.

Palomo answered 12/1, 2012 at 8:57 Comment(2)
Ace Editor has a read-only mode that basically makes the editor display only, but you still get the overhead of the full editor. Speed isn't a huge issue though - more the size of the editor. I use it for both editing and displaying on a few sites and it works well.Curcuma
@RickStrahl I'd be happy to know how to set the read only mode. because the example the closest I could find is static_highlight but it uses the kitchensink framework. I'd be happier with a one liner like editor.mode = readonly.Bradytelic
T
6

There is a server side version of the highlighter (which runs in node.js) available, that'll probably be portable to webbased javascript fairly easy.

Tartarus answered 24/1, 2012 at 23:55 Comment(0)
G
16

Highlight the word:

var range = new Range(rowStart, columnStart, rowEnd, columnEnd);
var marker = editor.getSession().addMarker(range,"ace_selected_word", "text");

Remove the highlighted word:

editor.getSession().removeMarker(marker);

Highlight the line:

editor.getSession().addMarker(range,"ace_active_line","background");
Giglio answered 21/2, 2012 at 10:47 Comment(0)
D
8

First you want to declare your line number as a global variable.

var erroneousLine;

This is the highlightError function, which takes in a line number (lineNumber) as its parameter. which could be triggered from an error message or using editor.selection.getCursor().row to get the current row, or something else.

function highlightError(lineNumber) {
  unhighlightError();
  var Range = ace.require("ace/range").Range
  erroneousLine = editor.session.addMarker(new Range(lineNumber, 0, lineNumber, 144), "errorHighlight", "fullLine");
}

Notice that I have declared a errorHighlight, which is how this will be highlighted. In your css place the following:

.errorHighlight{
  position:absolute;
  z-index:20;
  background-color:#F4B9B7;
}

This function unhighlights the already highlighted line

function unhighlightError(){
  editor.getSession().removeMarker(erroneousLine);
}
Doubly answered 14/1, 2015 at 21:28 Comment(0)
T
6

There is a server side version of the highlighter (which runs in node.js) available, that'll probably be portable to webbased javascript fairly easy.

Tartarus answered 24/1, 2012 at 23:55 Comment(0)
P
1

An idea:

function highlightSyntax(text) {
    var res = [];

    var Tokenizer = ace.require('ace/tokenizer').Tokenizer;
    var Rules = ace.require('ace/mode/sql_highlight_rules').SqlHighlightRules;
    var Text = ace.require('ace/layer/text').Text;

    var tok = new Tokenizer(new Rules().getRules());
    var lines = text.split('\n');

    lines.forEach(function(line) {
      var renderedTokens = [];
      var tokens = tok.getLineTokens(line);

      if (tokens && tokens.tokens.length) {
        new Text(document.createElement('div')).$renderSimpleLine(renderedTokens, tokens.tokens);
      }

      res.push('<div class="ace_line">' + renderedTokens.join('') + '</div>');
    });

    return '<div class="ace_editor ace-tomorrow"><div class="ace_layer" style="position: static;">' + res.join('') + '</div></div>';
}

This function should highlight SQL syntax (ace-tomorrow theme) in the given text without loading the whole editor and without the gutter.

Pistil answered 24/8, 2015 at 10:2 Comment(2)
Still working as of version 1.4.8, but just changing renderedTokens array for the HTML element where you want to append the childs.Solicit
Looks promising but in the latest version of Ace I get Uncaught TypeError: e.appendChild is not a functionOrthopterous
R
0

I think this is very late to answer, but I will still write in case it can help others.

I ended up creating a simple function in typescript which finds co-ordinates for range to highlight and also scrolls to it:

highlighText(text: string) {
    const value = this.aceEditor.session.getValue();
    const startRow = value.substr(0, value.indexOf(text)).split(/\r\n|\r|\n/).length - 1;
    const startCol = this.aceEditor.session.getLine(startRow).indexOf(text);
    const endRowOffset = text.split(/\r\n|\r|\n/).length;
    const endRow = startRow + endRowOffset - 1;
    const endCollOffset = text.split(/\r\n|\r|\n/)[endRowOffset - 1].length;
    const endCol = startCol + (endCollOffset > 1 ? endCollOffset + 1 : endCollOffset);
    const range = new ace.Range(startRow, startCol, endRow, endCol);

    this.aceEditor.session.selection.setRange(range);
    this.aceEditor.scrollToLine(startRow, true, true, () => {});
  }
Rambo answered 17/2, 2021 at 7:1 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.