2

I would like to display blocks of code as a site like StackOverflow does:

def func(A):
    result = 0
    n = len(A)
    while n > 1:
        n = n/2
        result = result + min(A[1,...,n])
    return result

It properly colors, formats and spaces all the code once it has been designated as a code block. I would like this to happen in my site as well. All code blocks will be python, by the way.

The font, background and spacing seem easy enough to implement (just designate a class in which the background is grey, the font is that font and the spacing is monospace).

However, I am wondering how to color the text appropriately? I am assuming I would need to use JavaScript, and loop through all the words in the code block, checking if they match a list of words that I have preset to become certain colors.

Let me know if I made any incorrect assumptions anywhere here, or things that may complicate my approach.

Andrew Zaw
  • 754
  • 1
  • 9
  • 16

1 Answers1

2

Update 2021-05-14:

  • Updated code snippets so they can run when the file:// protocol is used
  • Changed CodeMirror's links to point to a proper CDN

Snippets still require an internet connection to be able to download CodeMirror

Update 2020-11-09:

It's been quite some time but if the only thing you want is to highlight code there's a lighter alternative than implementing a read-only, fully-fledged code editor:

CodeMirror has an addon that does precisely the highlighting part without all of the fancy functionality of the full editor, the only downside is that you don't get the option to render line numbers but well...

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>CodeMirror RunMode Highlighting Example</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/codemirror@5.61.0/lib/codemirror.min.css">
    <script src="https://cdn.jsdelivr.net/npm/codemirror@5.61.0/addon/runmode/runmode-standalone.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/codemirror@5.61.0/mode/python/python.min.js"></script>
  </head>
  <body>
    <pre><code id="python_code">def func(A):
    result = 0
    n = len(A)
    while n > 1:
        n = n/2
        result = result + min(A[1,...,n])
    return result</code></pre>
    <script type="text/javascript">
        window.onload = function(){
            var codeElement = document.getElementById('python_code');
            // Add code mirror class for coloring (default is the theme)
            codeElement.classList.add( 'cm-s-default' );
            var code = codeElement.innerText;

            codeElement.innerHTML = "";

            CodeMirror.runMode(
              code,
              'python',
              codeElement
            );
        };
    </script>
  </body>
</html>

Source: https://codemirror.net/demo/runmode.html

P.S. There's also a "colorizer" addon that colorizes pre elements automatically, look on how to implement it in the CodeMirror manual

Original Answer

You can use CodeMirror's read-only mode in a code element. Code Mirror itself has several languages to pick, in the example I use the python mode to colorize the code as python. Basically what0 I'm doing in the example is load the library, load the language mode for the coloring, and whenever the page is loaded, we get the element with an id, get the code, then delete the contents of that element and generate a colorized version of the code, you can tweak the lineNumbersif you want. Hope this works for you :)

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>CodeMirror Read-only Highlighting Example</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/codemirror@5.61.0/lib/codemirror.min.css">
    <script src="https://cdn.jsdelivr.net/npm/codemirror@5.61.0/lib/codemirror.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/codemirror@5.61.0/mode/python/python.min.js"></script>
  </head>
  <body>
    <pre><code id="python_code">def func(A):
    result = 0
    n = len(A)
    while n > 1:
        n = n/2
        result = result + min(A[1,...,n])
    return result</code></pre>
    <script type="text/javascript">
        window.onload = function(){
            var codeElement = document.getElementById('python_code');
            var code = codeElement.innerText;
          
            codeElement.innerHTML = "";
          
            var codeMirror = CodeMirror(
              codeElement,
              {
                value: code,
                mode: "python",
                theme: "default",
                lineNumbers: false,
                readOnly: true
              }
            );
        };
    </script>
  </body>
</html>
  • 1
    The updated answer didn't work for me for some reason. All I did was copy paste the code block into an html file, and then open that file in chrome. I get a blank web page. Not sure what I'm doing wrong. When I press "Run code snippet" here on stack overflow, I actually get colored code. – steoiatsl May 12 '21 at 21:02
  • 1
    @MinaMichael, I just updated the answer, it assumed that you'd use an http server to load the files and by opening them just from your filesystem you were using the `file://` protocol, which has some restrictions, besides the fact of the links being "protocolless" which meant the protocol part of the links from code mirror were being populated with `file:` instead of `http:` or `https:` as was the original intent of the code – Miguel Sánchez Villafán May 14 '21 at 14:34