Skip to content

Keep your content externally addressable

A heading gets a computed anchor automatically, from its own text, so it is already a link target the moment you write it. Content tabs can also be configured to have anchors, but everything else is not a link target by default.

Zensical Studio keeps links in your project valid as you edit your content and automatically created anchors change. However, it can only update links that are under its control. If you have external links that are important, such as those published in a release note, a blog post, or that are frequently bookmarked, these break silently instead.

Python Markdown's attr_list extension makes it possible to manually assign IDs to many block and inline elements such as admonitions, plain paragraphs, code block, or table cells. By assigning explicit IDs, you can not only make content linkable that is not by default. You can also ensure that the anchors do not change even if text does.

Example project

This workflow uses the project in zensical-example-project.zip but you can explore the same behavior in your own project.

Use Run the code actionRun the code actionToggle Code ActionsShow Context ActionsCtrl+.macOSCmd+.WindowsCtrl+.LinuxCtrl+. on a heading, paragraph, list item, definition term, table cell, fenced code block, or Markdown-enabled HTML element, including one nested inside a block quote or admonition, then choose Add link target. Zensical Studio generates a unique ID and inserts it using the correct syntax and position for you.

Exceptions

Whole implied containers, such as lists or tables are exceptions in that attr_list cannot assign attributes to them as a whole. The solution is to assign an ID to a first list item or table cell instead.

The action creates the correct Python Markdown's attr_list syntax for each element. Try some of these:

# Usage { #use }

Paragraph content.
{ #paragraph-id }

- List item
  { #item-id }

Term
: Definition text
{ #term-id }

| Role                  | Can do                            |
| --------------------- | --------------------------------- |
| Agent { #role-agent } | Reply to and assign conversations |

```python { #code-id }
print("Anchored code block")
```

You can write this directly instead of running the action but Zensical Studio makes it easier to get the syntax right. Either way, once a block has an ID, it behaves like any other workspace symbol: it completes in links, shows up in navigation, supports Find References, and renames along with its incoming links.

Check what depends on an anchor before you change it

A CodeLens above a heading or an explicit ID shows how many links reference it, so you can tell at a glance whether anything else would change if you were to edit it. Use Find All ReferencesFind All ReferencesFind referencesFind UsagesShift+F12 on any anchor, a heading or a block with an explicit ID, to see every link that depends on it, including links in other Markdown files.

inspect references lets you search for headings in all files

Check this before you reword a heading, restructure a table, or remove a paragraph that looks unused. It tells you whether the change is local or reaches content you cannot see from the file you have open.

Redirects are next

Zensical is also working on support for the mkdocs-redirects plugin, tracked in issue #23, so a page's old address can keep resolving even after the page itself moves, not just an anchor within it.

Where to go next