ajaxorg / ace

Ace (Ajax.org Cloud9 Editor)
https://ace.c9.io
Other
26.77k stars 5.29k forks source link

Proper Print Support. #5411

Open MarketingPip opened 11 months ago

MarketingPip commented 11 months ago

Describe the feature

A easy function to print code from editor / export to html.

Use Case

This is a useful function for the editor. And has been requested / asked how to achieve before via Google and issues...

Proposed Solution

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Ace Editor Print Button</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.12/ace.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.12/ext-static_highlight.js"></script>
    <style>
        #editor {
            height: 300px;
        }
    </style>
</head>
<body>

<div id="editor">function printCode() {
    console.log("Hello, world!");
}</div>
<button id="printButton">Print Code</button>

<script>
 function Print(code, css, removeGutter = false) {
    try {
        // Create an iframe
        var printIframe = document.createElement('iframe');
        printIframe.style.width = '800px';
        printIframe.style.height = '400px';
        printIframe.style.display = 'none'; // Hide the iframe

        document.body.appendChild(printIframe);

        // Get the document of the iframe
        var printDocument = printIframe.contentDocument || printIframe.contentWindow.document;

        printDocument.write(`<html><head><title>${document.title}</title></head><body>`);

      printDocument.write(`<style> ${css}</style>`)

        if(removeGutter){
         code = code.replaceAll(`<span class="ace_gutter ace_gutter-cell"></span>`, "").replaceAll("ace_show_gutter", "")
        }
        printDocument.write(code);
        printDocument.write("</body></html>");

        printDocument.close();

        printIframe.contentWindow.print();

            document.body.removeChild(printIframe);
       // You  may adjust the delay based on your needs
    } catch (error) {
        console.error("Error printing:", error);
    }
}
    // Initialize Ace editor
    var editor = ace.edit("editor");
    editor.setTheme("ace/theme/monokai");
    editor.getSession().setMode("ace/mode/javascript");

    // Function to print code from Ace editor using ext/static_highlight
    function printCode() {
        require("ace/config").loadModule("ace/ext/static_highlight", function(m) {
            var result = m.renderSync(
                editor.getValue(), editor.session.getMode(), editor.renderer.theme
            );
            var d = document.createElement("div");
            d.innerHTML = result.html;
         Print(d.innerHTML, result.css)
        });
    }

    // Attach the printCode function to the button click event
    document.getElementById("printButton").addEventListener("click", printCode);
</script>

</body>
</html>

Other Information

Looking for some feedback from the Ace Editor team. (It would be cool if I could contribute it), just looking for some feedback on this solution.

This could also be used as export to HTML function. To properly structure the syntax highlighter as a HTML document.

Notes: print margin does NOT match... And need a better solution for removing gutters preferably via API.

Acknowledgements

ACE version used

1.4.12

MarketingPip commented 11 months ago

Reference for self -

printIframe.contentWindow.document.documentElement

Access HTML document from iframe for exports.

andredcoliveira commented 11 months ago

@nightwing looks like you've looked at this before in https://github.com/ajaxorg/ace/issues/1480#issuecomment-20201314; do you have any particular thoughts?

nightwing commented 11 months ago

I guess we can add this as a demo and to the playground to make it easier to find, but i don't see a way to integrate this into the main package.

MarketingPip commented 11 months ago

@nightwing - I seen your solution from 2014, but this just seemed like a better updated solution (that appears a few have needed via Google Searches). Tho don't ask me why I had the half baked idea to grab document element lol. We could just write it out as string the have it exportAsHTML.string() & exportAsHTML.html()````and then a print using the exportAsHTML.html().

Being 2 new API methods. .print() & .exportAsHTML(). I think it would be a nice add to main core / editor.

ps; quick question, wanna give me an example how to get the Ace Editor current mode including caption / extensions etc?