FPs

Pelican 文章生成目錄

最近翻譯了一篇Google Shell 編程風格指南,發現章節一多,沒有目錄非常不友好。文章是用Markdown 寫成的,手寫html 代碼加目錄太不方便了。
Pelican 有一個生成目錄的插件:extract_toc,試用了一下,發現使用三個反引號標註的代碼塊亂掉了,這個插件似乎調用的pandoc,而pandoc 支持的markdown 語法不包含試用三個反引號標註代碼塊,所以悲劇了。

改變思路,在文章頁面使用JavaScript 解析DOM 樹,生成目錄表格。
Google 了下,Stackoverflow 看到一問題:
Is there a JavaScript solution to generating a “table of contents” for a page?
參考答案直接拿來用:

toc.js

window.onload = function () {
    var toc = "";
    var level = 0;

    document.getElementById("contents").innerHTML =
        document.getElementById("contents").innerHTML.replace(
            /<h([\d])>([^<]+)<\/h([\d])>/gi,
            function (str, openLevel, titleText, closeLevel) {
                if (openLevel != closeLevel) {
                    return str;
                }

                if (openLevel > level) {
                    toc += (new Array(openLevel - level + 1)).join("<ul>");
                } else if (openLevel < level) {
                    toc += (new Array(level - openLevel + 1)).join("</ul>");
                }

                level = parseInt(openLevel);

                var anchor = titleText.replace(/ /g, "_");
                    toc += "<li><a href=\"#" + anchor + "\">" + titleText
                        + "</a></li>";

                    return "<h" + openLevel + "><a name=\"" + anchor + "\">"
                        + titleText + "</a></h" + closeLevel + ">";
            }
        );

    if (level) {
        toc += (new Array(level + 1)).join("</ul>");
    }

    document.getElementById("toc").innerHTML += toc;
};

修改pelican 主題 的base.html 之類模板文件的,引入這個JavaScript 文件:

<script src="{{ SITEURL }}/theme/static/js/toc.js" type="text/javascript"></script>

修改pelican 主題的生成文章的html 模板,加一個div,另外還需要給文章內容的div 加一個id="contents"

<div id="toc">
</div>

<div id="contents" class="entry-content">
{{ article.content }}
  </div><!-- /.entry-content -->
...

大功告成,效果如下:
pelican_toc

2016-04-25 pelican toc js