Explorar o código

add notebook tag

Jake Vanderplas %!s(int64=12) %!d(string=hai) anos
pai
achega
1ae1833864

+ 0 - 1
liquid_tags/img.py

@@ -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

+ 2 - 4
liquid_tags/include_code.py

@@ -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()
 

+ 2 - 1
liquid_tags/mdx_liquid_tags.py

@@ -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 - 0
liquid_tags/notebook.py

@@ -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

+ 0 - 2
liquid_tags/video.py

@@ -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