obsidian-excalidraw-plugin
obsidian-excalidraw-plugin copied to clipboard
FR: Setting to allow exporting internal links as relative file paths in SVG
Is your feature request related to a problem? Please describe. I host my diagrams with my obsidian markdown files on a static website. I do this by enabling auto-export to SVG for the excalidraw files.
Currently the auto-export and regular save methods use the getSVG() with a file obviously and as such run the updateElementLinksToObsidianLinks() method, which cause the embedded links in the final svg to try opening the markdown in obsidian, rather than according to the existing relative path that I have.
Describe the solution you'd like
Add a configurable setting that allows for exporting SVG with relative links, so for example the excalidraw drawing located in excalidraw/example which links to [[docs/example]] will have href="../docs/example.md"
Describe alternatives you've considered
I tried running the createSVG method on ExcalidrawAutomate, but it just exports the links directly as the original [[wikilinks]], which isn't helpful
I also tried placing the relative url directly in excalidraw, but then I don't have all the fun features of hovering and seeing a preview or even able to jump to the file by ctrl+click
Any other ideas are welcome :D
This is doable. I'll add a setting for this.
In 2.0.23 I created a new Excalidraw hook: onUpdateElementLinkForExportHook. Feel free to edit the link however you like. When you are done with your function, please post it here for others to see it as a reference. Also let me know if you were able to solve your need with this solution.
You can access the startup script through plugin settings here:
You can set this like this:
/**
* If set, this callback is triggered whenever a drawing is exported to SVG.
* The string returned will replace the link in the exported SVG.
* The hook is only executed if the link is to a file internal to Obsidian
* see: https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/1605
* onUpdateElementLinkForExportHook: (data: {
* originalLink: string,
* obsidianLink: string,
* linkedFile: TFile | null,
* hostFile: TFile,
* }) => string = null;
*/
//ea.onUpdateElementLinkForExportHook = (data) => {};
Amazing! I added this to my startup scripts, the fact that it's a hook actually makes it really easy to switch it to pointing to the final html static files on my jekyll site.
/**
* If set, this callback is triggered whenever a drawing is exported to SVG.
* The string returned will replace the link in the exported SVG.
* The hook is only executed if the link is to a file internal to Obsidian
* see: https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/1605
* onUpdateElementLinkForExportHook: (data: {
* originalLink: string,
* obsidianLink: string,
* linkedFile: TFile | null,
* hostFile: TFile,
* }) => string = null;
*/
const path = require('path').posix;
ea.onUpdateElementLinkForExportHook = (data) => {
if (!data.linkedFile?.path) return originalLink;
return path.relative(data.hostFile.parent.path, data.linkedFile.path).replace('md', 'html');
};
Here is my hook in case someone comes looking:
I wanted to be a bit more explicit, so I leverage the syntax for custom text. This works particularly nicely for object links as the custom text is not shown.
[[ObsidianLink|export-as:../MyCustomLink]]
/**
* If set, this callback is triggered whenever a drawing is exported to SVG.
* The string returned will replace the link in the exported SVG.
* The hook is only executed if the link is to a file internal to Obsidian
* see: https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/1605
* onUpdateElementLinkForExportHook: (data: {
* originalLink: string,
* obsidianLink: string,
* linkedFile: TFile | null,
* hostFile: TFile,
* }) => string = null;
*/
//ea.onUpdateElementLinkForExportHook = (data) => {
// const decodedObsidianURI = decodeURIComponent(data.obsidianLink);
//};
ea.onUpdateElementLinkForExportHook = (data) => {
var matches = data.originalLink.match(/.*\|export\-as:(.*)\]\]/)
if (matches)
{
return matches[1];
}
const decodedObsidianURI = decodeURIComponent(data.obsidianLink);
return decodedObsidianURI;
};
In case anyone is curious, my use-case is geared towards putting SVGs on Confluence, but also being able to navigate via Obsidian.
Edit: Any chance this hook could be made aware if the SVG is being generated as an embed into another obsidian document? My ideal scenario would be a custom link when exported as a file and obsidian link when exported as an embed.