Liquid filter to generate Table of Content into Jeklyll pages
This filter adds to jekyll pages a Table of Content (TOC), it generates the necessary HTML code.
The image below shows the result for the markdown page alignRules.md
To use tocGenerator.rb you need nokogiri
- copy the file
tocGenerator.rb
into the_plugins
folder - copy the file
css/toc.css
to you css site and include into_layouts
(this is recommended but not necessary) - finished
You must replace the {{ content }}
directive with {{ content | toc_generate }}
The output contains the HTML code with the TOC and anchor's targets with the id
attribute
Example
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<title>{{ page.title }}</title>
<!-- This css contains the default style for TOC -->
<link rel="stylesheet" type="text/css" media="screen" href="css/toc.css">
</head>
<body>
<div>
{{ content | toc_generate }}
</div>
</body>
</html>
The TOC must have some CSS style to appear correctly, you can find a default implementation into file css/toc.css
The style is compatible with mediawiki themes
It is possible to suppress the TOC generation in specific pages, for example the index page normally hasn't a TOC. This can be done into the Front Matter section used by jekyll
You must add the noToc: true
directive
---
permalink: index.html
layout: default
title: Main Page with TOC
noToc: true
---
Normally no configuration is necessary but you can set some parameter into you _config.yml
file
Parameter name | Description | Default value |
---|---|---|
minItemsToShowToc | Minimum number of items to show the TOC Suppose you want to generated the TOC only if there are at least 3 H1 |
0 (no limit) |
anchorPrefix | The prefix used to generate the anchor name | tocAnchor- |
showToggleButton | The TOC has a button used to collapse/expand the list, this requires a little of Javascript
This package contains a jQuery plugin to handle the click |
false |
If the toogle button is visible you can use the jquery plugin included in this repository
Below is shown an usage example
<!DOCTYPE html>
<html>
<head>
<title>{{ page.title }}</title>
<!-- This css contains the default style for TOC -->
<link rel="stylesheet" type="text/css" media="screen" href="css/toc.css">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="js/jquery.tocLight.js"></script>
<script type="text/javascript">
$(function() {
$.toc.clickHideButton();
});
</script>
</head>
<body id="small">
{{ content | toc_generate }}
</body>
</html>
The filter converts all H1
and H2
elements in a parent-child TOC based on how the markdown code is traslated in HTML.
Markdown generates H1
and H2
as siblings
For example the markdown code shown below
heading 1
=========
blah blah
heading 1.1
-----------
Generates the following HTML code
<h1>heading 1</h1>
<p>blah blah</p>
<h2>heading 1.1</h2>
If you host your jekyll pages on github you can't run plugins, in this scenario you can use a full javascript solution using TOC Generator for Markdown
Codeblock is can write blocks of code directly in your posts and optionally add titles and links.
Codeblock
is uses a special indentation.
sample source
<figure class="code"><div class="highlight"><table><tbody><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
</pre></td><td class="code"><pre><code class="bash"><span class="line"><span class="nv">$ </span>osascript -e <span class="s1">'tell application "iTerm" to activate'</span>
</span></code></pre></td></tr></tbody></table></div></figure>
But, it is different when using a nokogiri of .to_xhtml
.
sample source
<figure class="code">
<div class="highlight">
<table>
<tbody><tr>
<td class="gutter">
<pre class="line-numbers"><span class="line-number">1</span>
</pre>
</td>
<td class="code">
<pre> <code class="bash">
<span class="line"><span class="nv">$ </span>osascript -e <span class="s1">'tell application "iTerm" to activate'</span>
</span>
</code>
</pre>
</td>
</tr>
</tbody></table>
</div>
</figure>
So, I've rewritten the code.
jekyll-toc-generator/_plugins/tocGenerator.rb
- doc.css('body').children.to_xhtml(indent:3, indent_text:" ")
+ doc.css('body').children.to_html