File location by item record identifier?

I would like to be able to preview Markdown documents externally with something like marked 2 and have marked 2 understand where files, such as images live based on their DEVONthink item id and x-devonthink URI.

Imagine an image stored in DEVONthink. I could copy the item link. It might look like x-devonthink-item://<recordID>. I would then add a query parameter to get DEVONthink to either re-direct to the current location on disk, or reply by streaming the content. Imagine how this works in a web server.

Example:

x-devonthink-item://<recordID>?source=1

Then when some external markdown editor or previewer sees x-devonthink-item://<recordID>?source=1, it can actually render the image.

How can I make this work?

1 Like

There may be a way, but outside my knowledge and expertise. Others can comment.

But it occurs to me that if I were wanting to do this I would not have the images imported into DEVONthink, but keep them on the file system. In your markdown, point to the file system location, and as you want the images in DEVONthink also, then index them. Can do this now, AFAIK.

1 Like

You can’t. A URL scheme isn’t the file. It’s a pointer to a file no different than a web address is. DEVONthink is the registered application for our item links.

If it is no different than a web address, then there is still hope.

What I mean is that DEVONthink has a URL scheme such that any URL identified with x-devonthink is opened and processed by DEVONthink. Currently if I click a URL like x-devonthink-item then DEVONthink finds a item identified with the provided record id, and opens it in DEVONthink. If I add a query parameter of ?reveal=1 then the default open behavior is changed. The query parameter causes DEVONthink to reveal the item in the item list instead of opening it in a new window. In both cases the same item is found, by its record id, but the action taken by DEVONthink was different.

If I provide a URL like x-devonthink://<command>? <parameter=value&parameter=value&...> then DEVONthink takes an action quite different than what I would expect for a simple pointer to a file. One example would be x-devonthink://search?query=DEVONthink where a search is performed with the provided search query criteria.

This tells me that DEVONthink intercepts the URL requests and processes them according to its full URL content. The key for me is that the result from the URL is not fixed like with a file:// URL. It should be possible then to do something like a 302 redirect to the content if a special query key is sent.

Maybe something like?:

  • x-devonthink-item://<recordID> —> Open the item with the given record id in a new window.
  • x-devonthink-item://<recordID>?reveal=1 —> Reveal the item identified with the record id, in the item list.
  • x-devonthink-item://<redordID>?stream=1 —> Stream back the actual content of the URL much like how an image or an HTML file is returned for an HTTP request.

I describe 302 redirect, not because I think that DEVONthink would actually perform a 302 redirect, but rather that DEVONthink could alter its behavior, much like how a 302 alters behavior. The good thing is that DEVONthink already does this with reveal=1.

My question is how can DEVONthink be made to alter its behavior based on a key to permit x-devonthink-item URLs to be used inside Markdown documents so they can be processed by external markdown readers like marked 2. The devonthink-item URLs already work in Markdown documents that are rendered inside DEVONthink but not outside.

Example:

<img src="x-devonthink-item://865AE536-0CDC-44EE-A177-DE7E2DC1340D" 
alt="example" 
width="40%">

Inside a Markdown document rendered in DEVONthink looks like:

The same outside DEVONthink, in marked 2 looks like:

These URLs are just references (to easily jump to the referenced item in DEVONthink), this not a client/server connection like http(s).

Would it be possible to create and register an AppleScript action to provide the system file location based on the record id? Perhaps using the command schema, x-devonthink: rather than the item reference, x-devonthink-item:?

x-devonthink:getItemLocation?recordid=<recordId>

Same issue - DEVONthink does neither get these requests automatically nor can it return any data.

Hmm. This is tricky.

Is an item’s location persistent? If it is persistent then perhaps when I create the Markdown document I could find the item’s physical location from the item id, then rather than add the x-devonthink-item URL I could add the file’s physical location.

So rather than:

<img src="x-devonthink-item://865AE536-0CDC-44EE-A177-DE7E2DC1340D" 
alt="example" 
width="40%">

