aboutsummaryrefslogtreecommitdiffstats
path: root/nikola/plugins/compile_rest
diff options
context:
space:
mode:
authorLibravatarAgustin Henze <tin@sluc.org.ar>2013-05-30 17:41:06 -0300
committerLibravatarAgustin Henze <tin@sluc.org.ar>2013-05-30 17:41:06 -0300
commit0c4dfdec5b55b6064dccc38bbfb0a7c0699c895a (patch)
treea6707225ccc559f7edf50ddd3fdc7fc85145c921 /nikola/plugins/compile_rest
parent8b14a1e5b2ca574fdd4fd2377567ec98a110d4b6 (diff)
Imported Upstream version 5.4.4
Diffstat (limited to 'nikola/plugins/compile_rest')
-rw-r--r--nikola/plugins/compile_rest/__init__.py81
-rw-r--r--nikola/plugins/compile_rest/dummy.py44
-rw-r--r--nikola/plugins/compile_rest/gist_directive.py2
-rw-r--r--nikola/plugins/compile_rest/listing.py121
-rw-r--r--nikola/plugins/compile_rest/pygments_code_block_directive.py424
-rw-r--r--nikola/plugins/compile_rest/slides.py79
-rw-r--r--nikola/plugins/compile_rest/soundcloud.py62
-rw-r--r--nikola/plugins/compile_rest/vimeo.py114
-rw-r--r--nikola/plugins/compile_rest/youtube.py57
9 files changed, 387 insertions, 597 deletions
diff --git a/nikola/plugins/compile_rest/__init__.py b/nikola/plugins/compile_rest/__init__.py
index b0a0c00..3d41571 100644
--- a/nikola/plugins/compile_rest/__init__.py
+++ b/nikola/plugins/compile_rest/__init__.py
@@ -26,26 +26,28 @@ from __future__ import unicode_literals
import codecs
import os
-import docutils.core
-import docutils.io
-from docutils.parsers.rst import directives
-
-from .pygments_code_block_directive import (
- code_block_directive,
- listings_directive)
-directives.register_directive('code-block', code_block_directive)
-directives.register_directive('listing', listings_directive)
-
-from .youtube import youtube
-directives.register_directive('youtube', youtube)
-from .vimeo import vimeo
-directives.register_directive('vimeo', vimeo)
-from .slides import slides
-directives.register_directive('slides', slides)
-from .gist_directive import GitHubGist
-directives.register_directive('gist', GitHubGist)
-from .soundcloud import soundcloud
-directives.register_directive('soundcloud', soundcloud)
+try:
+ import docutils.core
+ import docutils.io
+ from docutils.parsers.rst import directives
+
+ from .listing import Listing, CodeBlock
+ directives.register_directive('code-block', CodeBlock)
+ directives.register_directive('sourcecode', CodeBlock)
+ directives.register_directive('listing', Listing)
+ from .youtube import Youtube
+ directives.register_directive('youtube', Youtube)
+ from .vimeo import Vimeo
+ directives.register_directive('vimeo', Vimeo)
+ from .slides import Slides
+ directives.register_directive('slides', Slides)
+ from .gist_directive import GitHubGist
+ directives.register_directive('gist', GitHubGist)
+ from .soundcloud import SoundCloud
+ directives.register_directive('soundcloud', SoundCloud)
+ has_docutils = True
+except ImportError:
+ has_docutils = False
from nikola.plugin_categories import PageCompiler
@@ -57,6 +59,9 @@ class CompileRest(PageCompiler):
def compile_html(self, source, dest):
"""Compile reSt into HTML."""
+ if not has_docutils:
+ raise Exception('To build this site, you need to install the '
+ '"docutils" package.')
try:
os.makedirs(os.path.dirname(dest))
except:
@@ -65,24 +70,38 @@ class CompileRest(PageCompiler):
with codecs.open(dest, "w+", "utf8") as out_file:
with codecs.open(source, "r", "utf8") as in_file:
data = in_file.read()
- output, error_level = rst2html(
- data, settings_overrides={'initial_header_level': 2})
+ output, error_level, deps = rst2html(
+ data, settings_overrides={
+ 'initial_header_level': 2,
+ 'record_dependencies': True,
+ 'stylesheet_path': None,
+ 'link_stylesheet': True,
+ 'syntax_highlight': 'short',
+ })
out_file.write(output)
+ deps_path = dest + '.dep'
+ if deps.list:
+ with codecs.open(deps_path, "wb+", "utf8") as deps_file:
+ deps_file.write('\n'.join(deps.list))
+ else:
+ if os.path.isfile(deps_path):
+ os.unlink(deps_path)
if error_level < 3:
return True
else:
return False
- def create_post(self, path, onefile=False, title="", slug="", date="",
- tags=""):
+ def create_post(self, path, onefile=False, **kw):
+ metadata = {}
+ metadata.update(self.default_metadata)
+ metadata.update(kw)
+ d_name = os.path.dirname(path)
+ if not os.path.isdir(d_name):
+ os.makedirs(os.path.dirname(path))
with codecs.open(path, "wb+", "utf8") as fd:
if onefile:
- fd.write('.. title: {0}\n'.format(title))
- fd.write('.. slug: {0}\n'.format(slug))
- fd.write('.. date: {0}\n'.format(date))
- fd.write('.. tags: {0}\n'.format(tags))
- fd.write('.. link: \n')
- fd.write('.. description: \n\n')
+ for k, v in metadata.items():
+ fd.write('.. {0}: {1}\n'.format(k, v))
fd.write("\nWrite your post here.")
@@ -116,4 +135,4 @@ def rst2html(source, source_path=None, source_class=docutils.io.StringInput,
settings_overrides=settings_overrides,
config_section=config_section,
enable_exit_status=enable_exit_status)
- return pub.writer.parts['fragment'], pub.document.reporter.max_level
+ return pub.writer.parts['fragment'], pub.document.reporter.max_level, pub.settings.record_dependencies
diff --git a/nikola/plugins/compile_rest/dummy.py b/nikola/plugins/compile_rest/dummy.py
new file mode 100644
index 0000000..39543fd
--- /dev/null
+++ b/nikola/plugins/compile_rest/dummy.py
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2012 Roberto Alsina y otros.
+
+# 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.
+
+"""A stupid codeblock replacement for neanderthals and users of Debian Sid."""
+
+from __future__ import unicode_literals
+
+from docutils import nodes
+from docutils.parsers.rst import Directive, directives
+
+CODE = '<pre>{0}</pre>'
+
+
+class CodeBlock(Directive):
+ required_arguments = 1
+ has_content = True
+
+ def run(self):
+ """ Required by the Directive interface. Create docutils nodes """
+ return [nodes.raw('', CODE.format('\n'.join(self.content)), format='html')]
+
+directives.register_directive('code', CodeBlock)
diff --git a/nikola/plugins/compile_rest/gist_directive.py b/nikola/plugins/compile_rest/gist_directive.py
index 0ea8f23..1506519 100644
--- a/nikola/plugins/compile_rest/gist_directive.py
+++ b/nikola/plugins/compile_rest/gist_directive.py
@@ -28,7 +28,7 @@ class GitHubGist(Directive):
return requests.get(url).text
def get_raw_gist(self, gistID):
- url = "https://raw.github.com/gist/{0}/".format(gistID)
+ url = "https://raw.github.com/gist/{0}".format(gistID)
return requests.get(url).text
def run(self):
diff --git a/nikola/plugins/compile_rest/listing.py b/nikola/plugins/compile_rest/listing.py
new file mode 100644
index 0000000..1b816f5
--- /dev/null
+++ b/nikola/plugins/compile_rest/listing.py
@@ -0,0 +1,121 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2012 Roberto Alsina y otros.
+
+# 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.
+
+
+""" Define and register a listing directive using the existing CodeBlock """
+
+
+from __future__ import unicode_literals
+from codecs import open as codecs_open # for patching purposes
+try:
+ from urlparse import urlunsplit
+except ImportError:
+ from urllib.parse import urlunsplit # NOQA
+
+from docutils import core
+from docutils.parsers.rst import directives
+try:
+ from docutils.parsers.rst.directives.body import CodeBlock
+except ImportError: # docutils < 0.9 (Debian Sid For The Loss)
+ from dummy import CodeBlock # NOQA
+
+import os
+
+
+class Listing(CodeBlock):
+ """ listing directive: create a CodeBlock from file
+
+ Usage:
+
+ .. listing:: nikola.py python
+ :number-lines:
+
+ """
+ has_content = False
+ required_arguments = 1
+ optional_arguments = 1
+
+ option_spec = {
+ 'start-at': directives.unchanged,
+ 'end-at': directives.unchanged,
+ 'start-after': directives.unchanged,
+ 'end-before': directives.unchanged,
+ }
+
+ def run(self):
+ fname = self.arguments.pop(0)
+ with codecs_open(os.path.join('listings', fname), 'rb+', 'utf8') as fileobject:
+ self.content = fileobject.read().splitlines()
+ self.trim_content()
+ target = urlunsplit(("link", 'listing', fname, '', ''))
+ generated_nodes = (
+ [core.publish_doctree('`{0} <{1}>`_'.format(fname, target))[0]])
+ generated_nodes += self.get_code_from_file(fileobject)
+ return generated_nodes
+
+ def trim_content(self):
+ """Cut the contents based in options."""
+ start = 0
+ end = len(self.content)
+ if 'start-at' in self.options:
+ for start, l in enumerate(self.content):
+ if self.options['start-at'] in l:
+ break
+ else:
+ start = 0
+ elif 'start-before' in self.options:
+ for start, l in enumerate(self.content):
+ if self.options['start-before'] in l:
+ if start > 0:
+ start -= 1
+ break
+ else:
+ start = 0
+ if 'end-at' in self.options:
+ for end, l in enumerate(self.content):
+ if self.options['end-at'] in l:
+ break
+ else:
+ end = len(self.content)
+ elif 'end-before' in self.options:
+ for end, l in enumerate(self.content):
+ if self.options['end-before'] in l:
+ end -= 1
+ break
+ else:
+ end = len(self.content)
+
+ self.content = self.content[start:end]
+
+ def get_code_from_file(self, data):
+ """ 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 """
+ pass
+
+
+directives.register_directive('listing', Listing)
diff --git a/nikola/plugins/compile_rest/pygments_code_block_directive.py b/nikola/plugins/compile_rest/pygments_code_block_directive.py
deleted file mode 100644
index 79bada2..0000000
--- a/nikola/plugins/compile_rest/pygments_code_block_directive.py
+++ /dev/null
@@ -1,424 +0,0 @@
-# -*- coding: utf-8 -*-
-#$Date: 2012-02-28 21:07:21 -0300 (Tue, 28 Feb 2012) $
-#$Revision: 2443 $
-
-# :Author: a Pygments author|contributor; Felix Wiemann; Guenter Milde
-# :Date: $Date: 2012-02-28 21:07:21 -0300 (Tue, 28 Feb 2012) $
-# :Copyright: This module has been placed in the public domain.
-#
-# This is a merge of `Using Pygments in ReST documents`_ from the pygments_
-# documentation, and a `proof of concept`_ by Felix Wiemann.
-#
-# ========== ===========================================================
-# 2007-06-01 Removed redundancy from class values.
-# 2007-06-04 Merge of successive tokens of same type
-# (code taken from pygments.formatters.others).
-# 2007-06-05 Separate docutils formatter script
-# Use pygments' CSS class names (like the html formatter)
-# allowing the use of pygments-produced style sheets.
-# 2007-06-07 Merge in the formatting of the parsed tokens
-# (misnamed as docutils_formatter) as class DocutilsInterface
-# 2007-06-08 Failsave implementation (fallback to a standard literal block
-# if pygments not found)
-# ========== ===========================================================
-#
-# ::
-
-"""Define and register a code-block directive using pygments"""
-
-from __future__ import unicode_literals
-
-# Requirements
-# ------------
-# ::
-
-import codecs
-from copy import copy
-import os
-try:
- from urlparse import urlunsplit
-except ImportError:
- from urllib.parse import urlunsplit # NOQA
-
-from docutils import nodes, core
-from docutils.parsers.rst import directives
-
-pygments = None
-try:
- import pygments
- from pygments.lexers import get_lexer_by_name
- from pygments.formatters.html import _get_ttype_class
-except ImportError:
- pass
-
-
-# Customisation
-# -------------
-#
-# Do not insert inline nodes for the following tokens.
-# (You could add e.g. Token.Punctuation like ``['', 'p']``.) ::
-
-unstyled_tokens = ['']
-
-
-# DocutilsInterface
-# -----------------
-#
-# This interface class combines code from
-# pygments.formatters.html and pygments.formatters.others.
-#
-# It does not require anything of docutils and could also become a part of
-# pygments::
-
-class DocutilsInterface(object):
- """Parse `code` string and yield "classified" tokens.
-
- Arguments
-
- code -- string of source code to parse
- language -- formal language the code is written in.
-
- Merge subsequent tokens of the same token-type.
-
- Yields the tokens as ``(ttype_class, value)`` tuples,
- where ttype_class is taken from pygments.token.STANDARD_TYPES and
- corresponds to the class argument used in pygments html output.
-
- """
-
- def __init__(self, code, language, custom_args={}):
- self.code = code
- self.language = language
- self.custom_args = custom_args
-
- def lex(self):
- """Get lexer for language (use text as fallback)"""
- try:
- if self.language and str(self.language).lower() != 'none':
- lexer = get_lexer_by_name(self.language.lower(),
- **self.custom_args)
- else:
- lexer = get_lexer_by_name('text', **self.custom_args)
- except ValueError:
- # what happens if pygment isn't present ?
- lexer = get_lexer_by_name('text')
- return pygments.lex(self.code, lexer)
-
- def join(self, tokens):
- """join subsequent tokens of same token-type
- """
- tokens = iter(tokens)
- (lasttype, lastval) = next(tokens)
- for ttype, value in tokens:
- if ttype is lasttype:
- lastval += value
- else:
- yield(lasttype, lastval)
- (lasttype, lastval) = (ttype, value)
- yield(lasttype, lastval)
-
- def __iter__(self):
- """parse code string and yield "clasified" tokens
- """
- try:
- tokens = self.lex()
- except IOError:
- yield ('', self.code)
- return
-
- for ttype, value in self.join(tokens):
- yield (_get_ttype_class(ttype), value)
-
-
-# code_block_directive
-# --------------------
-# ::
-
-def code_block_directive(name, arguments, options, content, lineno,
- content_offset, block_text, state, state_machine):
- """Parse and classify content of a code_block."""
- if 'include' in options:
- try:
- if 'encoding' in options:
- encoding = options['encoding']
- else:
- encoding = 'utf-8'
- content = codecs.open(
- options['include'], 'r', encoding).read().rstrip()
- except (IOError, UnicodeError): # no file or problem reading it
- content = ''
- line_offset = 0
- if content:
- # here we define the start-at and end-at options
- # so that limit is included in extraction
- # this is different than the start-after directive of docutils
- # (docutils/parsers/rst/directives/misc.py L73+)
- # which excludes the beginning
- # the reason is we want to be able to define a start-at like
- # def mymethod(self)
- # and have such a definition included
-
- after_text = options.get('start-at', None)
- if after_text:
- # skip content in include_text before
- # *and NOT incl.* a matching text
- after_index = content.find(after_text)
- if after_index < 0:
- raise state_machine.reporter.severe(
- 'Problem with "start-at" option of "{0}" '
- 'code-block directive:\nText not found.'.format(
- options['start-at']))
- # patch mmueller start
- # Move the after_index to the beginning of the line with the
- # match.
- for char in content[after_index:0:-1]:
- # codecs always opens binary. This works with '\n',
- # '\r' and '\r\n'. We are going backwards, so
- # '\n' is found first in '\r\n'.
- # Going with .splitlines() seems more appropriate
- # but needs a few more changes.
- if char == '\n' or char == '\r':
- break
- after_index -= 1
- # patch mmueller end
-
- content = content[after_index:]
- line_offset = len(content[:after_index].splitlines())
-
- after_text = options.get('start-after', None)
- if after_text:
- # skip content in include_text before
- # *and incl.* a matching text
- after_index = content.find(after_text)
- if after_index < 0:
- raise state_machine.reporter.severe(
- 'Problem with "start-after" option of "{0}" '
- 'code-block directive:\nText not found.'.format(
- options['start-after']))
- line_offset = len(content[:after_index +
- len(after_text)].splitlines())
- content = content[after_index + len(after_text):]
-
- # same changes here for the same reason
- before_text = options.get('end-at', None)
- if before_text:
- # skip content in include_text after
- # *and incl.* a matching text
- before_index = content.find(before_text)
- if before_index < 0:
- raise state_machine.reporter.severe(
- 'Problem with "end-at" option of "{0}" '
- 'code-block directive:\nText not found.'.format(
- options['end-at']))
- content = content[:before_index + len(before_text)]
-
- before_text = options.get('end-before', None)
- if before_text:
- # skip content in include_text after
- # *and NOT incl.* a matching text
- before_index = content.find(before_text)
- if before_index < 0:
- raise state_machine.reporter.severe(
- 'Problem with "end-before" option of "{0}" '
- 'code-block directive:\nText not found.'.format(
- options['end-before']))
- content = content[:before_index]
-
- else:
- content = '\n'.join(content)
-
- if 'tabsize' in options:
- tabw = options['tabsize']
- else:
- tabw = int(options.get('tab-width', 8))
-
- content = content.replace('\t', ' ' * tabw)
-
- withln = "linenos" in options
- if not "linenos_offset" in options:
- line_offset = 0
-
- language = arguments[0]
- # create a literal block element and set class argument
- code_block = nodes.literal_block(classes=["code", language])
-
- if withln:
- lineno = 1 + line_offset
- total_lines = content.count('\n') + 1 + line_offset
- lnwidth = len(str(total_lines))
- fstr = "\n%{0}d ".format(lnwidth)
- code_block += nodes.inline(fstr[1:].format(lineno),
- fstr[1:].format(lineno),
- classes=['linenumber'])
-
- # parse content with pygments and add to code_block element
- content = content.rstrip()
- if pygments is None:
- code_block += nodes.Text(content, content)
- else:
- # The [:-1] is because pygments adds a trailing \n which looks bad
- l = list(DocutilsInterface(content, language, options))
- if l[-1] == ('', '\n'):
- l = l[:-1]
- # We strip last element for the same reason (trailing \n looks bad)
- if l:
- l[-1] = (l[-1][0], l[-1][1].rstrip())
- for cls, value in l:
- if withln and "\n" in value:
- # Split on the "\n"s
- values = value.split("\n")
- # The first piece, pass as-is
- code_block += nodes.Text(values[0], values[0])
- # On the second and later pieces, insert \n and linenos
- linenos = list(range(lineno, lineno + len(values)))
- for chunk, ln in zip(values, linenos)[1:]:
- if ln <= total_lines:
- code_block += nodes.inline(fstr.format(ln),
- fstr.format(ln),
- classes=['linenumber'])
- code_block += nodes.Text(chunk, chunk)
- lineno += len(values) - 1
-
- elif cls in unstyled_tokens:
- # insert as Text to decrease the verbosity of the output.
- code_block += nodes.Text(value, value)
- else:
- code_block += nodes.inline(value, value, classes=[cls])
-
- return [code_block]
-
-# Custom argument validators
-# --------------------------
-# ::
-#
-# Move to separated module??
-
-
-def string_list(argument):
- """
- Converts a space- or comma-separated list of values into a python list
- of strings.
- (Directive option conversion function)
- Based in positive_int_list of docutils.parsers.rst.directives
- """
- if ',' in argument:
- entries = argument.split(',')
- else:
- entries = argument.split()
- return entries
-
-
-def string_bool(argument):
- """
- Converts True, true, False, False in python boolean values
- """
- if argument is None:
- msg = 'argument required but none supplied; choose "True" or "False"'
- raise ValueError(msg)
-
- elif argument.lower() == 'true':
- return True
- elif argument.lower() == 'false':
- return False
- else:
- raise ValueError('"{0}" unknown; choose from "True" or "False"'.format(
- argument))
-
-
-def csharp_unicodelevel(argument):
- return directives.choice(argument, ('none', 'basic', 'full'))
-
-
-def lhs_litstyle(argument):
- return directives.choice(argument, ('bird', 'latex'))
-
-
-def raw_compress(argument):
- return directives.choice(argument, ('gz', 'bz2'))
-
-
-def listings_directive(name, arguments, options, content, lineno,
- content_offset, block_text, state, state_machine):
- fname = arguments[0]
- options['include'] = os.path.join('listings', fname)
- target = urlunsplit(("link", 'listing', fname, '', ''))
- generated_nodes = [core.publish_doctree('`{0} <{1}>`_'.format(fname,
- target))[0]]
- generated_nodes += code_block_directive(name, [arguments[1]], options,
- content, lineno, content_offset,
- block_text, state, state_machine)
- return generated_nodes
-
-code_block_directive.arguments = (1, 0, 1)
-listings_directive.arguments = (2, 0, 1)
-code_block_directive.content = 1
-listings_directive.content = 1
-code_block_directive.options = {'include': directives.unchanged_required,
- 'start-at': directives.unchanged_required,
- 'end-at': directives.unchanged_required,
- 'start-after': directives.unchanged_required,
- 'end-before': directives.unchanged_required,
- 'linenos': directives.unchanged,
- 'linenos_offset': directives.unchanged,
- 'tab-width': directives.unchanged,
- # generic
- 'stripnl': string_bool,
- 'stripall': string_bool,
- 'ensurenl': string_bool,
- 'tabsize': directives.positive_int,
- 'encoding': directives.encoding,
- # Lua
- 'func_name_hightlighting': string_bool,
- 'disabled_modules': string_list,
- # Python Console
- 'python3': string_bool,
- # Delphi
- 'turbopascal': string_bool,
- 'delphi': string_bool,
- 'freepascal': string_bool,
- 'units': string_list,
- # Modula2
- 'pim': string_bool,
- 'iso': string_bool,
- 'objm2': string_bool,
- 'gm2ext': string_bool,
- # CSharp
- 'unicodelevel': csharp_unicodelevel,
- # Literate haskell
- 'litstyle': lhs_litstyle,
- # Raw
- 'compress': raw_compress,
- # Rst
- 'handlecodeblocks': string_bool,
- # Php
- 'startinline': string_bool,
- 'funcnamehighlighting': string_bool,
- 'disabledmodules': string_list,
- }
-
-listings_directive.options = copy(code_block_directive.options)
-listings_directive.options.pop('include')
-
-# .. _doctutils: http://docutils.sf.net/
-# .. _pygments: http://pygments.org/
-# .. _Using Pygments in ReST documents: http://pygments.org/docs/rstdirective/
-# .. _proof of concept:
-# http://article.gmane.org/gmane.text.docutils.user/3689
-#
-# Test output
-# -----------
-#
-# If called from the command line, call the docutils publisher to render the
-# input::
-
-if __name__ == '__main__':
- from docutils.core import publish_cmdline, default_description
- from docutils.parsers.rst import directives
- directives.register_directive('code-block', code_block_directive)
- description = "code-block directive test output" + default_description
- try:
- import locale
- locale.setlocale(locale.LC_ALL, '')
- except Exception:
- pass
- publish_cmdline(writer_name='html', description=description)
diff --git a/nikola/plugins/compile_rest/slides.py b/nikola/plugins/compile_rest/slides.py
index f9901f5..57fb754 100644
--- a/nikola/plugins/compile_rest/slides.py
+++ b/nikola/plugins/compile_rest/slides.py
@@ -22,71 +22,44 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-import json
+from __future__ import unicode_literals
from docutils import nodes
from docutils.parsers.rst import Directive, directives
-class slides(Directive):
+class Slides(Directive):
""" Restructured text extension for inserting slideshows."""
has_content = True
- option_spec = {
- "preload": directives.flag,
- "preloadImage": directives.uri,
- "container": directives.unchanged,
- "generateNextPrev": directives.flag,
- "next": directives.unchanged,
- "prev": directives.unchanged,
- "pagination": directives.flag,
- "generatePagination": directives.flag,
- "paginationClass": directives.unchanged,
- "currentClass": directives.unchanged,
- "fadeSpeed": directives.positive_int,
- "fadeEasing": directives.unchanged,
- "slideSpeed": directives.positive_int,
- "slideEasing": directives.unchanged,
- "start": directives.positive_int,
- "effect": directives.unchanged,
- "crossfade": directives.flag,
- "randomize": directives.flag,
- "play": directives.positive_int,
- "pause": directives.positive_int,
- "hoverPause": directives.flag,
- "autoHeight": directives.flag,
- "autoHeightSpeed": directives.positive_int,
- "bigTarget": directives.flag,
- "animationStart": directives.unchanged,
- "animationComplete": directives.unchanged,
- }
def run(self):
if len(self.content) == 0:
return
- for opt in ("preload", "generateNextPrev", "pagination",
- "generatePagination", "crossfade", "randomize",
- "hoverPause", "autoHeight", "bigTarget"):
- if opt in self.options:
- self.options[opt] = True
- options = {
- "autoHeight": True,
- "bigTarget": True,
- "paginationClass": "pager",
- "currentClass": "slide-current"
- }
- options.update(self.options)
- options = json.dumps(options)
output = []
- output.append('<script> $(function(){ $("#slides").slides(' + options +
- '); });'
- '</script>')
- output.append('<div id="slides" class="slides"><div '
- 'class="slides_container">')
- for image in self.content:
- output.append("""<div><img src="{0}"></div>""".format(image))
- output.append("""</div></div>""")
-
+ output.append("""
+ <div id="myCarousel" class="carousel slide">
+ <ol class="carousel-indicators">
+ """)
+ for i in range(len(self.content)):
+ if i == 0:
+ classname = 'class="active"'
+ else:
+ classname = ''
+ output.append(' <li data-target="#myCarousel" data-slide-to="{0}" {1}></li>'.format(i, classname))
+ output.append("""</ol>
+ <div class="carousel-inner">
+ """)
+ for i, image in enumerate(self.content):
+ if i == 0:
+ classname = "item active"
+ else:
+ classname = "item"
+ output.append("""<div class="{0}"><img src="{1}" alt="" style="margin: 0 auto 0 auto;"></div>""".format(classname, image))
+ output.append("""</div>
+ <a class="left carousel-control" href="#myCarousel" data-slide="prev">&lsaquo;</a>
+ <a class="right carousel-control" href="#myCarousel" data-slide="next">&rsaquo;</a>
+ </div>""")
return [nodes.raw('', '\n'.join(output), format='html')]
-directives.register_directive('slides', slides)
+directives.register_directive('slides', Slides)
diff --git a/nikola/plugins/compile_rest/soundcloud.py b/nikola/plugins/compile_rest/soundcloud.py
index d47bebf..6bdd4d5 100644
--- a/nikola/plugins/compile_rest/soundcloud.py
+++ b/nikola/plugins/compile_rest/soundcloud.py
@@ -1,5 +1,9 @@
+# coding: utf8
+
+
from docutils import nodes
-from docutils.parsers.rst import directives
+from docutils.parsers.rst import Directive, directives
+
CODE = ("""<iframe width="{width}" height="{height}"
scrolling="no" frameborder="no"
@@ -8,25 +12,39 @@ src="https://w.soundcloud.com/player/?url=http://api.soundcloud.com/tracks/"""
</iframe>""")
-def soundcloud(name, args, options, content, lineno,
- contentOffset, blockText, state, stateMachine):
- """ Restructured text extension for inserting SoundCloud embedded music """
- string_vars = {
- 'sid': content[0],
- 'width': 600,
- 'height': 160,
- 'extra': ''
+class SoundCloud(Directive):
+ """ Restructured text extension for inserting SoundCloud embedded music
+
+ Usage:
+ .. soundcloud:: <sound id>
+ :height: 400
+ :width: 600
+
+ """
+ has_content = True
+ required_arguments = 1
+ option_spec = {
+ 'width': directives.positive_int,
+ 'height': directives.positive_int,
}
- extra_args = content[1:] # Because content[0] is ID
- extra_args = [ea.strip().split("=") for ea in extra_args] # key=value
- extra_args = [ea for ea in extra_args if len(ea) == 2] # drop bad lines
- extra_args = dict(extra_args)
- if 'width' in extra_args:
- string_vars['width'] = extra_args.pop('width')
- if 'height' in extra_args:
- string_vars['height'] = extra_args.pop('height')
-
- return [nodes.raw('', CODE.format(**string_vars), format='html')]
-
-soundcloud.content = True
-directives.register_directive('soundcloud', soundcloud)
+
+ def run(self):
+ """ Required by the Directive interface. Create docutils nodes """
+ self.check_content()
+ options = {
+ 'sid': self.arguments[0],
+ 'width': 600,
+ 'height': 160,
+ }
+ options.update(self.options)
+ return [nodes.raw('', CODE.format(**options), format='html')]
+
+ def check_content(self):
+ """ Emit a deprecation warning if there is content """
+ if self.content:
+ raise self.warning("This directive does not accept content. The "
+ "'key=value' format for options is deprecated, "
+ "use ':key: value' instead")
+
+
+directives.register_directive('soundcloud', SoundCloud)
diff --git a/nikola/plugins/compile_rest/vimeo.py b/nikola/plugins/compile_rest/vimeo.py
index 34f2a50..c1dc143 100644
--- a/nikola/plugins/compile_rest/vimeo.py
+++ b/nikola/plugins/compile_rest/vimeo.py
@@ -1,3 +1,4 @@
+# coding: utf8
# Copyright (c) 2012 Roberto Alsina y otros.
# Permission is hereby granted, free of charge, to any
@@ -22,8 +23,9 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
from docutils import nodes
-from docutils.parsers.rst import directives
+from docutils.parsers.rst import Directive, directives
try:
import requests
@@ -37,6 +39,7 @@ except ImportError:
except ImportError:
json = None
+
CODE = """<iframe src="http://player.vimeo.com/video/{vimeo_id}"
width="{width}" height="{height}"
frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen>
@@ -47,46 +50,69 @@ VIDEO_DEFAULT_HEIGHT = 500
VIDEO_DEFAULT_WIDTH = 281
-def vimeo(name, args, options, content, lineno, contentOffset, blockText,
- state, stateMachine):
- """ Restructured text extension for inserting vimeo embedded videos """
- if requests is None:
- raise Exception("To use the Vimeo directive you need to install the "
- "requests module.")
- if json is None:
- raise Exception("To use the Vimeo directive you need python 2.6 or to "
- "install the simplejson module.")
- if len(content) == 0:
- return
-
- string_vars = {'vimeo_id': content[0]}
- extra_args = content[1:] # Because content[0] is ID
- extra_args = [ea.strip().split("=") for ea in extra_args] # key=value
- extra_args = [ea for ea in extra_args if len(ea) == 2] # drop bad lines
- extra_args = dict(extra_args)
- if 'width' in extra_args:
- string_vars['width'] = extra_args.pop('width')
- if 'height' in extra_args:
- string_vars['height'] = extra_args.pop('height')
-
- # Only need to make a connection if width and height aren't provided
- if 'height' not in string_vars or 'width' not in string_vars:
- string_vars['height'] = VIDEO_DEFAULT_HEIGHT
- string_vars['width'] = VIDEO_DEFAULT_WIDTH
-
- if json: # we can attempt to retrieve video attributes from vimeo
- try:
- url = ('http://vimeo.com/api/v2/video/{vimeo_id}'
- '.json'.format(**string_vars))
- data = requests.get(url).text
- video_attributes = json.loads(data)
- string_vars['height'] = video_attributes['height']
- string_vars['width'] = video_attributes['width']
- except Exception:
- # fall back to the defaults
- pass
-
- return [nodes.raw('', CODE.format(**string_vars), format='html')]
-
-vimeo.content = True
-directives.register_directive('vimeo', vimeo)
+class Vimeo(Directive):
+ """ Restructured text extension for inserting vimeo embedded videos
+
+ Usage:
+ .. vimeo:: 20241459
+ :height: 400
+ :width: 600
+
+ """
+ has_content = True
+ required_arguments = 1
+ option_spec = {
+ "width": directives.positive_int,
+ "height": directives.positive_int,
+ }
+
+ # set to False for not querying the vimeo api for size
+ request_size = True
+
+ def run(self):
+ self.check_content()
+ options = {
+ 'vimeo_id': self.arguments[0],
+ 'width': VIDEO_DEFAULT_WIDTH,
+ 'height': VIDEO_DEFAULT_HEIGHT,
+ }
+ if self.request_size:
+ self.check_modules()
+ self.set_video_size()
+ options.update(self.options)
+ return [nodes.raw('', CODE.format(**options), format='html')]
+
+ def check_modules(self):
+ if requests is None:
+ raise Exception("To use the Vimeo directive you need to install "
+ "the requests module.")
+ if json is None:
+ raise Exception("To use the Vimeo directive you need python 2.6 "
+ "or to install the simplejson module.")
+
+ def set_video_size(self):
+ # 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
+ self.options['width'] = VIDEO_DEFAULT_WIDTH
+
+ if json: # we can attempt to retrieve video attributes from vimeo
+ try:
+ url = ('http://vimeo.com/api/v2/video/{0}'
+ '.json'.format(self.arguments[0]))
+ data = requests.get(url).text
+ video_attributes = json.loads(data)[0]
+ self.options['height'] = video_attributes['height']
+ self.options['width'] = video_attributes['width']
+ except Exception:
+ # fall back to the defaults
+ pass
+
+ def check_content(self):
+ if self.content:
+ raise self.warning("This directive does not accept content. The "
+ "'key=value' format for options is deprecated, "
+ "use ':key: value' instead")
+
+
+directives.register_directive('vimeo', Vimeo)
diff --git a/nikola/plugins/compile_rest/youtube.py b/nikola/plugins/compile_rest/youtube.py
index 30ac000..767be32 100644
--- a/nikola/plugins/compile_rest/youtube.py
+++ b/nikola/plugins/compile_rest/youtube.py
@@ -23,7 +23,8 @@
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
from docutils import nodes
-from docutils.parsers.rst import directives
+from docutils.parsers.rst import Directive, directives
+
CODE = """\
<iframe width="{width}"
@@ -32,25 +33,37 @@ src="http://www.youtube.com/embed/{yid}?rel=0&amp;hd=1&amp;wmode=transparent"
></iframe>"""
-def youtube(name, args, options, content, lineno,
- contentOffset, blockText, state, stateMachine):
- """ Restructured text extension for inserting youtube embedded videos """
- if len(content) == 0:
- return
- string_vars = {
- 'yid': content[0],
- 'width': 425,
- 'height': 344,
- 'extra': ''
+class Youtube(Directive):
+ """ Restructured text extension for inserting youtube embedded videos
+
+ Usage:
+ .. youtube:: lyViVmaBQDg
+ :height: 400
+ :width: 600
+
+ """
+ has_content = True
+ required_arguments = 1
+ option_spec = {
+ "width": directives.positive_int,
+ "height": directives.positive_int,
}
- extra_args = content[1:] # Because content[0] is ID
- extra_args = [ea.strip().split("=") for ea in extra_args] # key=value
- extra_args = [ea for ea in extra_args if len(ea) == 2] # drop bad lines
- extra_args = dict(extra_args)
- if 'width' in extra_args:
- string_vars['width'] = extra_args.pop('width')
- if 'height' in extra_args:
- string_vars['height'] = extra_args.pop('height')
- return [nodes.raw('', CODE.format(**string_vars), format='html')]
-youtube.content = True
-directives.register_directive('youtube', youtube)
+
+ def run(self):
+ self.check_content()
+ options = {
+ 'yid': self.arguments[0],
+ 'width': 425,
+ 'height': 344,
+ }
+ options.update(self.options)
+ return [nodes.raw('', CODE.format(**options), format='html')]
+
+ def check_content(self):
+ if self.content:
+ raise self.warning("This directive does not accept content. The "
+ "'key=value' format for options is deprecated, "
+ "use ':key: value' instead")
+
+
+directives.register_directive('youtube', Youtube)