I think I have an earlier version of this snippet from you somewhere - I was going to take a look at it for this purpose. So thanks!
J^n On Saturday, March 23, 2024 at 10:42:32 PM UTC tbp1...@gmail.com wrote: > I've been using an "images" subdirectory under the location of the > outline, or under the @path location if you use one. It would make backup > or sharing easier than some random location in the file system. The script > could check for its existence and create it if needed. > > Here's how I get the path of the node or it's @path into the clipboard: > > """Copy the effective path of the current node to the clipboard. > > This command honors @path directives. > """ > from pathlib import Path > > pth = Path(c.fullPath(p)) > if pth.exists(): > if pth.is_file(): > direc = pth.parent > else: > direc = pth > else: > direc = Path(g.scanAllAtPathDirectives(c, p)) > > if direc: > normdir = str(direc.resolve()) > g.app.gui.replaceClipboardWith(normdir) > else: > g.es(f"Path {direc} doesn't exist") > > BTW, I have this script linked to a button, which is very convenient > sometimes. > On Saturday, March 23, 2024 at 6:30:21 PM UTC-4 jkn wrote: > >> Hi Thomas >> not sure what an undoer would do here? maybe delete the file? There >> is no leo-relevant action here (yet) >> >> I'm well aware I don't *need* the main(), but I prefer to write this way. >> Same as with bash scripts etc. It helps for future modularity, I find. Of >> course, 'YAGNI', but still. f course you are right that main() could be >> more descriptive, this is only a POC. >> >> The tricky bit is deciding where to store the clipboard files. Obsidian >> has a special action when you click on inserted 'snippet' images; it just >> stores the filename in the 'body', and uses its knowledge of where the >> snippets are located when you do the equivalent of CTRL-click on the URL >> >> Linking the location of the 'snippets' to the leo file and/or node is an >> interesting challenge... >> >> >> >> On Saturday, March 23, 2024 at 10:09:59 PM UTC tbp1...@gmail.com wrote: >> >>> Looks pretty straightforward. Perhaps you'll want to make it undoable >>> (so far as Leo is concerned). As a matter of Python programming, defining >>> a main() function here isn't needed. If you are only going to use it as a >>> script, then you don't need a function at all. Just unindent those lines of >>> code (and delete the "main()" line) and they will run when the script >>> runs. No need to call main() at all. If you want that clipboard part of >>> the block to run and if it succeeds then insert the markdown text into a >>> node, then the function shouldn't be called "main" but something more >>> descriptive. >>> >>> On Saturday, March 23, 2024 at 4:59:25 PM UTC-4 jkn wrote: >>> >>>> OK, here is a simple demonstration of part of the feature I am >>>> interested in. >>>> >>>> When run with an image in the (global) clipboard, it saves this to a >>>> local timestamped file (under ~/tmp), and indicates how a markdown >>>> reference to that file could be inserted. >>>> >>>> There's plenty more needed but this is the QClipboard part, I think. >>>> >>>> import os >>>> import time >>>> >>>> def unique_png_fname(): >>>> """ return a unique (timestamped) filename to use >>>> """ >>>> FORMAT="%Y-%m-%d-%H-%M-%S.png" >>>> return time.strftime(FORMAT) >>>> >>>> def link_string_md(fname): >>>> """ get markdown format to insert a filename >>>> """ >>>> return "![[%s]]" % fname >>>> >>>> def main(): >>>> # get clipboard contents - default mode is global clipboard >>>> cb = g.app.gui.qtApp.clipboard() >>>> # is it in image format? >>>> img = cb.image() >>>> if not img.isNull(): >>>> basefiledir = os.path.expanduser("~/tmp") >>>> fqfilepath = os.path.join(basefiledir, unique_png_fname()) >>>> img.save(fqfilepath, "PNG") >>>> g.es("wrote clipboard to:", fqfilepath) >>>> g.es("could insert:", link_string_md(fqfilepath)) >>>> else: >>>> g.es("clipboard not in image format") >>>> >>>> main() >>>> >>>> >>>> On Monday, March 11, 2024 at 8:23:42 PM UTC jkn wrote: >>>> >>>>> Doh! should have read the documentation better. >>>>> >>>>> you have to test for a 'null image' using eg. img.isnull() >>>>> >>>>> on with my trivial experiments... >>>>> >>>>> >>>>> On Monday, March 11, 2024 at 8:10:03 PM UTC jkn wrote: >>>>> >>>>>> Has anyone played much with class QClipboard? I did a couple of >>>>>> trivial experiments but I must be misunderstanding something. >>>>>> >>>>>> for instance, QClipboard.image() returns a non-null value even if the >>>>>> clipboard does not contain an image. >>>>>> >>>>>> J^n >>>>>> >>>>>> >>>>>> On Monday, March 11, 2024 at 4:33:23 PM UTC tbp1...@gmail.com wrote: >>>>>> >>>>>>> It turns out that to get the relative path conversion w have to >>>>>>> remove any quotation marks around the path before running os.relpath(). >>>>>>> So >>>>>>> the script becomes: >>>>>>> >>>>>>> """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 = PATH.replace('"', '').replace("'", '') >>>>>>> PATH = relpath(PATH) >>>>>>> PATH = PATH.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() >>>>>>> >>>>>>> On Saturday, March 9, 2024 at 2:04:19 PM UTC-5 Thomas Passin wrote: >>>>>>> >>>>>>>> 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. >>>>>>>> >>>>>>> -- You received this message because you are subscribed to the Google Groups "leo-editor" group. To unsubscribe from this group and stop receiving emails from it, send an email to leo-editor+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/leo-editor/9b9d6744-4de0-4760-a65e-19228a0eab06n%40googlegroups.com.