summaryrefslogtreecommitdiffstats
path: root/nikola/plugins/compile_rest
diff options
context:
space:
mode:
Diffstat (limited to 'nikola/plugins/compile_rest')
-rw-r--r--nikola/plugins/compile_rest/__init__.py36
-rw-r--r--nikola/plugins/compile_rest/gist_directive.py56
-rw-r--r--nikola/plugins/compile_rest/pygments_code_block_directive.py32
-rw-r--r--nikola/plugins/compile_rest/slides.py26
-rw-r--r--nikola/plugins/compile_rest/vimeo.py92
-rw-r--r--nikola/plugins/compile_rest/youtube.py11
6 files changed, 209 insertions, 44 deletions
diff --git a/nikola/plugins/compile_rest/__init__.py b/nikola/plugins/compile_rest/__init__.py
index 0e677e1..4191add 100644
--- a/nikola/plugins/compile_rest/__init__.py
+++ b/nikola/plugins/compile_rest/__init__.py
@@ -8,11 +8,11 @@
# 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
@@ -38,8 +38,12 @@ 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 nikola.plugin_categories import PageCompiler
@@ -59,23 +63,33 @@ 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 = rst2html(
+ data, settings_overrides={'initial_header_level': 2})
out_file.write(output)
if error_level < 3:
return True
else:
return False
+ def create_post(self, path, onefile=False, title="", slug="", date="",
+ tags=""):
+ with codecs.open(path, "wb+", "utf8") as fd:
+ if onefile:
+ fd.write('.. title: %s\n' % title)
+ fd.write('.. slug: %s\n' % slug)
+ fd.write('.. date: %s\n' % date)
+ fd.write('.. tags: %s\n' % tags)
+ fd.write('.. link: \n')
+ fd.write('.. description: \n\n')
+ fd.write("\nWrite your post here.")
+
def rst2html(source, source_path=None, source_class=docutils.io.StringInput,
- destination_path=None,
- reader=None, reader_name='standalone',
- parser=None, parser_name='restructuredtext',
- writer=None, writer_name='html',
- settings=None, settings_spec=None,
- settings_overrides=None, config_section=None,
- enable_exit_status=None):
+ destination_path=None, reader=None, reader_name='standalone',
+ parser=None, parser_name='restructuredtext', writer=None,
+ writer_name='html', settings=None, settings_spec=None,
+ settings_overrides=None, config_section=None,
+ enable_exit_status=None):
"""
Set up & run a `Publisher`, and return a dictionary of document parts.
Dictionary keys are the names of parts, and values are Unicode strings;
diff --git a/nikola/plugins/compile_rest/gist_directive.py b/nikola/plugins/compile_rest/gist_directive.py
new file mode 100644
index 0000000..3bfe818
--- /dev/null
+++ b/nikola/plugins/compile_rest/gist_directive.py
@@ -0,0 +1,56 @@
+# This file is public domain according to its author, Brian Hsu
+
+from docutils.parsers.rst import Directive, directives
+from docutils import nodes
+
+try:
+ import requests
+except ImportError:
+ requests = None # NOQA
+
+
+class GitHubGist(Directive):
+ """ Embed GitHub Gist.
+
+ Usage:
+ .. gist:: GIST_ID
+
+ """
+
+ required_arguments = 1
+ optional_arguments = 1
+ option_spec = {'file': directives.unchanged}
+ final_argument_whitespace = True
+ has_content = False
+
+ def get_raw_gist_with_filename(self, gistID, filename):
+ url = "https://raw.github.com/gist/%s/%s" % (gistID, filename)
+ return requests.get(url).text
+
+ def get_raw_gist(self, gistID):
+ url = "https://raw.github.com/gist/%s/" % (gistID)
+ return requests.get(url).text
+
+ def run(self):
+ if requests is None:
+ print('To use the gist directive, you need to install the '
+ '"requests" package.')
+ return []
+ gistID = self.arguments[0].strip()
+ embedHTML = ""
+ rawGist = ""
+
+ if 'file' in self.options:
+ filename = self.options['file']
+ rawGist = (self.get_raw_gist_with_filename(gistID, filename))
+ embedHTML = ('<script src="https://gist.github.com/%s.js?file=%s">'
+ '</script>') % (gistID, filename)
+ else:
+ rawGist = (self.get_raw_gist(gistID))
+ embedHTML = ('<script src="https://gist.github.com/%s.js">'
+ '</script>') % gistID
+
+ return [nodes.raw('', embedHTML, format='html'),
+ nodes.raw('', '<noscript>', format='html'),
+ nodes.literal_block('', rawGist),
+ nodes.raw('', '</noscript>', format='html')]
diff --git a/nikola/plugins/compile_rest/pygments_code_block_directive.py b/nikola/plugins/compile_rest/pygments_code_block_directive.py
index a83098f..f858427 100644
--- a/nikola/plugins/compile_rest/pygments_code_block_directive.py
+++ b/nikola/plugins/compile_rest/pygments_code_block_directive.py
@@ -36,9 +36,9 @@ import codecs
from copy import copy
import os
try:
- from urlparse import urlparse, urlunsplit
+ from urlparse import urlunsplit
except ImportError:
- from urllib.parse import urlparse, urlunsplit
+ from urllib.parse import urlunsplit # NOQA
from docutils import nodes, core
from docutils.parsers.rst import directives
@@ -96,8 +96,7 @@ class DocutilsInterface(object):
try:
if self.language and str(self.language).lower() != 'none':
lexer = get_lexer_by_name(self.language.lower(),
- **self.custom_args
- )
+ **self.custom_args)
else:
lexer = get_lexer_by_name('text', **self.custom_args)
except ValueError:
@@ -136,7 +135,7 @@ class DocutilsInterface(object):
# ::
def code_block_directive(name, arguments, options, content, lineno,
- content_offset, block_text, state, state_machine):
+ content_offset, block_text, state, state_machine):
"""Parse and classify content of a code_block."""
if 'include' in options:
try:
@@ -173,8 +172,8 @@ def code_block_directive(name, arguments, options, content, lineno,
# 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
+ # 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.
@@ -197,7 +196,7 @@ def code_block_directive(name, arguments, options, content, lineno,
'code-block directive:\nText not found.' %
options['start-after'])
line_offset = len(content[:after_index +
- len(after_text)].splitlines())
+ len(after_text)].splitlines())
content = content[after_index + len(after_text):]
# same changes here for the same reason
@@ -249,7 +248,7 @@ def code_block_directive(name, arguments, options, content, lineno,
lnwidth = len(str(total_lines))
fstr = "\n%%%dd " % lnwidth
code_block += nodes.inline(fstr[1:] % lineno, fstr[1:] % lineno,
- classes=['linenumber'])
+ classes=['linenumber'])
# parse content with pygments and add to code_block element
content = content.rstrip()
@@ -260,6 +259,9 @@ def code_block_directive(name, arguments, options, content, lineno,
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
@@ -271,7 +273,7 @@ def code_block_directive(name, arguments, options, content, lineno,
for chunk, ln in zip(values, linenos)[1:]:
if ln <= total_lines:
code_block += nodes.inline(fstr % ln, fstr % ln,
- classes=['linenumber'])
+ classes=['linenumber'])
code_block += nodes.Text(chunk, chunk)
lineno += len(values) - 1
@@ -317,8 +319,8 @@ def string_bool(argument):
elif argument.lower() == 'false':
return False
else:
- raise ValueError('"%s" unknown; choose from "True" or "False"'
- % argument)
+ raise ValueError('"%s" unknown; choose from "True" or "False"' %
+ argument)
def csharp_unicodelevel(argument):
@@ -339,9 +341,9 @@ def listings_directive(name, arguments, options, content, lineno,
options['include'] = os.path.join('listings', fname)
target = urlunsplit(("link", 'listing', fname, '', ''))
generated_nodes = [core.publish_doctree('`%s <%s>`_' % (fname, target))[0]]
- generated_nodes += code_block_directive(name, [arguments[1]],
- options, content, lineno, content_offset, block_text,
- state, state_machine)
+ 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)
diff --git a/nikola/plugins/compile_rest/slides.py b/nikola/plugins/compile_rest/slides.py
index 942a7d4..c9d55f3 100644
--- a/nikola/plugins/compile_rest/slides.py
+++ b/nikola/plugins/compile_rest/slides.py
@@ -8,11 +8,11 @@
# 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
@@ -27,10 +27,9 @@ import json
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,
@@ -60,12 +59,13 @@ class slides(Directive):
"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"):
+ for opt in ("preload", "generateNextPrev", "pagination",
+ "generatePagination", "crossfade", "randomize",
+ "hoverPause", "autoHeight", "bigTarget"):
if opt in self.options:
self.options[opt] = True
options = {
@@ -73,17 +73,19 @@ class slides(Directive):
"bigTarget": True,
"paginationClass": "pager",
"currentClass": "slide-current"
- }
+ }
options.update(self.options)
options = json.dumps(options)
output = []
- output.append("""<script> $(function(){ $("#slides").slides(%s); }); </script>""" % options)
- output.append("""<div id="slides" class="slides"><div class="slides_container">""")
+ output.append('<script> $(function(){ $("#slides").slides(%s); });'
+ '</script>' % options)
+ output.append('<div id="slides" class="slides"><div '
+ 'class="slides_container">')
for image in self.content:
output.append("""<div><img src="%s"></div>""" % image)
output.append("""</div></div>""")
-
+
return [nodes.raw('', '\n'.join(output), format='html')]
-
+
directives.register_directive('slides', slides)
diff --git a/nikola/plugins/compile_rest/vimeo.py b/nikola/plugins/compile_rest/vimeo.py
new file mode 100644
index 0000000..3eefcc4
--- /dev/null
+++ b/nikola/plugins/compile_rest/vimeo.py
@@ -0,0 +1,92 @@
+# 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.
+
+from docutils import nodes
+from docutils.parsers.rst import directives
+
+try:
+ import requests
+except ImportError:
+ requests = None # NOQA
+try:
+ import json # python 2.6 or higher
+except ImportError:
+ try:
+ import simplejson as json # NOQA
+ except ImportError:
+ json = None
+
+CODE = """<iframe src="http://player.vimeo.com/video/%(vimeo_id)s"
+width="%(width)s" height="%(height)s"
+frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen>
+</iframe>
+"""
+
+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)s.json' %
+ 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 % string_vars, format='html')]
+
+vimeo.content = True
+directives.register_directive('vimeo', vimeo)
diff --git a/nikola/plugins/compile_rest/youtube.py b/nikola/plugins/compile_rest/youtube.py
index 0765158..fe3b28b 100644
--- a/nikola/plugins/compile_rest/youtube.py
+++ b/nikola/plugins/compile_rest/youtube.py
@@ -8,11 +8,11 @@
# 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
@@ -28,9 +28,8 @@ from docutils.parsers.rst import directives
CODE = """\
<iframe width="%(width)s"
height="%(height)s"
-src="http://www.youtube.com/embed/%(yid)s?rel=0&amp;hd=1&amp;wmode=transparent">
-</iframe>
-"""
+src="http://www.youtube.com/embed/%(yid)s?rel=0&amp;hd=1&amp;wmode=transparent"
+></iframe>"""
def youtube(name, args, options, content, lineno,
@@ -43,7 +42,7 @@ def youtube(name, args, options, content, lineno,
'width': 425,
'height': 344,
'extra': ''
- }
+ }
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