guysv / ilua

Portable Lua kernel for Jupyter
GNU General Public License v2.0
119 stars 12 forks source link

printing #5

Open kenlo88 opened 4 years ago

kenlo88 commented 4 years ago

Can I print html or md code (i.e. something like display() or HTML() of iPython) ? I cannot find any hint from the source code. Likewise, is it possible to print html5 charts (e.g. C3.js) or use jQuery ?

Thank you in advance.

guysv commented 4 years ago

ILua does not support rich output to jupyter notebooks, plain text is currently the only option. It is possible to implement such feature, but I'm not sure its going to be an easy fit into the codebase.

sjcooke commented 4 years ago

A basic implementation for rich output appears to be straightforward, and could be used to build a higher level interface as a separate Lua module:

Jupyter's display_data messages can be handled in the do_execute method in kernel.py, after the initial execute request has been sent and before the result is checked:

        while result["type"] == "display_data":
            if not silent:
                self.send_update("display_data", {
                    'data':     result["payload"]["data"],
                    'metadata': result["payload"]["metadata"]
                })
            result = yield self.proto.sendRequest({"type": "...", "payload": "..."})

After the display_data message is forwarded to Jupyter, result receives the next message.

Messages can now be sent from Lua using a global function (defined just before the message loop at the end of interp.lua) that sends a display_data message and waits for the new request:

function _send_display_data(data,metadata)
    metadata = metadata or { }
    if next(metadata) == nil then metadata['']='' end -- force dict
    netstring.write(ret_pipe, json.encode({
        type = "display_data",
        payload = {
            data     = data,
            metadata = metadata,
        }
    }))
    ret_pipe:flush()
    local message = json.decode(netstring.read(cmd_pipe))
end

From Jupyter notebook it should now be possible to create rich output of any supported type:

_G._send_display_data { ['text/html'] = '<h3>Lua logo</h3>' }
_G._send_display_data { ['text/markdown'] = [[
- From http://lua-users.org/wiki/LuaLogo
- Converted to base64
]] }
local logo16x16 = [[iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA
AAAAAAD5Q7t/AAAACXBIWXMAAAABAAAAAQBPJcTWAAAAB3RJTUUH1wQKDjopNFerjAAAAnpJREFUeJ
xtk89LVFEcxT/3vTvP54w/xlFnIEfNVMQyalNYpCBhUNQi2rfPbQtD6B/QllLUwn0bV4aLpDa1iiCo
Jgk1E8QxUx/Nszfz5r17W1xFE7+rC/eee77ne77H5sQSApIZcNNQUwduI1g2xBVznz0H3aMQeOIY0I
JELThJiCoQhaA1WBbYCbAd8+mtp5C9AEuv5CHYkoZNxRD8gUw35M6D2wTBDvz6ArvL0HYF2odAutB9
Ux4y19QZ1mQWrj6EvruQypnWVWxZf4taL85q/X0OthehuQ+KH/clOCmj222GOy/g9HUDNNXf38LY2G
WCIIynp1++XlubfwKWA78Lcl+3C2XfMP8PltJifPwa9+9fRCltx7EenZhY+qb1wiOobbTMhOPIaO67
exR84IfjyP2zwHGkDf33oKkLooqERBL+7kB2AFLZgYEsq6sevh8CUK0qpqbeEceKIIh49uwDWqdy0H
IWvJ8SdARagZsBIQcH83hegO+H9PZmWF8vUSqFTE6+p6eniWo1BoSE2gxobQHCNFreMZ8JQCAEDA93
ksm4DA11ks/X09qaYmSkC1CRsdayJMQhSAc2P8PeZiJhtbe3NwDgupJcro502qW+3sHzyqRSCWBvA7
a+gp2wISqD2wClDWhokzJ/qaMjbSWTCYpFn7a2BgqFLTyvghACzwuilZW3M0oVZsGpPdiDJAgbatJw
+zmcuXHcDVMqguV5mHsAYQlUtP9IxSYDoQ8/Fszu158yDgkBKoTSOnyagTePobwLtoRw70iYjmYhCq
HpNLSeNe4E27BVAG/VLJ0QUPFBxSel0TXMcdUMWCvjlHRMgCq+mZtWAP8Azi3klkVk/CYAAAAASUVO
RK5CYII=]]
_G._send_display_data( 
    { ['image/png'] = logo16x16 }, 
    { ['image/png'] = { width=24, height=24 } }
)
guysv commented 4 years ago

Interesting, If you want to work on it, id love to add this feature!

sjcooke commented 4 years ago

It appears that different kernels have similar, but different, interfaces for this feature. I'll take a look at how it might work for Lua.

BrettRToomey commented 4 years ago

@sjcooke any update on this? I'd love to have this feature and can help if needed.

rhaberkorn commented 10 months ago

Well, the changes suggested by @sjcooke work! Why don't we just merge them? Even in this primitive form, it's already very useful. And definitely something, I'd like to integrate into my project. I can send a merge request if you like... Also attached them as a patch.

screenshot-1699988999

rhaberkorn commented 10 months ago

Some extremely crude plotting into Jupyter cells using _send_display_data and GNU plot within my project. (It's a LuaJIT-based real-time-audio-programming-thing and cannot yet be released publicly.)

screenshot-1699993173