1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
|
---
layout: default
title: Table of Contents Extension
description: The Table of Contents extension automatically inserts links to the headings in your document.
---
# Table of Contents Extension
The `TableOfContentsExtension` automatically inserts a table of contents into your document with links to the various headings.
The [Heading Permalink](/2.1/extensions/heading-permalinks/) extension must also be included for this to work.
## Installation
This extension is bundled with `league/commonmark`. This library can be installed via Composer:
```bash
composer require league/commonmark
```
See the [installation](/2.1/installation/) section for more details.
## Usage
Configure your `Environment` as usual and simply add the `TableOfContentsExtension` and `HeadingPermalinkExtension` provided by this package:
```php
use League\CommonMark\Environment\Environment;
use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
use League\CommonMark\Extension\HeadingPermalink\HeadingPermalinkExtension;
use League\CommonMark\Extension\TableOfContents\TableOfContentsExtension;
use League\CommonMark\MarkdownConverter;
// Define your configuration, if needed
// Extension defaults are shown below
// If you're happy with the defaults, feel free to remove them from this array
$config = [
'table_of_contents' => [
'html_class' => 'table-of-contents',
'position' => 'top',
'style' => 'bullet',
'min_heading_level' => 1,
'max_heading_level' => 6,
'normalize' => 'relative',
'placeholder' => null,
],
];
// Configure the Environment with all the CommonMark parsers/renderers
$environment = new Environment($config);
$environment->addExtension(new CommonMarkCoreExtension());
// Add the two extensions
$environment->addExtension(new HeadingPermalinkExtension());
$environment->addExtension(new TableOfContentsExtension());
// Instantiate the converter engine and start converting some Markdown!
$converter = new MarkdownConverter($environment);
echo $converter->convertToHtml('# Awesome!');
```
## Configuration
This extension can be configured by providing a `table_of_contents` array with several nested configuration options. The defaults are shown in the code example above.
### `html_class`
The value of this nested configuration option should be a `string` that you want set as the `<ul>` or `<ol>` tag's `class` attribute. This defaults to `'table-of-contents'`.
### `normalize`
This should be a `string` that defines one of three different strategies to use when generating a (potentially-nested) list from your various headings:
- `'flat'`
- `'as-is'`
- **`'relative'`** (default)
See "[Normalization Strategies](#normalization-strategies)" below for more information.
### `position`
This `string` controls where in the document your table of contents will be placed. There are two options:
- **`'top'`** (default) - Insert at the very top of the document, before any content
- `'before-headings'` - Insert just before the very first heading - useful if you want to have some descriptive text show above the table of content.
- `'placeholder'` - Location is manually defined by a user-provided placeholder somewhere in the document (see the `placeholder` option below)
If you'd like to customize this further, you can implement a [custom event listener](/2.1/customization/event-dispatcher/#registering-listeners) to locate the `TableOfContents` node and reposition it somewhere else in the document prior to rendering.
### `placeholder`
When combined with `'position' => 'placeholder'`, this setting tells the extension which placeholder content should be replaced with the Table of Contents. For example, if you set this option to `[TOC]`, then any lines in your document consisting of that `[TOC]` placeholder will be replaced by the Table of Contents. Note that this option has no default value - you must provide this string yourself.
### `style`
This `string` option controls what style of HTML list should be used to render the table of contents:
- **`'bullet'`** (default) - Unordered, bulleted list (`<ul>`)
- `'ordered'` - Ordered list (`<ol>`)
### `min_heading_level` and `max_heading_level`
These two settings control which headings should appear in the list. By default, all 6 levels (`1`, `2`, `3`, `4`, `5`, and `6`). You can override this by setting the `min_heading_level` and/or `max_heading_level` to a different number (`int` value).
## Normalization Strategies
Consider this sample Markdown input:
```markdown
## Level 2 Heading
This is a sample document that starts with a level 2 heading
#### Level 4 Heading
Notice how we went from a level 2 heading to a level 4 heading!
### Level 3 Heading
And now we have a level 3 heading here.
```
Here's how the different normalization strategies would handle this input:
### Strategy: `'flat'`
All links in your table of contents will be shown in a flat, single-level list:
```html
<ul class="table-of-contents">
<li>
<p><a href="#level-2-heading">Level 2 Heading</a></p>
</li>
<li>
<p><a href="#level-4-heading">Level 4 Heading</a></p>
</li>
<li>
<p><a href="#level-3-heading">Level 3 Heading</a></p>
</li>
</ul>
<!-- The rest of the content would go here -->
```
### Strategy: `'as-is'`
Level 1 headings (`<h1>`) will appear on the first level of the list, with level 2 headings (`<h2>`) nested under those, and so forth - exactly as they occur within the document. But this can get weird if your document doesn't start with level 1 headings, or it doesn't properly nest the levels:
```html
<ul class="table-of-contents">
<li>
<ul>
<li>
<p><a href="#level-2-heading">Level 2 Heading</a></p>
<ul>
<li>
<ul>
<li>
<p><a href="#level-4-heading">Level 4 Heading</a></p>
</li>
</ul>
</li>
<li>
<p><a href="#level-3-heading">Level 3 Heading</a></p>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<!-- The rest of the content would go here -->
```
### Strategy: `'relative'`
Applies nesting, but handles edge cases (like incorrect nesting levels) as you'd expect:
```html
<ul class="table-of-contents">
<li>
<p><a href="#level-2-heading">Level 2 Heading</a></p>
<ul>
<li>
<p><a href="#level-4-heading">Level 4 Heading</a></p>
</li>
</ul>
<ul>
<li>
<p><a href="#level-3-heading">Level 3 Heading</a></p>
</li>
</ul>
</li>
</ul>
<!-- The rest of the content would go here -->
```
|