Browse Source

enable plugins

pull/2/head
rra 1 year ago
parent
commit
11986f6e9b

+ 2
- 2
pelicanconf.py View File

@@ -35,8 +35,8 @@ EXTRA_PATH_METADATA = {
35 35
 }
36 36
 
37 37
 #Pelican Plugins & Markdown extensions
38
-#PLUGIN_PATHS = ['plugins']
39
-#PLUGINS = ['extract_toc', 'summary','representative_image','addressable_paragraphs']
38
+PLUGIN_PATHS = ['plugins']
39
+PLUGINS = ['extract_toc', 'summary','representative_image','addressable_paragraphs']
40 40
 MARKDOWN = {'extensions':
41 41
 	['markdown.extensions.codehilite',
42 42
 	'markdown.extensions.extra',

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

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

+ 48
- 0
plugins/addressable_paragraphs/addressable_paragraphs.py View File

@@ -0,0 +1,48 @@
1
+"""
2
+Addressable Paragraphs
3
+------------------------
4
+In converting from .md to .html, images are wrapped in <p> tags.
5
+This plugin gives those paragraphs the 'img' class for styling enhancements.
6
+In case there is any description immediately following that image, it is wrapped in another paragraph with the 'caption' class.
7
+
8
+Copyright (C) 2018  Roel Roscam Abbing
9
+
10
+This program is free software: you can redistribute it and/or modify
11
+it under the terms of the GNU General Public License as published by
12
+the Free Software Foundation, either version 3 of the License, or
13
+(at your option) any later version.
14
+
15
+This program is distributed in the hope that it will be useful,
16
+but WITHOUT ANY WARRANTY; without even the implied warranty of
17
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
+GNU General Public License for more details.
19
+
20
+You should have received a copy of the GNU General Public License
21
+along with this program.  If not, see <https://www.gnu.org/licenses/>.
22
+"""
23
+
24
+from __future__ import unicode_literals
25
+from pelican import signals
26
+from bs4 import BeautifulSoup
27
+
28
+def content_object_init(instance):
29
+
30
+    if instance._content is not None:
31
+        content = instance._content
32
+        soup = BeautifulSoup(content, 'html.parser')
33
+
34
+        for p in soup(['p', 'object']):
35
+                if p.findChild('img'):
36
+                    p.attrs['class'] = 'img'
37
+                    caption = soup.new_tag('p',**{'class':'caption'})
38
+                    if len(p.contents) > 1: #if we have more than just the <img> tag
39
+                        for i in reversed(p.contents):
40
+                            if i.name != 'img': #if it is not an <img> tag
41
+                                caption.insert(0,i.extract())
42
+                        p.insert_after(caption)
43
+
44
+        instance._content = soup.decode()
45
+
46
+
47
+def register():
48
+    signals.content_object_init.connect(content_object_init)

+ 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 *

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

@@ -0,0 +1,64 @@
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
+
33
+    # default reStructuredText reader
34
+    if not toc and readers.RstReader.enabled and extension in readers.RstReader.file_extensions:
35
+        toc = soup.find('div', class_='contents topic')
36
+        if toc:
37
+            toc.extract()
38
+            tag = BeautifulSoup(str(toc), 'html.parser')
39
+            tag.div['class'] = 'toc'
40
+            tag.div['id'] = ''
41
+            p = tag.find('p', class_='topic-title first')
42
+            if p:
43
+                p.extract()
44
+            toc = tag
45
+
46
+    # Pandoc reader (markdown and other formats)
47
+    if 'pandoc_reader' in content.settings['PLUGINS']:
48
+        try:
49
+            from pandoc_reader import PandocReader
50
+        except ImportError:
51
+            PandocReader = False
52
+        if not toc and PandocReader and PandocReader.enabled and extension in PandocReader.file_extensions:
53
+            toc = soup.find('nav', id='TOC')
54
+
55
+    if toc:
56
+        toc.extract()
57
+        content._content = soup.decode()
58
+        content.toc = toc.decode()
59
+        if content.toc.startswith('<html>'):
60
+            content.toc = content.toc[12:-14]
61
+
62
+
63
+def register():
64
+    signals.content_object_init.connect(extract_toc)

+ 49
- 0
plugins/representative_image/Readme.md View File

@@ -0,0 +1,49 @@
1
+# Summary
2
+
3
+This plugin extracts a representative image (i.e, featured image) from the article's summary or content if not specified in the metadata. 
4
+
5
+The plugin also removes any images from the summary after extraction to avoid duplication. 
6
+
7
+It allows the flexibility on where and how to display the featured image of an article together with its summary in a template page. For example, the article metadata can be displayed in thumbnail format, in which there is a short summary and an image. The layout of the summary and the image can be varied for aesthetical purpose. It doesn't have to depend on article's content format. 
8
+
9
+## Installation
10
+
11
+This plugin requires BeautifulSoup:
12
+
13
+```bash
14
+pip install beautifulsoup4
15
+```
16
+
17
+To enable, add the following to your settings.py:
18
+
19
+```python
20
+PLUGIN_PATH = 'path/to/pelican-plugins'
21
+PLUGINS = ["representative_image"]
22
+```
23
+
24
+`PLUGIN_PATH` can be a path relative to your settings file or an absolute path.
25
+
26
+## Usage
27
+
28
+To override the default behavior of selecting the first image in the article's summary or content, set the image property the article's metadata to the URL of the image to display, e.g:
29
+
30
+```markdown
31
+Title: My super title
32
+Date: 2010-12-03 10:20
33
+Category: Python
34
+Tags: pelican, publishing
35
+Slug: my-super-post
36
+Author: Alexis Metaireau
37
+Summary: Short version for index and feeds
38
+Image: /images/my-super-image.png
39
+
40
+Article content...
41
+```
42
+
43
+To include a representative image in a page add the following to the template:
44
+
45
+```html
46
+{% if  article.featured_image %}
47
+    <img src="{{ article.featured_image }}">
48
+{% endif %}
49
+```

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

@@ -0,0 +1 @@
1
+from .representative_image import *  # noqa

+ 58
- 0
plugins/representative_image/representative_image.py View File

@@ -0,0 +1,58 @@
1
+import six
2
+from bs4 import BeautifulSoup
3
+
4
+from pelican import signals
5
+from pelican.contents import Article, Page
6
+from pelican.generators import ArticlesGenerator
7
+
8
+
9
+def images_extraction(instance):
10
+    representativeImage = None
11
+    if type(instance) in (Article, Page):
12
+        if 'image' in instance.metadata:
13
+            representativeImage = instance.metadata['image']
14
+
15
+        # Process Summary:
16
+        # If summary contains images, extract one to be the representativeImage
17
+        # and remove images from summary
18
+        soup = BeautifulSoup(instance.summary, 'html.parser')
19
+        images = soup.find_all('img')
20
+        for i in images:
21
+            if not representativeImage:
22
+                representativeImage = i['src']
23
+            i.extract()
24
+        if len(images) > 0:
25
+            # set _summary field which is based on metadata. summary field is
26
+            # only based on article's content and not settable
27
+            instance._summary = six.text_type(soup)
28
+
29
+        # If there are no image in summary, look for it in the content body
30
+        if not representativeImage:
31
+            soup = BeautifulSoup(instance._content, 'html.parser')
32
+            imageTag = soup.find('img')
33
+            if imageTag:
34
+                representativeImage = imageTag['src']
35
+
36
+        # Set the attribute to content instance
37
+        instance.featured_image = representativeImage
38
+        instance.featured_alt = instance.metadata.get('alt', None)
39
+        instance.featured_link = instance.metadata.get('link', None)
40
+        instance.featured_caption = instance.metadata.get('caption', None)
41
+
42
+
43
+def run_plugin(generators):
44
+    for generator in generators:
45
+        if isinstance(generator, ArticlesGenerator):
46
+            for article in generator.articles:
47
+                images_extraction(article)
48
+                for translation in article.translations:
49
+                    images_extraction(translation)
50
+
51
+
52
+def register():
53
+    try:
54
+        signals.all_generators_finalized.connect(run_plugin)
55
+    except AttributeError:
56
+        # NOTE: This results in #314 so shouldn't really be relied on
57
+        # https://github.com/getpelican/pelican-plugins/issues/314
58
+        signals.content_object_init.connect(images_extraction)

+ 61
- 0
plugins/representative_image/test_representative_image.py View File

@@ -0,0 +1,61 @@
1
+#!/bin/sh
2
+import unittest
3
+
4
+import representative_image
5
+from jinja2.utils import generate_lorem_ipsum
6
+from pelican.contents import Article
7
+
8
+# Generate content with image
9
+TEST_CONTENT_IMAGE_URL = 'https://testimage.com/test.jpg'
10
+TEST_CONTENT = str(generate_lorem_ipsum(n=3, html=True)) + '<img src="' + TEST_CONTENT_IMAGE_URL + '"/>'+ str(generate_lorem_ipsum(n=2,html=True))  # noqa
11
+TEST_SUMMARY_IMAGE_URL = 'https://testimage.com/summary.jpg'
12
+TEST_SUMMARY_WITHOUTIMAGE = str(generate_lorem_ipsum(n=1, html=True))
13
+TEST_SUMMARY_WITHIMAGE = TEST_SUMMARY_WITHOUTIMAGE + '<img src="' + TEST_SUMMARY_IMAGE_URL + '"/>'  # noqa
14
+TEST_CUSTOM_IMAGE_URL = 'https://testimage.com/custom.jpg'
15
+
16
+
17
+class TestRepresentativeImage(unittest.TestCase):
18
+
19
+    def setUp(self):
20
+        super(TestRepresentativeImage, self).setUp()
21
+        representative_image.register()
22
+
23
+    def test_extract_image_from_content(self):
24
+        args = {
25
+            'content': TEST_CONTENT,
26
+            'metadata': {
27
+                'summary': TEST_SUMMARY_WITHOUTIMAGE,
28
+            },
29
+        }
30
+
31
+        article = Article(**args)
32
+        self.assertEqual(article.featured_image, TEST_CONTENT_IMAGE_URL)
33
+
34
+    def test_extract_image_from_summary(self):
35
+        args = {
36
+            'content': TEST_CONTENT,
37
+            'metadata': {
38
+                'summary': TEST_SUMMARY_WITHIMAGE,
39
+            },
40
+        }
41
+
42
+        article = Article(**args)
43
+        self.assertEqual(article.featured_image, TEST_SUMMARY_IMAGE_URL)
44
+        self.assertEqual(article.summary, TEST_SUMMARY_WITHOUTIMAGE)
45
+
46
+    def test_extract_image_from_summary_with_custom_image(self):
47
+        args = {
48
+            'content': TEST_CONTENT,
49
+            'metadata': {
50
+                'summary': TEST_SUMMARY_WITHIMAGE,
51
+                'image': TEST_CUSTOM_IMAGE_URL,
52
+            },
53
+        }
54
+
55
+        article = Article(**args)
56
+        self.assertEqual(article.featured_image, TEST_CUSTOM_IMAGE_URL)
57
+        self.assertEqual(article.summary, TEST_SUMMARY_WITHOUTIMAGE)
58
+
59
+
60
+if __name__ == '__main__':
61
+    unittest.main()

+ 56
- 0
plugins/summary/Readme.rst View File

@@ -0,0 +1,56 @@
1
+Summary
2
+-------
3
+
4
+This plugin allows easy, variable length summaries directly embedded into the
5
+body of your articles. It introduces two new settings: ``SUMMARY_BEGIN_MARKER``
6
+and ``SUMMARY_END_MARKER``: strings which can be placed directly into an article
7
+to mark the beginning and end of a summary. When found, the standard
8
+``SUMMARY_MAX_LENGTH`` setting will be ignored. The markers themselves will also
9
+be removed from your articles before they are published. The default values
10
+are ``<!-- PELICAN_BEGIN_SUMMARY -->`` and ``<!-- PELICAN_END_SUMMARY -->``.
11
+For example::
12
+
13
+    Title: My super title
14
+    Date: 2010-12-03 10:20
15
+    Tags: thats, awesome
16
+    Category: yeah
17
+    Slug: my-super-post
18
+    Author: Alexis Metaireau
19
+
20
+    This is the content of my super blog post.
21
+    <!-- PELICAN_END_SUMMARY -->
22
+    and this content occurs after the summary.
23
+
24
+Here, the summary is taken to be the first line of the post. Because no
25
+beginning marker was found, it starts at the top of the body. It is possible
26
+to leave out the end marker instead, in which case the summary will start at the
27
+beginning marker and continue to the end of the body.
28
+
29
+If no beginning or end marker is found, and if ``SUMMARY_USE_FIRST_PARAGRAPH``
30
+is enabled in the settings, the summary will be the first paragraph of the post.
31
+
32
+The plugin also sets a ``has_summary`` attribute on every article. It is True
33
+for articles with an explicitly-defined summary, and False otherwise.  (It is
34
+also False for an article truncated by ``SUMMARY_MAX_LENGTH``.)  Your templates
35
+can use this e.g. to add a link to the full text at the end of the summary.
36
+
37
+reST example
38
+~~~~~~~~~~~~
39
+
40
+Inserting the markers into a reStructuredText document makes use of the
41
+comment directive, because raw HTML is automatically escaped. The reST equivalent of the above Markdown example looks like this::
42
+
43
+    My super title
44
+    ##############
45
+
46
+    :date: 2010-12-03 10:20
47
+    :tags: thats, awesome
48
+    :category: yeah
49
+    :slug: my-super-post
50
+    :author: Alexis Metaireau
51
+
52
+    This is the content of my super blog post.
53
+
54
+    .. PELICAN_END_SUMMARY
55
+
56
+    and this content occurs after the summary.

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

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

+ 111
- 0
plugins/summary/summary.py View File

@@ -0,0 +1,111 @@
1
+"""
2
+Summary
3
+-------
4
+
5
+This plugin allows easy, variable length summaries directly embedded into the
6
+body of your articles.
7
+"""
8
+
9
+from __future__ import unicode_literals
10
+from pelican import signals
11
+from pelican.generators import ArticlesGenerator, StaticGenerator, PagesGenerator
12
+import re
13
+
14
+def initialized(pelican):
15
+    from pelican.settings import DEFAULT_CONFIG
16
+    DEFAULT_CONFIG.setdefault('SUMMARY_BEGIN_MARKER',
17
+                              '<!-- PELICAN_BEGIN_SUMMARY -->')
18
+    DEFAULT_CONFIG.setdefault('SUMMARY_END_MARKER',
19
+                              '<!-- PELICAN_END_SUMMARY -->')
20
+    DEFAULT_CONFIG.setdefault('SUMMARY_USE_FIRST_PARAGRAPH', False)
21
+    if pelican:
22
+        pelican.settings.setdefault('SUMMARY_BEGIN_MARKER',
23
+                                    '<!-- PELICAN_BEGIN_SUMMARY -->')
24
+        pelican.settings.setdefault('SUMMARY_END_MARKER',
25
+                                    '<!-- PELICAN_END_SUMMARY -->')
26
+        pelican.settings.setdefault('SUMMARY_USE_FIRST_PARAGRAPH', False)
27
+
28
+def extract_summary(instance):
29
+    # if summary is already specified, use it
30
+    # if there is no content, there's nothing to do
31
+    if hasattr(instance, '_summary') or 'summary' in instance.metadata:
32
+        instance.has_summary = True
33
+        return
34
+
35
+    if not instance._content:
36
+        instance.has_summary = False
37
+        return
38
+
39
+    begin_marker = instance.settings['SUMMARY_BEGIN_MARKER']
40
+    end_marker   = instance.settings['SUMMARY_END_MARKER']
41
+    use_first_paragraph = instance.settings['SUMMARY_USE_FIRST_PARAGRAPH']
42
+    remove_markers = True
43
+
44
+    content = instance._update_content(instance._content, instance.settings['SITEURL'])
45
+    begin_summary = -1
46
+    end_summary = -1
47
+    if begin_marker:
48
+        begin_summary = content.find(begin_marker)
49
+    if end_marker:
50
+        end_summary = content.find(end_marker)
51
+
52
+    if begin_summary == -1 and end_summary == -1 and use_first_paragraph:
53
+        begin_marker, end_marker = '<p>', '</p>'
54
+        remove_markers = False
55
+        begin_summary = content.find(begin_marker)
56
+        end_summary = content.find(end_marker)
57
+
58
+    if begin_summary == -1 and end_summary == -1:
59
+        instance.has_summary = False
60
+        return
61
+
62
+    # skip over the begin marker, if present
63
+    if begin_summary == -1:
64
+        begin_summary = 0
65
+    else:
66
+        begin_summary = begin_summary + len(begin_marker)
67
+
68
+    if end_summary == -1:
69
+        end_summary = None
70
+
71
+    summary = content[begin_summary:end_summary]
72
+
73
+    if remove_markers:
74
+        # remove the markers from the content
75
+        if begin_summary:
76
+            content = content.replace(begin_marker, '', 1)
77
+        if end_summary:
78
+            content = content.replace(end_marker, '', 1)
79
+
80
+    summary = re.sub(r"<div.*>", "", summary)
81
+    summary = re.sub(r"</div>", "", summary)
82
+
83
+    instance._content = content
84
+    # default_status was added to Pelican Content objects after 3.7.1.
85
+    # Its use here is strictly to decide on how to set the summary.
86
+    # There's probably a better way to do this but I couldn't find it.
87
+    if hasattr(instance, 'default_status'):
88
+        instance.metadata['summary'] = summary
89
+    else:
90
+        instance._summary = summary
91
+    instance.has_summary = True
92
+
93
+
94
+def run_plugin(generators):
95
+    for generator in generators:
96
+        if isinstance(generator, ArticlesGenerator):
97
+            for article in generator.articles:
98
+                extract_summary(article)
99
+        elif isinstance(generator, PagesGenerator):
100
+            for page in generator.pages:
101
+                extract_summary(page)
102
+
103
+
104
+def register():
105
+    signals.initialized.connect(initialized)
106
+    try:
107
+        signals.all_generators_finalized.connect(run_plugin)
108
+    except AttributeError:
109
+        # NOTE: This results in #314 so shouldn't really be relied on
110
+        # https://github.com/getpelican/pelican-plugins/issues/314
111
+        signals.content_object_init.connect(extract_summary)

+ 96
- 0
plugins/summary/test_summary.py View File

@@ -0,0 +1,96 @@
1
+# -*- coding: utf-8 -*-
2
+
3
+import unittest
4
+
5
+from jinja2.utils import generate_lorem_ipsum
6
+
7
+# generate one paragraph, enclosed with <p>
8
+TEST_CONTENT = str(generate_lorem_ipsum(n=1))
9
+TEST_SUMMARY = generate_lorem_ipsum(n=1, html=False)
10
+
11
+
12
+from pelican.contents import Page
13
+import pelican.settings
14
+
15
+import summary
16
+
17
+class TestSummary(unittest.TestCase):
18
+    def setUp(self):
19
+        super(TestSummary, self).setUp()
20
+        pelican.settings.DEFAULT_CONFIG['SUMMARY_MAX_LENGTH'] = None
21
+        pelican.settings.DEFAULT_CONFIG['SUMMARY_USE_FIRST_PARAGRAPH'] = False
22
+
23
+        summary.register()
24
+        summary.initialized(None)
25
+        self.page_kwargs = {
26
+            'content': TEST_CONTENT,
27
+            'context': {
28
+                'localsiteurl': '',
29
+            },
30
+            'metadata': {
31
+                'summary': TEST_SUMMARY,
32
+                'title': 'foo bar',
33
+                'author': 'Blogger',
34
+            },
35
+        }
36
+
37
+    def _copy_page_kwargs(self):
38
+        # make a deep copy of page_kwargs
39
+        page_kwargs = dict([(key, self.page_kwargs[key]) for key in
40
+                            self.page_kwargs])
41
+        for key in page_kwargs:
42
+            if not isinstance(page_kwargs[key], dict):
43
+                break
44
+            page_kwargs[key] = dict([(subkey, page_kwargs[key][subkey])
45
+                                     for subkey in page_kwargs[key]])
46
+
47
+        return page_kwargs
48
+
49
+    def test_end_summary(self):
50
+        page_kwargs = self._copy_page_kwargs()
51
+        del page_kwargs['metadata']['summary']
52
+        page_kwargs['content'] = (
53
+            TEST_SUMMARY + '<!-- PELICAN_END_SUMMARY -->' + TEST_CONTENT)
54
+        page = Page(**page_kwargs)
55
+        summary.extract_summary(page)
56
+        # test both the summary and the marker removal
57
+        self.assertEqual(page.summary, TEST_SUMMARY)
58
+        self.assertEqual(page.content, TEST_SUMMARY + TEST_CONTENT)
59
+
60
+    def test_begin_summary(self):
61
+        page_kwargs = self._copy_page_kwargs()
62
+        del page_kwargs['metadata']['summary']
63
+        page_kwargs['content'] = (
64
+            'FOOBAR<!-- PELICAN_BEGIN_SUMMARY -->' + TEST_CONTENT)
65
+        page = Page(**page_kwargs)
66
+        summary.extract_summary(page)
67
+        # test both the summary and the marker removal
68
+        self.assertEqual(page.summary, TEST_CONTENT)
69
+        self.assertEqual(page.content, 'FOOBAR' + TEST_CONTENT)
70
+
71
+    def test_begin_end_summary(self):
72
+        page_kwargs = self._copy_page_kwargs()
73
+        del page_kwargs['metadata']['summary']
74
+        page_kwargs['content'] = (
75
+                'FOOBAR<!-- PELICAN_BEGIN_SUMMARY -->' + TEST_SUMMARY +
76
+                '<!-- PELICAN_END_SUMMARY -->' + TEST_CONTENT)
77
+        page = Page(**page_kwargs)
78
+        summary.extract_summary(page)
79
+        # test both the summary and the marker removal
80
+        self.assertEqual(page.summary, TEST_SUMMARY)
81
+        self.assertEqual(page.content, 'FOOBAR' + TEST_SUMMARY + TEST_CONTENT)
82
+
83
+    def test_use_first_paragraph(self):
84
+        page_kwargs = self._copy_page_kwargs()
85
+        del page_kwargs['metadata']['summary']
86
+        pelican.settings.DEFAULT_CONFIG['SUMMARY_USE_FIRST_PARAGRAPH'] = True
87
+        page_kwargs['content'] = '<p>' + TEST_SUMMARY + '</p>' + TEST_CONTENT
88
+        page = Page(**page_kwargs)
89
+        summary.extract_summary(page)
90
+        # test both the summary and the marker removal
91
+        self.assertEqual(page.summary, TEST_SUMMARY)
92
+        self.assertEqual(page.content, '<p>' + TEST_SUMMARY + '</p>' + TEST_CONTENT)
93
+
94
+
95
+if __name__ == '__main__':
96
+    unittest.main()

Loading…
Cancel
Save