Table of Contents

Hello,

I did a search in the Actions directory for “table of contents” and didn’t find anything, so made a quick Table of Contents Action.

The handy “Your topic is similar to…” prompt showed me a thread about the \{{TOC}} feature of MultiMarkdown, so maybe my Action is redundant. If you would like the table of contents rendered as Markdown in your draft not just the preview, or you are using GitHub Flavored Markdown, maybe this action is still useful for you.

I also want to add links to headers from the table of contents in the next version. It looks like the \{{TOC}} feature tries to do this, but it doesn’t work.

If the Action gets some usage I will add proper helpful error handling when headers and placeholders can’t be found, &c.

I made another Action that uses Write Good to check your writing style a while ago but didn’t post it here. You can search for “Write Good” in the directory, sorry I’ve hit my link limit for my first post.

I hope someone finds this useful. If you use it I welcome any feedback.

Hi,

This looks like it will be awesome. I get the following error when I run it:
Script Error: TypeError: null is not an object (evaluating ‘startMatch.index’)
Line number: 13, Column 26

Any tips to fixing? I’m using the latest Beta release of Drafts on iPadOS.

Thank you for trying it!

You do need to prepare the Draft before you can use the Action. I put instructions in the Action description but it doesn’t explain it other than that.

Put the placeholder <!– start toc –><!– end toc –> where you want the table of contents to appear.

Those are HTML “comments” so they won’t appear when you preview the Markdown.

I’m planning to add a helpful error message explaining that instead of the error you are seeing. I’m also thinking of placing the table of contents somewhere intuitive like before the second header of there is no placeholder.

All of that takes some extra effort, so I thought I’d let people use it first to see how it goes.

That sounds like it is probably just your settings.

Thanks for taking a look @sylumer. I think I’ve got all the right settings based on that thread (Using MultiMarkdown, compatibility mode off) but the names or ids don’t get added to the header so the \{{TOC}} can’t link to them properly.

Here’s a quick example. This markdown:

\{{TOC}}

# Test

is rendered as this HTML:

<div class="TOC">

<ul>
<li><a href="#test">Test</a></li>
</ul>
</div>

<h1>Test</h1>

If you know of any other settings which could affect this let me know, I will probably still use \{{TOC}} sometimes so will be useful to get the links working.

I’ve updated the Action in the directory so it works without the placeholder, and shows useful messages when it can’t make a table of contents. @skrimfid you may be interested in the updates, you shouldn’t see the error you saw before now.

1 Like

Can you upload a video off how to use this feature? I keep getting an error that says ‘no H1 header’ or some such thing. The title of my note is

[Test]

Hello @yashodhankhare I hope this example video helps. To make best use of this Action you need to understand Markdown headers a little bit already.

That was helpful. Can you show me how the TOC page looks. I have just one header at the top, that’s it

This is what it looks like:

It is just a list, no other formatting. I might add links to the headers later.

If your only header is the title, the Action doesn’t include that and will show the message “No Markdown headers (e.g. ## Header) found”. I decided not to include the title because you already know the title when reading it, and most tables of contents I’ve seen don’t include it.

Thanks, that was helpful. How can I adapt this to a note that LINKS to the various notes that I have in the drafts app and arranges them either by date of creation or modification or alphabetically?

I’m sorry @yashodhankhare, I don’t think you can. That sounds a lot more complicated than what this Action is doing. Maybe there are some other Actions that can do that already?

Not that I know of. Maybe, the great @sylumer can chip in, or maybe Greg himself. There must be such an action. Anyway, thanks for the quick replies!

Yes, it looks like @sylumer has already made lots of useful actions for making wiki style links to Drafts, maybe they can be combined with something else to list all the Drafts and link them.

Here is an example draft, the Markdown settings I have set, the live preview, and the HTML where I have the table of contents working just fine by default. It is not updating the content, but if that was where the navigation was to go, I would use section-based wiki links instead and build these using navigation markers (see the scripting documentation).

What do you want to do exactly? Generate a web page that links to individual drafts, build a table of contents for a web page built from drafts that also incorporates transcoding other drafts, or something else?

Aha! I have the “No labels” setting on. If I turn it off it puts the ids in the headers. I’m fairly sure I haven’t changed the settings since the Markdown processor options were added, so maybe “No labels” is the default.

I see what you mean about wiki links. Having the table of contents in the draft was useful for me this time, because I could copy and paste it to other places that support Markdown. A wiki style links version could be useful for making a table of contents you can use in Drafts. Maybe there is a use case for two versions with links. One with HTML anchors for copying to other things that support Markdown, and one with wiki style links.

Well the builtin support for table of contents I think covers the case for generating an HTML page.

For generating and refreshing a wiki link based TOC, I would take this sort of approach:

const TOC_TITLE = "# Table of Contents";
createTOC(TOC_TITLE);

function createTOC(p_strTOCTitle)
{
	//Find the TOC if it exists and select it otherwise leave the cursor where it is
	if(draft.content.includes(p_strTOCTitle))
	{
		//Get the start position of the TOC title
		let intStart = editor.getText().indexOf(p_strTOCTitle);

		//The TOC is based on a bulleted list, so we extend to the next blank line
		let intEnd = editor.getText().indexOf("\n\n", intStart);
		//If there was no blank line, the TOC must be at the end of the draft
		//so we will extend to that instead.
		if(intEnd == -1) intEnd = editor.getText().length;

		//Select the TOC
		editor.setSelectedRange(intStart, intEnd - intStart);
	}

	//Initialise the TOC
	let strTOC = p_strTOCTitle + "\n"
	let astrHeadings = [];
	editor.navigationMarkers.forEach(function(nmHeading)
	{
		//Build a line of the TOC
		let strHeading = "";
		if (nmHeading.level > 1) strHeading = "\t".repeat(nmHeading.level - 1);
		strHeading = strHeading + "- [[" + draft.displayTitle + "/" + nmHeading.label + "]]" 
		astrHeadings.push(strHeading);
	});
	//Build the TOC
	strTOC += astrHeadings.join("\n");
	//Insert the TOC
	editor.setSelectedText(strTOC);
	return;
}

However, do note that the Drafts editor does kind of already have built in navigation too. So if it is purely for navigation purposes, I’d be tempted to stick to that.

I want a page in my drafts app that links to other notes in the drafts app itself. I have many individual notes in the app and some are archived. As a result, it is sometimes tough to find a draft when I want it. If I can have a page that links to these drafts in the app, that solves my problem.