From 9d6cd593e8529d5a88e4a43277762f6968480f23 Mon Sep 17 00:00:00 2001 From: arne314 <73391160+arne314@users.noreply.github.com> Date: Fri, 1 Nov 2024 23:50:17 +0100 Subject: [PATCH] feat: insert & open obsidian excalidraw drawings --- lua/typstar/config.lua | 21 +++++++++++ lua/typstar/excalidraw.lua | 41 +++++++++++++++++++++ lua/typstar/init.lua | 9 ++--- lua/typstar/utils.lua | 16 +++++++++ python/obsidian_open.py | 52 +++++++++++++++++++++++++++ res/excalidraw_template.excalidraw.md | 14 ++++++++ res/obsidian_open_config_example.json | 3 ++ 7 files changed, 152 insertions(+), 4 deletions(-) create mode 100644 lua/typstar/config.lua create mode 100644 lua/typstar/excalidraw.lua create mode 100644 lua/typstar/utils.lua create mode 100644 python/obsidian_open.py create mode 100644 res/excalidraw_template.excalidraw.md create mode 100644 res/obsidian_open_config_example.json diff --git a/lua/typstar/config.lua b/lua/typstar/config.lua new file mode 100644 index 0000000..b9af3b9 --- /dev/null +++ b/lua/typstar/config.lua @@ -0,0 +1,21 @@ +local M = {} + +local default_config = { + typstarRoot = '~/typstar', + excalidraw = { + assetsDir = 'assets', + filename = 'drawing-%Y-%m-%d-%H-%M-%S', + fileExtensionInserted = '.excalidraw.svg', + obsidianOpenConfig = nil, + } +} + +function M.merge_config(args) + M.config = vim.tbl_deep_extend('force', default_config, args or {}) + M.config.excalidraw.obsidianOpenConfig = M.config.excalidraw.obsidianOpenConfig or + M.config.typstarRoot .. '/res/obsidian_open_config_example.json' +end + +M.merge_config(nil) + +return M diff --git a/lua/typstar/excalidraw.lua b/lua/typstar/excalidraw.lua new file mode 100644 index 0000000..c15a756 --- /dev/null +++ b/lua/typstar/excalidraw.lua @@ -0,0 +1,41 @@ +local M = {} +local config = require('typstar.config') +local utils = require('typstar.utils') + + +local cfg = config.config.excalidraw +local affix = [[ +#figure( + image("%s"), +) +]] + +local function launch_obsidian_open(path) + print(string.format('Opening %s in Excalidraw', path)) + utils.run_shell_command('python3 ' .. + config.config.typstarRoot .. '/python/obsidian_open.py ' .. + path .. ' --config ' .. cfg.obsidianOpenConfig) +end + + +function M.insert_drawing() + local assets_dir = vim.fn.expand('%:p:h') .. '/' .. cfg.assetsDir + if vim.fn.isdirectory(assets_dir) == 0 then + vim.fn.mkdir(assets_dir, 'p') + end + local filename = os.date(cfg.filename) + local path = assets_dir .. '/' .. filename .. '.excalidraw.md' + local path_inserted = cfg.assetsDir .. '/' .. filename .. cfg.fileExtensionInserted + utils.insert_snippet(string.format(affix, path_inserted)) + launch_obsidian_open(path) +end + +function M.open_drawing() + local line = vim.api.nvim_get_current_line() + local path = vim.fn.expand('%:p:h') .. + '/' .. string.match(line, 'image%("(.*)' .. string.gsub(cfg.fileExtensionInserted, '%.', '%%%.')) .. + '.excalidraw.md' + launch_obsidian_open(path) +end + +return M diff --git a/lua/typstar/init.lua b/lua/typstar/init.lua index 532c00c..0e8df90 100644 --- a/lua/typstar/init.lua +++ b/lua/typstar/init.lua @@ -1,12 +1,13 @@ local M = {} -local default_config = { -} +local config = require('typstar.config') +local excalidraw = require('typstar.excalidraw') -M.config = default_config +vim.api.nvim_create_user_command('TypstarInsertExcalidraw', excalidraw.insert_drawing, {}) +vim.api.nvim_create_user_command('TypstarOpenExcalidraw', excalidraw.open_drawing, {}) M.setup = function(args) - M.config = vim.tbl_deep_extend("force", M.config, args or {}) + config.merge_config(args) end return M diff --git a/lua/typstar/utils.lua b/lua/typstar/utils.lua new file mode 100644 index 0000000..1e378bf --- /dev/null +++ b/lua/typstar/utils.lua @@ -0,0 +1,16 @@ +local M = {} + +function M.insert_snippet(snip) + local line_num = vim.fn.getcurpos()[2] + local lines = {} + for line in snip:gmatch '[^\r\n]+' do + table.insert(lines, line) + end + vim.api.nvim_buf_set_lines(0, line_num, line_num, false, lines) +end + +function M.run_shell_command(cmd) + vim.fn.jobstart(cmd) +end + +return M diff --git a/python/obsidian_open.py b/python/obsidian_open.py new file mode 100644 index 0000000..b7b07dd --- /dev/null +++ b/python/obsidian_open.py @@ -0,0 +1,52 @@ +import argparse +import json +import os +import re +import urllib.parse + +argument_parser = argparse.ArgumentParser( + formatter_class=argparse.RawDescriptionHelpFormatter, + prog="Obsidian File Opener", + description="Open and create files in Obsidian with template support.", + epilog=""" + \n\n + Template config file format (json): + + { + "filename_regex": "template_path" + } + + example: + { + "\\\\.md$": "~/Templates/default.md" + "\\\\.excalidraw\\\\.md$": "~/Templates/excalidraw.md" + } + """, +) +argument_parser.add_argument("file", help="file to open/create") +argument_parser.add_argument( + "-c", "--config", help="path to json template config file", required=True +) +args = argument_parser.parse_args() +path = os.path.abspath(args.file) +url_params = { + "path": path, +} + +if not os.path.exists(path): + filename = os.path.basename(path) + with open(args.config) as f: + config = json.loads(f.read()) + template_content = "" + + for regex, template in config.items(): + if re.search(regex, filename): + print(f"Template regex is matching: {regex}") + with open(os.path.expanduser(template), encoding="utf-8") as f: + template_content = f.read() + break + with open(path, "w", encoding="utf-8") as f: + f.write(template_content) + +encoded = urllib.parse.urlencode(url_params, quote_via=urllib.parse.quote) +os.system(f"xdg-open obsidian://open?{encoded}") diff --git a/res/excalidraw_template.excalidraw.md b/res/excalidraw_template.excalidraw.md new file mode 100644 index 0000000..8f0c596 --- /dev/null +++ b/res/excalidraw_template.excalidraw.md @@ -0,0 +1,14 @@ +--- + +excalidraw-plugin: parsed +tags: [excalidraw] + +--- +==⚠ Switch to EXCALIDRAW VIEW in the MORE OPTIONS menu of this document. ⚠== You can decompress Drawing data with the command palette: 'Decompress current Excalidraw file'. For more info check in plugin settings under 'Saving' + + +## Drawing +```compressed-json +N4IgLgngDgpiBcIYA8DGBDANgSwCYCd0B3EAGhADcZ8BnbAewDsEAmcm+gV31TkQAswYKDXgB6MQHNsYfpwBGAOlT0AtmIBeNCtlQbs6RmPry6uA4wC0KDDgLFLUTJ2lH8MTDHQ0YNMWHRJMRZFADZFFjIkT1UYRjAaBABtAF1ydCgoAGUAsD5QSXw8LOwNPkZOTExyHRgiACF0VABrQq5GXABhekx6fAQQAGIAM1GxkABfCaA== +``` +%% diff --git a/res/obsidian_open_config_example.json b/res/obsidian_open_config_example.json new file mode 100644 index 0000000..46fa4a3 --- /dev/null +++ b/res/obsidian_open_config_example.json @@ -0,0 +1,3 @@ +{ + "\\.excalidraw\\.md$": "~/typstar/res/excalidraw_template.excalidraw.md" +}