Skip to content
Permalink
Browse files
Merge pull request #2247 from getnikola/rst_extensions_exposed_as_sho…
…rtcodes

Implement some rst directives as shortcode for markdown (Issue #2170)
  • Loading branch information
ralsina committed Mar 8, 2016
2 parents 3f1a22d + b8a155a commit 2f7c91b636a424fb6058f6178638ef2fd05aa894
Showing with 70 additions and 30 deletions.
  1. +1 −0 CHANGES.txt
  2. +22 −1 docs/manual.txt
  3. +1 −1 nikola/nikola.py
  4. +36 −23 nikola/plugins/compile/rest/chart.py
  5. +10 −5 nikola/plugins/compile/rest/media.py
@@ -4,6 +4,7 @@ New in master
Features
--------

* New Pygal-based chart shortcode (Issue #2170)
* Add ``post_type`` to post-list directive (Issue #2272)
* Use ``sys.executable`` for launching pip in ``plugin`` (Issue #2275)

@@ -813,7 +813,7 @@ To use them from plugins, please see `Extending Nikola <https://getnikola.com/ex
Using a shortcode
~~~~~~~~~~~~~~~~~

In your content files, a shortcode can be called by using the ``{{% name parameters %}}`` form. Shortcode parameters are space delimited. Parameters with spaces can be quoted (or backslash escaped).
In your content files, a shortcode can be called by using the {{% raw %}}{{% name parameters %}}{{% /raw %}} form. Shortcode parameters are space delimited. Parameters with spaces can be quoted (or backslash escaped).

The first word is always the name of the shortcode. Parameters follow the name. Depending upon how the shortcode is defined, the parameters may be named, positional or both. The format for named parameters models that of HTML with the format name="value".

@@ -829,6 +829,27 @@ Built-in shortcodes
post-list
Will show a list of posts, see the `Post List directive for details <#post-list>`__

media
Display media embedded from a URL, for example, this will embed a youtube video::

{{% raw %}}{{% media url="https://www.youtube.com/watch?v=Nck6BZga7TQ" %}}{{% /raw %}}

In reStructuredText this shortcode will fail because docutils turns that URL to a link and everything breaks, use the `media directive <#media>`__ instead.

chart
Create charts via PyGal. This is similar to the `chart directive <#chart>`__ except the syntax is adapted to
shortcodes. This is an example::

{{% raw %}}{{% chart Bar title='Browser usage evolution (in %)' %}}
x_labels='["2002","2003","2004","2005","2006","2007","2008","2009","2010","2011","2012"]'%}}
'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]
{{% /chart %}}{{% /raw %}}

In reStructuredText the quoting needed to pass arguments gets insane really fast, use the chart directive
instead (the syntax is nicer anyway)

Template-based shortcodes
~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1336,7 +1336,7 @@ def render_shortcode(t_data=template_data, **kw):
def register_shortcode(self, name, f):
"""Register function f to handle shortcode "name"."""
if name in self.shortcode_registry:
utils.LOGGER.warn('Shortcode name conflict: %s', name)
utils.LOGGER.warn('Shortcode name conflict: {}', name)
return
self.shortcode_registry[name] = f

@@ -52,6 +52,7 @@ def set_site(self, site):
global _site
_site = self.site = site
directives.register_directive('chart', Chart)
self.site.register_shortcode('chart', _gen_chart)
return super(Plugin, self).set_site(site)


@@ -134,29 +135,41 @@ 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('', '<div class="text-error">{0}</div>'.format(msg), format='html')]
options = {}
if 'style' in self.options:
style_name = self.options.pop('style')
else:
style_name = 'BlueStyle'
if '(' in style_name: # Parametric style
style = eval('pygal.style.' + style_name)
else:
style = getattr(pygal.style, style_name)
for k, v in self.options.items():
self.options['site'] = None
html = _gen_chart(self.arguments[0], data='\n'.join(self.content), **self.options)
return [nodes.raw('', html, format='html')]


def _gen_chart(chart_type, **_options):
if pygal is None:
msg = req_missing(['pygal'], 'use the Chart directive', optional=True)
return '<div class="text-error">{0}</div>'.format(msg)
options = {}
data = _options.pop('data')
_options.pop('site')
if 'style' in _options:
style_name = _options.pop('style')
else:
style_name = 'BlueStyle'
if '(' in style_name: # Parametric style
style = eval('pygal.style.' + style_name)
else:
style = getattr(pygal.style, style_name)
for k, v in _options.items():
try:
options[k] = literal_eval(v)
chart = pygal
for o in self.arguments[0].split('.'):
chart = getattr(chart, o)
chart = chart(style=style)
if _site and _site.invariant:
chart.no_prefix = True
chart.config(**options)
for line in self.content:
except:
options[k] = v
chart = pygal
for o in chart_type.split('.'):
chart = getattr(chart, o)
chart = chart(style=style)
if _site and _site.invariant:
chart.no_prefix = True
chart.config(**options)
for line in data.splitlines():
line = line.strip()
if line:
label, series = literal_eval('({0})'.format(line))
chart.add(label, series)
data = chart.render().decode('utf8')
return [nodes.raw('', data, format='html')]
return chart.render().decode('utf8')
@@ -48,6 +48,7 @@ def set_site(self, site):
"""Set Nikola site."""
self.site = site
directives.register_directive('media', Media)
self.site.register_shortcode('media', _gen_media_embed)
return super(Plugin, self).set_site(site)


@@ -60,9 +61,13 @@ class Media(Directive):

def run(self):
"""Run media directive."""
if micawber is None:
msg = req_missing(['micawber'], 'use the media directive', optional=True)
return [nodes.raw('', '<div class="text-error">{0}</div>'.format(msg), format='html')]
html = _gen_media_embed(" ".join(self.arguments))
return [nodes.raw('', html, format='html')]

providers = micawber.bootstrap_basic()
return [nodes.raw('', micawber.parse_text(" ".join(self.arguments), providers), format='html')]

def _gen_media_embed(url, *q, **kw):
if micawber is None:
msg = req_missing(['micawber'], 'use the media directive', optional=True)
return '<div class="text-error">{0}</div>'.format(msg)
providers = micawber.bootstrap_basic()
return micawber.parse_text(url, providers)

0 comments on commit 2f7c91b

Please sign in to comment.