Self-Upgrading In Document Table of Contents Plugin

I, too, would like to make use of a [[TOC]] block that automatically updates based on my document’s contents. I’ve grown accustomed to it in things like Azure DevOps Wikis. Also, unfortunately, GitHub - Aidurber/obsidian-plugin-dynamic-toc: An Obsidian plugin for creating Tables of Contents that stay updated with your document stopped working for me, as of 1.0.0. :sob:

Definitely going to give the Floating TOC a try, as well as Dataview.

Just wanted to add my comment here so that OP knows they are not alone…and I joined these forums to post that.

Also, Obsidian is changing my life. Thank you!

1 Like

I also agree that [TOC] rendering is a useful feature

3 Likes

i forgot to mention, there is also the “Quiet outline” plugin which renders a prettier TOC than the built in outline.

2 Likes

I’m +1 on this plugin Idea. I’d love to have a Table of Contents outline that is automatically updated in my document. It’s a useful feature in other note apps and I’m glad to see it being addressed here.

And, I agree this feature is perfect for a community or core plugin.

Update
I just found the core plugin Outline and it does what I was looking for. When turned on there is a document outline / Table of Contents based on headers in the left panel. If I click on the outline heading in the panel, the cursor jumps to that position in the main window document. Perfect.

I think the updating automatically is the issue, but I just close and reopen the doc to update the outline. Thanks

The core outline plugin should update in real time I thought.

If you want a TOC in the note itself, I just stumbled over this awesome Dataview solution:

2 Likes

Thanks for that , works nicely but i see some issues.

It only sees Header one and two. Header three is not showing.
Underlying header does not print previous header. So for example when i start a header 2 under header 1 i would expect something like 1.1 but it only prints 1

Can this be tweaked in your sample script?

Thanks!

1 Like

That’s strange since I don’t experience that in the Sandbox vault - so potentially there is an issue with some plugin you have installed?

This is just CSS related. You can add a snippet like this to change your numbering format:

ol {
  list-style-type: none;
  counter-reset: item;
  margin: 0;
  padding: 0;
  padding-inline-start: 10px !important;
}
li {
  display: table;
  counter-increment: item;
  padding-bottom:20px;
}
li:before {
  content: counters(item, ".") ". ";
  display: table-cell;
  padding-right: 0.6em;
  padding-top: 0.2em;
}
li li {
  margin: 0;
}
li li:before {
  content: counters(item, ".") " ";
}
2 Likes

The floating Toc plugin is currently working flawlessly for me here- and it even implement that in the way i like most wich is besides the main document (much like the outline panel), so one can quickly jump to other headers no matter where they are on the page.

1 Like

Thank for the css it now has the output as i like it. :grinning:

And the third header is also solved. Apparently when you have one space too many the header is not seen as a header :slight_smile: So i was have 2 Spaces in between the # and the header.

Looks great now. Thanks a lot!

Hello,

I notice the references in the toc refer to obsidian locations. Can i also refer just to the headers inside the document without refering to obsidian. I wan to be able to export the note to PDF and send this to someone that does not have my obsidian :slight_smile:

Thanks!

Johan

thank u :slight_smile:

Why doesn’t it show all headers addresses?

Thanks! This works very well, except the numbering formatting a bit weird.
I don’t know is this because theme style setting or what

That’s theme related. Normally doing the entire list with 1. works fine in Markdown, but you can provide the actual numbers like this:

const startAtLevel = input?.level || 2
const content = await dv.io.load(dv.current().file.path)
const counter = [0, startAtLevel]
let numbers = [1]
const toc = content.match(new RegExp(`^#{${startAtLevel},} \\S.*`, 'mg'))
    .map(heading => {
        const [_, level, text] = heading.match(/^(#+) (.+)$/)
        const link = dv.current().file.path + '#' + text
        if (level.length > counter[1]) {
            counter[0]++
            numbers[counter[0]] = 1
        } else if (level.length < counter[1]) {
            counter[0] = Math.max(0, counter[0] - 1)
            numbers[counter[0]]++
            numbers = numbers.slice(0, counter[0] + 1)
        }
        counter[1] = level.length
        return '\t'.repeat(counter[0]) + `${input?.style || numbers[numbers.length - 1] + '.'} [[${link}|${text}]]`
    })
if (input?.heading !== false) {
    dv.header(2, 'Table of contents')
}
dv.paragraph(toc.join('\n'))
1 Like

Well, we could add a copy button to the outline core plugin

Why reinventing wheel ??

This is a one-liner that displays an automatically-updating table of contents inside the note, rather than in the sidebar and/or manually copy/pasting.

It’s a different wheel.

Maybe i didn’t explain very well.
My suggestion is very simple and doable, we only need a copy button in the core Outline plugin tab

This way we could paste a nicely formatted toc into our notes. I myself wrote a script copying a table of content to the clipboard. Then i copy this wiki-links into my note. It’s a bit manually but hey, i think adding a toc is something you do at the end of the day, basically for your readers and less, for yourself
I’d like to have this one integrated in Obsidian :wink:

To add to this: a TOC feature like Markdown All in One in vscode would be perfect.

The problem with one of the previous suggestions mentioning DataView or this obsidian-automatic-table-of-contents plugin is they’re only viewable in Obsidian. If we were to commit this to our team wiki, then readers would see this:

```table-of-contents
```

instead of a table of contents.

Hi Alan,

I love your solution and am using it widely.
I’m not very savvy when it comes to js though and I’d like to remove the numbering. Is that possible within the script, or would I have to do it with css?

There’s not a specific class to the TOC, and I don’t want to hide the numbering everywhere…

Thanks in advance!