add notebook tag
This commit is contained in:
@@ -36,7 +36,6 @@ ReTitleAlt = re.compile("""(?:"|')(?P<title>[^"']+)?(?:"|')\s+(?:"|')(?P<alt>[^"
|
||||
|
||||
@LiquidTags.register('img')
|
||||
def img(preprocessor, tag, markup):
|
||||
markup = markup.strip()
|
||||
attrs = None
|
||||
|
||||
# Parse the markup string
|
||||
|
||||
@@ -8,7 +8,7 @@ Syntax
|
||||
------
|
||||
{% include_code path/to/code [Title text] %}
|
||||
|
||||
The "path to code" is relative to the code path in
|
||||
The "path to code" is relative to the code subdirectory of
|
||||
the content directory (TODO: allow this to be set in configs).
|
||||
|
||||
Example
|
||||
@@ -37,8 +37,6 @@ FORMAT = re.compile(r"""^(?:\s+)?(?P<src>\S+)(?:\s+)?(?:(?:lang:)(?P<lang>\S+))?
|
||||
|
||||
@LiquidTags.register('include_code')
|
||||
def include_code(preprocessor, tag, markup):
|
||||
markup = markup.strip()
|
||||
|
||||
title = None
|
||||
lang = None
|
||||
src = None
|
||||
@@ -59,7 +57,7 @@ def include_code(preprocessor, tag, markup):
|
||||
code_path = os.path.join('content', code_dir, src)
|
||||
|
||||
if not os.path.exists(code_path):
|
||||
return "File {0} could not be found".format(code_path)
|
||||
raise ValueError("File {0} could not be found".format(code_path))
|
||||
|
||||
code = open(code_path).read()
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ Where "tag" is associated with some user-defined extension.
|
||||
These result in a preprocess step within markdown that produces
|
||||
either markdown or html.
|
||||
"""
|
||||
import warnings
|
||||
import markdown
|
||||
import itertools
|
||||
import re
|
||||
@@ -35,7 +36,7 @@ class _LiquidTagsPreprocessor(markdown.preprocessors.Preprocessor):
|
||||
tag = EXTRACT_TAG.match(markup).groups()[0]
|
||||
markup = EXTRACT_TAG.sub('', markup, 1)
|
||||
if tag in self._tags:
|
||||
liquid_tags[i] = self._tags[tag](self, tag, markup)
|
||||
liquid_tags[i] = self._tags[tag](self, tag, markup.strip())
|
||||
|
||||
# add an empty string to liquid_tags so that chaining works
|
||||
liquid_tags.append('')
|
||||
|
||||
148
liquid_tags/notebook.py
Normal file
148
liquid_tags/notebook.py
Normal file
@@ -0,0 +1,148 @@
|
||||
"""
|
||||
Notebook Tag
|
||||
------------
|
||||
This is a liquid-style tag to include a static html rendering of an IPython
|
||||
notebook in a blog post.
|
||||
|
||||
Syntax
|
||||
------
|
||||
{% notebook filename.ipynb %}
|
||||
|
||||
The file should be specified relative to the ``notebook`` subdirectory of the
|
||||
content directory. [TODO: make this configurable].
|
||||
This will include the IPython notebook in the file.
|
||||
|
||||
Details
|
||||
-------
|
||||
Because the conversion and formatting of notebooks is rather involved, there
|
||||
are a few extra steps required for this plugin:
|
||||
|
||||
- First, the plugin requires that the nbconvert package [1]_ to be in the
|
||||
python path. For example, in bash, this can be set via
|
||||
|
||||
>$ export PYTHONPATH=/path/to/nbconvert/
|
||||
|
||||
- After typing "make html" when using the notebook tag, a file called
|
||||
``_nb_header.html`` will be produced in the main directory. The content
|
||||
of the file should be included in the header of the theme. An easy way
|
||||
to accomplish this is to add the following lines within the header template
|
||||
of the theme you use:
|
||||
|
||||
{% if IPYNB_FORMATTING %}
|
||||
{{ IPYNB_FORMATTING }}
|
||||
{% endif %}
|
||||
|
||||
and in your ``pelicanconf.py`` file, include the line:
|
||||
|
||||
IPYNB_FORMATTING = open('_nb_header.html').read().decode('utf-8')
|
||||
|
||||
[1] https://github.com/ipython/nbconvert
|
||||
"""
|
||||
import re
|
||||
import os
|
||||
from .mdx_liquid_tags import LiquidTags
|
||||
from converters import ConverterBloggerHTML # part of the nbconvert package
|
||||
|
||||
SYNTAX = "{% notebook /path/to/notebook.ipynb %}"
|
||||
FORMAT = re.compile(r"""^(?:\s+)?(?P<src>\S+)(?:\s+)?$""")
|
||||
|
||||
|
||||
def process_body(body):
|
||||
body = '\n'.join(body)
|
||||
|
||||
# replace the highlight tags
|
||||
body = body.replace('class="highlight"', 'class="highlight-ipynb"')
|
||||
|
||||
# specify <pre> tags
|
||||
body = body.replace('<pre', '<pre class="ipynb"')
|
||||
|
||||
# create a special div for notebook
|
||||
body = '<div class="ipynb">\n\n' + body + "\n\n</div>"
|
||||
|
||||
# specialize headers
|
||||
for h in '123456':
|
||||
body = body.replace('<h%s' % h, '<h%s class="ipynb"' % h)
|
||||
|
||||
return body.split('\n')
|
||||
|
||||
|
||||
def process_header(header):
|
||||
header = '\n'.join(header)
|
||||
|
||||
# replace the highlight tags
|
||||
header = header.replace('highlight', 'highlight-ipynb')
|
||||
|
||||
# specify <pre> tags
|
||||
header = header.replace('html, body', '\n'.join(('pre.ipynb {',
|
||||
' color: black;',
|
||||
' background: #f7f7f7;',
|
||||
' border: 0;',
|
||||
' box-shadow: none;',
|
||||
' margin-bottom: 0;',
|
||||
' padding: 0;'
|
||||
'}\n',
|
||||
'html, body')))
|
||||
|
||||
# create a special div for notebook
|
||||
header = header.replace('body {', 'div.ipynb {')
|
||||
|
||||
# specialize headers
|
||||
header = header.replace('html, body,',
|
||||
'\n'.join((('h1.ipynb h2.ipynb h3.ipynb '
|
||||
'h4.ipynb h5.ipynb h6.ipynb {'),
|
||||
'h1.ipynb h2.ipynb ... {',
|
||||
' margin: 0;',
|
||||
' padding: 0;',
|
||||
' border: 0;',
|
||||
' font-size: 100%;',
|
||||
' font: inherit;',
|
||||
' vertical-align: baseline;',
|
||||
'}\n',
|
||||
'html, body,')))
|
||||
|
||||
header = header.replace('html, body,',
|
||||
'/*html, body,*/')
|
||||
header = header.replace('h1, h2, h3, h4, h5, h6,',
|
||||
'/*h1, h2, h3, h4, h5, h6,*/')
|
||||
|
||||
return header.split('\n')
|
||||
|
||||
|
||||
@LiquidTags.register('notebook')
|
||||
def notebook(preprocessor, tag, markup):
|
||||
match = FORMAT.search(markup)
|
||||
if match:
|
||||
argdict = match.groupdict()
|
||||
src = argdict['src']
|
||||
else:
|
||||
raise ValueError("Error processing input, "
|
||||
"expected syntax: {0}".format(SYNTAX))
|
||||
|
||||
# TODO: make the notebook directory a configurable setting
|
||||
nb_dir = 'notebooks'
|
||||
nb_path = os.path.join('content', nb_dir, src)
|
||||
url = '/{0}/{1}/{2}'.format('static', nb_dir, src)
|
||||
|
||||
if not os.path.exists(nb_path):
|
||||
raise ValueError("File {0} could not be found".format(nb_path))
|
||||
|
||||
# Call the notebook converter
|
||||
converter = ConverterBloggerHTML(nb_path)
|
||||
converter.read()
|
||||
|
||||
header_lines = process_header(converter.header_body())
|
||||
|
||||
print ("\n *** Writing styles to _nb_header.html: "
|
||||
"this should be included in the theme.\n")
|
||||
open('_nb_header.html', 'w').write('\n'.join(header_lines).encode('utf-8'))
|
||||
|
||||
body_lines = process_body(converter.main_body('\n'))
|
||||
|
||||
body = preprocessor.configs.htmlStash.store('\n'.join(body_lines),
|
||||
safe=True)
|
||||
return body
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# This import allows image tag to be a Pelican plugin
|
||||
from liquid_tags import register
|
||||
@@ -35,8 +35,6 @@ VID_TYPEDICT = {'.mp4':"type='video/mp4; codecs=\"avc1.42E01E, mp4a.40.2\"'",
|
||||
|
||||
@LiquidTags.register('video')
|
||||
def video(preprocessor, tag, markup):
|
||||
markup = markup.strip()
|
||||
|
||||
videos = []
|
||||
width = None
|
||||
height = None
|
||||
|
||||
Reference in New Issue
Block a user