diff --git a/liquid_tags/Readme.md b/liquid_tags/Readme.md
index bb2203c3c..4cc37864d 100644
--- a/liquid_tags/Readme.md
+++ b/liquid_tags/Readme.md
@@ -74,7 +74,7 @@ filename.
The script must be in the ``code`` subdirectory of your content folder:
this default location can be changed by specifying
- CODE_DIR = 'code'
+ CODE_DIR = 'code'
within your configuration file. Additionally, in order for the resulting
hyperlink to work, this directory must be listed under the STATIC_PATHS
@@ -97,7 +97,7 @@ config file:
Because the conversion and rendering of notebooks is rather involved, there
are a few extra steps required for this plugin:
-- First, you will need to install IPython >= 1.0 [1]_
+- First, you will need to install IPython >= 1.0 [[1](#1)]
- After typing "make html" when using the notebook tag, a file called
``_nb_header.html`` will be produced in the main directory. The content
@@ -115,6 +115,31 @@ are a few extra steps required for this plugin:
this will insert the proper css formatting into your document.
+### Optional Arguments for Notebook Tags
+
+The notebook tag also has two optional arguments: ``cells`` and ``language``.
+
+- You can specify a slice of cells to include:
+
+ ``{% notebook filename.ipynb cells[2:8] %}``
+
+- You can also specify the name of a language which Pygments should use for
+ highlighting code cells. A list of the short names for languages that Pygments
+ will highlight can be found [here](http://www.pygments.org/docs/lexers/).
+
+ ``{% notebook filename.ipynb language[julia] %}``
+
+ This may be helpful for those using [IJulia](https://github.com/JuliaLang/IJulia.jl)
+ or notebooks in any other language, especially as the IPython project [broadens its
+ scope](https://github.com/ipython/ipython/wiki/Roadmap:-IPython) of [language
+ compatibility](http://jupyter.org/). By default, the language for highlighting
+ will be ``ipython``.
+
+- These options can be used separately, together, or not at all. However,
+ if both tags are used then ``cells`` must come before ``language``:
+
+ ``{% notebook filename.ipynb cells[2:8] language[julia] %}``
+
### Collapsible Code in IPython Notebooks
The plugin also enables collapsible code input boxes. For this to work
@@ -127,4 +152,4 @@ comment line ``# `` will be open on load but
can be collapsed by clicking on their header. Cells without collapse
comments are rendered as standard code input cells.
-[1] http://ipython.org/
+[1] http://ipython.org/
diff --git a/liquid_tags/notebook.py b/liquid_tags/notebook.py
index 1208f1e13..7f58fab75 100644
--- a/liquid_tags/notebook.py
+++ b/liquid_tags/notebook.py
@@ -46,6 +46,8 @@
"""
import re
import os
+from functools import partial
+
from .mdx_liquid_tags import LiquidTags
from distutils.version import LooseVersion
@@ -230,8 +232,8 @@ def custom_highlighter(source, language='ipython', metadata=None):
#----------------------------------------------------------------------
# Below is the pelican plugin code.
#
-SYNTAX = "{% notebook /path/to/notebook.ipynb [ cells[start:end] ] %}"
-FORMAT = re.compile(r"""^(\s+)?(?P\S+)(\s+)?((cells\[)(?P-?[0-9]*):(?P-?[0-9]*)(\]))?(\s+)?$""")
+SYNTAX = "{% notebook /path/to/notebook.ipynb [ cells[start:end] ] [ language[language] ] %}"
+FORMAT = re.compile(r"""^(\s+)?(?P\S+)(\s+)?((cells\[)(?P-?[0-9]*):(?P-?[0-9]*)(\]))?(\s+)?((language\[)(?P-?[a-z0-9\+\-]*)(\]))?(\s+)?$""")
@LiquidTags.register('notebook')
@@ -242,6 +244,7 @@ def notebook(preprocessor, tag, markup):
src = argdict['src']
start = argdict['start']
end = argdict['end']
+ language = argdict['language']
else:
raise ValueError("Error processing input, "
"expected syntax: {0}".format(SYNTAX))
@@ -256,6 +259,8 @@ def notebook(preprocessor, tag, markup):
else:
end = None
+ language_applied_highlighter = partial(custom_highlighter, language=language)
+
settings = preprocessor.configs.config['settings']
nb_dir = settings.get('NOTEBOOK_DIR', 'notebooks')
nb_path = os.path.join('content', nb_dir, src)
@@ -284,7 +289,7 @@ def notebook(preprocessor, tag, markup):
exporter = HTMLExporter(config=c,
template_file=template_file,
- filters={'highlight2html': custom_highlighter},
+ filters={'highlight2html': language_applied_highlighter},
**subcell_kwarg)
# read and parse the notebook
diff --git a/liquid_tags/test_notebook.py b/liquid_tags/test_notebook.py
new file mode 100644
index 000000000..042d6d1cc
--- /dev/null
+++ b/liquid_tags/test_notebook.py
@@ -0,0 +1,92 @@
+import re
+
+from pelican.tests.support import unittest
+
+import notebook
+
+
+class TestNotebookTagRegex(unittest.TestCase):
+
+ def get_argdict(self, markup):
+
+ match = notebook.FORMAT.search(markup)
+
+ if match:
+ argdict = match.groupdict()
+
+ src = argdict['src']
+ start = argdict['start']
+ end = argdict['end']
+ language = argdict['language']
+
+ return src, start, end, language
+
+ return None
+
+ def test_basic_notebook_tag(self):
+ markup = u'path/to/thing.ipynb'
+ src, start, end, language = self.get_argdict(markup)
+
+ self.assertEqual(src, u'path/to/thing.ipynb')
+ self.assertIsNone(start)
+ self.assertIsNone(end)
+ self.assertIsNone(language)
+
+ def test_basic_notebook_tag_insensitive_to_whitespace(self):
+ markup = u' path/to/thing.ipynb '
+ src, start, end, language = self.get_argdict(markup)
+
+ self.assertEqual(src, u'path/to/thing.ipynb')
+ self.assertIsNone(start)
+ self.assertIsNone(end)
+ self.assertIsNone(language)
+
+ def test_notebook_tag_with_cells(self):
+ markup = u'path/to/thing.ipynb cells[1:5]'
+ src, start, end, language = self.get_argdict(markup)
+
+ self.assertEqual(src, u'path/to/thing.ipynb')
+ self.assertEqual(start, u'1')
+ self.assertEqual(end, u'5')
+ self.assertIsNone(language)
+
+ def test_notebook_tag_with_alphanumeric_language(self):
+ markup = u'path/to/thing.ipynb language[python3]'
+ src, start, end, language = self.get_argdict(markup)
+
+ self.assertEqual(src, u'path/to/thing.ipynb')
+ self.assertIsNone(start)
+ self.assertIsNone(end)
+ self.assertEqual(language, u'python3')
+
+ def test_notebook_tag_with_symbol_in_name_language(self):
+ for short_name in [u'c++', u'cpp-objdump', u'c++-objdumb', u'cxx-objdump']:
+ markup = u'path/to/thing.ipynb language[{}]'.format(short_name)
+ src, start, end, language = self.get_argdict(markup)
+
+ self.assertEqual(src, u'path/to/thing.ipynb')
+ self.assertIsNone(start)
+ self.assertIsNone(end)
+ self.assertEqual(language, short_name)
+
+ def test_notebook_tag_with_language_and_cells(self):
+ markup = u'path/to/thing.ipynb cells[1:5] language[julia]'
+ src, start, end, language = self.get_argdict(markup)
+
+ self.assertEqual(src, u'path/to/thing.ipynb')
+ self.assertEqual(start, u'1')
+ self.assertEqual(end, u'5')
+ self.assertEqual(language, u'julia')
+
+ def test_notebook_tag_with_language_and_cells_and_weird_spaces(self):
+ markup = u' path/to/thing.ipynb cells[1:5] language[julia] '
+ src, start, end, language = self.get_argdict(markup)
+
+ self.assertEqual(src, u'path/to/thing.ipynb')
+ self.assertEqual(start, u'1')
+ self.assertEqual(end, u'5')
+ self.assertEqual(language, u'julia')
+
+
+if __name__ == '__main__':
+ unittest.main()
\ No newline at end of file