60

Can CodeMirror 2 be used to highlight code from a DIV or PRE tag (without the editor)?

Like CodeMirror 1 used to be able to do with the hightlightText() function? For example here: http://codemirror.net/1/highlight.html, after you press run highlight (the highlighted text below)

Also can it highlight code from a inline element, like <code>, and keep the results inline, like Google's Prettify does?

Alex
  • 66,732
  • 177
  • 439
  • 641
  • Wow 70% of your rep - are you generous or desperate? ;) - I'll give you a +1 to help you back up! – UpTheCreek Apr 05 '11 at 12:26
  • Do you have a particular constraint for not using a standalone highlighter? – bpierre Apr 05 '11 at 12:31
  • 1
    no, I just like codeMirror :) Right now I'm using highlight.js, which is great, but I'd like to see how CodeMirror behaves too. Also CM has the advantage of being able to highlight mixed php/html/js/css code... – Alex Apr 05 '11 at 19:28
  • 1
    From how she sets bounties, this is evident that Alex could not possibly care less about reputation. I kind of like that, but still hope she is left some. She has less rep than the bounty set here (apparently because she lost points in another bounty question after this one started). Now, if because of insufficient rep amount, this bounty is cancelled, I'd be happy. Anyway I'm curious to see how the system handles this. – Majid Fouladpour Apr 08 '11 at 18:50
  • @bpierre CodeMirror is JS; can work on the browser as well as on the server (Node). It is very flexible and allows for nested modes (code inside of code). Two big reasons. – Alba Mendez Jul 29 '12 at 12:39

7 Answers7

57

A much nicer and easier solution is to just set the readOnly property of the CodeMirror instance to true, like this:

$('.code').each(function() {

    var $this = $(this),
        $code = $this.html();

    $this.empty();

    var myCodeMirror = CodeMirror(this, {
        value: $code,
        mode: 'javascript',
        lineNumbers: !$this.is('.inline'),
        readOnly: true
    });

});

Just add the class .code to the tag containing the code and it will be syntax highlighted. I've also added support for inline code, by using the class .inline.

Example on jsfiddle

Eli
  • 17,397
  • 4
  • 36
  • 49
Sindre Sorhus
  • 62,972
  • 39
  • 168
  • 232
40

As a somewhat late update, CodeMirror 2 recently gained this ability. See http://codemirror.net/demo/runmode.html

Marijn
  • 8,691
  • 2
  • 34
  • 37
3

You should use a standalone code syntax highlighter: SyntaxHighlighter 3 works really well.

If you really want CodeMirror, there is a readOnly option:

var myCodeMirror = CodeMirror(function(elt) {
    myElement.parentNode.replaceChild(myElement, elt); // myElement is your <pre> or <div>
  }, {
    value: myElement.value,
    readOnly: true
  });
bpierre
  • 10,957
  • 2
  • 26
  • 27
2

Heres an simpler solution using codemirror runmode and jquery:

<pre class='code'>{:message => 'sample code'}</pre>

$(document).ready(function() {
    $('.code').each(function(index, e) {
        $(e).addClass('cm-s-default'); // apply a theme class
        CodeMirror.runMode($(e).text(), "javascript", $(e)[0]);
    });
});
desheikh
  • 286
  • 4
  • 7
2

Actually you can't. Codemirror2 is written in the way that all implementation is hidden in closures. Public methods which can be used are described in documentation http://codemirror.net/manual.html
The only available options are to use anothe syntax highlighters or dive into the code of CodeMirror2 to strip necessary parts out.
If you will chose last option, please give attention to

function refreshDisplay(from, to) method

it loops through lines and highlights them.

Eldar Djafarov
  • 23,327
  • 2
  • 33
  • 27
2

Edit
Just realized a simpler method exists. Read method 2 below. I'm keeping the old method and its explanations intact and just include the improved jQuery code.


If you are asking about a native method of the package, the answer is no, it only works with textarea. But if you are open to using workarounds, here is one that works (tested).

I have used jQuery here, but its use is not a must and you can achieve the same with pure js code, though it would be longer and not as neat as jQuery code.

Now, let's get to the workaround.

Suppose you have a <pre> with code inside, that you want to turn into editor-less syntax-highlighted codemirror container:

<pre id="mycode">
<?php
  echo 'hi';
  $a = 10;
  if($a == 5) echo 'too small';
?>
</pre>

What you do is,

  1. change the <pre> to <textarea>,
  2. attach codemirror to the textarea,
  3. hide the fake cursor and keep it hidden, and
  4. do not allow the hidden codemirror's textarea grab the focus (and snatch it back when it does).

For the last action I have used the method suggested by Travis Webb. Here is the jQuery code that does these four things:

$(document).ready(function() {

    // (1) replace pre with textarea
    $('#mycode').replaceWith('<textarea id="code">' + $('#mycode').html() + '</textarea>');

    // (2) attach codemirror 
    var editor = CodeMirror.fromTextArea($("#code"), {
        lineNumbers: true,
        mode: "application/x-httpd-php"
    });

    // (3) hide the fake cursor    
    $('pre.CodeMirror-cursor').hide();

    // [4] textarea to grab and keep the focus
    $('body').append('<textarea id="tricky" style="height: 1px; position: fixed; width: 1px; top: 0; margin-top: -100px;" wrap="off"></textarea>');

    // (4) grab focus
    $('#tricky').focus();

    // [4] if focus is lost (probably to codemirror)
    $('#tricky').blur(function() {

            // (4) re-claim focus
            $('#tricky').focus();

            // (3) keep the fake cursor hidden
            $('pre.CodeMirror-cursor').hide();
    });

});

Method Two

Instead of wrestling with cursor and all that, we can remove the elements that make the editor tick. Here is the code:

$(document).ready(function() {
    $('#mycode').replaceWith('<textarea id="code">' + $('#mycode').html() + '</textarea>'); 
    var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
        lineNumbers: true,
        mode: "application/x-httpd-php"
    });

    $('pre.CodeMirror-cursor').remove();
    $('div.CodeMirror').find('textarea').blur().parent().remove();
    $('div.CodeMirror').find('pre:first').remove();
    $('textarea#code').remove();
});
Community
  • 1
  • 1
Majid Fouladpour
  • 29,356
  • 21
  • 76
  • 127
2

CodeMirror V2 contains a runmode.js.

I've wrote an example using runmode with gutter.

check: http://jsfiddle.net/lyhcode/37vHL/2/

Eliran Malka
  • 15,821
  • 6
  • 77
  • 100
lyhcode
  • 81
  • 1
  • 5