Added support 'Table of Content' [Toc]
This commit is contained in:
parent
e4a8f433b6
commit
c6d0c67bc0
@ -520,3 +520,40 @@ h4 > a:hover {
|
|||||||
color: #dd7325;
|
color: #dd7325;
|
||||||
background-color: #dd7325;
|
background-color: #dd7325;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* table of contents */
|
||||||
|
.toc {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toctitle {
|
||||||
|
display: block;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 1rem;
|
||||||
|
color: white;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav.toc {
|
||||||
|
background-color: #0c0f0f;
|
||||||
|
border: 1px solid #dd7325;
|
||||||
|
margin: 1rem 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.toc {
|
||||||
|
margin: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.headerlink {
|
||||||
|
color: grey;
|
||||||
|
padding-left: .5em;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1:hover > a.headerlink, h2:hover > a.headerlink,
|
||||||
|
h3:hover > a.headerlink, h4:hover > a.headerlink,
|
||||||
|
h5:hover > a.headerlink, h6:hover > a.headerlink,
|
||||||
|
dt:hover > a.headerlink {
|
||||||
|
text-decoration: none;
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
@ -77,6 +77,12 @@
|
|||||||
<div class="card-inner-wrapper">
|
<div class="card-inner-wrapper">
|
||||||
<!-- post text -->
|
<!-- post text -->
|
||||||
<div class="card-content-text has-text-justified">
|
<div class="card-content-text has-text-justified">
|
||||||
|
{% if article.toc %}
|
||||||
|
<nav class="toc">
|
||||||
|
{{ article.toc }}
|
||||||
|
</nav>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{{ article.content }}
|
{{ article.content }}
|
||||||
</div>
|
</div>
|
||||||
<!-- end of post text -->
|
<!-- end of post text -->
|
||||||
|
@ -12,6 +12,10 @@ DISPLAY_CATEGORIES_ON_MENU = True
|
|||||||
DISPLAY_PAGES_ON_MENU = True
|
DISPLAY_PAGES_ON_MENU = True
|
||||||
MARKDOWN = {
|
MARKDOWN = {
|
||||||
'extension_configs': {
|
'extension_configs': {
|
||||||
|
'markdown.extensions.toc': {
|
||||||
|
'title': 'Tabla de Contenidos',
|
||||||
|
'permalink': 'true'
|
||||||
|
},
|
||||||
'markdown.extensions.codehilite': {'css_class': 'highlight'},
|
'markdown.extensions.codehilite': {'css_class': 'highlight'},
|
||||||
'markdown.extensions.extra': {},
|
'markdown.extensions.extra': {},
|
||||||
'markdown.extensions.footnotes': {'BACKLINK_TITLE': 'Volver a la nota %d en el texto'},
|
'markdown.extensions.footnotes': {'BACKLINK_TITLE': 'Volver a la nota %d en el texto'},
|
||||||
@ -24,7 +28,7 @@ MARKDOWN = {
|
|||||||
|
|
||||||
PATH = 'content'
|
PATH = 'content'
|
||||||
PLUGIN_PATHS = ['plugins']
|
PLUGIN_PATHS = ['plugins']
|
||||||
PLUGINS = ['another_read_more_link', 'i18n_subsites', 'neighbors', 'pelican-css', 'pelican-js', 'sitemap', 'tag-cloud', 'tipue-search']
|
PLUGINS = ['another_read_more_link', 'extract_toc', 'i18n_subsites', 'neighbors', 'pelican-css', 'pelican-js', 'sitemap', 'tag-cloud', 'tipue-search']
|
||||||
SITENAME = 'Conocimientos Libres'
|
SITENAME = 'Conocimientos Libres'
|
||||||
SITENAME_SINGLE = 'CL'
|
SITENAME_SINGLE = 'CL'
|
||||||
SITEURL = 'https://conocimientoslibres.tuxfamily.org'
|
SITEURL = 'https://conocimientoslibres.tuxfamily.org'
|
||||||
@ -128,6 +132,9 @@ I18N_SUBSITES = {
|
|||||||
'LOCALE': ('en_US.UTF-8'),
|
'LOCALE': ('en_US.UTF-8'),
|
||||||
'MARKDOWN': {
|
'MARKDOWN': {
|
||||||
'extension_configs': {
|
'extension_configs': {
|
||||||
|
'markdown.extensions.toc': {
|
||||||
|
'title': 'Table of Contents',
|
||||||
|
},
|
||||||
'markdown.extensions.codehilite': {'css_class': 'highlight'},
|
'markdown.extensions.codehilite': {'css_class': 'highlight'},
|
||||||
'markdown.extensions.extra': {},
|
'markdown.extensions.extra': {},
|
||||||
'markdown.extensions.footnotes': {'BACKLINK_TITLE': 'Jump back to footnote %d in the text'},
|
'markdown.extensions.footnotes': {'BACKLINK_TITLE': 'Jump back to footnote %d in the text'},
|
||||||
|
137
plugins/extract_toc/README.md
Normal file
137
plugins/extract_toc/README.md
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
Extract Table of Content
|
||||||
|
========================
|
||||||
|
|
||||||
|
A Pelican plugin to extract table of contents (ToC) from `article.content` and
|
||||||
|
place it in its own `article.toc` variable for use in templates.
|
||||||
|
|
||||||
|
Copyright (c) Talha Mansoor
|
||||||
|
|
||||||
|
Author | Talha Mansoor
|
||||||
|
----------------|-----
|
||||||
|
Author Email | talha131@gmail.com
|
||||||
|
Author Homepage | http://onCrashReboot.com
|
||||||
|
Github Account | https://github.com/talha131
|
||||||
|
|
||||||
|
|
||||||
|
Acknowledgement
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Thanks to [Avaris](https://github.com/avaris) for going out of the way to help
|
||||||
|
me fix Unicode issues and doing a thorough code review.
|
||||||
|
|
||||||
|
Thanks to [gw0](http://gw.tnode.com/) for adding Pandoc reader support.
|
||||||
|
|
||||||
|
|
||||||
|
Why do you need it?
|
||||||
|
===================
|
||||||
|
|
||||||
|
Pelican can generate ToC of reST and Markdown files, using markup's respective
|
||||||
|
directive and extension. Such ToC is generated and placed at the beginning of
|
||||||
|
`article.content` like a string. Consequently it can not be placed anywhere
|
||||||
|
else on the page (eg. `<nav>` HTML5 tag, in header, or at the end of your
|
||||||
|
article's contents).
|
||||||
|
|
||||||
|
To solve this problem, this plugin extracts ToC from `article.content` and
|
||||||
|
places it in its own `article.toc` variable for use in templates.
|
||||||
|
|
||||||
|
|
||||||
|
Requirements
|
||||||
|
============
|
||||||
|
|
||||||
|
`extract_toc` requires BeautifulSoup.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install beautifulsoup4
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
How to Use
|
||||||
|
==========
|
||||||
|
|
||||||
|
This plugin works by extracting the first occurrence of enclosed in:
|
||||||
|
|
||||||
|
- `<div class="toc">` for the default Markdown reader
|
||||||
|
- `<div class="contents topic">` for the default reStructuredText reader
|
||||||
|
- `<nav class="TOC">` for the Pandoc reader
|
||||||
|
|
||||||
|
If ToC appears in your article at more than one places, `extract_toc` will
|
||||||
|
remove only the first occurrence. You shouldn't probably need to have multiple
|
||||||
|
ToC in your article. In case you need to display it multiple times, you can
|
||||||
|
print it via your template.
|
||||||
|
|
||||||
|
|
||||||
|
Template example
|
||||||
|
----------------
|
||||||
|
|
||||||
|
Add something like this to your Pelican templates if missing:
|
||||||
|
|
||||||
|
```python
|
||||||
|
{% if article.toc %}
|
||||||
|
<nav class="toc">
|
||||||
|
{{ article.toc }}
|
||||||
|
</nav>
|
||||||
|
{% endif %}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
reStructuredText reader
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
To add a table of contents to your reStructuredText document (`.rst`) you need to add a `.. contents::` directive to its beginning. See the [docutils documentation](http://docutils.sourceforge.net/docs/ref/rst/directives.html#table-of-contents) for more details.
|
||||||
|
|
||||||
|
```rst
|
||||||
|
My super title
|
||||||
|
##############
|
||||||
|
|
||||||
|
:date: 2010-10-03
|
||||||
|
:tags: thats, awesome
|
||||||
|
|
||||||
|
.. contents::
|
||||||
|
..
|
||||||
|
1 Head 1
|
||||||
|
1.1 Head 2
|
||||||
|
2 Head 3
|
||||||
|
3 head 4
|
||||||
|
|
||||||
|
Heading 1
|
||||||
|
---------
|
||||||
|
|
||||||
|
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Markdown reader
|
||||||
|
---------------
|
||||||
|
|
||||||
|
To enable table of contents generation for the Markdown reader you need to set `MD_EXTENSIONS = (['toc'])` in your Pelican configuration file.
|
||||||
|
|
||||||
|
To add a table of contents to your Markdown document (`.md`) you need to place the `[TOC]` marker to its beginning. See the [Python Markdown documentation](http://pythonhosted.org/Markdown/extensions/toc.html) for more details.
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
title: My super title
|
||||||
|
date: 4-4-2013
|
||||||
|
tags: thats, awesome
|
||||||
|
|
||||||
|
[TOC]
|
||||||
|
|
||||||
|
# Heading 1 #
|
||||||
|
|
||||||
|
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Pandoc reader
|
||||||
|
-------------
|
||||||
|
|
||||||
|
To enable table of contents generation for the Pandoc reader you need to set `PANDOC_ARGS = (['--toc', '--template=pandoc-template-toc'])` in your Pelican configuration file.
|
||||||
|
|
||||||
|
Contents of the Pandoc template file `pandoc-template-toc.html5`:
|
||||||
|
|
||||||
|
```html
|
||||||
|
$if(toc)$
|
||||||
|
<nav id="TOC">
|
||||||
|
$toc$
|
||||||
|
</nav>
|
||||||
|
$endif$
|
||||||
|
$body$
|
||||||
|
```
|
1
plugins/extract_toc/__init__.py
Normal file
1
plugins/extract_toc/__init__.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
from .extract_toc import *
|
66
plugins/extract_toc/extract_toc.py
Normal file
66
plugins/extract_toc/extract_toc.py
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Extract Table of Content
|
||||||
|
========================
|
||||||
|
|
||||||
|
A Pelican plugin to extract table of contents (ToC) from `article.content` and
|
||||||
|
place it in its own `article.toc` variable for use in templates.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from os import path
|
||||||
|
from bs4 import BeautifulSoup
|
||||||
|
from pelican import signals, readers, contents
|
||||||
|
import logging
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def extract_toc(content):
|
||||||
|
if isinstance(content, contents.Static):
|
||||||
|
return
|
||||||
|
|
||||||
|
soup = BeautifulSoup(content._content, 'html.parser')
|
||||||
|
filename = content.source_path
|
||||||
|
extension = path.splitext(filename)[1][1:]
|
||||||
|
toc = None
|
||||||
|
|
||||||
|
# default Markdown reader
|
||||||
|
if not toc and readers.MarkdownReader.enabled and extension in readers.MarkdownReader.file_extensions:
|
||||||
|
toc = soup.find('div', class_='toc')
|
||||||
|
if toc:
|
||||||
|
toc.extract()
|
||||||
|
if len(toc.find_next('ul').find_all('li')) == 0:
|
||||||
|
toc = None
|
||||||
|
|
||||||
|
# default reStructuredText reader
|
||||||
|
if not toc and readers.RstReader.enabled and extension in readers.RstReader.file_extensions:
|
||||||
|
toc = soup.find('div', class_='contents topic')
|
||||||
|
if toc:
|
||||||
|
toc.extract()
|
||||||
|
tag = BeautifulSoup(str(toc), 'html.parser')
|
||||||
|
tag.div['class'] = 'toc'
|
||||||
|
tag.div['id'] = ''
|
||||||
|
p = tag.find('p', class_='topic-title first')
|
||||||
|
if p:
|
||||||
|
p.extract()
|
||||||
|
toc = tag
|
||||||
|
|
||||||
|
# Pandoc reader (markdown and other formats)
|
||||||
|
if 'pandoc_reader' in content.settings['PLUGINS']:
|
||||||
|
try:
|
||||||
|
from pandoc_reader import PandocReader
|
||||||
|
except ImportError:
|
||||||
|
PandocReader = False
|
||||||
|
if not toc and PandocReader and PandocReader.enabled and extension in PandocReader.file_extensions:
|
||||||
|
toc = soup.find('nav', id='TOC')
|
||||||
|
|
||||||
|
if toc:
|
||||||
|
toc.extract()
|
||||||
|
content._content = soup.decode()
|
||||||
|
content.toc = toc.decode()
|
||||||
|
if content.toc.startswith('<html>'):
|
||||||
|
content.toc = content.toc[12:-14]
|
||||||
|
|
||||||
|
|
||||||
|
def register():
|
||||||
|
signals.content_object_init.connect(extract_toc)
|
Loading…
x
Reference in New Issue
Block a user