Auto-generated Table of Contents in Mardkdown documents for Fossil-FossMD (and hopefully for Fossil as well)
See README.fossil-fossmd.toc.longlong.md for the long long ToC story (useless for most readers).
Example ToC
What you have: Example Markdown (only headers, other text omitted)
# Using a mouse
## Basic mouse actions
### Left button
### Right button
#### Context menus
## Selecting
### Click and drag
### Double click
What you get: The rendered HTML Title and ToC (ToC at top of page by default)
Using a mouse
1. Basic mouse actions
1.1. Left button
1.2. Right button
1.2.1. Context menus
2. Selecting
2.1. Click and drag
2.2. Double click
Note that the first header in a Markdown document, in this case # Using a mouse, is considered the document's title,
so it should not be included in the ToC.
Install
The FossMD ToC is not enabled by default (for now, at least), so it must configured before compiled:
./configure ---with-md-toc
make
Usage
If compiled as mentioned above, ToC is enabled and rendered by default with any Markdown document in a Fossil repository.
No additional configuration is needed, and any existing Markdown documents do not have to be modified for the ToC to render.
If one or more ToC markers are inserted somewhere in the Markdown document, the ToC is rendered at the marker instead of after the document title.
See marker details in the "Supported ToC marker syntaxes" section.
Configuration flags
Configuration is only needed to customize the ToC.
The configuration syntax is the same as for any other Fossil settings.
The ToC configuration is a string composed by 5 configuration flags:
fossil settings [--global] md-toc <depth|auto|trailing|top|style>
Example which resets the ToC configuration to the default settings:
fossil unset [--global] md-toc
Examples which sets the ToC configuration to the default settings (same as the example above, but set explicitly):
fossil settings [--global] md-toc 51111
To display the current settings:
fossil settings md-toc
When setting the configuration, any invalid value is ignored. When reading an invalid value, the default settings are used.
Flag: depth
Chapter/section/subsection level to include in ToC.
Values:
- 0: ToC is not displayed at all.
When set to 0, ToC is disabled, and all other md-toc flags are ignored. - 1-5: ToC level to display (examples below).
The default value is 5 (display all levels).
Examples of how the depth flag affects the rendered ToC:
depth=1:
Using a mouse
1. Basic mouse actions
2. Selecting
depth=2:
Using a mouse
1. Basic mouse actions
1.1. Left button
1.2. Right button
2 Selecting
2.1. Click and drag
2.2 Double click
depth=5:
Using a mouse
1. Basic mouse actions
1.1. Left button
1.2. Right button
1.2.1. Context menus
2 Selecting
2.1. Click and drag
2.2 Double click
Flag: auto
Values:
0: Manual ToC Mode.
Only rendered if and where a[toc]marker is present in the Markdown document.
(One way to disable the ToC is to use this option and not including a[toc]marker.)1: Automatic ToC Mode (default).
Always rendered, just below the title.
If one (or more)[toc]marker is present, the ToC is rendered there instead, as in Manual Mode.
Flag: trailing
Values:
0: no trailing dot: 1.2.3.4.5
1: trailing dot (default): 1.2.3.4.5.
Flag: top
Values:
0: The rendered headers do not include a trailing top-link.
1: The rendered headers include a trailing top-link (default).
Examples of how the top flag affects the rendered headers (not the ToC):
Markdown header:
## Selecting
Rendered HTML:
top=0:
<h2 id="2."><span class="chapter-label">2. </span>Selecting</h2>
top=1:
<h2 id="2."><span class="chapter-label">2. </span>Selecting</h2><a class="href-top" href="#toc-top">Top</a>
Flag: style
Style for the Chapter Label (the 1.2.3.4.5. chapter prefix)
Values (most of the list below has shamelessly been copied from the DocBook documentation):
0: Off (do not display chapter labels)
Note: This may also be achieved by using CSS:.chapter-label {display: none}1: Arabic numerals (default): 1, 2, 3, 4, ...
A: Uppercase letters: A, B, C, D, ...
a: Lowercase letters: a, b, c, d, ...
I: Uppercase Roman numerals: I, II, III, IV, ...
i Lowercase Roman numerals: i, ii, iii, iv, ...
x661 Arabic-Indic numerals ١, ٢, ٣, ٤
With this style, the HTML entities٠to٩are used to display numbers from ٠ to ٩ (0 to 9)
Note that any unicode in the&#xNNN;format may be given as a "unicode symbol 1", and the range&#xNNN-1;to&#xNNN+8;will be used.
Note the difference between the HTML Entity١and the config valuex661. The&#and;chars have been omitted from the config value to avoid weird shell misinterpretations.xhh1xhh2xhh3xhh4xhh5xhh6xhh7xhh8xhh9xhh0 Customized 0 - 9 Unicode numerals
This is just an extension of the syntax for the Arabic-Indic numerals.
This allows for using any Unicode symbols for the range 0 - 9.
The list should start with the Unicode symbol for '1', and end with '0', in this order: 1,2,3,4,5,6,7,8,9,0. To use this syntax,- Unicode symbols must be given in hexadecimal, preceeded by an x.
- Each hexadecimal value must be in the range of 2-6 characters. (1 character Unicode does not make sense - not printable.)
- There must be exactly 10 hexadecimal values in the list.
Not all languages use the 0 - 9 range for numerals, though.
In such a case, an alternative solution may be to disable the Chapter Label Style (0) and using CSS techniques instead.
The CSS3 propertylist-style-typeis increasingly supporting many different alphabetic and numeric types for different language groups.
Combining this property with CSS counters may render Chapter Labels in a wide variety of languages.
People who want to write in any of these non-Latin languages are probably much more up-to-date than myself with these techniques.
Anyway, here are a few links to start with:Unicode lists:
https://www.compart.com/en/unicode/blockCSS3 techniques:
https://developer.mozilla.org/en-US/docs/Web/CSS/list-style-type
https://www.w3schools.com/cssref/pr_list-style-type.asp
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Lists_and_Counters/Using_CSS_counters
https://css-tricks.com/numbering-in-style/
Example configurations
Disable ToC (depth=0):
fossil settings [--global] md-toc 01111Change depth (depth=4):
fossil settings [--global] md-toc 41111See "Flag: depth" section for example output.
Use manual ToC (auto=0):
fossil settings [--global] md-toc 50111Using this setting, a ToC is only rendered if a ToC marker (
[toc]) is inserted into the Markdown document.
See marker details in the "Supported ToC marker syntaxes" section.No trailing dot (trailing=0):
fossil settings [--global] md-toc 51011No top-link (top=0):
fossil settings [--global] md-toc 51101Use Uppercase letters (style=A):
fossil settings [--global] md-toc 5111AOutput:
Using a mouse
A. Basic mouse actions
A.A. Left button
A.B. Right button
A.B.A. Context menus
B Selecting
B.A. Click and drag
B.B Double clickUse Uppercase Roman numerals (style=I):
fossil settings [--global] md-toc 5111IOutput:
Using a mouse
I. Basic mouse actions
I.I. Left button
I.II. Right button
I.II.I. Context menus
II Selecting
II.I. Click and drag
II.II Double clickNote:
Taste is personal, but IMHO, using either Letters (A/a) or Roman numerals (I/i) in a ToC soon becomes illegible when used with subchapters at deeper levels.
Recommended only with Header 1 headers.Use Arabic-Indic numerals (style=
x661):fossil settings [--global] md-toc 5111x661Output:
Using a mouse
١. Basic mouse actions
١.١. Left button
١.٢. Right button
١.٢.١. Context menus
٢ Selecting
٢.١. Click and drag
٢.٢ Double clickNote:
Except numbers from 0 - 9, my Arabic-Indic knowledge is non-existing, which explains why the rest of the example ToC above is written in English.Use customized Unicode style: Dingbats, style=
x2780x2781x2782x2783x2784x2785x2786x2787x2788x1f10b, renders to ➀➁➂➃➄➅➆➇➈🄋 :fossil settings [--global] md-toc 5111x2780x2781x2782x2783x2784x2785x2786x2787x2788x1f10bOutput:
Using a mouse
➀. Basic mouse actions
➀.➀. Left button
➀.➁. Right button
➀.➁.➀. Context menus
➁ Selecting
➁.➀. Click and drag
➁.➁ Double click
How to test the ToC feature
Command-line:
fossil test-markdown-render toc-test.md
./fossil-fossmd test-markdown-render toc-test.md
Browser:
Source code for Chapter Level demo: toc/hl2chl.c
Supported ToC marker syntaxes
This list of markers is heavily inspired by the CommonMark Spec.
There are no Proposed Extension for ToC.
Anyway, there are several Deployed Extensions ToC:
NOTE: Example 7. example in the list below is my own proposal, rendered by default as a "Markdown comment".
The advantage of that syntax is that it does not render any HTML if the Markdown parser in use doesn't support ToC.
The disadvantage is that the syntax is not intiutive. :-(
Marker:
{toc}[toc][[toc]]@[toc](heading)<!-- toc --><!-- md-toc -->[//]:#(TOC)
Rendered: (note that marker 5., 6. and 7. do not render any HTML output when ToC is disabled)
{toc}
[toc]
[[toc]]
@toc
HTML changes when enabling ToC
The rendered HTML for ToC is a nested ordered list inside a nav element:
<nav class="toc" id="toc-top">
<ol>
<li><a href="#1.">1. Basic Mouse Actions</a>
<ol>
<li>...</li>
</ol>
</li>
</ol>
</nav>
The HTML for each header also changes when enabling ToC:
## Basic Mouse Actions
normally renders to
<h2>Basic Mouse Actions</h2>
but when enabling ToC, the HTML output changes to
<h2 id="1."><span class="chapter-label">1. </span>Basic Mouse Actions</h2> <a class="href-top" href="#toc-top">Top</a>
Note the added "top-link" after each header is included by default, as it (hopefully) makes navigation easier.
Anyway, the "top-link" may be disabled by the top flag, see below.
Adding additional ToC:s (see "Supported ToC marker syntaxes") to a Markdown document do not affect the "top-link" target,
as it always will point to the first ToC in the document.
When setting the DEPTH flag to a value lower than 5, some headers (i.e. subchapters) may be excluded from ToC.
These excluded headers are not modified in the document either.
How the depth flag affects the HTML changes
Markdown title:
###### A h6 title
depth=5
Title is included in ToC and modified in document:
ToC entry:
<dt><a href="#1.2.3.4.5.">1.2.3.4.5. A h6 title</a></dt>HTML header:
<h6 id="1.2.3.4.5.">1.2.3.4.5. A h6 title</h6> <a class="href-top" href="#toc-top">Top</a>
depth=4
Title is not included in ToC and not modified in document:
ToC entry:
(none)HTML header:
<h6>A h6 title</h6>
Respecting existing 'id' attribute in raw HTML headers
A Markdown Header Level 2 normally is written this way:
## Basic Mouse Actions
But as raw HTML is also allowed in Markdown documents, the header may perfectly be written this way:
Rendered HTML:
<h2 id="mylittleid">Basic Mouse Actions</h2>
When parsing the raw HTML Header, we cannot change the id attribute, as it may be referred from somewhere else in the document.
That means that we need to preserve any existing HTML Header id, and copy it to the ToC, like this:
<nav class="toc" id="toc-top">
<ol>
<li><a href="#mylittleid">1. Basic Mouse Actions</a>
<ol>
<li>...</li>
</ol>
</li>
</ol>
</nav>
And the rendered HTML Header will look like this:
<h2 id="mylittleid"><span class="chapter-label">1. </span>Basic Mouse Actions</h2> <a class="href-top" href="#toc-top">Top</a>
Read more
See README.fossil-fossmd.md for more info about Fossil-FossMD.
See README.fossmd.md for all gory details about Markdown extensions.
CommonMark: ATX Header syntax
CommonMark: Setext Header syntax
CommonMark: Proposed Extension for Markdown
CommonMark: Deployed Extensions for Markdown