DEVONthink Markdown Table-of-Contents generator

6 minute read comments

I really love how MultiMarkdown (MMD) automatically generates a Table-of-Contents (TOC) by simply adding the {{TOC}} command to your Markdown files. It’s indeed practical as it updates the TOC after every change you apply to the headings of your document, without any further user-interaction being required. However, there is drawback of how MMD version 6 internally generates the TOC while rendering the Markdown file.


This drawback concerns links in headings: Whenever you add a link to a heading, the TOC-link to that heading gets split from the position where the link is inserted:

A Markdown file in DEVONthink with an auto-generated table-of-contents (TOC) in preview (left) and edit mode (right).

In the example in the screenshots above, the second TOC-entry gets split into

"Section title with a" + "link" + "and some more text"

By clicking on the intact TOC-link part before the split (“Section title with a”), the document correctly jumps to the corresponding heading. However, when you click on the TOC-link part after the split, i.e., on the name of the actual inserted link (“link”), the document will open the associated link destination instead to jump to the corresponding heading. The part after the inserted link (“and some more text”) remains unlinked at all. In cases where the entire heading text is a link, the whole TOC-entry links to the associated link destination and there is no possibility to jump to the corresponding heading overall.

A solution to this miss-behavior could simply be to stop adding links to the headings. Indeed, I never add links to the headings of my Markdown files. However, the problem re-occurs when you use DEVONthink with its automatic WikiLinks function in combination with the “Names and Aliases” option.

img DEVONthink’s automatic WikiLinks function with the selected “Names and Aliases” option.

Having this option selected, DEVONthink automatically converts name and alias mentions within your document into links to the mentioned files. I.e., you don’t have to manually add WikiLinks by enclosing the word with straight brackets (e.g., [[The Wikilink]]), they automatically occur while writing the text.

While being so useful within the contents of your document, automatic WikiLinks get in conflict with the MMD TOC generation in headings due to the miss-behavior explained above. When DEVONthink renders the Markdown document, it internally converts the WikiLinks into html-links. You can’t control, when DEVONthink converts a name and alias mention into a WikiLink and when it should avoid doing it: all mentions are converted automatically.

A Markdown file in DEVONthink with an auto-generated TOC and automatic WikiLinks in a heading in preview (left) and edit mode (right).

In the example in the screenshots above, the second TOC-entry gets again split as in the previous example:

"Section with a WikiLink:" + "Some Test File" + "and some more text"

“Some Test File” is not a manually added Markdown reference link, but a detected automatic WikiLink that links to the file Some Test File. When you now click on the TOC-link part “Some Test File”, the linked file opens instead of jumping to the corresponding headline within the current document.

As mentioned above, you can’t turn off the automatic WikiLinks for specific mentions. The only workaround here would be to rewrite the mention in the heading so that it won’t match the corresponding name and alias anymore. E.g., “Some Test File” rewritten as “S0me Tes7 F1le” would deactivate the WikiLink. However, I don’t really like the idea of intentionally adding typos and blemish to my documents.

The same Markdown file from above, including the mentioned automatic WikiLink bypass ("Some Test File" ⟶ "S0me Tes7 F1le").

Since I couldn’t find any other workaround to that problem and as there is no info about any future update of MMD, I actually came back again to my former solution for generating a TOC in DEVONthink Markdown files. This solution relies on an AppleScript in combination with a Python script. The Python script scans the contents of the selected document for any occurring heading, generates the corresponding TOC and inserts it into the document. It also adds Back-to-toc links above each heading. The disadvantage of this solution is, that it doesn’t auto-update the TOC, i.e., after every change to your headings you have to re-run the AppleScript. However, it solves the TOC-link problem mentioned above. Therefore, I updated the script a bit so that it adds a floating Back-to-top button instead of links. The TOC now also includes the updated style, that I’ve introduced in my default CSS file:

The same Markdown file from above, now including the TOC generated by the AppleScript: Links in headings do not affect the links in the TOC.

You can find the script including the Python files and an additional script to remove the TOC on GitHub. Please let me know if you notice any bugs or flaws by reporting them in the issue section of the repository. Please, also read the warning carefully and create backups of your files before applying the script.

I just discovered, that encapsulating headings, that contain links and DEVONthink’s auto-WikiLinks, by angle brackets (<,>) also bypasses the MMD TOC-link problem. E.g., in my example from above, I have to encapsulate the heading “Section 1.1 …” (which contains an auto-WikiLink),

"<Section 1.1 with Some Test File in heading>",

and the TOC-links generated by the {{TOC}} command will still work:

Enclosing links and DEVONthink's auto-WikiLinks in headings by angle brackets (<,>) bypasses the TOC-link problem in MultiMarkdown version 6.

The bypass with the angle brackets also works in DEVONthink To Go (DTTG). While this seems to be a trivial notice, other solutions to suppress auto-WikiLinks in headings by, e.g., placing a soft-hyphen somewhere in the auto-linked name/alias only worked in the desktop app, but not in DTTG (clicking on the corresponding TOC-link became effectless).


Commenting on this post is currently disabled.

Comments on this website are based on a Mastodon-powered comment system. Learn more about it here.