Skip to content

Instantly share code, notes, and snippets.

@daeh
Last active September 25, 2023 19:04
Show Gist options
  • Save daeh/6d924a634de51d024dd4435a229b9fc3 to your computer and use it in GitHub Desktop.
Save daeh/6d924a634de51d024dd4435a229b9fc3 to your computer and use it in GitHub Desktop.
Obsidian Templater Helper to Insert Clipboard Contents into MD Notes
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Obsidian Templater Helper to Insert Clipboard Contents into MD Notes
Use Templater to control how Obsidian processes images pasted into notes.
N.B. Its functionality would be better as a plugin. This solution is fairly hacky.
Only tested on MacOS with Python 3.8.
Image in clipboard is saved to:
./_resources/{note_basename}.assets/imgpaste.png
If the content of the clipboard is a file path (image, zip archive, etc.),
that file is copied to `./_resources/{note_basename}.assets/`.
__DEPENDENCIES__
Obsidian: https://obsidian.md
Templater plugin: https://silentvoid13.github.io/Templater
obsidian-hotkeys-for-templates plugin: https://github.com/Vinzent03/obsidian-hotkeys-for-templates
__USAGE__
- In Templater preferences, "Enable System Commands".
- Make a User Function with name "assethelper" and replace the `path_to_python_executable`
and `path_to_this_script` placeholders:
path_to_python_executable path_to_this_script "<% tp.file.path(false) %>"
- E.g. the function might be:
~/anaconda3/envs/myenv/bin/python ~/templater-helpers/asset-helper.py "<% tp.file.path(false) %>"
- In your vault's Template Folder make the template file `attach-asset.md` containing:
<% tp.user.assethelper() %>
- Optional: Use obsidian-hotkeys-for-templates plugin to assign attach-asset.md to a hotkey.
- Copy an image (e.g. screenshot) or file path (e.g. the text `/User/daeh/archive.zip`) to
your clipboard, then activate the `attach-asset` template (e.g. by using a hot-key). The image
in the clipboard or the file pointed to will be added to `./_resources/{note_basename}.assets/`
and a wiki link or an url encoded MD link added to the note.
"""
import sys
from pathlib import Path
from shutil import copy
from PIL import ImageGrab
from urllib.parse import quote
from subprocess import check_output
import traceback
def main(mdpathstr):
### map note assets directory ###
mdpath = Path(mdpathstr)
resource_dir_path = mdpath.parent / "_resources" / f"{mdpath.with_suffix('').name}.assets"
img = ImageGrab.grabclipboard()
if isinstance(img, type(None)):
### if clipboard content is a string representing the path to a file (image or otherwise) ###
cbpath = Path(check_output('pbpaste', env={'LANG': 'en_US.UTF-8'}).decode('utf-8'))
file_suffix = cbpath.suffix
if not cbpath.is_file():
print(f"pbpaste content:: \n. . .\n{cbpath}\n. . .\n")
raise Exception
### copy image to assets directory ###
fnamebase = cbpath.with_suffix('').name
imgpath = resource_dir_path / f"{fnamebase}{file_suffix}"
ii = 0
while imgpath.exists():
ii += 1
imgpath = resource_dir_path / f"{fnamebase}-{ii}{file_suffix}"
resource_dir_path.mkdir(parents=True, exist_ok=True)
copy(cbpath, imgpath)
else:
### if clipboard content is an image ###
file_suffix = '.png'
### copy image to assets directory ###
fnamebase = "imgpaste"
imgpath = resource_dir_path / f"{fnamebase}{file_suffix}"
ii = 0
while imgpath.exists():
ii += 1
imgpath = resource_dir_path / f"{fnamebase}-{ii}{file_suffix}"
resource_dir_path.mkdir(parents=True, exist_ok=True)
img.save(str(imgpath), 'PNG')
### return md link ###
imgpathstr = str(imgpath).split(str(mdpath.parent))[-1].lstrip('/')
imgpath_encoded = quote(imgpathstr, safe="/@,")
### as wiki link ###
print(f"![[{imgpathstr}]]")
### as url encoded link ###
# print(f"![]({imgpath_encoded})")
if __name__ == '__main__':
try:
main(sys.argv[1])
except Exception:
print("Error when running user template.")
print("```")
traceback.print_exc(file=sys.stdout)
print("```")

<% tp.user.assethelper() %>

@daeh
Copy link
Author

daeh commented Dec 26, 2021

There's now a good plugin that let you specify relative paths for assets: https://github.com/RainCat1998/obsidian-custom-attachment-location

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment