I'm using Pandoc, as described here, to convert Markdown to HTML and I'm trying to customize the output so that the table of contents appears under a specific heading in my document. However, I'm encountering difficulties in achieving this with the default HTML template.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="$lang$" xml:lang="$lang$"$if(dir)$ dir="$dir$"$endif$>
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
$for(author-meta)$
<meta name="author" content="$author-meta$" />
$endfor$
$if(date-meta)$
<meta name="dcterms.date" content="$date-meta$" />
$endif$
$if(keywords)$
<meta name="keywords" content="$for(keywords)$$keywords$$sep$, $endfor$" />
$endif$
$if(description-meta)$
<meta name="description" content="$description-meta$" />
$endif$
<title>$if(title-prefix)$$title-prefix$ – $endif$$pagetitle$</title>
<style>
$styles.html()$
</style>
$for(css)$
<link rel="stylesheet" href="$css$" />
$endfor$
$for(header-includes)$
$header-includes$
$endfor$
$if(math)$
$if(mathjax)$
<script src="https://cdnjs.cloudflare.com/polyfill/v3/polyfill.min.js?features=es6"></script>
$endif$
$math$
$endif$
</head>
<body>
$for(include-before)$
$include-before$
$endfor$
$if(title)$
<header id="title-block-header">
<h1 class="title">$title$</h1>
$if(subtitle)$
<p class="subtitle">$subtitle$</p>
$endif$
$for(author)$
<p class="author">$author$</p>
$endfor$
$if(date)$
<p class="date">$date$</p>
$endif$
$if(abstract)$
<div class="abstract">
<div class="abstract-title">$abstract-title$</div>
$abstract$
</div>
$endif$
</header>
$endif$
$if(toc)$
<nav id="$idprefix$TOC" role="doc-toc">
$if(toc-title)$
<h2 id="$idprefix$toc-title">$toc-title$</h2>
$endif$
$table-of-contents$
</nav>
$endif$
$body$
$for(include-after)$
$include-after$
$endfor$
</body>
</html>
I'm using the following Pandoc command:
pandoc -F "C:\Users\foobar\AppData\Local\Yarn\bin\mermaid-filter.cmd" -t html --standalone --css=custom.css --toc --template=custom-template.html -o output.html input.md
My Markdown file structure looks like this:
# Document Title
Some introductory text...
## Table of Contents
(I want the auto-generated ToC to appear here)
## First Section
Content of the first section...
I've exported the default HTML template using:
pandoc -D html > custom-template.html
How can I modify the Pandoc HTML template and/or CSS to ensure that the auto-generated table of contents is inserted right after my "Table of Contents" heading in the output HTML?
Here's the content of my custom.css
file:
table {
margin-left: auto;
margin-right: auto;
margin-bottom: 24px;
border-spacing: 0;
border-collapse: collapse;
border: 2px solid black;
}
table th {
padding: 3px 10px;
background-color: white;
border: 1px solid black;
}
table td {
padding: 3px 10px;
border: 1px solid black;
}
Any help or guidance on customizing Pandoc's output to achieve this specific table of contents placement would be greatly appreciated!
The table of contents is inserted in your template via $table-of-contents$
. You cannot change it in the template.
But you could insert the $table-of-contents$
in a javascript part of your template and placing it to whatever element in your dom. You can see such an approach in toc-css.
Or you write a simple Lua filter that inserts the table of contents in your document. Here an example:
Your input.md
markdown file:
# Document Title
Some introductory text...
## Table of Contents
YOURTOCMARKER
## First Section
Content of the first section...
A Lua filter my_filter.lua
local your_toc = {}
Pandoc = function(elem)
your_toc = pandoc.structure.table_of_contents(elem)
print(your_toc)
return elem:walk{
Block = function(s)
if pandoc.utils.stringify(s) == "YOURTOCMARKER" then
print(type(your_toc))
return {
pandoc.RawBlock('html', '<nav id="my_toc">'),
your_toc,
pandoc.RawBlock('html', '</nav>'),
}
end
end
}
end
Run with the following
pandoc input.md -f markdown -t html -o output.html --lua-filter your_filter.lua
produces the following output output.html
:
<h1 id="document-title">Document Title</h1>
<p>Some introductory text…</p>
<h2 id="table-of-contents">Table of Contents</h2>
<nav id="my_toc">
<ul>
<li>
<a href="#document-title" id="toc-document-title">Document Title</a>
<ul>
<li>
<a href="#table-of-contents" id="toc-table-of-contents">Table of Contents</a>
</li>
<li>
<a href="#first-section" id="toc-first-section">First Section</a>
</li>
</ul>
</li>
</ul>
</nav>
<h2 id="first-section">First Section</h2>
<p>Content of the first section…</p>
You can of course combine this approach with the --css
and --template
options.