Skip to content

Commit 2f7c91b

Browse files
committedMar 8, 2016
Merge pull request #2247 from getnikola/rst_extensions_exposed_as_shortcodes
Implement some rst directives as shortcode for markdown (Issue #2170)
2 parents 3f1a22d + b8a155a commit 2f7c91b

File tree

5 files changed

+70
-30
lines changed

5 files changed

+70
-30
lines changed
 

‎CHANGES.txt

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ New in master
44
Features
55
--------
66

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

‎docs/manual.txt

+22-1
Original file line numberDiff line numberDiff line change
@@ -813,7 +813,7 @@ To use them from plugins, please see `Extending Nikola <https://getnikola.com/ex
813813
Using a shortcode
814814
~~~~~~~~~~~~~~~~~
815815

816-
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).
816+
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).
817817

818818
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".
819819

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

832+
media
833+
Display media embedded from a URL, for example, this will embed a youtube video::
834+
835+
{{% raw %}}{{% media url="https://www.youtube.com/watch?v=Nck6BZga7TQ" %}}{{% /raw %}}
836+
837+
In reStructuredText this shortcode will fail because docutils turns that URL to a link and everything breaks, use the `media directive <#media>`__ instead.
838+
839+
chart
840+
Create charts via PyGal. This is similar to the `chart directive <#chart>`__ except the syntax is adapted to
841+
shortcodes. This is an example::
842+
843+
{{% raw %}}{{% chart Bar title='Browser usage evolution (in %)' %}}
844+
x_labels='["2002","2003","2004","2005","2006","2007","2008","2009","2010","2011","2012"]'%}}
845+
'Firefox', [None, None, 0, 16.6, 25, 31]
846+
'Chrome', [None, None, None, None, None, None]
847+
'IE', [85.8, 84.6, 84.7, 74.5, 66, 58.6]
848+
'Others', [14.2, 15.4, 15.3, 8.9, 9, 10.4]
849+
{{% /chart %}}{{% /raw %}}
850+
851+
In reStructuredText the quoting needed to pass arguments gets insane really fast, use the chart directive
852+
instead (the syntax is nicer anyway)
832853

833854
Template-based shortcodes
834855
~~~~~~~~~~~~~~~~~~~~~~~~~

‎nikola/nikola.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1336,7 +1336,7 @@ def render_shortcode(t_data=template_data, **kw):
13361336
def register_shortcode(self, name, f):
13371337
"""Register function f to handle shortcode "name"."""
13381338
if name in self.shortcode_registry:
1339-
utils.LOGGER.warn('Shortcode name conflict: %s', name)
1339+
utils.LOGGER.warn('Shortcode name conflict: {}', name)
13401340
return
13411341
self.shortcode_registry[name] = f
13421342

‎nikola/plugins/compile/rest/chart.py

+36-23
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ def set_site(self, site):
5252
global _site
5353
_site = self.site = site
5454
directives.register_directive('chart', Chart)
55+
self.site.register_shortcode('chart', _gen_chart)
5556
return super(Plugin, self).set_site(site)
5657

5758

@@ -134,29 +135,41 @@ class Chart(Directive):
134135

135136
def run(self):
136137
"""Run the directive."""
137-
if pygal is None:
138-
msg = req_missing(['pygal'], 'use the Chart directive', optional=True)
139-
return [nodes.raw('', '<div class="text-error">{0}</div>'.format(msg), format='html')]
140-
options = {}
141-
if 'style' in self.options:
142-
style_name = self.options.pop('style')
143-
else:
144-
style_name = 'BlueStyle'
145-
if '(' in style_name: # Parametric style
146-
style = eval('pygal.style.' + style_name)
147-
else:
148-
style = getattr(pygal.style, style_name)
149-
for k, v in self.options.items():
138+
self.options['site'] = None
139+
html = _gen_chart(self.arguments[0], data='\n'.join(self.content), **self.options)
140+
return [nodes.raw('', html, format='html')]
141+
142+
143+
def _gen_chart(chart_type, **_options):
144+
if pygal is None:
145+
msg = req_missing(['pygal'], 'use the Chart directive', optional=True)
146+
return '<div class="text-error">{0}</div>'.format(msg)
147+
options = {}
148+
data = _options.pop('data')
149+
_options.pop('site')
150+
if 'style' in _options:
151+
style_name = _options.pop('style')
152+
else:
153+
style_name = 'BlueStyle'
154+
if '(' in style_name: # Parametric style
155+
style = eval('pygal.style.' + style_name)
156+
else:
157+
style = getattr(pygal.style, style_name)
158+
for k, v in _options.items():
159+
try:
150160
options[k] = literal_eval(v)
151-
chart = pygal
152-
for o in self.arguments[0].split('.'):
153-
chart = getattr(chart, o)
154-
chart = chart(style=style)
155-
if _site and _site.invariant:
156-
chart.no_prefix = True
157-
chart.config(**options)
158-
for line in self.content:
161+
except:
162+
options[k] = v
163+
chart = pygal
164+
for o in chart_type.split('.'):
165+
chart = getattr(chart, o)
166+
chart = chart(style=style)
167+
if _site and _site.invariant:
168+
chart.no_prefix = True
169+
chart.config(**options)
170+
for line in data.splitlines():
171+
line = line.strip()
172+
if line:
159173
label, series = literal_eval('({0})'.format(line))
160174
chart.add(label, series)
161-
data = chart.render().decode('utf8')
162-
return [nodes.raw('', data, format='html')]
175+
return chart.render().decode('utf8')

‎nikola/plugins/compile/rest/media.py

+10-5
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ def set_site(self, site):
4848
"""Set Nikola site."""
4949
self.site = site
5050
directives.register_directive('media', Media)
51+
self.site.register_shortcode('media', _gen_media_embed)
5152
return super(Plugin, self).set_site(site)
5253

5354

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

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

67-
providers = micawber.bootstrap_basic()
68-
return [nodes.raw('', micawber.parse_text(" ".join(self.arguments), providers), format='html')]
67+
68+
def _gen_media_embed(url, *q, **kw):
69+
if micawber is None:
70+
msg = req_missing(['micawber'], 'use the media directive', optional=True)
71+
return '<div class="text-error">{0}</div>'.format(msg)
72+
providers = micawber.bootstrap_basic()
73+
return micawber.parse_text(url, providers)

0 commit comments

Comments
 (0)
Please sign in to comment.