We can't directly insert an image into a standard Leo node because they are text-only. I find this very annoying sometimes, especially when I am writing a note and want to include an image.
But we can do the next best thing - insert an ReStructuredText (RsT) instruction to display an image so that we can view it with the viewrendered3 plugin (VR3). The instruction is short and easy, but it's still annoying to type and I usually forget the exact details. I have a button that toggles VR3 on and off so that it's easy to view an embedded image once the RsT instruction is there. An embedding command would make embedding with Leo as easy as embedding an image in a word processor. Aha, this is Leo, let's write a script!
Here is a script that pops up a file dialog and inserts a relative path to the chosen file. There are several small variations which I discuss after the code.
"""Insert RsT code at cursor to display an image.
The path to the image file will come from a file dialog.
This action is undoable.
"""
PATH = g.app.gui.runOpenFileDialog(c,
title="Import File",
filetypes=[("All files", "*"),],
defaultextension=".*",
multiple=False)
if PATH:
from os.path import relpath
PATH = relpath(PATH)
PATH = PATH.replace('\\', '/').replace('"', '').replace("'", '')
IMAGE_TEMPLATE = f'''
.. figure:: {PATH}
:scale: 50%
'''
w = c.frame.body.wrapper
p = c.p
s = p.b
u = c.undoer
start, _ = w.getSelectionRange()
undoType = 'insert-rst-image-code'
undoData = u.beforeChangeNodeContents(p)
head, tail = s[:start], s[start:]
p.b = head + IMAGE_TEMPLATE + tail
c.setChanged()
p.setDirty()
u.afterChangeNodeContents(p, undoType, undoData)
c.redraw()
Variations:
1. If you want an absolute path instead of a relative path, delete the lines
from os.path import relpath
PATH = relpath(PATH)
with
2. If you want to get the path from the clipboard instead of a file dialog, replace the lines
PATH = g.app.gui.runOpenFileDialog(c,
title="Import File",
filetypes=[("All files", "*"),],
defaultextension=".*",
multiple=False)
with the line
PATH = g.app.gui.getTextFromClipboard()
3. If you want the embedded image to be full width instead of 50%, delete the line
:scale: 50%
4. You can make this work with Markdown or Asciidoc by using their embedding instruction in the TEMPLATE instead of the RsT one.
I have added the command to my own local menu. VR3 can open in a tab in the log pane; the command for toggling in a tab is vr3-toggle-tab. I usually like opening it in the log pane instead of in its own separate pane.
If you would like to create a local menu of your own and don't know how, it's easy. Just ask and I'll show what to add to myLeoSettings,leo.