Search code examples
ace-editorhtml-rendering

Ace code editor: Render entire code to HTML?


Ace is smart when it comes to rendering code with highlighting and doesn't render all the code, but only a bit more than the current view requires.

However, for my use case I need to get the rendered HTML source of the entire code. Is there a way to make it render all my code at once?


Solution

  • "a user" pointed me in the right direction. I hacked together something that works for me using an ace build: https://github.com/ajaxorg/ace-builds/

    Preview of solution

    Regular ACE editor on the left, statically highlighted HTML on the right. Initially, the page source is used as content, but can be changed in the editor and the right panel is re-rendered instantly.

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title>ACE Static Highlighter</title>
            <style type="text/css" media="screen">
                body {
                    overflow: hidden;
                }
    
                #editor, #static { 
                    margin: 0;
                    position: absolute;
                    top: 0;
                    bottom: 0;
                    left: 0;
                    right: 50%;
                }
    
                #static {
                    left: 50%;
                    right: 0;
                    overflow: auto;
                }
            </style>
        </head>
        <body>
            <pre id="editor"></pre>
            <pre id="static"></pre>
            <script src="ace/build/src/ace.js"></script>
            <script src="ace/build/src/ext-static_highlight.js"></script>
            <script>
                var highlight = ace.require("ace/ext/static_highlight")
                var dom = ace.require("ace/lib/dom")
    
                var codeEl = document.getElementById("static");
                var editor = ace.edit("editor");
                //editor.session.setMode("ace/mode/html");
                //editor.setTheme("ace/theme/twilight");
                editor.setOptions({
                    showPrintMargin: false,
                    mode: "ace/mode/html",
                    theme: "ace/theme/twilight"
                });
                editor.session.setValue(document.documentElement.outerHTML);
                doHighlight(editor, codeEl);
    
                editor.session.on("change", function() {
                    doHighlight(editor, codeEl);
                });
    
                function doHighlight(editor, codeEl) {
                    codeEl.textContent = editor.session.getValue();
                    highlight(codeEl, {
                        // broken, see https://stackoverflow.com/a/31882064/2044940
                        //mode: editor.session.getMode().$id,
                        mode: editor.session.$modeId,
                        theme: editor.getTheme(),
                        startLineNumber: 1,
                        showPrintMargin: false,
                        trim: true
                    }, function (highlighted) {
                        var themeStyleId = editor.getTheme().replace("/theme/", "-");
                        var match = document.getElementById(themeStyleId).innerHTML.match(
                            new RegExp(`.${themeStyleId}\\s+\\{[^}]*?background-color:\\s*?([^;,}]+)`)
                        );
                        if (match) {
                            codeEl.style.backgroundColor = match[1];
                        }
                    });
                }
            </script>
        </body>
    </html>
    

    If there's a less hackish way to get the theme's background color, please let me know.