This site was created with the static site generator, Pelican. I chose Pelican in order to use jakevdp's liquid_tags notebook plugin that allows for posting a subset of IPython notebook cells. The comments below are for Pelican v3.5.0, IPython v1.2, and a December 30, 2014 clone of pelican-plugins.
Below are steps used to install Pelican. Python and node.js must be installed (I was unable to generate posts containing IPython notebook files without node.js). Console/terminal commands are contained in brackets.
An older version of IPython is needed because the CSS class names used for python syntax highlighting changed in IPython v2.3. The liquid_tags notebook plugin appears to only know about the v1.2 CSS class names. For example, in an IPython notebook, a function named foo
gets wrapped in a class by way of a <span>
element. In IPython v1.2 this becomes <span class="nf">foo</span>
, but in v2.3 this is <span class="cm-def">foo</span>
(I used Chrome to inspect the elements). I'm not smart enough to fix it, but I assume the problem begins in the plugin's notebook.custom_highlighter() function. Inside this function a call is made to HtmlFormatter(cssclass='highlight-ipynb')
where HtmlFormatter
comes from the Pygments library.
Quick pelican setup
- Make a dedicated directory to house the site's contents and change into it.
- Set up a virtual environment
a. [virtualenv env]
b. [env\scripts\activate]
c. [pip install pelican markdown ipython==1.2] - Install plugins/themes
a. [git clone https://github.com/getpelican/pelican-plugins.git]
b. [git clone https://github.com/getpelican/pelican-themes.git]
c. Find other themes by looking at other users' github repositories (e.g. octopress, middle-theme) - [pelican-quickstart] // see here for a list of questions that are asked
- Configure Pelican via pelicanconf.py
a. DELETE_OUTPUT_DIRECTORY = False
b. PLUGIN_PATHS = ['path/to/pelican-plugins']
c. PLUGINS = ['liquid_tags.notebook', 'liquid_tags.literal']
d. EXTRA_HEADER = open('_nb_header.html').read().decode('utf-8') if os.path.exists('_nb_header.html') else None
e. NOTEBOOK_DIR = 'notebooks'
f. THEME = 'path/to/theme'
g. LOAD_CONTENT_CACHE = False - Edit the chosen theme's 'base.html' and add
{% if EXTRA_HEADER %}{{ EXTRA_HEADER }}{% endif %}
to the<head>
block - Configure 'content' directory
a. [mkdir content/images]
b. [mkdir content/notebooks] - Run the site generator with [make html] or [make regenerate]
- Serve the site locally with [make serve] or regenerate files + serve with [make devserver] if not on Windows.
Posts are written in markdown by the user and stored in content/, where each post's filename should have extension 'md'. Notebooks are incorporated in a markdown post with:
{% notebook file.ipynb cells[i:j] %}
The 'cells' argument is optional and can be omitted; the slices are standard python syntax. The LOAD_CONTENT_CACHE setting should be False if notebooks are edited after they're added to content/notebooks/. Otherwise, the cached version is used by Pelican.
Initially, [make html] must be run twice because '_nb_header.html' is only generated after the first run. This file contains all the CSS/JS present in an IPython notebook.
Math blocks were left-aligned in IPython v1.2 but are centered in IPython v2.3, which is the preferred behavior. To force centering of math blocks while using v1.2, I made copy of _nb_header.html, edited it to include the addition below, and pointed to it in pelicanconf.py's EXTRA_HEADER setting.
<style type="text/css">
.MathJax_Display{text-align: center !important;}
</style>
Repositories
My choice was to have two repositories.
- Inside the master directory where [pelican-quickstart] is run.
- A subdirectory of the above that holds the content pushed to the web server.
The former has a .gitignore file that contains:
*.pyc
cache/
env/
output/
username.github.io/
The latter repository is a GitHub Pages repository. The 'output/' directory generated by Pelican is copied to this repository.
This site's repository containing the raw Pelican content can be found here. The generated site can be found here.
Helpful references
- Migrating from Octopress to Pelican
- How to setup Github User Page with Pelican
- Migrating to GitHub Pages using Pelican
- Getting started (Pelican docs)
- tags-vs-categories in Pelican
Script to summarize available Pelican themes
"""
Ugly script used to summarize all pelican-themes.
https://github.com/getpelican/pelican-themes.
Place this script one level below THEMES_DIR.
It will generate summary.html containing the themes.
"""
import os
from collections import OrderedDict as od
THEMES_DIR = 'pelican-themes'
# first, discover all themes that have screenshots
# each screenshot's filename is stored
contents = os.listdir(THEMES_DIR)
accumulated_screenshots = od()
for entry in contents:
theme_directory = os.path.join(THEMES_DIR, entry)
if os.path.isdir(theme_directory) and entry != '.git':
theme_contents = os.listdir(theme_directory)
accumulated_screenshots[entry] = []
for theme_file in theme_contents:
if theme_file[-3:] in ('jpg', 'png', 'gif'):
accumulated_screenshots[entry].append(theme_file)
# second, create an HTML file
# the IMG elements point to the accumulated screenshots
to_write = ['<html><body>\n']
for theme, screenshots in accumulated_screenshots.iteritems():
path = os.path.join(THEMES_DIR, theme)
for i, screenshot in enumerate(screenshots):
if i == 0:
# print the theme's name only once
to_write.append('<h1>%s</h1><br />\n' % theme)
screenshot_path = os.path.join(path, screenshot)
to_write.append('<center>\n')
to_write.append(
'<img src="%s" height=500>\n' % screenshot_path
)
to_write.append('</center><br />\n')
to_write.append('<br />\n')
to_write.append('</body></html>\n')
with open('summary.html', 'w') as f:
f.writelines(to_write)
Comments !