Fork me on GitHub

Автоматическое содержание в Pelican Sep 02, 2015

Так получается, что некоторые статьи, например ралли на браузерах. Содержат в себе несколько уровней заголовков. И в связи с этим, сделаем автоматическую навигацию по статье.

Якоря в заголовках markdown

Для написания постов блога я использую markdown разметку текста. Для того, чтобы при генерации html заголовкам присваивались якоря - необходимо подключить расширение Table of Contents. Делается это элементарно прописав в pelicanconf.py следующую строчку:

MD_EXTENSIONS = [
    'codehilite(css_class=highlight)', 'extra', 'markdown.extensions.toc' ]

Теперь при генерации html каждому заголовку будет присваиваться id содержащимся текстом. Заголовок:

##Markdown anchors

Будет сгенерирован в такой html:

<h2 id="markdown-anchors">Markdown&nbsp;anchors</h2>

Ссылки в заголовках

Чтобы заголовки были непросто тегами h1h6, а содержали ссылку на самих себя нужно добавить аргумент anchorlink. Теперь конфигурация MD_EXTENSIONS выглядит так:

MD_EXTENSIONS = [
    'codehilite(css_class=highlight)', 'extra',
    'markdown.extensions.toc(anchorlink=True)' ]

Заголовок:

##Markdown anchors

Будет сгенерирован в такой html:

<h2 id="markdown-anchors">
    <a class="toclink" href="#markdown-anchors">Markdown&nbsp;anchors</a>
</h2>

Кириллица в заголовках

К сожалению, стандартный slugify который используется в markdown toc не умеет обрабатывать кириллические символы, и поэтому заголовок.

##Ссылка в заголовке

Будет сгенерирован в такой html:

<h2 id="_1">
    <a class="toclink" href="#_1">Ссылка в&nbsp;заголовке</a>
</h2>

Что бы исправить это, можно воспользоваться библиотекой python slugify, задав TocExtension объект slugify. Объект slugify должен быть callable поэтому не обойтись просто строковым указанием аргументов, придется явно импортировать и указывать в конструкторе аргументы для расширения:

from markdown.extensions.toc import TocExtension
from slugify import slugify
MD_EXTENSIONS = [
    'codehilite(css_class=highlight)', 'extra',
    TocExtension(anchorlink=True, slugify=slugify), ]

Меню авто содержания

Для навигации по заголовкам будем использовать jQuery plugin Anchorific.js. Данный плагин умеет самостоятельно присваивать id заголовкам, но поскольку заголовки уже сгенерированы с якорями, то создание ссылок джаваскриптом использоваться не будет, в конструкторе укажем null значения для текста и позиции ссылки в заголовке.

    $('article.content').anchorific({
        anchorClass: null, anchorText: null, spy: true, position: null, anchor: null,
    });

Так же пришлось немного подправить напильником этот плагин, под конкретные задачи, например заставить его искать не все заголовки, а только с идентификаторами.

- self.headers = self.$elem.find( 'h1, h2, h3, h4, h5, h6' );
+ self.headers = self.$elem.find( 'h1[id], h2[id], h3[id], h4[id], h5[id], h6[id]' );

Липучее” меню

Для того, что бы при скроллинге страницы меню навигации всегда оставалось доступным будем использовать position: fixed;, но присваивать его только при достижении вершины объекта при скроллинге.

Создадим класс sticky и будем навешивать его по событию скролл.

.sticky {
    position: fixed;
    top: 33px;
    z-index: 999;
}
var $window = $(window),
    $sticky = $('div.anchorific'),
    sticky_top = $sticky.offset().top;

$window.scroll(function() {
    $sticky.toggleClass('sticky', $window.scrollTop() > sticky_top - 33);
});

Получилось такое авто содержание:

nav