I could add:

<img src="file:///Users/mmynsted/Databases/Primary.dtBase2/Files.noindex/png/e/example.png" 
alt="example" 
width="40%">

Usage of internal paths is not recommended as they’re not necessarily persistent. This should work in case of indexed files/folders (as long as you don’t rename or move them). Then you could probably use relative paths instead of absolute ones (assuming that the Markdown editor supports this).

Your best bet is to follow @rmschne’s advice and store the images outside of DT in the file system. Also, you might want to read up on the discussions on images in MD files here in the forum.
Generally speaking, images in MD files are tricky. And if you need images in MD, why not use the MD syntax to attach them but rather HTML? That add’s another layer of complexity, quite unnecessarily, I think.

1 Like

I will explore that.

I want to keep all the necessary content together and be able to export the group just like I would export anything else in DEVONthink. This might not be a problem with indexed content but then I wonder why I am using DEVONthink. It does not make sense to have some content in DEVONthink and some outside.

The referenced files are not always images. Sometimes they are PDFs, or other Markdown files.
I keep an assets group for all the Markdown document’s referenced items. It is built using my Markdown document template. Files might be directly stored there, or replicated there.

The very simple example (from above).

The image referenced by

<img src="x-devonthink-item://865AE536-0CDC-44EE-A177-DE7E2DC1340D" 
alt="example" 
width="40%">

lives in the assets group for that document. In this example it is not replicated there, it is just a PNG named example, imported to directly to the group.

I do not understand. What does this mean? If you mean "why am I using an HTML img tag rather than a Markdown image tag, then I am just doing it because it was easiest way I knew of to supply width that works with any Markdown flavor.

Why are you using item links at all if you’re using a well-defined folder structure like this??

Just use the relative path, e.g., /assets/example.png.
This will works just fine when exporting this group.

That’s what CSS was invented for - to separate meaning from representation.

1 Like

Normally I do use relative URLs like this.

<img src="./assets/example.png" alt="example" width="40%">

These work the same in DEVONthink but do not work outside DEVONthink, in something like marked 2.
This is because while DEVONthink can somehow find the file, marked 2 can not. Here is why.

The URL for the Markdown document is:

file:///Users/mmynsted/Databases/Primary.dtBase2/Files.noindex/md/8/VIM%20-%20quick%20notes.md

and the URL for the PNG is:

file:///Users/mmynsted/Databases/Primary.dtBase2/Files.noindex/png/e/example.png

This means that the relative URL is interpreted to be:

/Users/mmynsted/Databases/Primary.dtBase2/Files.noindex/md/8/assets/example.png

This is not correct. Somehow DEVONthink is able to figure out the correct relative URL.

https://daringfireball.net/projects/markdown/syntax#img

I suppose I could provide an id for every img then decorate each img by id using a CSS block in every markdown document. If link out to some common CSS I suffer the same link out problem that I am having now. I do agree that using CSS will be a better solution.

  1. The syntax would be ![example image](/assets/example.png) in the Markdown.
  2. If you exported this parent group, containing the Markdown document and the assets group, it would open and show the images in any reliable Markdown application.

and in MacDown, the exported file in its group…

1 Like

If you needed a different width for every image: yes. But that begs the question if MD is really the best format for what you want to achieve: different widths for every image are calling for a layout program rather than a markup language like MD.
If you want to use CSS with MD, you can set a global file for that in DT (and in many dedicated MD editors). No need to put it in every MD file, although that’s possible, too. Also, the CSS permits you to set the font, font size, indentation and all that. In a single place, no need to touch any MD file.

1 Like

:grinning: Good suggestion. Since I already use a stylesheet for Markdown, I could add a default width for images there and only update the width with IDs, for those special images.

That is true. Markdown is really my starting markup. Most documents do not get promoted beyond Markdown. I like LaTeX for more complicated works but that is a later step in my process. Having most documents be written with Markdown makes it easy to share content around.