From 8041475aab2b8efad7d2857027331bd626d26312 Mon Sep 17 00:00:00 2001
From: Agustin Henze Text of the gist:
@@ -50,10 +50,10 @@ Basic Example:
Example with filename:
>>> import markdown
- >>> text = """
+ >>> text = '''
... Text of the gist:
... [:gist: 4747847 zen.py]
- ... """
+ ... '''
>>> html = markdown.markdown(text, [GistExtension()])
>>> print(html)
Text of the gist:
@@ -68,10 +68,10 @@ Example with filename:
Basic Example with hexidecimal id:
>>> import markdown
- >>> text = """
+ >>> text = '''
... Text of the gist:
... [:gist: c4a43d6fdce612284ac0]
- ... """
+ ... '''
>>> html = markdown.markdown(text, [GistExtension()])
>>> print(html)
Text of the gist:
@@ -86,10 +86,10 @@ Basic Example with hexidecimal id:
Example with hexidecimal id filename:
>>> import markdown
- >>> text = """
+ >>> text = '''
... Text of the gist:
... [:gist: c4a43d6fdce612284ac0 cow.txt]
- ... """
+ ... '''
>>> html = markdown.markdown(text, [GistExtension()])
>>> print(html)
Text of the gist:
@@ -104,10 +104,10 @@ Example with hexidecimal id filename:
Example using reStructuredText syntax:
>>> import markdown
- >>> text = """
+ >>> text = '''
... Text of the gist:
... .. gist:: 4747847 zen.py
- ... """
+ ... '''
>>> html = markdown.markdown(text, [GistExtension()])
>>> print(html)
Text of the gist:
@@ -122,10 +122,10 @@ Example using reStructuredText syntax:
Example using hexidecimal ID with reStructuredText syntax:
>>> import markdown
- >>> text = """
+ >>> text = '''
... Text of the gist:
... .. gist:: c4a43d6fdce612284ac0
- ... """
+ ... '''
>>> html = markdown.markdown(text, [GistExtension()])
>>> print(html)
Text of the gist:
@@ -140,10 +140,10 @@ Example using hexidecimal ID with reStructuredText syntax:
Example using hexidecimal ID and filename with reStructuredText syntax:
>>> import markdown
- >>> text = """
+ >>> text = '''
... Text of the gist:
... .. gist:: c4a43d6fdce612284ac0 cow.txt
- ... """
+ ... '''
>>> html = markdown.markdown(text, [GistExtension()])
>>> print(html)
Text of the gist:
@@ -158,38 +158,36 @@ Example using hexidecimal ID and filename with reStructuredText syntax:
Error Case: non-existent Gist ID:
>>> import markdown
- >>> text = """
+ >>> text = '''
... Text of the gist:
... [:gist: 0]
- ... """
+ ... '''
>>> html = markdown.markdown(text, [GistExtension()])
>>> print(html)
Text of the gist:
Text of the gist:
(.*?)', flags=re.M class NikolaPostProcessor(Postprocessor): + + """Nikola-specific post-processing for Markdown.""" + def run(self, text): + """Run the postprocessor.""" output = text # python-markdown's highlighter uses
@@ -52,11 +57,16 @@ class NikolaPostProcessor(Postprocessor):
class NikolaExtension(MarkdownExtension, Extension):
+
+ """Extension for injecting the postprocessor."""
+
def extendMarkdown(self, md, md_globals):
+ """Extend Markdown with the postprocessor."""
pp = NikolaPostProcessor()
md.postprocessors.add('nikola_post_processor', pp, '_end')
md.registerExtension(self)
-def makeExtension(configs=None):
+def makeExtension(configs=None): # pragma: no cover
+ """Make extension."""
return NikolaExtension(configs)
diff --git a/nikola/plugins/compile/markdown/mdx_podcast.plugin b/nikola/plugins/compile/markdown/mdx_podcast.plugin
index dc16044..c92a8a0 100644
--- a/nikola/plugins/compile/markdown/mdx_podcast.plugin
+++ b/nikola/plugins/compile/markdown/mdx_podcast.plugin
@@ -1,9 +1,14 @@
[Core]
-Name = mdx_podcast
-Module = mdx_podcast
+name = mdx_podcast
+module = mdx_podcast
+
+[Nikola]
+compiler = markdown
+plugincategory = CompilerExtension
[Documentation]
-Author = Roberto Alsina
-Version = 0.1
-Website = http://getnikola.com
-Description = Markdown extensions for embedding podcasts and other audio files
+author = Roberto Alsina
+version = 0.1
+website = http://getnikola.com
+description = Markdown extensions for embedding podcasts and other audio files
+
diff --git a/nikola/plugins/compile/markdown/mdx_podcast.py b/nikola/plugins/compile/markdown/mdx_podcast.py
index 670973a..61afdbf 100644
--- a/nikola/plugins/compile/markdown/mdx_podcast.py
+++ b/nikola/plugins/compile/markdown/mdx_podcast.py
@@ -24,21 +24,19 @@
# Inspired by "[Python] reStructuredText GitHub Podcast directive"
# (https://gist.github.com/brianhsu/1407759), public domain by Brian Hsu
-from __future__ import print_function, unicode_literals
-
-
-'''
-Extension to Python Markdown for Embedded Audio
+"""
+Extension to Python Markdown for Embedded Audio.
Basic Example:
>>> import markdown
->>> text = """[podcast]http://archive.org/download/Rebeldes_Stereotipos/rs20120609_1.mp3[/podcast]"""
+>>> text = "[podcast]http://archive.org/download/Rebeldes_Stereotipos/rs20120609_1.mp3[/podcast]"
>>> html = markdown.markdown(text, [PodcastExtension()])
>>> print(html)
-
-'''
+
+"""
+from __future__ import print_function, unicode_literals
from nikola.plugin_categories import MarkdownExtension
try:
from markdown.extensions import Extension
@@ -53,12 +51,15 @@ PODCAST_RE = r'\[podcast\](?P.+)\[/podcast\]'
class PodcastPattern(Pattern):
- """ InlinePattern for footnote markers in a document's body text. """
+
+ """InlinePattern for footnote markers in a document's body text."""
def __init__(self, pattern, configs):
+ """Initialize pattern."""
Pattern.__init__(self, pattern)
def handleMatch(self, m):
+ """Handle pattern matches."""
url = m.group('url').strip()
audio_elem = etree.Element('audio')
audio_elem.set('controls', '')
@@ -69,7 +70,11 @@ class PodcastPattern(Pattern):
class PodcastExtension(MarkdownExtension, Extension):
+
+ """"Podcast extension for Markdown."""
+
def __init__(self, configs={}):
+ """Initialize extension."""
# set extension defaults
self.config = {}
@@ -78,13 +83,15 @@ class PodcastExtension(MarkdownExtension, Extension):
self.setConfig(key, value)
def extendMarkdown(self, md, md_globals):
+ """Extend Markdown."""
podcast_md_pattern = PodcastPattern(PODCAST_RE, self.getConfigs())
podcast_md_pattern.md = md
md.inlinePatterns.add('podcast', podcast_md_pattern, "`_.
@@ -236,8 +238,8 @@ def rst2html(source, source_path=None, source_class=docutils.io.StringInput,
writer_name='html', settings=None, settings_spec=None,
settings_overrides=None, config_section=None,
enable_exit_status=None, logger=None, l_add_ln=0, transforms=None):
- """
- Set up & run a `Publisher`, and return a dictionary of document parts.
+ """Set up & run a ``Publisher``, and return a dictionary of document parts.
+
Dictionary keys are the names of parts, and values are Unicode strings;
encoding is up to the client. For programmatic use with string I/O.
diff --git a/nikola/plugins/compile/rest/chart.plugin b/nikola/plugins/compile/rest/chart.plugin
index 3e27a25..438abe4 100644
--- a/nikola/plugins/compile/rest/chart.plugin
+++ b/nikola/plugins/compile/rest/chart.plugin
@@ -1,10 +1,14 @@
[Core]
-Name = rest_chart
-Module = chart
+name = rest_chart
+module = chart
+
+[Nikola]
+compiler = rest
+plugincategory = CompilerExtension
[Documentation]
-Author = Roberto Alsina
-Version = 0.1
-Website = http://getnikola.com
-Description = Chart directive based in PyGal
+author = Roberto Alsina
+version = 0.1
+website = http://getnikola.com
+description = Chart directive based in PyGal
diff --git a/nikola/plugins/compile/rest/chart.py b/nikola/plugins/compile/rest/chart.py
index 59b9dc7..88fdff3 100644
--- a/nikola/plugins/compile/rest/chart.py
+++ b/nikola/plugins/compile/rest/chart.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Chart directive for reSTructuredText."""
+
from ast import literal_eval
from docutils import nodes
@@ -42,9 +44,12 @@ _site = None
class Plugin(RestExtension):
+ """Plugin for chart role."""
+
name = "rest_chart"
def set_site(self, site):
+ """Set Nikola site."""
global _site
_site = self.site = site
directives.register_directive('chart', Chart)
@@ -52,17 +57,18 @@ class Plugin(RestExtension):
class Chart(Directive):
- """ Restructured text extension for inserting charts as SVG
- Usage:
- .. chart:: Bar
- :title: 'Browser usage evolution (in %)'
- :x_labels: ["2002", "2003", "2004", "2005", "2006", "2007"]
+ """reStructuredText extension for inserting charts as SVG.
+
+ Usage:
+ .. chart:: Bar
+ :title: 'Browser usage evolution (in %)'
+ :x_labels: ["2002", "2003", "2004", "2005", "2006", "2007"]
- 'Firefox', [None, None, 0, 16.6, 25, 31]
- 'Chrome', [None, None, None, None, None, None]
- 'IE', [85.8, 84.6, 84.7, 74.5, 66, 58.6]
- 'Others', [14.2, 15.4, 15.3, 8.9, 9, 10.4]
+ 'Firefox', [None, None, 0, 16.6, 25, 31]
+ 'Chrome', [None, None, None, None, None, None]
+ 'IE', [85.8, 84.6, 84.7, 74.5, 66, 58.6]
+ 'Others', [14.2, 15.4, 15.3, 8.9, 9, 10.4]
"""
has_content = True
@@ -129,6 +135,7 @@ class Chart(Directive):
}
def run(self):
+ """Run the directive."""
if pygal is None:
msg = req_missing(['pygal'], 'use the Chart directive', optional=True)
return [nodes.raw('', '{0}'.format(msg), format='html')]
diff --git a/nikola/plugins/compile/rest/doc.plugin b/nikola/plugins/compile/rest/doc.plugin
index 1984f52..facdd03 100644
--- a/nikola/plugins/compile/rest/doc.plugin
+++ b/nikola/plugins/compile/rest/doc.plugin
@@ -1,10 +1,14 @@
[Core]
-Name = rest_doc
-Module = doc
+name = rest_doc
+module = doc
+
+[Nikola]
+compiler = rest
+plugincategory = CompilerExtension
[Documentation]
-Author = Manuel Kaufmann
-Version = 0.1
-Website = http://getnikola.com
-Description = Role to link another page / post from the blog
+author = Manuel Kaufmann
+version = 0.1
+website = http://getnikola.com
+description = Role to link another page / post from the blog
diff --git a/nikola/plugins/compile/rest/doc.py b/nikola/plugins/compile/rest/doc.py
index 703c234..99cce81 100644
--- a/nikola/plugins/compile/rest/doc.py
+++ b/nikola/plugins/compile/rest/doc.py
@@ -24,6 +24,7 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""reST role for linking to other documents."""
from docutils import nodes
from docutils.parsers.rst import roles
@@ -34,9 +35,12 @@ from nikola.plugin_categories import RestExtension
class Plugin(RestExtension):
+ """Plugin for doc role."""
+
name = 'rest_doc'
def set_site(self, site):
+ """Set Nikola site."""
self.site = site
roles.register_canonical_role('doc', doc_role)
doc_role.site = site
@@ -45,7 +49,7 @@ class Plugin(RestExtension):
def doc_role(name, rawtext, text, lineno, inliner,
options={}, content=[]):
-
+ """Handle the doc role."""
# split link's text and post's slug in role content
has_explicit_title, title, slug = split_explicit_title(text)
# check if the slug given is part of our blog posts/pages
@@ -82,5 +86,6 @@ def doc_role(name, rawtext, text, lineno, inliner,
def make_link_node(rawtext, text, url, options):
+ """Make a reST link node."""
node = nodes.reference(rawtext, text, refuri=url, *options)
return node
diff --git a/nikola/plugins/compile/rest/gist.plugin b/nikola/plugins/compile/rest/gist.plugin
index 8f498ec..9fa2e82 100644
--- a/nikola/plugins/compile/rest/gist.plugin
+++ b/nikola/plugins/compile/rest/gist.plugin
@@ -1,10 +1,14 @@
[Core]
-Name = rest_gist
-Module = gist
+name = rest_gist
+module = gist
+
+[Nikola]
+compiler = rest
+plugincategory = CompilerExtension
[Documentation]
-Author = Roberto Alsina
-Version = 0.1
-Website = http://getnikola.com
-Description = Gist directive
+author = Roberto Alsina
+version = 0.1
+website = http://getnikola.com
+description = Gist directive
diff --git a/nikola/plugins/compile/rest/gist.py b/nikola/plugins/compile/rest/gist.py
index ab4d56d..736ee37 100644
--- a/nikola/plugins/compile/rest/gist.py
+++ b/nikola/plugins/compile/rest/gist.py
@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-
# This file is public domain according to its author, Brian Hsu
+"""Gist directive for reStructuredText."""
+
import requests
from docutils.parsers.rst import Directive, directives
from docutils import nodes
@@ -10,26 +12,28 @@ from nikola.plugin_categories import RestExtension
class Plugin(RestExtension):
+ """Plugin for gist directive."""
+
name = "rest_gist"
def set_site(self, site):
+ """Set Nikola site."""
self.site = site
directives.register_directive('gist', GitHubGist)
return super(Plugin, self).set_site(site)
class GitHubGist(Directive):
- """ Embed GitHub Gist.
-
- Usage:
- .. gist:: GIST_ID
+ """Embed GitHub Gist.
- or
+ Usage:
- .. gist:: GIST_URL
+ .. gist:: GIST_ID
+ or
+ .. gist:: GIST_URL
"""
required_arguments = 1
@@ -39,10 +43,12 @@ class GitHubGist(Directive):
has_content = False
def get_raw_gist_with_filename(self, gistID, filename):
+ """Get raw gist text for a filename."""
url = '/'.join(("https://gist.github.com/raw", gistID, filename))
return requests.get(url).text
def get_raw_gist(self, gistID):
+ """Get raw gist text."""
url = "https://gist.github.com/raw/{0}".format(gistID)
try:
return requests.get(url).text
@@ -50,6 +56,7 @@ class GitHubGist(Directive):
raise self.error('Cannot get gist for url={0}'.format(url))
def run(self):
+ """Run the gist directive."""
if 'https://' in self.arguments[0]:
gistID = self.arguments[0].split('/')[-1].strip()
else:
diff --git a/nikola/plugins/compile/rest/listing.plugin b/nikola/plugins/compile/rest/listing.plugin
index 4c9883e..85c780f 100644
--- a/nikola/plugins/compile/rest/listing.plugin
+++ b/nikola/plugins/compile/rest/listing.plugin
@@ -1,10 +1,14 @@
[Core]
-Name = rest_listing
-Module = listing
+name = rest_listing
+module = listing
+
+[Nikola]
+compiler = rest
+plugincategory = CompilerExtension
[Documentation]
-Author = Roberto Alsina
-Version = 0.1
-Website = http://getnikola.com
-Description = Extension for source listings
+author = Roberto Alsina
+version = 0.1
+website = http://getnikola.com
+description = Extension for source listings
diff --git a/nikola/plugins/compile/rest/listing.py b/nikola/plugins/compile/rest/listing.py
index b8340cf..4871bf3 100644
--- a/nikola/plugins/compile/rest/listing.py
+++ b/nikola/plugins/compile/rest/listing.py
@@ -25,7 +25,7 @@
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-""" Define and register a listing directive using the existing CodeBlock """
+"""Define and register a listing directive using the existing CodeBlock."""
from __future__ import unicode_literals
@@ -55,7 +55,9 @@ from nikola.plugin_categories import RestExtension
# A sanitized version of docutils.parsers.rst.directives.body.CodeBlock.
class CodeBlock(Directive):
+
"""Parse and mark up content of a code block."""
+
optional_arguments = 1
option_spec = {'class': directives.class_option,
'name': directives.unchanged,
@@ -65,6 +67,7 @@ class CodeBlock(Directive):
has_content = True
def run(self):
+ """Run code block directive."""
self.assert_has_content()
if 'linenos' in self.options:
@@ -124,9 +127,12 @@ docutils.parsers.rst.directives.misc.CodeBlock = CodeBlock
class Plugin(RestExtension):
+ """Plugin for listing directive."""
+
name = "rest_listing"
def set_site(self, site):
+ """Set Nikola site."""
self.site = site
# Even though listings don't use CodeBlock anymore, I am
# leaving these to make the code directive work with
@@ -146,7 +152,8 @@ listing_spec['linenos'] = directives.unchanged
class Listing(Include):
- """ listing directive: create a highlighted block of code from a file in listings/
+
+ """Create a highlighted block of code from a file in listings/.
Usage:
@@ -154,12 +161,14 @@ class Listing(Include):
:number-lines:
"""
+
has_content = False
required_arguments = 1
optional_arguments = 1
option_spec = listing_spec
def run(self):
+ """Run listing directive."""
_fname = self.arguments.pop(0)
fname = _fname.replace('/', os.sep)
lang = self.arguments.pop(0)
@@ -185,9 +194,9 @@ class Listing(Include):
return generated_nodes
def get_code_from_file(self, data):
- """ Create CodeBlock nodes from file object content """
+ """Create CodeBlock nodes from file object content."""
return super(Listing, self).run()
def assert_has_content(self):
- """ Listing has no content, override check from superclass """
+ """Listing has no content, override check from superclass."""
pass
diff --git a/nikola/plugins/compile/rest/media.plugin b/nikola/plugins/compile/rest/media.plugin
index 5f5276b..9803c8f 100644
--- a/nikola/plugins/compile/rest/media.plugin
+++ b/nikola/plugins/compile/rest/media.plugin
@@ -1,10 +1,14 @@
[Core]
-Name = rest_media
-Module = media
+name = rest_media
+module = media
+
+[Nikola]
+compiler = rest
+plugincategory = CompilerExtension
[Documentation]
-Author = Roberto Alsina
-Version = 0.1
-Website = http://getnikola.com
-Description = Directive to support oembed via micawber
+author = Roberto Alsina
+version = 0.1
+website = http://getnikola.com
+description = Directive to support oembed via micawber
diff --git a/nikola/plugins/compile/rest/media.py b/nikola/plugins/compile/rest/media.py
index 0363d28..345e331 100644
--- a/nikola/plugins/compile/rest/media.py
+++ b/nikola/plugins/compile/rest/media.py
@@ -24,6 +24,7 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Media directive for reStructuredText."""
from docutils import nodes
from docutils.parsers.rst import Directive, directives
@@ -40,21 +41,27 @@ from nikola.utils import req_missing
class Plugin(RestExtension):
+ """Plugin for reST media directive."""
+
name = "rest_media"
def set_site(self, site):
+ """Set Nikola site."""
self.site = site
directives.register_directive('media', Media)
return super(Plugin, self).set_site(site)
class Media(Directive):
- """ Restructured text extension for inserting any sort of media using micawber."""
+
+ """reST extension for inserting any sort of media using micawber."""
+
has_content = False
required_arguments = 1
optional_arguments = 999
def run(self):
+ """Run media directive."""
if micawber is None:
msg = req_missing(['micawber'], 'use the media directive', optional=True)
return [nodes.raw('', '{0}'.format(msg), format='html')]
diff --git a/nikola/plugins/compile/rest/post_list.plugin b/nikola/plugins/compile/rest/post_list.plugin
index 82450a0..48969bf 100644
--- a/nikola/plugins/compile/rest/post_list.plugin
+++ b/nikola/plugins/compile/rest/post_list.plugin
@@ -1,9 +1,14 @@
[Core]
-Name = rest_post_list
-Module = post_list
+name = rest_post_list
+module = post_list
+
+[Nikola]
+compiler = rest
+plugincategory = CompilerExtension
[Documentation]
-Author = Udo Spallek
-Version = 0.1
-Website = http://getnikola.com
-Description = Includes a list of posts with tag and slide based filters.
+author = Udo Spallek
+version = 0.1
+website = http://getnikola.com
+description = Includes a list of posts with tag and slide based filters.
+
diff --git a/nikola/plugins/compile/rest/post_list.py b/nikola/plugins/compile/rest/post_list.py
index ddbd82d..a22ee85 100644
--- a/nikola/plugins/compile/rest/post_list.py
+++ b/nikola/plugins/compile/rest/post_list.py
@@ -23,6 +23,9 @@
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+"""Post list directive for reStructuredText."""
+
from __future__ import unicode_literals
import os
@@ -40,9 +43,13 @@ from nikola.plugin_categories import RestExtension
class Plugin(RestExtension):
+
+ """Plugin for reST post-list directive."""
+
name = "rest_post_list"
def set_site(self, site):
+ """Set Nikola site."""
self.site = site
directives.register_directive('post-list', PostList)
PostList.site = site
@@ -50,14 +57,15 @@ class Plugin(RestExtension):
class PostList(Directive):
- """
+
+ """Provide a reStructuredText directive to create a list of posts.
+
Post List
=========
:Directive Arguments: None.
- :Directive Options: lang, start, stop, reverse, sort, tags, template, id
+ :Directive Options: lang, start, stop, reverse, sort, tags, categories, slugs, all, template, id
:Directive Content: None.
- Provides a reStructuredText directive to create a list of posts.
The posts appearing in the list can be filtered by options.
*List slicing* is provided with the *start*, *stop* and *reverse* options.
@@ -87,6 +95,10 @@ class PostList(Directive):
Filter posts to show only posts having at least one of the ``tags``.
Defaults to None.
+ ``categories`` : string [, string...]
+ Filter posts to show only posts having one of the ``categories``.
+ Defaults to None.
+
``slugs`` : string [, string...]
Filter posts to show only posts having at least one of the ``slugs``.
Defaults to None.
@@ -107,12 +119,14 @@ class PostList(Directive):
A manual id for the post list.
Defaults to a random name composed by 'post_list_' + uuid.uuid4().hex.
"""
+
option_spec = {
'start': int,
'stop': int,
'reverse': directives.flag,
'sort': directives.unchanged,
'tags': directives.unchanged,
+ 'categories': directives.unchanged,
'slugs': directives.unchanged,
'all': directives.flag,
'lang': directives.unchanged,
@@ -121,11 +135,14 @@ class PostList(Directive):
}
def run(self):
+ """Run post-list directive."""
start = self.options.get('start')
stop = self.options.get('stop')
reverse = self.options.get('reverse', False)
tags = self.options.get('tags')
tags = [t.strip().lower() for t in tags.split(',')] if tags else []
+ categories = self.options.get('categories')
+ categories = [c.strip().lower() for c in categories.split(',')] if categories else []
slugs = self.options.get('slugs')
slugs = [s.strip() for s in slugs.split(',')] if slugs else []
show_all = self.options.get('all', False)
@@ -145,6 +162,9 @@ class PostList(Directive):
else:
timeline = [p for p in self.site.timeline if p.use_in_feeds]
+ if categories:
+ timeline = [p for p in timeline if p.meta('category', lang=lang).lower() in categories]
+
for post in timeline:
if tags:
cont = True
diff --git a/nikola/plugins/compile/rest/slides.plugin b/nikola/plugins/compile/rest/slides.plugin
index cee4b06..5c05b89 100644
--- a/nikola/plugins/compile/rest/slides.plugin
+++ b/nikola/plugins/compile/rest/slides.plugin
@@ -1,10 +1,14 @@
[Core]
-Name = rest_slides
-Module = slides
+name = rest_slides
+module = slides
+
+[Nikola]
+compiler = rest
+plugincategory = CompilerExtension
[Documentation]
-Author = Roberto Alsina
-Version = 0.1
-Website = http://getnikola.com
-Description = Slides directive
+author = Roberto Alsina
+version = 0.1
+website = http://getnikola.com
+description = Slides directive
diff --git a/nikola/plugins/compile/rest/slides.py b/nikola/plugins/compile/rest/slides.py
index 7826f6a..2522e55 100644
--- a/nikola/plugins/compile/rest/slides.py
+++ b/nikola/plugins/compile/rest/slides.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Slides directive for reStructuredText."""
+
from __future__ import unicode_literals
import uuid
@@ -36,9 +38,12 @@ from nikola.plugin_categories import RestExtension
class Plugin(RestExtension):
+ """Plugin for reST slides directive."""
+
name = "rest_slides"
def set_site(self, site):
+ """Set Nikola site."""
self.site = site
directives.register_directive('slides', Slides)
Slides.site = site
@@ -46,11 +51,14 @@ class Plugin(RestExtension):
class Slides(Directive):
- """ Restructured text extension for inserting slideshows."""
+
+ """reST extension for inserting slideshows."""
+
has_content = True
def run(self):
- if len(self.content) == 0:
+ """Run the slides directive."""
+ if len(self.content) == 0: # pragma: no cover
return
if self.site.invariant: # for testing purposes
diff --git a/nikola/plugins/compile/rest/soundcloud.plugin b/nikola/plugins/compile/rest/soundcloud.plugin
index 1d31a8f..75469e4 100644
--- a/nikola/plugins/compile/rest/soundcloud.plugin
+++ b/nikola/plugins/compile/rest/soundcloud.plugin
@@ -1,10 +1,14 @@
[Core]
-Name = rest_soundcloud
-Module = soundcloud
+name = rest_soundcloud
+module = soundcloud
+
+[Nikola]
+compiler = rest
+plugincategory = CompilerExtension
[Documentation]
-Author = Roberto Alsina
-Version = 0.1
-Website = http://getnikola.com
-Description = Soundcloud directive
+author = Roberto Alsina
+version = 0.1
+website = http://getnikola.com
+description = Soundcloud directive
diff --git a/nikola/plugins/compile/rest/soundcloud.py b/nikola/plugins/compile/rest/soundcloud.py
index a26806c..30134a9 100644
--- a/nikola/plugins/compile/rest/soundcloud.py
+++ b/nikola/plugins/compile/rest/soundcloud.py
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
+"""SoundCloud directive for reStructuredText."""
from docutils import nodes
from docutils.parsers.rst import Directive, directives
@@ -10,9 +11,12 @@ from nikola.plugin_categories import RestExtension
class Plugin(RestExtension):
+ """Plugin for soundclound directive."""
+
name = "rest_soundcloud"
def set_site(self, site):
+ """Set Nikola site."""
self.site = site
directives.register_directive('soundcloud', SoundCloud)
directives.register_directive('soundcloud_playlist', SoundCloudPlaylist)
@@ -27,7 +31,8 @@ src="https://w.soundcloud.com/player/?url=http://api.soundcloud.com/{preslug}/""
class SoundCloud(Directive):
- """ Restructured text extension for inserting SoundCloud embedded music
+
+ """reST extension for inserting SoundCloud embedded music.
Usage:
.. soundcloud::
@@ -35,6 +40,7 @@ class SoundCloud(Directive):
:width: 600
"""
+
has_content = True
required_arguments = 1
option_spec = {
@@ -44,7 +50,7 @@ class SoundCloud(Directive):
preslug = "tracks"
def run(self):
- """ Required by the Directive interface. Create docutils nodes """
+ """Run the soundcloud directive."""
self.check_content()
options = {
'sid': self.arguments[0],
@@ -56,12 +62,15 @@ class SoundCloud(Directive):
return [nodes.raw('', CODE.format(**options), format='html')]
def check_content(self):
- """ Emit a deprecation warning if there is content """
- if self.content:
+ """Emit a deprecation warning if there is content."""
+ if self.content: # pragma: no cover
raise self.warning("This directive does not accept content. The "
"'key=value' format for options is deprecated, "
"use ':key: value' instead")
class SoundCloudPlaylist(SoundCloud):
+
+ """reST directive for SoundCloud playlists."""
+
preslug = "playlists"
diff --git a/nikola/plugins/compile/rest/thumbnail.plugin b/nikola/plugins/compile/rest/thumbnail.plugin
index 3b73340..0084310 100644
--- a/nikola/plugins/compile/rest/thumbnail.plugin
+++ b/nikola/plugins/compile/rest/thumbnail.plugin
@@ -1,9 +1,14 @@
[Core]
-Name = rest_thumbnail
-Module = thumbnail
+name = rest_thumbnail
+module = thumbnail
+
+[Nikola]
+compiler = rest
+plugincategory = CompilerExtension
[Documentation]
-Author = Pelle Nilsson
-Version = 0.1
-Website = http://getnikola.com
-Description = reST directive to facilitate enlargeable images with thumbnails
+author = Pelle Nilsson
+version = 0.1
+website = http://getnikola.com
+description = reST directive to facilitate enlargeable images with thumbnails
+
diff --git a/nikola/plugins/compile/rest/thumbnail.py b/nikola/plugins/compile/rest/thumbnail.py
index 5388d8d..1fae06c 100644
--- a/nikola/plugins/compile/rest/thumbnail.py
+++ b/nikola/plugins/compile/rest/thumbnail.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Thumbnail directive for reStructuredText."""
+
import os
from docutils.parsers.rst import directives
@@ -34,9 +36,12 @@ from nikola.plugin_categories import RestExtension
class Plugin(RestExtension):
+ """Plugin for thumbnail directive."""
+
name = "rest_thumbnail"
def set_site(self, site):
+ """Set Nikola site."""
self.site = site
directives.register_directive('thumbnail', Thumbnail)
return super(Plugin, self).set_site(site)
@@ -44,10 +49,14 @@ class Plugin(RestExtension):
class Thumbnail(Figure):
+ """Thumbnail directive for reST."""
+
def align(argument):
+ """Return thumbnail alignment."""
return directives.choice(argument, Image.align_values)
def figwidth_value(argument):
+ """Return figure width."""
if argument.lower() == 'image':
return 'image'
else:
@@ -59,6 +68,7 @@ class Thumbnail(Figure):
has_content = True
def run(self):
+ """Run the thumbnail directive."""
uri = directives.uri(self.arguments[0])
self.options['target'] = uri
self.arguments[0] = '.thumbnail'.join(os.path.splitext(uri))
diff --git a/nikola/plugins/compile/rest/vimeo.plugin b/nikola/plugins/compile/rest/vimeo.plugin
index e0ff3f1..688f981 100644
--- a/nikola/plugins/compile/rest/vimeo.plugin
+++ b/nikola/plugins/compile/rest/vimeo.plugin
@@ -1,7 +1,11 @@
[Core]
-Name = rest_vimeo
-Module = vimeo
+name = rest_vimeo
+module = vimeo
+
+[Nikola]
+compiler = rest
+plugincategory = CompilerExtension
[Documentation]
-Description = Vimeo directive
+description = Vimeo directive
diff --git a/nikola/plugins/compile/rest/vimeo.py b/nikola/plugins/compile/rest/vimeo.py
index bc44b0e..c694a87 100644
--- a/nikola/plugins/compile/rest/vimeo.py
+++ b/nikola/plugins/compile/rest/vimeo.py
@@ -24,6 +24,7 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Vimeo directive for reStructuredText."""
from docutils import nodes
from docutils.parsers.rst import Directive, directives
@@ -37,9 +38,12 @@ from nikola.plugin_categories import RestExtension
class Plugin(RestExtension):
+ """Plugin for vimeo reST directive."""
+
name = "rest_vimeo"
def set_site(self, site):
+ """Set Nikola site."""
self.site = site
directives.register_directive('vimeo', Vimeo)
return super(Plugin, self).set_site(site)
@@ -56,14 +60,16 @@ VIDEO_DEFAULT_WIDTH = 281
class Vimeo(Directive):
- """ Restructured text extension for inserting vimeo embedded videos
- Usage:
- .. vimeo:: 20241459
- :height: 400
- :width: 600
+ """reST extension for inserting vimeo embedded videos.
+
+ Usage:
+ .. vimeo:: 20241459
+ :height: 400
+ :width: 600
"""
+
has_content = True
required_arguments = 1
option_spec = {
@@ -75,6 +81,7 @@ class Vimeo(Directive):
request_size = True
def run(self):
+ """Run the vimeo directive."""
self.check_content()
options = {
'vimeo_id': self.arguments[0],
@@ -90,9 +97,11 @@ class Vimeo(Directive):
return [nodes.raw('', CODE.format(**options), format='html')]
def check_modules(self):
+ """Check modules."""
return None
def set_video_size(self):
+ """Set video size."""
# Only need to make a connection if width and height aren't provided
if 'height' not in self.options or 'width' not in self.options:
self.options['height'] = VIDEO_DEFAULT_HEIGHT
@@ -111,6 +120,7 @@ class Vimeo(Directive):
pass
def check_content(self):
+ """Check if content exists."""
if self.content:
raise self.warning("This directive does not accept content. The "
"'key=value' format for options is deprecated, "
diff --git a/nikola/plugins/compile/rest/youtube.plugin b/nikola/plugins/compile/rest/youtube.plugin
index 01275be..5fbd67b 100644
--- a/nikola/plugins/compile/rest/youtube.plugin
+++ b/nikola/plugins/compile/rest/youtube.plugin
@@ -1,8 +1,12 @@
[Core]
-Name = rest_youtube
-Module = youtube
+name = rest_youtube
+module = youtube
+
+[Nikola]
+compiler = rest
+plugincategory = CompilerExtension
[Documentation]
-Version = 0.1
-Description = Youtube directive
+version = 0.1
+description = Youtube directive
diff --git a/nikola/plugins/compile/rest/youtube.py b/nikola/plugins/compile/rest/youtube.py
index 7c6bba1..6c5c211 100644
--- a/nikola/plugins/compile/rest/youtube.py
+++ b/nikola/plugins/compile/rest/youtube.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""YouTube directive for reStructuredText."""
+
from docutils import nodes
from docutils.parsers.rst import Directive, directives
@@ -33,9 +35,12 @@ from nikola.plugin_categories import RestExtension
class Plugin(RestExtension):
+ """Plugin for the youtube directive."""
+
name = "rest_youtube"
def set_site(self, site):
+ """Set Nikola site."""
self.site = site
directives.register_directive('youtube', Youtube)
return super(Plugin, self).set_site(site)
@@ -49,7 +54,8 @@ src="//www.youtube.com/embed/{yid}?rel=0&hd=1&wmode=transparent"
class Youtube(Directive):
- """ Restructured text extension for inserting youtube embedded videos
+
+ """reST extension for inserting youtube embedded videos.
Usage:
.. youtube:: lyViVmaBQDg
@@ -57,6 +63,7 @@ class Youtube(Directive):
:width: 600
"""
+
has_content = True
required_arguments = 1
option_spec = {
@@ -65,6 +72,7 @@ class Youtube(Directive):
}
def run(self):
+ """Run the youtube directive."""
self.check_content()
options = {
'yid': self.arguments[0],
@@ -75,7 +83,8 @@ class Youtube(Directive):
return [nodes.raw('', CODE.format(**options), format='html')]
def check_content(self):
- if self.content:
+ """Check if content exists."""
+ if self.content: # pragma: no cover
raise self.warning("This directive does not accept content. The "
"'key=value' format for options is deprecated, "
"use ':key: value' instead")
diff --git a/nikola/plugins/loghandler/__init__.py b/nikola/plugins/loghandler/__init__.py
deleted file mode 100644
index a1d17a6..0000000
--- a/nikola/plugins/loghandler/__init__.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright © 2012-2015 Roberto Alsina and others.
-
-# Permission is hereby granted, free of charge, to any
-# person obtaining a copy of this software and associated
-# documentation files (the "Software"), to deal in the
-# Software without restriction, including without limitation
-# the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the
-# Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice
-# shall be included in all copies or substantial portions of
-# the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
-# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
-# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
-# PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
-# OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
-# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/nikola/plugins/loghandler/smtp.plugin b/nikola/plugins/loghandler/smtp.plugin
deleted file mode 100644
index 38c1d96..0000000
--- a/nikola/plugins/loghandler/smtp.plugin
+++ /dev/null
@@ -1,9 +0,0 @@
-[Core]
-Name = smtp
-Module = smtp
-
-[Documentation]
-Author = Daniel Devine
-Version = 1.0
-Website = http://getnikola.com
-Description = Log over smtp (email).
diff --git a/nikola/plugins/loghandler/smtp.py b/nikola/plugins/loghandler/smtp.py
deleted file mode 100644
index 146a658..0000000
--- a/nikola/plugins/loghandler/smtp.py
+++ /dev/null
@@ -1,54 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright © 2012-2015 Daniel Devine and others.
-
-# Permission is hereby granted, free of charge, to any
-# person obtaining a copy of this software and associated
-# documentation files (the "Software"), to deal in the
-# Software without restriction, including without limitation
-# the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the
-# Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice
-# shall be included in all copies or substantial portions of
-# the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
-# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
-# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
-# PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
-# OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
-# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-from nikola.plugin_categories import SignalHandler
-from blinker import signal
-import logbook
-
-
-class SmtpHandler(SignalHandler):
- name = 'smtp'
-
- def attach_handler(self, sender):
- """Add the handler to a list of handlers that are attached when get_logger() is called.."""
- smtpconf = self.site.config.get('LOGGING_HANDLERS').get('smtp')
- if smtpconf:
- smtpconf['format_string'] = '''\
-Subject: {record.level_name}: {record.channel}
-
-{record.message}
-'''
- self.site.loghandlers.append(logbook.MailHandler(
- smtpconf.pop('from_addr'),
- smtpconf.pop('recipients'),
- **smtpconf
- ))
-
- def set_site(self, site):
- self.site = site
-
- ready = signal('sighandlers_loaded')
- ready.connect(self.attach_handler)
diff --git a/nikola/plugins/loghandler/stderr.plugin b/nikola/plugins/loghandler/stderr.plugin
deleted file mode 100644
index 6c20ea1..0000000
--- a/nikola/plugins/loghandler/stderr.plugin
+++ /dev/null
@@ -1,9 +0,0 @@
-[Core]
-Name = stderr
-Module = stderr
-
-[Documentation]
-Author = Daniel Devine
-Version = 1.0
-Website = http://getnikola.com
-Description = Log to stderr, the default logger.
diff --git a/nikola/plugins/loghandler/stderr.py b/nikola/plugins/loghandler/stderr.py
deleted file mode 100644
index 79ace68..0000000
--- a/nikola/plugins/loghandler/stderr.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright © 2012-2015 Daniel Devine and others.
-
-# Permission is hereby granted, free of charge, to any
-# person obtaining a copy of this software and associated
-# documentation files (the "Software"), to deal in the
-# Software without restriction, including without limitation
-# the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the
-# Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice
-# shall be included in all copies or substantial portions of
-# the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
-# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
-# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
-# PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
-# OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
-# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-from nikola.plugin_categories import SignalHandler
-from blinker import signal
-import os
-
-from nikola import DEBUG
-from nikola.utils import ColorfulStderrHandler
-
-
-class StderrHandler(SignalHandler):
- """Logs messages to stderr."""
- name = 'stderr'
-
- def attach_handler(self, sender):
- """Attach the handler to the logger."""
- conf = self.site.config.get('LOGGING_HANDLERS').get('stderr')
- if conf or os.getenv('NIKOLA_DEBUG'):
- self.site.loghandlers.append(ColorfulStderrHandler(
- # We do not allow the level to be something else than 'DEBUG'
- # or 'INFO' Any other level can have bad effects on the user
- # experience and is discouraged.
- # (oh, and it was incorrectly set to WARNING before)
- level='DEBUG' if DEBUG or (conf.get('loglevel', 'INFO').upper() == 'DEBUG') else 'INFO',
- format_string=u'[{record.time:%Y-%m-%dT%H:%M:%SZ}] {record.level_name}: {record.channel}: {record.message}'
- ))
-
- def set_site(self, site):
- self.site = site
-
- ready = signal('sighandlers_loaded')
- ready.connect(self.attach_handler)
diff --git a/nikola/plugins/misc/__init__.py b/nikola/plugins/misc/__init__.py
new file mode 100644
index 0000000..c0d8961
--- /dev/null
+++ b/nikola/plugins/misc/__init__.py
@@ -0,0 +1,27 @@
+# -*- coding: utf-8 -*-
+
+# Copyright © 2012-2015 Roberto Alsina and others.
+
+# Permission is hereby granted, free of charge, to any
+# person obtaining a copy of this software and associated
+# documentation files (the "Software"), to deal in the
+# Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the
+# Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice
+# shall be included in all copies or substantial portions of
+# the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
+# OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+"""Miscellaneous Nikola plugins."""
diff --git a/nikola/plugins/misc/scan_posts.py b/nikola/plugins/misc/scan_posts.py
index a6f04e6..1f4f995 100644
--- a/nikola/plugins/misc/scan_posts.py
+++ b/nikola/plugins/misc/scan_posts.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""The default post scanner."""
+
from __future__ import unicode_literals, print_function
import glob
import os
@@ -35,13 +37,13 @@ from nikola.post import Post
class ScanPosts(PostScanner):
- """Render pages into output."""
+
+ """Scan posts in the site."""
name = "scan_posts"
def scan(self):
"""Create list of posts from POSTS and PAGES options."""
-
seen = set([])
if not self.site.quiet:
print("Scanning posts", end='', file=sys.stderr)
diff --git a/nikola/plugins/task/__init__.py b/nikola/plugins/task/__init__.py
index a1d17a6..fd9a48f 100644
--- a/nikola/plugins/task/__init__.py
+++ b/nikola/plugins/task/__init__.py
@@ -23,3 +23,5 @@
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+"""Tasks for Nikola."""
diff --git a/nikola/plugins/task/archive.plugin b/nikola/plugins/task/archive.plugin
index 6687209..25f1195 100644
--- a/nikola/plugins/task/archive.plugin
+++ b/nikola/plugins/task/archive.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = render_archive
-Module = archive
+name = render_archive
+module = archive
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Generates the blog's archive pages.
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Generates the blog's archive pages.
+
+[Nikola]
+plugincategory = Task
diff --git a/nikola/plugins/task/archive.py b/nikola/plugins/task/archive.py
index 533be69..126aed4 100644
--- a/nikola/plugins/task/archive.py
+++ b/nikola/plugins/task/archive.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Render the post archives."""
+
import copy
import os
@@ -35,17 +37,20 @@ from nikola.utils import config_changed, adjust_name_for_index_path, adjust_name
class Archive(Task):
+
"""Render the post archives."""
name = "render_archive"
def set_site(self, site):
+ """Set Nikola site."""
site.register_path_handler('archive', self.archive_path)
site.register_path_handler('archive_atom', self.archive_atom_path)
return super(Archive, self).set_site(site)
def _prepare_task(self, kw, name, lang, posts, items, template_name,
title, deps_translatable=None):
+ """Prepare an archive task."""
# name: used to build permalink and destination
# posts, items: posts or items; only one of them should be used,
# the other be None
@@ -53,17 +58,20 @@ class Archive(Task):
# title: the (translated) title for the generated page
# deps_translatable: dependencies (None if not added)
assert posts is not None or items is not None
-
+ task_cfg = [copy.copy(kw)]
context = {}
context["lang"] = lang
context["title"] = title
context["permalink"] = self.site.link("archive", name, lang)
+ context["pagekind"] = ["list", "archive_page"]
if posts is not None:
context["posts"] = posts
- n = len(posts)
+ # Depend on all post metadata because it can be used in templates (Issue #1931)
+ task_cfg.append([repr(p) for p in posts])
else:
+ # Depend on the content of items, to rebuild if links change (Issue #1931)
context["items"] = items
- n = len(items)
+ task_cfg.append(items)
task = self.site.generic_post_list_renderer(
lang,
[],
@@ -73,7 +81,7 @@ class Archive(Task):
context,
)
- task_cfg = {1: copy.copy(kw), 2: n}
+ task_cfg = {i: x for i, x in enumerate(task_cfg)}
if deps_translatable is not None:
task_cfg[3] = deps_translatable
task['uptodate'] = task['uptodate'] + [config_changed(task_cfg, 'nikola.plugins.task.archive')]
@@ -81,6 +89,7 @@ class Archive(Task):
return task
def _generate_posts_task(self, kw, name, lang, posts, title, deps_translatable=None):
+ """Genereate a task for an archive with posts."""
posts = sorted(posts, key=lambda a: a.date)
posts.reverse()
if kw['archives_are_indexes']:
@@ -97,13 +106,15 @@ class Archive(Task):
uptodate = []
if deps_translatable is not None:
uptodate += [config_changed(deps_translatable, 'nikola.plugins.task.archive')]
+ context = {"archive_name": name,
+ "is_feed_stale": kw["is_feed_stale"],
+ "pagekind": ["index", "archive_page"]}
yield self.site.generic_index_renderer(
lang,
posts,
title,
"archiveindex.tmpl",
- {"archive_name": name,
- "is_feed_stale": kw["is_feed_stale"]},
+ context,
kw,
str(self.name),
page_link,
@@ -113,6 +124,7 @@ class Archive(Task):
yield self._prepare_task(kw, name, lang, posts, None, "list_post.tmpl", title, deps_translatable)
def gen_tasks(self):
+ """Generate archive tasks."""
kw = {
"messages": self.site.MESSAGES,
"translations": self.site.config['TRANSLATIONS'],
@@ -211,6 +223,7 @@ class Archive(Task):
yield self._prepare_task(kw, None, lang, None, items, "list.tmpl", kw["messages"][lang]["Archive"])
def archive_path(self, name, lang, is_feed=False):
+ """Return archive paths."""
if is_feed:
extension = ".atom"
archive_file = os.path.splitext(self.site.config['ARCHIVE_FILENAME'])[0] + extension
@@ -228,4 +241,5 @@ class Archive(Task):
archive_file] if _f]
def archive_atom_path(self, name, lang):
+ """Return Atom archive paths."""
return self.archive_path(name, lang, is_feed=True)
diff --git a/nikola/plugins/task/bundles.plugin b/nikola/plugins/task/bundles.plugin
index 3fe049b..ca997d0 100644
--- a/nikola/plugins/task/bundles.plugin
+++ b/nikola/plugins/task/bundles.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = create_bundles
-Module = bundles
+name = create_bundles
+module = bundles
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Theme bundles using WebAssets
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Theme bundles using WebAssets
+
+[Nikola]
+plugincategory = Task
diff --git a/nikola/plugins/task/bundles.py b/nikola/plugins/task/bundles.py
index 6f88d0c..b9c57b9 100644
--- a/nikola/plugins/task/bundles.py
+++ b/nikola/plugins/task/bundles.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Bundle assets using WebAssets."""
+
from __future__ import unicode_literals
import os
@@ -38,12 +40,14 @@ from nikola import utils
class BuildBundles(LateTask):
+
"""Bundle assets using WebAssets."""
name = "create_bundles"
def set_site(self, site):
- self.logger = utils.get_logger('bundles', site.loghandlers)
+ """Set Nikola site."""
+ self.logger = utils.get_logger('bundles', utils.STDERR_HANDLER)
if webassets is None and site.config['USE_BUNDLES']:
utils.req_missing(['webassets'], 'USE_BUNDLES', optional=True)
self.logger.warn('Setting USE_BUNDLES to False.')
@@ -52,7 +56,6 @@ class BuildBundles(LateTask):
def gen_tasks(self):
"""Bundle assets using WebAssets."""
-
kw = {
'filters': self.site.config['FILTERS'],
'output_folder': self.site.config['OUTPUT_FOLDER'],
diff --git a/nikola/plugins/task/copy_assets.plugin b/nikola/plugins/task/copy_assets.plugin
index 0530ebf..c182150 100644
--- a/nikola/plugins/task/copy_assets.plugin
+++ b/nikola/plugins/task/copy_assets.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = copy_assets
-Module = copy_assets
+name = copy_assets
+module = copy_assets
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Copy theme assets into output.
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Copy theme assets into output.
+
+[Nikola]
+plugincategory = Task
diff --git a/nikola/plugins/task/copy_assets.py b/nikola/plugins/task/copy_assets.py
index a72bfdf..58521d4 100644
--- a/nikola/plugins/task/copy_assets.py
+++ b/nikola/plugins/task/copy_assets.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Copy theme assets into output."""
+
from __future__ import unicode_literals
import io
@@ -34,6 +36,7 @@ from nikola import utils
class CopyAssets(Task):
+
"""Copy theme assets into output."""
name = "copy_assets"
@@ -44,7 +47,6 @@ class CopyAssets(Task):
If a file is present on two themes, use the version
from the "youngest" theme.
"""
-
kw = {
"themes": self.site.THEMES,
"files_folders": self.site.config['FILES_FOLDERS'],
diff --git a/nikola/plugins/task/copy_files.plugin b/nikola/plugins/task/copy_files.plugin
index 073676b..ce8f5d0 100644
--- a/nikola/plugins/task/copy_files.plugin
+++ b/nikola/plugins/task/copy_files.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = copy_files
-Module = copy_files
+name = copy_files
+module = copy_files
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Copy static files into the output.
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Copy static files into the output.
+
+[Nikola]
+plugincategory = Task
diff --git a/nikola/plugins/task/copy_files.py b/nikola/plugins/task/copy_files.py
index 9a039f1..1232248 100644
--- a/nikola/plugins/task/copy_files.py
+++ b/nikola/plugins/task/copy_files.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Copy static files into the output folder."""
+
import os
from nikola.plugin_categories import Task
@@ -31,13 +33,13 @@ from nikola import utils
class CopyFiles(Task):
+
"""Copy static files into the output folder."""
name = "copy_files"
def gen_tasks(self):
"""Copy static files into the output folder."""
-
kw = {
'files_folders': self.site.config['FILES_FOLDERS'],
'output_folder': self.site.config['OUTPUT_FOLDER'],
diff --git a/nikola/plugins/task/galleries.plugin b/nikola/plugins/task/galleries.plugin
index 73085cd..9d3fa28 100644
--- a/nikola/plugins/task/galleries.plugin
+++ b/nikola/plugins/task/galleries.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = render_galleries
-Module = galleries
+name = render_galleries
+module = galleries
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Create image galleries automatically.
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Create image galleries automatically.
+
+[Nikola]
+plugincategory = Task
diff --git a/nikola/plugins/task/galleries.py b/nikola/plugins/task/galleries.py
index e887f18..c0df4a4 100644
--- a/nikola/plugins/task/galleries.py
+++ b/nikola/plugins/task/galleries.py
@@ -24,10 +24,12 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Render image galleries."""
+
from __future__ import unicode_literals
-import io
import datetime
import glob
+import io
import json
import mimetypes
import os
@@ -55,17 +57,19 @@ _image_size_cache = {}
class Galleries(Task, ImageProcessor):
+
"""Render image galleries."""
name = 'render_galleries'
dates = {}
def set_site(self, site):
+ """Set Nikola site."""
site.register_path_handler('gallery', self.gallery_path)
site.register_path_handler('gallery_global', self.gallery_global_path)
site.register_path_handler('gallery_rss', self.gallery_rss_path)
- self.logger = utils.get_logger('render_galleries', site.loghandlers)
+ self.logger = utils.get_logger('render_galleries', utils.STDERR_HANDLER)
self.kw = {
'thumbnail_size': site.config['THUMBNAIL_SIZE'],
@@ -118,17 +122,20 @@ class Galleries(Task, ImageProcessor):
sys.exit(1)
def gallery_path(self, name, lang):
+ """Return a gallery path."""
gallery_path = self._find_gallery_path(name)
return [_f for _f in [self.site.config['TRANSLATIONS'][lang]] +
gallery_path.split(os.sep) +
[self.site.config['INDEX_FILE']] if _f]
def gallery_global_path(self, name, lang):
+ """Return the global gallery path, which contains images."""
gallery_path = self._find_gallery_path(name)
return [_f for _f in gallery_path.split(os.sep) +
[self.site.config['INDEX_FILE']] if _f]
def gallery_rss_path(self, name, lang):
+ """Return path to the RSS file for a gallery."""
gallery_path = self._find_gallery_path(name)
return [_f for _f in [self.site.config['TRANSLATIONS'][lang]] +
gallery_path.split(os.sep) +
@@ -136,7 +143,6 @@ class Galleries(Task, ImageProcessor):
def gen_tasks(self):
"""Render image galleries."""
-
self.image_ext_list = self.image_ext_list_builtin
self.image_ext_list.extend(self.site.config.get('EXTRA_IMAGE_EXTENSIONS', []))
@@ -183,11 +189,13 @@ class Galleries(Task, ImageProcessor):
crumbs = utils.get_crumbs(gallery, index_folder=self)
- # Create index.html for each language
for lang in self.kw['translations']:
# save navigation links as dependencies
self.kw['navigation_links|{0}'.format(lang)] = self.kw['global_context']['navigation_links'](lang)
+ # Create index.html for each language
+ for lang in self.kw['translations']:
+
dst = os.path.join(
self.kw['output_folder'],
self.site.path("gallery", gallery, lang))
@@ -238,6 +246,7 @@ class Galleries(Task, ImageProcessor):
context["permalink"] = self.site.link("gallery", gallery, lang)
context["enable_comments"] = self.kw['comments_in_galleries']
context["thumbnail_size"] = self.kw["thumbnail_size"]
+ context["pagekind"] = ["gallery_front"]
if post:
yield {
@@ -246,7 +255,7 @@ class Galleries(Task, ImageProcessor):
'targets': [post.translated_base_path(lang)],
'file_dep': post.fragment_deps(lang),
'actions': [(post.compile, [lang])],
- 'uptodate': [utils.config_changed(self.kw, 'nikola.plugins.task.galleries:post')] + post.fragment_deps_uptodate(lang)
+ 'uptodate': [utils.config_changed(self.kw.copy(), 'nikola.plugins.task.galleries:post')] + post.fragment_deps_uptodate(lang)
}
context['post'] = post
else:
@@ -259,6 +268,8 @@ class Galleries(Task, ImageProcessor):
file_dep += [post.translated_base_path(l) for l in self.kw['translations']]
file_dep_dest += [post.translated_base_path(l) for l in self.kw['translations']]
+ context["pagekind"] = ["gallery_page"]
+
yield utils.apply_filters({
'basename': self.name,
'name': dst,
@@ -268,14 +279,14 @@ class Galleries(Task, ImageProcessor):
(self.render_gallery_index, (
template_name,
dst,
- context,
+ context.copy(),
dest_img_list,
img_titles,
thumbs,
file_dep))],
'clean': True,
'uptodate': [utils.config_changed({
- 1: self.kw,
+ 1: self.kw.copy(),
2: self.site.config["COMMENTS_IN_GALLERIES"],
3: context.copy(),
}, 'nikola.plugins.task.galleries:gallery')],
@@ -305,21 +316,19 @@ class Galleries(Task, ImageProcessor):
))],
'clean': True,
'uptodate': [utils.config_changed({
- 1: self.kw,
+ 1: self.kw.copy(),
}, 'nikola.plugins.task.galleries:rss')],
}, self.kw['filters'])
def find_galleries(self):
- """Find all galleries to be processed according to conf.py"""
-
+ """Find all galleries to be processed according to conf.py."""
self.gallery_list = []
for input_folder, output_folder in self.kw['gallery_folders'].items():
for root, dirs, files in os.walk(input_folder, followlinks=True):
self.gallery_list.append((root, input_folder, output_folder))
def create_galleries_paths(self):
- """Given a list of galleries, puts their paths into self.gallery_links."""
-
+ """Given a list of galleries, put their paths into self.gallery_links."""
# gallery_path is "gallery/foo/name"
self.proper_gallery_links = dict()
self.improper_gallery_links = dict()
@@ -350,7 +359,6 @@ class Galleries(Task, ImageProcessor):
def create_galleries(self):
"""Given a list of galleries, create the output folders."""
-
# gallery_path is "gallery/foo/name"
for gallery_path, input_folder, _ in self.gallery_list:
# have to use dirname because site.path returns .../index.html
@@ -366,12 +374,11 @@ class Galleries(Task, ImageProcessor):
'actions': [(utils.makedirs, (output_gallery,))],
'targets': [output_gallery],
'clean': True,
- 'uptodate': [utils.config_changed(self.kw, 'nikola.plugins.task.galleries:mkdir')],
+ 'uptodate': [utils.config_changed(self.kw.copy(), 'nikola.plugins.task.galleries:mkdir')],
}
def parse_index(self, gallery, input_folder, output_folder):
- """Returns a Post object if there is an index.txt."""
-
+ """Return a Post object if there is an index.txt."""
index_path = os.path.join(gallery, "index.txt")
destination = os.path.join(
self.kw["output_folder"], output_folder,
@@ -397,6 +404,7 @@ class Galleries(Task, ImageProcessor):
return post
def get_excluded_images(self, gallery_path):
+ """Get list of excluded images."""
exclude_path = os.path.join(gallery_path, "exclude.meta")
try:
@@ -409,7 +417,7 @@ class Galleries(Task, ImageProcessor):
return excluded_image_list
def get_image_list(self, gallery_path):
-
+ """Get list of included images."""
# Gather image_list contains "gallery/name/image_name.jpg"
image_list = []
@@ -424,6 +432,7 @@ class Galleries(Task, ImageProcessor):
return image_list
def create_target_images(self, img, input_path):
+ """Copy images to output."""
gallery_name = os.path.dirname(img)
output_gallery = os.path.dirname(
os.path.join(
@@ -473,6 +482,7 @@ class Galleries(Task, ImageProcessor):
}, self.kw['filters'])
def remove_excluded_image(self, img, input_folder):
+ """Remove excluded images."""
# Remove excluded images
# img is something like input_folder/demo/tesla2_lg.jpg so it's the *source* path
# and we should remove both the large and thumbnail *destination* paths
@@ -493,7 +503,7 @@ class Galleries(Task, ImageProcessor):
(utils.remove_file, (thumb_path,))
],
'clean': True,
- 'uptodate': [utils.config_changed(self.kw, 'nikola.plugins.task.galleries:clean_thumb')],
+ 'uptodate': [utils.config_changed(self.kw.copy(), 'nikola.plugins.task.galleries:clean_thumb')],
}, self.kw['filters'])
yield utils.apply_filters({
@@ -503,7 +513,7 @@ class Galleries(Task, ImageProcessor):
(utils.remove_file, (img_path,))
],
'clean': True,
- 'uptodate': [utils.config_changed(self.kw, 'nikola.plugins.task.galleries:clean_file')],
+ 'uptodate': [utils.config_changed(self.kw.copy(), 'nikola.plugins.task.galleries:clean_file')],
}, self.kw['filters'])
def render_gallery_index(
@@ -516,7 +526,6 @@ class Galleries(Task, ImageProcessor):
thumbs,
file_dep):
"""Build the gallery index."""
-
# The photo array needs to be created here, because
# it relies on thumbnails already being created on
# output
@@ -543,7 +552,7 @@ class Galleries(Task, ImageProcessor):
},
})
context['photo_array'] = photo_array
- context['photo_array_json'] = json.dumps(photo_array)
+ context['photo_array_json'] = json.dumps(photo_array, sort_keys=True)
self.site.render_template(template_name, output_name, context)
def gallery_rss(self, img_list, dest_img_list, img_titles, lang, permalink, output_path, title):
@@ -552,7 +561,6 @@ class Galleries(Task, ImageProcessor):
This doesn't use generic_rss_renderer because it
doesn't involve Post objects.
"""
-
def make_url(url):
return urljoin(self.site.config['BASE_URL'], url.lstrip('/'))
diff --git a/nikola/plugins/task/gzip.plugin b/nikola/plugins/task/gzip.plugin
index 4867fd6..7834d22 100644
--- a/nikola/plugins/task/gzip.plugin
+++ b/nikola/plugins/task/gzip.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = gzip
-Module = gzip
+name = gzip
+module = gzip
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Create gzipped copies of files
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Create gzipped copies of files
+
+[Nikola]
+plugincategory = Task
diff --git a/nikola/plugins/task/gzip.py b/nikola/plugins/task/gzip.py
index 5799839..cf16f63 100644
--- a/nikola/plugins/task/gzip.py
+++ b/nikola/plugins/task/gzip.py
@@ -35,12 +35,14 @@ from nikola.plugin_categories import TaskMultiplier
class GzipFiles(TaskMultiplier):
+
"""If appropiate, create tasks to create gzipped versions of files."""
name = "gzip"
is_default = True
def process(self, task, prefix):
+ """Process tasks."""
if not self.site.config['GZIP_FILES']:
return []
if task.get('name') is None:
@@ -70,6 +72,7 @@ class GzipFiles(TaskMultiplier):
def create_gzipped_copy(in_path, out_path, command=None):
+ """Create gzipped copy of in_path and save it as out_path."""
if command:
subprocess.check_call(shlex.split(command.format(filename=in_path)))
else:
diff --git a/nikola/plugins/task/indexes.plugin b/nikola/plugins/task/indexes.plugin
index 5d2bf5a..d9b0e5f 100644
--- a/nikola/plugins/task/indexes.plugin
+++ b/nikola/plugins/task/indexes.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = render_indexes
-Module = indexes
+name = render_indexes
+module = indexes
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Generates the blog's index pages.
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Generates the blog's index pages.
+
+[Nikola]
+plugincategory = Task
diff --git a/nikola/plugins/task/indexes.py b/nikola/plugins/task/indexes.py
index 03d36b1..c02818e 100644
--- a/nikola/plugins/task/indexes.py
+++ b/nikola/plugins/task/indexes.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Render the blog indexes."""
+
from __future__ import unicode_literals
from collections import defaultdict
import os
@@ -33,16 +35,19 @@ from nikola import utils
class Indexes(Task):
+
"""Render the blog indexes."""
name = "render_indexes"
def set_site(self, site):
+ """Set Nikola site."""
site.register_path_handler('index', self.index_path)
site.register_path_handler('index_atom', self.index_atom_path)
return super(Indexes, self).set_site(site)
def gen_tasks(self):
+ """Render the blog indexes."""
self.site.scan_posts()
yield self.group_task()
@@ -80,7 +85,10 @@ class Indexes(Task):
indexes_title = kw['indexes_title'](lang) or kw['blog_title'](lang)
self.number_of_pages[lang] = (len(filtered_posts) + kw['index_display_post_count'] - 1) // kw['index_display_post_count']
- yield self.site.generic_index_renderer(lang, filtered_posts, indexes_title, template_name, {}, kw, 'render_indexes', page_link, page_path)
+ context = {}
+ context["pagekind"] = ["index"]
+
+ yield self.site.generic_index_renderer(lang, filtered_posts, indexes_title, template_name, context, kw, 'render_indexes', page_link, page_path)
if not self.site.config["STORY_INDEX"]:
return
@@ -93,13 +101,17 @@ class Indexes(Task):
"strip_indexes": self.site.config['STRIP_INDEXES'],
}
template_name = "list.tmpl"
+ index_len = len(kw['index_file'])
for lang in kw["translations"]:
# Need to group by folder to avoid duplicated tasks (Issue #758)
# Group all pages by path prefix
groups = defaultdict(list)
for p in self.site.timeline:
if not p.is_post:
- dirname = os.path.dirname(p.destination_path(lang))
+ destpath = p.destination_path(lang)
+ if destpath[-(1 + index_len):] == '/' + kw['index_file']:
+ destpath = destpath[:-(1 + index_len)]
+ dirname = os.path.dirname(destpath)
groups[dirname].append(p)
for dirname, post_list in groups.items():
context = {}
@@ -108,10 +120,12 @@ class Indexes(Task):
output_name = os.path.join(kw['output_folder'], dirname, kw['index_file'])
short_destination = os.path.join(dirname, kw['index_file'])
link = short_destination.replace('\\', '/')
- index_len = len(kw['index_file'])
if kw['strip_indexes'] and link[-(1 + index_len):] == '/' + kw['index_file']:
link = link[:-index_len]
context["permalink"] = link
+ context["pagekind"] = ["list"]
+ if dirname == "/":
+ context["pagekind"].append("front_page")
for post in post_list:
# If there is an index.html pending to be created from
@@ -133,6 +147,7 @@ class Indexes(Task):
yield task
def index_path(self, name, lang, is_feed=False):
+ """Return path to an index."""
extension = None
if is_feed:
extension = ".atom"
@@ -149,4 +164,5 @@ class Indexes(Task):
extension=extension)
def index_atom_path(self, name, lang):
+ """Return path to an Atom index."""
return self.index_path(name, lang, is_feed=True)
diff --git a/nikola/plugins/task/listings.plugin b/nikola/plugins/task/listings.plugin
index a5ba77a..435234b 100644
--- a/nikola/plugins/task/listings.plugin
+++ b/nikola/plugins/task/listings.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = render_listings
-Module = listings
+name = render_listings
+module = listings
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Render code listings into output
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Render code listings into output
+
+[Nikola]
+plugincategory = Task
diff --git a/nikola/plugins/task/listings.py b/nikola/plugins/task/listings.py
index b913330..5f79724 100644
--- a/nikola/plugins/task/listings.py
+++ b/nikola/plugins/task/listings.py
@@ -24,10 +24,13 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Render code listings."""
+
from __future__ import unicode_literals, print_function
import sys
import os
+import lxml.html
from pygments import highlight
from pygments.lexers import get_lexer_for_filename, TextLexer
@@ -38,7 +41,8 @@ from nikola import utils
class Listings(Task):
- """Render pretty listings."""
+
+ """Render code listings."""
name = "render_listings"
@@ -51,6 +55,7 @@ class Listings(Task):
self.proper_input_file_mapping[rel_output_name] = rel_output_name
def set_site(self, site):
+ """Set Nikola site."""
site.register_path_handler('listing', self.listing_path)
# We need to prepare some things for the listings path handler to work.
@@ -105,12 +110,21 @@ class Listings(Task):
def gen_tasks(self):
"""Render pretty code listings."""
-
# Things to ignore in listings
ignored_extensions = (".pyc", ".pyo")
def render_listing(in_name, out_name, input_folder, output_folder, folders=[], files=[]):
- if in_name:
+ needs_ipython_css = False
+ if in_name and in_name.endswith('.ipynb'):
+ # Special handling: render ipynbs in listings (Issue #1900)
+ ipynb_compiler = self.site.plugin_manager.getPluginByName("ipynb", "PageCompiler").plugin_object
+ ipynb_raw = ipynb_compiler.compile_html_string(in_name, True)
+ ipynb_html = lxml.html.fromstring(ipynb_raw)
+ # The raw HTML contains garbage (scripts and styles), we can’t leave it in
+ code = lxml.html.tostring(ipynb_html.xpath('//*[@id="notebook"]')[0], encoding='unicode')
+ title = os.path.basename(in_name)
+ needs_ipython_css = True
+ elif in_name:
with open(in_name, 'r') as fd:
try:
lexer = get_lexer_for_filename(in_name)
@@ -149,7 +163,12 @@ class Listings(Task):
files, alg=natsort.ns.F | natsort.ns.IC),
'description': title,
'source_link': source_link,
+ 'pagekind': ['listing'],
}
+ if needs_ipython_css:
+ # If someone does not have ipynb posts and only listings, we
+ # need to enable ipynb CSS for ipynb listings.
+ context['needs_ipython_css'] = True
self.site.render_template('listing.tmpl', out_name, context)
yield self.group_task()
@@ -236,6 +255,7 @@ class Listings(Task):
}, self.kw["filters"])
def listing_path(self, namep, lang):
+ """Return path to a listing."""
namep = namep.replace('/', os.sep)
nameh = namep + '.html'
for name in (namep, nameh):
diff --git a/nikola/plugins/task/pages.plugin b/nikola/plugins/task/pages.plugin
index 4cad7b7..023d41b 100644
--- a/nikola/plugins/task/pages.plugin
+++ b/nikola/plugins/task/pages.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = render_pages
-Module = pages
+name = render_pages
+module = pages
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Create pages in the output.
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Create pages in the output.
+
+[Nikola]
+plugincategory = Task
diff --git a/nikola/plugins/task/pages.py b/nikola/plugins/task/pages.py
index d0edb56..e6a8a82 100644
--- a/nikola/plugins/task/pages.py
+++ b/nikola/plugins/task/pages.py
@@ -24,12 +24,15 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Render pages into output."""
+
from __future__ import unicode_literals
from nikola.plugin_categories import Task
from nikola.utils import config_changed
class RenderPages(Task):
+
"""Render pages into output."""
name = "render_pages"
@@ -49,8 +52,11 @@ class RenderPages(Task):
for post in self.site.timeline:
if not kw["show_untranslated_posts"] and not post.is_translation_available(lang):
continue
- for task in self.site.generic_page_renderer(lang, post,
- kw["filters"]):
+ if post.is_post:
+ context = {'pagekind': ['post_page']}
+ else:
+ context = {'pagekind': ['story_page']}
+ for task in self.site.generic_page_renderer(lang, post, kw["filters"], context):
task['uptodate'] = task['uptodate'] + [config_changed(kw, 'nikola.plugins.task.pages')]
task['basename'] = self.name
task['task_dep'] = ['render_posts']
diff --git a/nikola/plugins/task/posts.plugin b/nikola/plugins/task/posts.plugin
index 707b3c2..79b7c51 100644
--- a/nikola/plugins/task/posts.plugin
+++ b/nikola/plugins/task/posts.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = render_posts
-Module = posts
+name = render_posts
+module = posts
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Create HTML fragments out of posts.
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Create HTML fragments out of posts.
+
+[Nikola]
+plugincategory = Task
diff --git a/nikola/plugins/task/posts.py b/nikola/plugins/task/posts.py
index d3f17fd..a3a8375 100644
--- a/nikola/plugins/task/posts.py
+++ b/nikola/plugins/task/posts.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Build HTML fragments from metadata and text."""
+
from copy import copy
import os
@@ -32,7 +34,7 @@ from nikola import filters, utils
def update_deps(post, lang, task):
- """Updates file dependencies as they might have been updated during compilation.
+ """Update file dependencies as they might have been updated during compilation.
This is done for example by the ReST page compiler, which writes its
dependencies into a .dep file. This file is read and incorporated when calling
@@ -42,6 +44,7 @@ def update_deps(post, lang, task):
class RenderPosts(Task):
+
"""Build HTML fragments from metadata and text."""
name = "render_posts"
@@ -74,7 +77,11 @@ class RenderPosts(Task):
deps_dict = copy(kw)
deps_dict.pop('timeline')
for post in kw['timeline']:
-
+ # Extra config dependencies picked from config
+ for p in post.fragment_deps(lang):
+ if p.startswith('####MAGIC####CONFIG:'):
+ k = p.split('####MAGIC####CONFIG:', 1)[-1]
+ deps_dict[k] = self.site.config.get(k)
dest = post.translated_base_path(lang)
file_dep = [p for p in post.fragment_deps(lang) if not p.startswith("####MAGIC####")]
task = {
@@ -110,6 +117,7 @@ class RenderPosts(Task):
yield utils.apply_filters(task, {os.path.splitext(dest): flist})
def dependence_on_timeline(self, post, lang):
+ """Check if a post depends on the timeline."""
if "####MAGIC####TIMELINE" not in post.fragment_deps(lang):
return True # No dependency on timeline
elif self.tl_changed:
diff --git a/nikola/plugins/task/redirect.plugin b/nikola/plugins/task/redirect.plugin
index 0228c70..c3137b9 100644
--- a/nikola/plugins/task/redirect.plugin
+++ b/nikola/plugins/task/redirect.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = redirect
-Module = redirect
+name = redirect
+module = redirect
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Create redirect pages.
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Create redirect pages.
+
+[Nikola]
+plugincategory = Task
diff --git a/nikola/plugins/task/redirect.py b/nikola/plugins/task/redirect.py
index 428dd5a..8530f5e 100644
--- a/nikola/plugins/task/redirect.py
+++ b/nikola/plugins/task/redirect.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Generate redirections."""
+
from __future__ import unicode_literals
import os
@@ -33,13 +35,13 @@ from nikola import utils
class Redirect(Task):
- """Generate redirections"""
+
+ """Generate redirections."""
name = "redirect"
def gen_tasks(self):
"""Generate redirections tasks."""
-
kw = {
'redirections': self.site.config['REDIRECTIONS'],
'output_folder': self.site.config['OUTPUT_FOLDER'],
diff --git a/nikola/plugins/task/robots.plugin b/nikola/plugins/task/robots.plugin
index b4b43a3..72ce31f 100644
--- a/nikola/plugins/task/robots.plugin
+++ b/nikola/plugins/task/robots.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = robots
-Module = robots
+name = robots
+module = robots
[Documentation]
-Author = Daniel Aleksandersen
-Version = 1.0
-Website = http://getnikola.com
-Description = Generate /robots.txt exclusion file and promote sitemap.
+author = Daniel Aleksandersen
+version = 1.0
+website = http://getnikola.com
+description = Generate /robots.txt exclusion file and promote sitemap.
+
+[Nikola]
+plugincategory = Task
diff --git a/nikola/plugins/task/robots.py b/nikola/plugins/task/robots.py
index 2f25a21..65254b6 100644
--- a/nikola/plugins/task/robots.py
+++ b/nikola/plugins/task/robots.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Generate a robots.txt file."""
+
from __future__ import print_function, absolute_import, unicode_literals
import io
import os
@@ -37,12 +39,13 @@ from nikola import utils
class RobotsFile(LateTask):
- """Generate a robots.txt."""
+
+ """Generate a robots.txt file."""
name = "robots_file"
def gen_tasks(self):
- """Generate a robots.txt."""
+ """Generate a robots.txt file."""
kw = {
"base_url": self.site.config["BASE_URL"],
"site_url": self.site.config["SITE_URL"],
diff --git a/nikola/plugins/task/rss.plugin b/nikola/plugins/task/rss.plugin
index 56f0bf4..cf9b7a7 100644
--- a/nikola/plugins/task/rss.plugin
+++ b/nikola/plugins/task/rss.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = generate_rss
-Module = rss
+name = generate_rss
+module = rss
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Generate RSS feeds.
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Generate RSS feeds.
+
+[Nikola]
+plugincategory = Task
diff --git a/nikola/plugins/task/rss.py b/nikola/plugins/task/rss.py
index 26a4da1..9020a06 100644
--- a/nikola/plugins/task/rss.py
+++ b/nikola/plugins/task/rss.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Generate RSS feeds."""
+
from __future__ import unicode_literals, print_function
import os
try:
@@ -36,11 +38,13 @@ from nikola.plugin_categories import Task
class GenerateRSS(Task):
+
"""Generate RSS feeds."""
name = "generate_rss"
def set_site(self, site):
+ """Set Nikola site."""
site.register_path_handler('rss', self.rss_path)
return super(GenerateRSS, self).set_site(site)
@@ -102,5 +106,6 @@ class GenerateRSS(Task):
yield utils.apply_filters(task, kw['filters'])
def rss_path(self, name, lang):
+ """Return RSS path."""
return [_f for _f in [self.site.config['TRANSLATIONS'][lang],
self.site.config['RSS_PATH'], 'rss.xml'] if _f]
diff --git a/nikola/plugins/task/scale_images.plugin b/nikola/plugins/task/scale_images.plugin
index c0f0f28..d906b8c 100644
--- a/nikola/plugins/task/scale_images.plugin
+++ b/nikola/plugins/task/scale_images.plugin
@@ -1,9 +1,13 @@
[Core]
-Name = scale_images
-Module = scale_images
+name = scale_images
+module = scale_images
[Documentation]
-Author = Pelle Nilsson
-Version = 1.0
-Website = http://getnikola.com
-Description = Create down-scaled images and thumbnails.
+author = Pelle Nilsson
+version = 1.0
+website = http://getnikola.com
+description = Create down-scaled images and thumbnails.
+
+[Nikola]
+plugincategory = Task
+
diff --git a/nikola/plugins/task/scale_images.py b/nikola/plugins/task/scale_images.py
index f97027e..22ed2ab 100644
--- a/nikola/plugins/task/scale_images.py
+++ b/nikola/plugins/task/scale_images.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Resize images and create thumbnails for them."""
+
import os
from nikola.plugin_categories import Task
@@ -32,17 +34,18 @@ from nikola import utils
class ScaleImage(Task, ImageProcessor):
- """Copy static files into the output folder."""
+
+ """Resize images and create thumbnails for them."""
name = "scale_images"
def set_site(self, site):
- self.logger = utils.get_logger('scale_images', site.loghandlers)
+ """Set Nikola site."""
+ self.logger = utils.get_logger('scale_images', utils.STDERR_HANDLER)
return super(ScaleImage, self).set_site(site)
def process_tree(self, src, dst):
- """Processes all images in a src tree and put the (possibly) rescaled
- images in the dst folder."""
+ """Process all images in a src tree and put the (possibly) rescaled images in the dst folder."""
ignore = set(['.svn'])
base_len = len(src.split(os.sep))
for root, dirs, files in os.walk(src, followlinks=True):
@@ -68,12 +71,12 @@ class ScaleImage(Task, ImageProcessor):
}
def process_image(self, src, dst, thumb):
+ """Resize an image."""
self.resize_image(src, dst, self.kw['max_image_size'], False)
self.resize_image(src, thumb, self.kw['image_thumbnail_size'], False)
def gen_tasks(self):
"""Copy static files into the output folder."""
-
self.kw = {
'image_thumbnail_size': self.site.config['IMAGE_THUMBNAIL_SIZE'],
'max_image_size': self.site.config['MAX_IMAGE_SIZE'],
diff --git a/nikola/plugins/task/sitemap.plugin b/nikola/plugins/task/sitemap.plugin
index 0b992b8..e3c991f 100644
--- a/nikola/plugins/task/sitemap.plugin
+++ b/nikola/plugins/task/sitemap.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = sitemap
-Module = sitemap
+name = sitemap
+module = sitemap
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Generate google sitemap.
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Generate google sitemap.
+
+[Nikola]
+plugincategory = Task
diff --git a/nikola/plugins/task/sitemap/__init__.py b/nikola/plugins/task/sitemap/__init__.py
index 92d557d..fd781d6 100644
--- a/nikola/plugins/task/sitemap/__init__.py
+++ b/nikola/plugins/task/sitemap/__init__.py
@@ -24,9 +24,12 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Generate a sitemap."""
+
from __future__ import print_function, absolute_import, unicode_literals
import io
import datetime
+import dateutil.tz
import os
try:
from urlparse import urljoin, urlparse
@@ -42,6 +45,7 @@ from nikola.utils import config_changed, apply_filters
urlset_header = """
@@ -58,6 +62,7 @@ urlset_footer = " "
sitemapindex_header = """
@@ -76,7 +81,7 @@ sitemapindex_footer = " "
def get_base_path(base):
- """returns the path of a base URL if it contains one.
+ """Return the path of a base URL if it contains one.
>>> get_base_path('http://some.site') == '/'
True
@@ -101,6 +106,7 @@ def get_base_path(base):
class Sitemap(LateTask):
+
"""Generate a sitemap."""
name = "sitemap"
@@ -114,10 +120,12 @@ class Sitemap(LateTask):
"strip_indexes": self.site.config["STRIP_INDEXES"],
"index_file": self.site.config["INDEX_FILE"],
"sitemap_include_fileless_dirs": self.site.config["SITEMAP_INCLUDE_FILELESS_DIRS"],
- "mapped_extensions": self.site.config.get('MAPPED_EXTENSIONS', ['.atom', '.html', '.htm', '.xml', '.rss']),
+ "mapped_extensions": self.site.config.get('MAPPED_EXTENSIONS', ['.atom', '.html', '.htm', '.php', '.xml', '.rss']),
"robots_exclusions": self.site.config["ROBOTS_EXCLUSIONS"],
"filters": self.site.config["FILTERS"],
"translations": self.site.config["TRANSLATIONS"],
+ "tzinfo": self.site.config['__tzinfo__'],
+ "sitemap_plugin_revision": 1,
}
output = kw['output_folder']
@@ -132,6 +140,7 @@ class Sitemap(LateTask):
urlset = {}
def scan_locs():
+ """Scan site locations."""
for root, dirs, files in os.walk(output, followlinks=True):
if not dirs and not files and not kw['sitemap_include_fileless_dirs']:
continue # Totally empty, not on sitemap
@@ -169,17 +178,18 @@ class Sitemap(LateTask):
filehead = fh.read(1024)
fh.close()
- if path.endswith('.html') or path.endswith('.htm'):
+ if path.endswith('.html') or path.endswith('.htm') or path.endswith('.php'):
""" ignores "html" files without doctype """
if b'= kw["taglist_minimum_post_count"]],
- alg=natsort.ns.F | natsort.ns.IC)
+ """Create a global "all your tags/categories" page for each language."""
categories = [cat.category_name for cat in self.site.category_hierarchy]
- has_tags = (tags != []) and include_tags
has_categories = (categories != []) and include_categories
template_name = "tags.tmpl"
kw = kw.copy()
- if include_tags:
- kw['tags'] = tags
if include_categories:
kw['categories'] = categories
for lang in kw["translations"]:
+ tags = natsort.natsorted([tag for tag in self.site.tags_per_language[lang]
+ if len(self.site.posts_per_tag[tag]) >= kw["taglist_minimum_post_count"]],
+ alg=natsort.ns.F | natsort.ns.IC)
+ has_tags = (tags != []) and include_tags
+ if include_tags:
+ kw['tags'] = tags
output_name = os.path.join(
kw['output_folder'], self.site.path('tag_index' if has_tags else 'category_index', None, lang))
output_name = output_name
@@ -219,6 +224,7 @@ class RenderTags(Task):
context["cat_items"] = None
context["permalink"] = self.site.link("tag_index" if has_tags else "category_index", None, lang)
context["description"] = context["title"]
+ context["pagekind"] = ["list", "tags_page"]
task = self.site.generic_post_list_renderer(
lang,
[],
@@ -232,7 +238,7 @@ class RenderTags(Task):
yield task
def list_tags_page(self, kw):
- """a global "all your tags/categories" page for each language"""
+ """Create a global "all your tags/categories" page for each language."""
if self.site.config['TAG_PATH'] == self.site.config['CATEGORY_PATH']:
yield self._create_tags_page(kw, True, True)
else:
@@ -254,9 +260,7 @@ class RenderTags(Task):
return [(child.name, self.site.link("category", child.category_name)) for child in node.children]
def tag_page_as_index(self, tag, lang, post_list, kw, is_category):
- """render a sort of index page collection using only this
- tag's posts."""
-
+ """Render a sort of index page collection using only this tag's posts."""
kind = "category" if is_category else "tag"
def page_link(i, displayed_i, num_pages, force_addition, extension=None):
@@ -284,12 +288,13 @@ class RenderTags(Task):
context_source["description"] = self._get_description(tag, is_category, lang)
if is_category:
context_source["subcategories"] = self._get_subcategories(tag)
+ context_source["pagekind"] = ["index", "tag_page"]
template_name = "tagindex.tmpl"
yield self.site.generic_index_renderer(lang, post_list, indexes_title, template_name, context_source, kw, str(self.name), page_link, page_path)
def tag_page_as_list(self, tag, lang, post_list, kw, is_category):
- """We render a single flat link list with this tag's posts"""
+ """Render a single flat link list with this tag's posts."""
kind = "category" if is_category else "tag"
template_name = "tag.tmpl"
output_name = os.path.join(kw['output_folder'], self.site.path(
@@ -308,6 +313,7 @@ class RenderTags(Task):
context["description"] = self._get_description(tag, is_category, lang)
if is_category:
context["subcategories"] = self._get_subcategories(tag)
+ context["pagekind"] = ["list", "tag_page"]
task = self.site.generic_post_list_renderer(
lang,
post_list,
@@ -321,7 +327,7 @@ class RenderTags(Task):
yield task
def tag_rss(self, tag, lang, posts, kw, is_category):
- """RSS for a single tag / language"""
+ """Create a RSS feed for a single tag in a given language."""
kind = "category" if is_category else "tag"
# Render RSS
output_name = os.path.normpath(
@@ -352,21 +358,25 @@ class RenderTags(Task):
return utils.apply_filters(task, kw['filters'])
def slugify_tag_name(self, name):
+ """Slugify a tag name."""
if self.site.config['SLUG_TAG_PATH']:
name = utils.slugify(name)
return name
def tag_index_path(self, name, lang):
+ """Return path to the tag index."""
return [_f for _f in [self.site.config['TRANSLATIONS'][lang],
self.site.config['TAG_PATH'],
self.site.config['INDEX_FILE']] if _f]
def category_index_path(self, name, lang):
+ """Return path to the category index."""
return [_f for _f in [self.site.config['TRANSLATIONS'][lang],
self.site.config['CATEGORY_PATH'],
self.site.config['INDEX_FILE']] if _f]
def tag_path(self, name, lang):
+ """Return path to a tag."""
if self.site.config['PRETTY_URLS']:
return [_f for _f in [
self.site.config['TRANSLATIONS'][lang],
@@ -380,16 +390,19 @@ class RenderTags(Task):
self.slugify_tag_name(name) + ".html"] if _f]
def tag_atom_path(self, name, lang):
+ """Return path to a tag Atom feed."""
return [_f for _f in [self.site.config['TRANSLATIONS'][lang],
self.site.config['TAG_PATH'], self.slugify_tag_name(name) + ".atom"] if
_f]
def tag_rss_path(self, name, lang):
+ """Return path to a tag RSS feed."""
return [_f for _f in [self.site.config['TRANSLATIONS'][lang],
self.site.config['TAG_PATH'], self.slugify_tag_name(name) + ".xml"] if
_f]
def slugify_category_name(self, name):
+ """Slugify a category name."""
path = self.site.parse_category_name(name)
if self.site.config['CATEGORY_OUTPUT_FLAT_HIERARCHY']:
path = path[-1:] # only the leaf
@@ -404,6 +417,7 @@ class RenderTags(Task):
return path
def category_path(self, name, lang):
+ """Return path to a category."""
if self.site.config['PRETTY_URLS']:
return [_f for _f in [self.site.config['TRANSLATIONS'][lang],
self.site.config['CATEGORY_PATH']] if
@@ -414,11 +428,13 @@ class RenderTags(Task):
_f] + self._add_extension(self.slugify_category_name(name), ".html")
def category_atom_path(self, name, lang):
+ """Return path to a category Atom feed."""
return [_f for _f in [self.site.config['TRANSLATIONS'][lang],
self.site.config['CATEGORY_PATH']] if
_f] + self._add_extension(self.slugify_category_name(name), ".atom")
def category_rss_path(self, name, lang):
+ """Return path to a category RSS feed."""
return [_f for _f in [self.site.config['TRANSLATIONS'][lang],
self.site.config['CATEGORY_PATH']] if
_f] + self._add_extension(self.slugify_category_name(name), ".xml")
diff --git a/nikola/plugins/template/__init__.py b/nikola/plugins/template/__init__.py
index a1d17a6..d416ad7 100644
--- a/nikola/plugins/template/__init__.py
+++ b/nikola/plugins/template/__init__.py
@@ -23,3 +23,5 @@
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+"""Default template engines for Nikola."""
diff --git a/nikola/plugins/template/jinja.plugin b/nikola/plugins/template/jinja.plugin
index 0bdcb94..cfe9fa8 100644
--- a/nikola/plugins/template/jinja.plugin
+++ b/nikola/plugins/template/jinja.plugin
@@ -1,9 +1,13 @@
[Core]
-Name = jinja
-Module = jinja
+name = jinja
+module = jinja
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Support for Jinja2 templates.
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Support for Jinja2 templates.
+
+[Nikola]
+plugincategory = Template
+
diff --git a/nikola/plugins/template/jinja.py b/nikola/plugins/template/jinja.py
index 82e8397..b02d75c 100644
--- a/nikola/plugins/template/jinja.py
+++ b/nikola/plugins/template/jinja.py
@@ -24,8 +24,10 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-"""Jinja template handlers"""
+"""Jinja template handler."""
+
+from __future__ import unicode_literals
import os
import json
from collections import deque
@@ -40,14 +42,15 @@ from nikola.utils import makedirs, req_missing
class JinjaTemplates(TemplateSystem):
- """Wrapper for Jinja2 templates."""
+
+ """Support for Jinja2 templates."""
name = "jinja"
lookup = None
dependency_cache = {}
def __init__(self):
- """ initialize Jinja2 wrapper with extended set of filters"""
+ """Initialize Jinja2 environment with extended set of filters."""
if jinja2 is None:
return
self.lookup = jinja2.Environment()
@@ -59,26 +62,25 @@ class JinjaTemplates(TemplateSystem):
self.lookup.globals['tuple'] = tuple
def set_directories(self, directories, cache_folder):
- """Create a template lookup."""
+ """Create a new template lookup with set directories."""
if jinja2 is None:
req_missing(['jinja2'], 'use this theme')
self.directories = directories
self.create_lookup()
def inject_directory(self, directory):
- """if it's not there, add the directory to the lookup with lowest priority, and
- recreate the lookup."""
+ """Add a directory to the lookup and recreate it if it's not there yet."""
if directory not in self.directories:
self.directories.append(directory)
self.create_lookup()
def create_lookup(self):
- """Create a template lookup object."""
+ """Create a template lookup."""
self.lookup.loader = jinja2.FileSystemLoader(self.directories,
encoding='utf-8')
def set_site(self, site):
- """Sets the site."""
+ """Set the Nikola site."""
self.site = site
self.lookup.filters.update(self.site.config['TEMPLATE_FILTERS'])
@@ -99,6 +101,7 @@ class JinjaTemplates(TemplateSystem):
return self.lookup.from_string(template).render(**context)
def template_deps(self, template_name):
+ """Generate list of dependencies for a template."""
# Cache the lists of dependencies for each template name.
if self.dependency_cache.get(template_name) is None:
# Use a breadth-first search to find all templates this one
diff --git a/nikola/plugins/template/mako.plugin b/nikola/plugins/template/mako.plugin
index 2fe6d98..d256faf 100644
--- a/nikola/plugins/template/mako.plugin
+++ b/nikola/plugins/template/mako.plugin
@@ -1,9 +1,13 @@
[Core]
-Name = mako
-Module = mako
+name = mako
+module = mako
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Support for Mako templates.
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Support for Mako templates.
+
+[Nikola]
+plugincategory = Template
+
diff --git a/nikola/plugins/template/mako.py b/nikola/plugins/template/mako.py
index e5545f6..aed6596 100644
--- a/nikola/plugins/template/mako.py
+++ b/nikola/plugins/template/mako.py
@@ -24,14 +24,15 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-"""Mako template handlers"""
+"""Mako template handler."""
+
from __future__ import unicode_literals, print_function, absolute_import
import os
import shutil
import sys
import tempfile
-from mako import util, lexer
+from mako import util, lexer, parsetree
from mako.lookup import TemplateLookup
from mako.template import Template
from markupsafe import Markup # It's ok, Mako requires it
@@ -43,7 +44,8 @@ LOGGER = get_logger('mako', STDERR_HANDLER)
class MakoTemplates(TemplateSystem):
- """Wrapper for Mako templates."""
+
+ """Support for Mako templates."""
name = "mako"
@@ -54,6 +56,7 @@ class MakoTemplates(TemplateSystem):
cache_dir = None
def get_deps(self, filename):
+ """Get dependencies for a template (internal function)."""
text = util.read_file(filename)
lex = lexer.Lexer(text=text, filename=filename)
lex.parse()
@@ -61,13 +64,12 @@ class MakoTemplates(TemplateSystem):
deps = []
for n in lex.template.nodes:
keyword = getattr(n, 'keyword', None)
- if keyword in ["inherit", "namespace"]:
+ if keyword in ["inherit", "namespace"] or isinstance(n, parsetree.IncludeTag):
deps.append(n.attributes['file'])
- # TODO: include tags are not handled
return deps
def set_directories(self, directories, cache_folder):
- """Set directories and create a template lookup."""
+ """Create a new template lookup with set directories."""
cache_dir = os.path.join(cache_folder, '.mako.tmp')
# Workaround for a Mako bug, Issue #825
if sys.version_info[0] == 2:
@@ -83,21 +85,20 @@ class MakoTemplates(TemplateSystem):
self.create_lookup()
def inject_directory(self, directory):
- """if it's not there, add the directory to the lookup with lowest priority, and
- recreate the lookup."""
+ """Add a directory to the lookup and recreate it if it's not there yet."""
if directory not in self.directories:
self.directories.append(directory)
self.create_lookup()
def create_lookup(self):
- """Create a template lookup object."""
+ """Create a template lookup."""
self.lookup = TemplateLookup(
directories=self.directories,
module_directory=self.cache_dir,
output_encoding='utf-8')
def set_site(self, site):
- """Sets the site."""
+ """Set the Nikola site."""
self.site = site
self.filters.update(self.site.config['TEMPLATE_FILTERS'])
@@ -113,14 +114,12 @@ class MakoTemplates(TemplateSystem):
return data
def render_template_to_string(self, template, context):
- """ Render template to a string using context. """
-
+ """Render template to a string using context."""
context.update(self.filters)
-
return Template(template).render(**context)
def template_deps(self, template_name):
- """Returns filenames which are dependencies for a template."""
+ """Generate list of dependencies for a template."""
# We can cache here because dependencies should
# not change between runs
if self.cache.get(template_name, None) is None:
@@ -134,4 +133,5 @@ class MakoTemplates(TemplateSystem):
def striphtml(text):
+ """Strip HTML tags from text."""
return Markup(text).striptags()
--
cgit v1.2.3