add notebook tag
This commit is contained in:
@@ -36,7 +36,6 @@ ReTitleAlt = re.compile("""(?:"|')(?P<title>[^"']+)?(?:"|')\s+(?:"|')(?P<alt>[^"
|
|||||||
|
|
||||||
@LiquidTags.register('img')
|
@LiquidTags.register('img')
|
||||||
def img(preprocessor, tag, markup):
|
def img(preprocessor, tag, markup):
|
||||||
markup = markup.strip()
|
|
||||||
attrs = None
|
attrs = None
|
||||||
|
|
||||||
# Parse the markup string
|
# Parse the markup string
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ Syntax
|
|||||||
------
|
------
|
||||||
{% include_code path/to/code [Title text] %}
|
{% 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).
|
the content directory (TODO: allow this to be set in configs).
|
||||||
|
|
||||||
Example
|
Example
|
||||||
@@ -37,8 +37,6 @@ FORMAT = re.compile(r"""^(?:\s+)?(?P<src>\S+)(?:\s+)?(?:(?:lang:)(?P<lang>\S+))?
|
|||||||
|
|
||||||
@LiquidTags.register('include_code')
|
@LiquidTags.register('include_code')
|
||||||
def include_code(preprocessor, tag, markup):
|
def include_code(preprocessor, tag, markup):
|
||||||
markup = markup.strip()
|
|
||||||
|
|
||||||
title = None
|
title = None
|
||||||
lang = None
|
lang = None
|
||||||
src = None
|
src = None
|
||||||
@@ -59,7 +57,7 @@ def include_code(preprocessor, tag, markup):
|
|||||||
code_path = os.path.join('content', code_dir, src)
|
code_path = os.path.join('content', code_dir, src)
|
||||||
|
|
||||||
if not os.path.exists(code_path):
|
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()
|
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
|
These result in a preprocess step within markdown that produces
|
||||||
either markdown or html.
|
either markdown or html.
|
||||||
"""
|
"""
|
||||||
|
import warnings
|
||||||
import markdown
|
import markdown
|
||||||
import itertools
|
import itertools
|
||||||
import re
|
import re
|
||||||
@@ -35,7 +36,7 @@ class _LiquidTagsPreprocessor(markdown.preprocessors.Preprocessor):
|
|||||||
tag = EXTRACT_TAG.match(markup).groups()[0]
|
tag = EXTRACT_TAG.match(markup).groups()[0]
|
||||||
markup = EXTRACT_TAG.sub('', markup, 1)
|
markup = EXTRACT_TAG.sub('', markup, 1)
|
||||||
if tag in self._tags:
|
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
|
# add an empty string to liquid_tags so that chaining works
|
||||||
liquid_tags.append('')
|
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')
|
@LiquidTags.register('video')
|
||||||
def video(preprocessor, tag, markup):
|
def video(preprocessor, tag, markup):
|
||||||
markup = markup.strip()
|
|
||||||
|
|
||||||
videos = []
|
videos = []
|
||||||
width = None
|
width = None
|
||||||
height = None
|
height = None
|
||||||
|
|||||||
Reference in New Issue
Block a user