Improve Markdown viewing / editing with DTTG

DT and DTTG become more and more essential to my workflows - and it seems that there’s still more to explore. They’re obviously different applications on different platforms, but it’s already quite amazing the feature parity between the two products. A few questions regarding Markdown viewing / editing with DTTG:

  • I’m using metadata in Markdown with links to URL fields. On Mac I’m using a custom Javascript to extract that metadata (based on the meta tags in HTML). This JS script is referenced via a DT item URL. Would it be possibly to allow for such JS injection as well with DTTG?

  • When viewing Markdown it automatically shows the rendered view - it is possible to open the edit view by default instead?

  • In plain text data detectors work well for things like URLs, would it be possible to also recognize URLs in Markdown edit view? A bit analog to this discussion: Recognize links in Markdown WYSIWYG editor - #8 by cgrunenberg


No on all accounts.
The requests are noted with no promises.

Can you explain what exactly you’re doing in your MD files on DT to inject the JS?

Background: If you’re using the global preference for JS files in MD, that will of course not work in DTTG. I was hoping that
<script src="x-devonthink-item://xxx"></script> might work, but that seems to be a dead end: While it seems to work in DT, it does nothing in DTTG (or at least it does not execute window.alert(...), while it does that on DT. Similarly, it does nothing in my browser, since the x-devonthink-item protocol is used only to open files in DT, not to retrieve them from there.

Using the “file:///” protocol instead of “x-devonthink-item” is utterly pointless since the paths are completely different on macOS and iOS.

This is the script (which you helped me to improve ;-)) I’m using to display information from HTML meta tags ‘on the fly’ in the rendered HTML:

document.addEventListener('DOMContentLoaded', () => {
	const metadata = {};
	metadata["title"] = document.querySelector('title').innerText;
	["date", "url", "itemurl", "annotation", "path", "tags"].forEach( tag => {
		const node = document.querySelector(`meta[name="${tag}"]`)
		if (node)  metadata[tag] = node.content;

	if (metadata["itemurl"]) {
		body = document.querySelector("body").innerHTML;
		info = `<p><a href="${metadata['itemurl']}">Item</a> | <a href="obsidian://open?vault=Notes&file=${encodeURIComponent(metadata['title'])}.md">Obsidian</a> | <a href="kmtrigger://macro=Open&value=${encodeURIComponent('/Users/mdbraber/Library/Mobile Documents/com~apple~CloudDocs/Content/')+metadata["path"]}">File</a>`
		if (metadata["url"])  info = info + ` | <a href="${metadata['url']}">URL</a>`
		if (metadata["tags"]) info = info + `<br/>Tags: <i>${metadata['tags']}</i>`
		info = info + `</p><h1>${metadata['title']}</h1>`

		document.querySelector("body").innerHTML = info + "\n" + body;

I’m indeed using the global preference. As I’m doing this for every markdown file that’s the only way this would work. There’s already MathJAX and Prism support which I suppose are also done by injecting JS - so here’s to hoping it will be possible in future release.

Well, first off, DTTG does not seem to execute JS inside a MD file (except for Prism and Mermaid, that is). You could try by including the script code verbatim in a single MD file.
And since @BLUEFROG already said “no” to all three questions, that’s probably where we stand now.

Regardless: The script uses the protocols “obsidian://” and “kmtrigger://” which probably will not work on iOS (given that there’s no Keyboard Maestro on that platform …)

That’s clear - it won’t work unless DTTG allows for executing JS in rendered views by injecting. That’s not possible now - maybe it will be possible eventually.

For obsidian:// that works on iOS - I would replace kmtrigger:// with the shareddocuments:// protocol which opens the Files app on iOS.

I thought a bit more on that.

Firstly, it is no problem to have JS code execute within an MD file on macOS and iOS.
So this at the top of a markdown file

document.addEventListener("DOMContentLoaded", () => {
  const ul = document.querySelector('ul');
  const li = document.createElement('li');
  li.appendChild(document.createTextNode('second list element'));

appends an element to the first unordered list when the file is rendered as HTML.
So my assumption

is obviously wrong.

The problem is not with JS per se on i*OS but with loading external code via the script element. Interestingly, this

const body = document.body;
const script = document.createElement('script');
script.src = "x-devonthink-item://7FEF725B-D2EF-4339-9B3D-06CB43E9B765";

(where the DT item contains the code appending li to the ulas before) works perfectly fine in DT - but not in the browser. According to the log, the browser can’t do anything useful with the DT item link – as should be expected.

However, it does nothing in DTTG. And I’m not sure if that’s really to be expected, @aedwards? I’d suppose that the DT item link refers to the same file in DTTG as it does in DT. So shouldn’t DTTG’s webview do the same as the DT webview does, namely load the referenced DT item?

Or is that simpy not possible because of the limitations of iOS’s file “system”, sandboxing and what not?

Note A workaround could be to put the script file somewhere on the net where it can be accessed with https.

If that would be possible I hope development would consider a global JS script injection for markdown as on macOS. Injection of JS on a WebView is possible, but we’ll have to wait if this seems important enough to add to the list of updates.