TiddlerToC Example #1

 
Example #1The widgetThe settingsThe headingsAnd now to something completely different…This is the second example tiddler…Another transclusionNothing to see here…Back in the second example

Note: Please see the plugin tiddler for the complete documentation, as well as some more examples. The TiddlerToC Tabs Example demonstrates how tables of contents inside tabs are handled.

The widget

The table of contents to the right of this text is generated by adding the <$tiddlertoc/> widget to the tiddler, at the place you want it to appear (it doesn't have to be at the top of the tiddler).

Try clicking the table of contents' title to collapse it. Click it again to expand it.

The settings

Without any attributes, it uses the default values configured in its own tab under the control panel's Settings tab (or the built-in defaults, if these aren't set).

The headings

By default, the widget includes the standard HTML headings found in this tiddler (or transcluded tiddlers, provided that they're not in tabs) in the table of contents, but this can be configured as required.

And now to something completely different…

The following content — until the end of this tiddler — is transcluded from TiddlerToC Example #2. Note that the headings from transcluded tiddlers will be included in the table of contents, recursively.

This is the second example tiddler…

…to be transcluded into the TiddlerToC Example #1. It does contain its own table of contents widget, but it's not rendered if the tiddler is transcluded (unless in a tab).

Another transclusion

Now, this is TiddlerToC Example #3. Again, this tiddler does include its own <$tiddlertoc/> widget, but it's not rendered when transcluded.

Nothing to see here…

…please disperse.

Back in the second example

Just to show that the heading structure is preserved as expected.

$:/plugins/gœb/TiddlerToC

 

TiddlerToC: Single tiddler (heading-based) table of contents. 

$:/plugins/gœb/TiddlerToC

0.0.3

Table of contentsAboutInstallationUsageIncluded headingsExcluded headingsThe source tiddlerTurning off the table of contentsAutomatically adding the table of contentsCustomizing the appearancePerformanceLimitationsSettingsExamples

About

The TiddlerToC plugin for TiddlyWiki generates tables of contents for single tiddlers. Unlike TiddlyWiki's built-in <<toc>> etc. macros, which are based on tags and link to different individual tiddlers, this plugin's <$tiddlertoc/> widget generates the table of contents based on the headings found in the containing tiddler's text (including the content of transcluded tiddlers, widgets, macros…).

The source code (which can be used with the Node.js version of TiddlyWiki) is available on Gitlab.

Installation

Drag the plugin tiddler to your TiddlyWiki, save and reload. See the official installation instructions for more information.

Usage

Add the <$tiddlertoc/> widget to the tiddler, preferably at or near the top, to include a table of contents using the default settings.

Note that (almost) all default settings can be overridden in the control panel's SettingsTiddlerToC tab (or down below in the settings section), as well as by setting an individual widget's attributes (with the latter taking precedence).

Included headings

By default, the widget includes all standard HTML headings h1h6 in the table of contents. This can be changed by setting the attributes and/or options h1h6 of the widget to a custom pseudo-selector, see the settings section for an explanation on these. Also note that individual heading levels can be disabled by setting the respective attribute (or option) to an empty string.

For headings without an id attribute, the respective entry in the table of contents will trigger a JavaScript event handler when activated (clicked, for example), which will scroll to the heading.

If the heading does have an id attribute, a regular link will be created in the table of contents, linking to the ID. For more details, see tiddlywiki.com.

⚠ Warning: Don't use the <<qualify>> macro to generate unique IDs, it won't work. Instead, this plugin provides the (experimental) <<ttocid>> macro, which might (or might not) work for you. Its syntax is the same as for the <<qualify>> macro. Use it like this (don't forget the leading #):

<h1 id=<<ttocid "#some-prefix">>>A heading with an ID</h1>

Note that while the described handling of headings with IDs is the default, it can be configured by setting the useIDs option in the settings section.

Excluded headings

To exclude single headings, the ignore attribute can be used to set which tags and/or classes to ignore, see the settings for more information. The default is to ignore anything with a .toc-ignore class.

By default, headings in tiddlers transcluded with TiddlyWiki's <<tabs>> macro or one of the <<toc-tabbed-*-nav>> macros won't be included in the table of contents. The contents of <$reveal/> widgets will also be excluded (determined by div.tc-reveal/span.tc-reveal selectors).

However, if a tiddler inside a tab (or the view template used to render it) contains the <$tiddlertoc/> widget, it will create a table of contents for the tiddler inside the tab (this doesn't apply to the contents of the <<toc-*>> macros or the <$reveal/> widgets). This works recursively for tabs inside tabs (inside tabs…).

While the excluded elements can be changed, it's recommended to keep the defaults unless you know what you're doing.

The source tiddler

The top-level tiddler from which the table of contents is generated is determined by checking the currentTab and storyTiddler variable, in that order, the first one set will be used. If the checkStory option and/or attribute is set to a false value, currentTiddler will be used instead of storyTiddler (unless currentTiddler isn't set, in which case it will fall back to the latter). This should work in the majority of cases.

To override it, the widget attribute tiddler can be set to the title of the tiddler to use instead (by default, this attribute isn't set, and there is no option in the settings to change this default value).

Note: Using the tiddler attribute will not create a table of contents that allows navigation to another tiddler.

The source tiddler will be rendered internally and all headings, including those in transcluded tiddlers (with the exceptions mentioned), will be added to the table of contents. Note that the internal rendering of the tiddler might not be accurate, depending on your customizations.

Turning off the table of contents

A table of contents won't be generated if the currentTiddler (containing the <$tiddlertoc/> widget) isn't the storyTiddler, that is, if it's transcluded (unless inside a <<tabs>> macro). This can be changed by setting the checkStory option and/or widget attribute to a false value, if you know what you're doing.

Several fields will be checked in the currentTab, currentTiddler, storyTiddler and thisTiddler, and — if truthy — will prevent the table of contents to be generated, and there is also a variable you can set to achieve the same (noToC by default, its name can be changed). See the settings for details.

Automatically adding the table of contents

The widget can be added to the default view template (probably $:/core/ui/ViewTemplate/body) to automatically include the table of contents in all suitable tiddlers. You can still turn it off for individual tiddlers as described. This also works for other templates, for example, templates used with the <<tabs>> macro.

Customizing the appearance

The title of the table of contents can be changed by setting the title attribute (or the default value set in the settings). Note that clicking this title adds (or removes) the data-collapsed attribute from the main div container, this is used in the default style sheet to collapse or expand the table of contents. It's impossible to toggle the table of contents this way if no title is set.

The table of contents' appearance is configured by the plugin's style sheet. This includes the colors, position, etc., but also hiding the element when the table of contents is empty, and, as mentioned, collapsing or expanding it.

The main container is div.tiddler-toc, every heading inside is a span element (for headings without id attribute), or an a element (for those with an ID). Their classes are toc-heading, plus toc-heading-1toc-heading-6 (for h1h6). The table of contents' title itself is a span with the classes toc-heading and toc-heading-0. The title element won't be created if the table of contents is empty. If the option addClasses is truthy (the default), all classes present on the original heading in the tiddler will also be added to its entry in the table of contents. The class attribute and/or option can be used to add other classes to the main container.

By default, clicking an entry in the table of contents will scroll the respective heading to the top of the page. If your wiki includes a fixed bar at the top, it might obstruct the heading. You can set an offset in the style sheet (or, better yet, create a custom style sheet for your overrides), look for

h1, h2, h3, h4, h5, h6 {
   scroll-margin-top: 0;
}

at the end, uncomment it, and adjust the value to match the height of the bar. Note that you have to change the selectors, too, if you customized those used to match the headings for the widget. You can also set the attribute and/or option scrollBlock to center, to scroll the heading to the center of the page. This won't work for the anchor links created for headings with an id attribute, though. More information can be found in the settings section.

Performance

To get the list of headings, <$tiddlertoc/> calls TiddlyWiki's render methods to get the actual (wikified) text of the tiddler (including its transclusions, macros…). This means, that any tiddler containing the widget will be rendered twice (or more often, if the widget is included multiple times) when it's displayed. When the tiddler or any transcluded tiddler is changed, which might cause a change in the table of contents, the widget will do the same thing again. For complex tiddlers or slow macros etc. this might considerably slow down the wiki.

Also note that the widget has to get a list of the transcluded tiddlers, which also requires to parse the original tiddler, and any tiddlers found, recursively. This is probably not quite as slow as the rendering, but should still be considered. This can be disabled by setting the refresh attribute of the widget to the value relaxed, restricting the refreshing of the widget to changes in the original tiddler (and the control panel tiddler), see the settings section.

Limitations

Colors are hard-coded, made for a light theme, but can be adjusted in the style sheet.

For heavily customized TiddlyWikis, or complex macros etc., the widget might fail to gather an accurate list of headings. This also means that navigation might lead to a heading different from the one clicked on. There could be workarounds like restricting headings by class, but this depends on the individual circumstances.

Navigation to headings without an id attribute relies on finding the heading based on its configured selector and position in the tiddler when the table of contents is created. If matching elements are dynamically added or removed, navigation might lead to the wrong one. Also, there is no way to use this widget to navigate to another tiddler, regardless whether it's already open or not.

The widget was written in a way that allows the table of contents to be generated when running under Node.js, for example, when rendering static pages. However, due to the JavaScript handler required to jump to a heading without an ID, actual navigation doesn't work in this case.

Settings

SettingsTable of contents titleTable of contents classesAdd heading classes to table of contentsIncluded headingsIgnored headingsHeading IDsMain tiddler containerExcluded containersCheck current and story tiddlerDisable table of contents using a variableDisable table of contents with tiddler fieldsRefresh behaviourscrollIntoView parameters

Controls can also be found in the control panel's SettingsTiddlerToC tab.

The following controls change the defaults of the <$tiddlertoc/> widget. All settings can be overridden for an individual widget using the respective attributes.

For settings marked as pseudo-selector, the basic format is [<tag>][.<class>]…, that's zero or one tag, followed by zero or more class selectors (each starting with a dot followed by the class name). Multiple of these can be separated by comma to match multiple elements, for example, h1,div.foo.bar. No other attributes (#<ID>…) or selectors are supported. Values must not include spaces. An empty selector will never match anything.

For settings marked as boolean, truthy values are enable, enabled, on, true and yes - case doesn't matter. All other values (including an empty string) will be interpreted as false.


Use the buttons to set a value to an empty string (same as entering some text and deleting it - enabled only where it makes sense).

Use the buttons to reset the respective option to its default, or use the button below to reset all options to the default values (warning: this will delete all customizations of the options below, there is no undo).


Table of contents title (attribute: title). The title at the top of the table of contents. Defaults to Table of contents. Can be set to an empty string to not add a title element at all. Note that clicking the title collapses or expands the title of contents, and won't be possible if the title is empty.

Table of contents classes (attribute: class). Space-separated list of classes to add to the main <div> container of the table of contents. The class tiddler-toc will always be added. By default this option is empty.

Add heading classes to table of contents (attribute: addClasses, boolean). If truthy, the classes of the heading element (for example, classes of an h1 element in the tiddler) will be added to the respective element in the table of contents. Defaults to yes.


Included headings (attribute: h1h6, pseudo-selector). These selectors will be used to find the headings in the tiddler. The default values for the six levels of headings are h1h6, same as the attribute names. Note that if multiple selectors match one heading, its level will be set to the highest (the numerically lowest) one. Empty strings will turn off the respective headings.

Ignored headings (attribute: ignore, pseudo-selector). Headings that match this pseudo-selector won't be included in the table of contents. The default value is .toc-ignore.

Heading IDs (attribute: useIDs, either yes, no or force). If yes (the default), anchor links will be created in the table of contents (instead of spans with a JavaScript handler) for all headings with an id attribute. If no, id attributes will be ignored. If set to force, the table of contents will only include headings with an id attribute (using anchor links for navigation).


Main tiddler container (attribute: tiddlerBody, pseudo-selector). The outer container of the tiddler contents, in which the widget will look for headings when navigating using the JavaScript handler (outside of excluded containers, see below). The default, div.tc-tiddler-body, should only be changed if you know what you're doing.

Excluded containers (attribute: exclude, pseudo-selector). Defines the container elements that will be skipped in a tiddler when gathering the headings (that is, headings within such containers won't be included in the table of contents). The default value excludes the content of TiddlyWiki's <<tabs>> and <<toc-tabbed-external-nav>>/<<toc-tabbed-internal-nav>> macros, as well as the <$reveal/> widget. Note that for tiddlers inside tabs, if they contain the <$tiddlertoc/> widget, the table of contents will be rendered unless turned off by other means (this only applies to the <<tabs>>). The default selector contains the following elements:

  • div.tc-tab-set
  • div.tc-tabbed-table-of-contents
  • div.tc-reveal
  • span.tc-reveal


Check current and story tiddler (attribute: checkStory, boolean). If this is set to a truthy value, no table of contents will be generated if the currentTiddler variable doesn't equal the storyTiddler variable. This defaults to yes, and shouldn't be changed unless you know what you're doing. Note that turning this off will use the currentTiddler instead of the storyTiddler as the source tiddler for the table of contents. A more detailed explanation on how the source tiddler is selected can be found in the plugin's Readme tiddler.

Disable table of contents using a variable (attribute: skipVar). If a variable by the configured name, which defaults to noToC, is set to a truthy value, no table of contents will be created.

Disable table of contents with tiddler fields. The following settings define the names of fields used to turn off the table of contents if set to a truthy value. The widget will look for such a field in four tiddlers: the currentTab, currentTiddler, storyTiddler, and thisTiddler — these are variable names, not tiddler titles — and if one of these contains its respective field set to a truthy value, no table of contents will be generated.

For currentTab (attribute: skipTab), default: noTabToC:

For currentTiddler (attribute: skipCurrent), default: noCurrentToC:

For storyTiddler (attribute: skipStory), default: noStoryToC:

For thisTiddler (attribute: skipThis), default: noThisToC:


Refresh behaviour (attribute: refresh, either default or relaxed). If set to default (the default), the widget will try to get a list of all transcluded tiddlers and the table of contents will be refreshed on any change in any of these tiddlers. This might be slow, so the relaxed setting disables this behaviour (the widget will still be refreshed when source tiddler changes, as well as whenever the default settings are modified).


scrollIntoView parameters. The following values will be passed to the scrollIntoView() method when an entry in the table of contents is triggered (clicked, …) to scroll to the heading (doesn't apply to headings with an id attribute). For more details, see the documentation at https://developer.mozilla.org/docs/Web/API/Element/scrollIntoView.

The behaviour parameter (attribute: scrollBehaviour), default: smooth:

The block parameter (attribute: scrollBlock), default: start:

The inline parameter (attribute: scrollInline), default: nearest:


Examples

Table of contentsAboutInstallation

This example disables h2 headings (with the h1 attribute defaulting to h1), and ignores all headings of the class toc-ex-ignore (the Usage, Settings and Examples headings in this tiddler, there are no h3h6 in here). Headings will be centered vertically when navigating.

<$tiddlertoc h2="" ignore=".toc-ex-ignore" scrollBlock="center"/>

The table of contents in the settings section is created using the following widget:

<$tiddlertoc title="Settings" h1="span.cfg" h2=""/>

This sets the selector for top-level headings to include <span> elements with the cfg class and disables h2 headings, and sets the title to Settings.

Note that the table of contents widget for the settings is also included in this Readme tiddler, it would not be rendered if it were transcluded (by default).