Browse Source

Added support 'Table of Content' [Toc]

Jesús 4 weeks ago
parent
commit
c6d0c67bc0
Signed by: Jesús <heckyel@hyperbola.info> GPG Key ID: F6EE7BC59A315766

+ 44
- 7
cl-theme/static/css/style.css View File

@@ -503,20 +503,57 @@ h4 > a:hover {
503 503
 
504 504
 /* aplaylist */
505 505
 .play-menu {
506
-  height: 200px;
507
-  overflow-y: auto;
506
+    height: 200px;
507
+    overflow-y: auto;
508 508
 }
509 509
 
510 510
 .play-menu a {
511
-  color: white;
511
+    color: white;
512 512
 }
513 513
 
514 514
 .play-menu a:hover {
515
-  background-color: #484848;
516
-  color: #fff;
515
+    background-color: #484848;
516
+    color: #fff;
517 517
 }
518 518
 
519 519
 .is-active-play {
520
-  color: #dd7325;
521
-  background-color: #dd7325;
520
+    color: #dd7325;
521
+    background-color: #dd7325;
522
+}
523
+
524
+/* table of contents */
525
+.toc {
526
+    font-size: 0.85rem;
527
+}
528
+
529
+.toctitle {
530
+    display: block;
531
+    text-align: center;
532
+    font-size: 1rem;
533
+    color: white;
534
+    text-decoration: underline;
535
+}
536
+
537
+nav.toc {
538
+    background-color: #0c0f0f;
539
+    border: 1px solid #dd7325;
540
+    margin: 1rem 0px;
541
+}
542
+
543
+div.toc {
544
+    margin: 1rem;
545
+}
546
+
547
+a.headerlink {
548
+    color: grey;
549
+    padding-left: .5em;
550
+    visibility: hidden;
551
+}
552
+
553
+h1:hover > a.headerlink, h2:hover > a.headerlink,
554
+h3:hover > a.headerlink, h4:hover > a.headerlink,
555
+h5:hover > a.headerlink, h6:hover > a.headerlink,
556
+dt:hover > a.headerlink {
557
+    text-decoration: none;
558
+    visibility: visible;
522 559
 }

+ 6
- 0
cl-theme/templates/article.html View File

@@ -77,6 +77,12 @@
77 77
                             <div class="card-inner-wrapper">
78 78
                                 <!-- post text -->
79 79
                                 <div class="card-content-text has-text-justified">
80
+                                    {% if article.toc %}
81
+                                        <nav class="toc">
82
+                                            {{ article.toc }}
83
+                                        </nav>
84
+                                    {% endif %}
85
+
80 86
                                     {{ article.content }}
81 87
                                 </div>
82 88
                                 <!-- end of post text -->

+ 8
- 1
pelicanconf.py View File

@@ -12,6 +12,10 @@ DISPLAY_CATEGORIES_ON_MENU = True
12 12
 DISPLAY_PAGES_ON_MENU = True
13 13
 MARKDOWN = {
14 14
     'extension_configs': {
15
+        'markdown.extensions.toc': {
16
+            'title': 'Tabla de Contenidos',
17
+            'permalink': 'true'
18
+        },
15 19
         'markdown.extensions.codehilite': {'css_class': 'highlight'},
16 20
         'markdown.extensions.extra': {},
17 21
         'markdown.extensions.footnotes': {'BACKLINK_TITLE': 'Volver a la nota %d en el texto'},
@@ -24,7 +28,7 @@ MARKDOWN = {
24 28
 
25 29
 PATH = 'content'
26 30
 PLUGIN_PATHS = ['plugins']
27
-PLUGINS = ['another_read_more_link', 'i18n_subsites', 'neighbors', 'pelican-css', 'pelican-js', 'sitemap', 'tag-cloud', 'tipue-search']
31
+PLUGINS = ['another_read_more_link', 'extract_toc', 'i18n_subsites', 'neighbors', 'pelican-css', 'pelican-js', 'sitemap', 'tag-cloud', 'tipue-search']
28 32
 SITENAME = 'Conocimientos Libres'
29 33
 SITENAME_SINGLE = 'CL'
30 34
 SITEURL = 'https://conocimientoslibres.tuxfamily.org'
@@ -128,6 +132,9 @@ I18N_SUBSITES = {
128 132
         'LOCALE': ('en_US.UTF-8'),
129 133
         'MARKDOWN': {
130 134
             'extension_configs': {
135
+                'markdown.extensions.toc': {
136
+                    'title': 'Table of Contents',
137
+                },
131 138
                 'markdown.extensions.codehilite': {'css_class': 'highlight'},
132 139
                 'markdown.extensions.extra': {},
133 140
                 'markdown.extensions.footnotes': {'BACKLINK_TITLE': 'Jump back to footnote %d in the text'},

+ 137
- 0
plugins/extract_toc/README.md View File

@@ -0,0 +1,137 @@
1
+Extract Table of Content
2
+========================
3
+
4
+A Pelican plugin to extract table of contents (ToC) from `article.content` and
5
+place it in its own `article.toc` variable for use in templates.
6
+
7
+Copyright (c) Talha Mansoor
8
+
9
+Author          | Talha Mansoor
10
+----------------|-----
11
+Author Email    | talha131@gmail.com
12
+Author Homepage | http://onCrashReboot.com
13
+Github Account  | https://github.com/talha131
14
+
15
+
16
+Acknowledgement
17
+---------------
18
+
19
+Thanks to [Avaris](https://github.com/avaris) for going out of the way to help
20
+me fix Unicode issues and doing a thorough code review.
21
+
22
+Thanks to [gw0](http://gw.tnode.com/) for adding Pandoc reader support.
23
+
24
+
25
+Why do you need it?
26
+===================
27
+
28
+Pelican can generate ToC of reST and Markdown files, using markup's respective
29
+directive and extension. Such ToC is generated and placed at the beginning of
30
+`article.content` like a string. Consequently it can not be placed anywhere
31
+else on the page (eg. `<nav>` HTML5 tag, in header, or at the end of your
32
+article's contents).
33
+
34
+To solve this problem, this plugin extracts ToC from `article.content` and
35
+places it in its own `article.toc` variable for use in templates.
36
+
37
+
38
+Requirements
39
+============
40
+
41
+`extract_toc` requires BeautifulSoup.
42
+
43
+```bash
44
+pip install beautifulsoup4
45
+```
46
+
47
+
48
+How to Use
49
+==========
50
+
51
+This plugin works by extracting the first occurrence of enclosed in:
52
+
53
+- `<div class="toc">` for the default Markdown reader
54
+- `<div class="contents topic">` for the default reStructuredText reader
55
+- `<nav class="TOC">` for the Pandoc reader
56
+
57
+If ToC appears in your article at more than one places, `extract_toc` will
58
+remove only the first occurrence. You shouldn't probably need to have multiple
59
+ToC in your article. In case you need to display it multiple times, you can
60
+print it via your template.
61
+
62
+
63
+Template example
64
+----------------
65
+
66
+Add something like this to your Pelican templates if missing:
67
+
68
+```python
69
+{% if article.toc %}
70
+    <nav class="toc">
71
+    {{ article.toc }}
72
+    </nav>
73
+{% endif %}
74
+```
75
+
76
+
77
+reStructuredText reader
78
+-----------------------
79
+
80
+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.
81
+
82
+```rst
83
+My super title
84
+##############
85
+
86
+:date: 2010-10-03
87
+:tags: thats, awesome
88
+
89
+.. contents::
90
+..
91
+   1  Head 1
92
+     1.1  Head 2
93
+   2  Head 3
94
+   3  head 4
95
+
96
+Heading 1
97
+---------
98
+
99
+Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.
100
+```
101
+
102
+
103
+Markdown reader
104
+---------------
105
+
106
+To enable table of contents generation for the Markdown reader you need to set `MD_EXTENSIONS = (['toc'])` in your Pelican configuration file.
107
+
108
+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.
109
+
110
+```markdown
111
+title: My super title
112
+date: 4-4-2013
113
+tags: thats, awesome
114
+
115
+[TOC]
116
+
117
+# Heading 1 #
118
+
119
+Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.
120
+```
121
+
122
+
123
+Pandoc reader
124
+-------------
125
+
126
+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.
127
+
128
+Contents of the Pandoc template file `pandoc-template-toc.html5`:
129
+
130
+```html
131
+$if(toc)$
132
+<nav id="TOC">
133
+$toc$
134
+</nav>
135
+$endif$
136
+$body$
137
+```

+ 1
- 0
plugins/extract_toc/__init__.py View File

@@ -0,0 +1 @@
1
+from .extract_toc import *

+ 66
- 0
plugins/extract_toc/extract_toc.py View File

@@ -0,0 +1,66 @@
1
+# -*- coding: utf-8 -*-
2
+"""
3
+Extract Table of Content
4
+========================
5
+
6
+A Pelican plugin to extract table of contents (ToC) from `article.content` and
7
+place it in its own `article.toc` variable for use in templates.
8
+"""
9
+
10
+from os import path
11
+from bs4 import BeautifulSoup
12
+from pelican import signals, readers, contents
13
+import logging
14
+
15
+logger = logging.getLogger(__name__)
16
+
17
+
18
+def extract_toc(content):
19
+    if isinstance(content, contents.Static):
20
+        return
21
+
22
+    soup = BeautifulSoup(content._content, 'html.parser')
23
+    filename = content.source_path
24
+    extension = path.splitext(filename)[1][1:]
25
+    toc = None
26
+
27
+    # default Markdown reader
28
+    if not toc and readers.MarkdownReader.enabled and extension in readers.MarkdownReader.file_extensions:
29
+        toc = soup.find('div', class_='toc')
30
+        if toc:
31
+            toc.extract()
32
+            if len(toc.find_next('ul').find_all('li')) == 0:
33
+                toc = None
34
+
35
+    # default reStructuredText reader
36
+    if not toc and readers.RstReader.enabled and extension in readers.RstReader.file_extensions:
37
+        toc = soup.find('div', class_='contents topic')
38
+        if toc:
39
+            toc.extract()
40
+            tag = BeautifulSoup(str(toc), 'html.parser')
41
+            tag.div['class'] = 'toc'
42
+            tag.div['id'] = ''
43
+            p = tag.find('p', class_='topic-title first')
44
+            if p:
45
+                p.extract()
46
+            toc = tag
47
+
48
+    # Pandoc reader (markdown and other formats)
49
+    if 'pandoc_reader' in content.settings['PLUGINS']:
50
+        try:
51
+            from pandoc_reader import PandocReader
52
+        except ImportError:
53
+            PandocReader = False
54
+        if not toc and PandocReader and PandocReader.enabled and extension in PandocReader.file_extensions:
55
+            toc = soup.find('nav', id='TOC')
56
+
57
+    if toc:
58
+        toc.extract()
59
+        content._content = soup.decode()
60
+        content.toc = toc.decode()
61
+        if content.toc.startswith('<html>'):
62
+            content.toc = content.toc[12:-14]
63
+
64
+
65
+def register():
66
+    signals.content_object_init.connect(extract_toc)