Commit 99c2d36c authored by Matthieu Boileau's avatar Matthieu Boileau
Browse files

Better handle book generation

parent a9d2c1fe
......@@ -3,22 +3,27 @@ Build a small website to host Jupyter notebooks as course chapters
"""
import argparse
from .nbcourse import get_config, build_site, DEFAULT_CONFIG_FILE
from .quickstart import quickstart
from .nbcourse import NbCourse, DEFAULT_CONFIG_FILE
from .quickstart import init
from pathlib import Path
def main():
parser = argparse.ArgumentParser(description=__name__.__doc__)
config_group = parser.add_mutually_exclusive_group()
config_group.add_argument('--config', default=DEFAULT_CONFIG_FILE,
help='load YAML file containing site configuration')
quickstart_group = parser.add_mutually_exclusive_group()
quickstart_group.add_argument('--quickstart', action='store_true',
help='initiate a nbcourse directory')
generate = parser.add_argument_group('generate')
generate.add_argument('--config', type=Path, default=DEFAULT_CONFIG_FILE,
help='load YAML file containing site configuration')
generate.add_argument('--book', type=Path,
help='Generate a pdf book using bookbook')
parser.add_argument('--init', type=str, dest='course_title',
help='initiate a nbcourse directory')
args = parser.parse_args()
if args.quickstart:
quickstart()
if args.course_title:
init(args.course_title)
else:
config = get_config(args.config)
build_site(config)
course = NbCourse(args.config)
if args.book:
course.build_book(args.book)
else:
course.build_pages()
......@@ -2,31 +2,26 @@
"""
Build a small website to host Jupyter notebooks as course chapters
"""
import argparse
import os
from pathlib import Path
import jinja2
import yaml
from pprint import pprint
from pprint import pformat
import markdown
from bs4 import BeautifulSoup
import re
import nbformat
import logging
from bookbook.latex import combine_and_convert
DEFAULT_CONFIG_FILE = "nbcourse.yml"
THEME_DIR = 'theme/default'
TEMPLATE_PATH = Path(THEME_DIR, 'templates')
NB_DIR = 'notebooks'
DEFAULT_PDF_TITLE = 'nbcourse.pdf'
def get_config(config_file=DEFAULT_CONFIG_FILE):
"""
Parse yaml file to build the corresponding configuration dictionary
"""
with open(config_file, 'r') as f:
config = yaml.safe_load(f)
config['configpath'] = Path(os.path.dirname(os.path.abspath(config_file)))
return config
log = logging.getLogger(__name__)
class HomePage:
......@@ -64,6 +59,7 @@ class HomePage:
def _get_variables(self, config: dict):
"""Set some variables from config dictionnary and notebooks files"""
logging.basicConfig(level=logging.INFO)
self.title = config['title']
self.nbdir = config['configpath'] / Path(config.get('nbdir', NB_DIR))
self.variables = config
......@@ -77,8 +73,8 @@ class HomePage:
chapters.append(chapter)
chapters.sort(key=lambda chapter: chapter['number'])
self.variables.update({'chapters': chapters})
print(">>> Homepage template variables:")
pprint(self.variables)
log.info("Homepage template variables:")
log.info(pformat(self.variables))
def _render_template(self, config):
"""Return html rendered from template and variables"""
......@@ -148,16 +144,44 @@ class MarkdownPage(HomePage):
self._render_template(config)
def build_site(config: dict):
"""Build a mini website using html templating and markdown conversion"""
# Render homepage
homepage = HomePage('index.html')
homepage.render(config)
# Render markdown pages
manual = MarkdownPage('manual.html', title='Notice', src='pages/manual.md',
parent=homepage)
anaconda = MarkdownPage('anaconda.html', title='Anaconda',
src='pages/anaconda.md', parent=manual)
anaconda.render(config)
manual.render(config)
class NbCourse:
def __init__(self, config_file=DEFAULT_CONFIG_FILE):
self.config = self._get_config(config_file)
@staticmethod
def _get_config(config_file):
"""
Parse yaml file to build the corresponding configuration dictionary
"""
with open(config_file, 'r') as f:
config = yaml.safe_load(f)
config['configpath'] = Path(os.path.dirname(os.path.abspath(config_file)))
return config
def build_pages(self):
"""Build a mini website using html templating and markdown conversion"""
# Render homepage
homepage = HomePage('index.html')
homepage.render(self.config)
# Render markdown pages
manual = MarkdownPage('manual.html', title='Notice', src='pages/manual.md',
parent=homepage)
anaconda = MarkdownPage('anaconda.html', title='Anaconda',
src='pages/anaconda.md', parent=manual)
anaconda.render(self.config)
manual.render(self.config)
def build_book(self, pdf_title=DEFAULT_PDF_TITLE):
"""Build a pdf book using bookbook"""
logging.basicConfig(level=logging.INFO)
template_file = self.config['configpath'] / TEMPLATE_PATH / 'book.tplx'
combine_and_convert(Path('.'),
Path(pdf_title),
pdf=True,
template_file=template_file)
def build(self):
self.build_pages()
self.build_book()
import os
from distutils.dir_util import copy_tree
from pathlib import Path
SKEL_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)),
"../skeleton")
SKEL_DIR = Path(os.path.dirname(os.path.abspath(__file__))) / Path("../skeleton")
def quickstart():
def init(course_title):
copy_tree(SKEL_DIR, os.getcwd())
makefile_inc = """\
course_title = {}
config_file = nbcourse.yml
notebook_dir = notebooks
output_dir = build
theme_dir = theme/default
""".format(course_title)
with open("Makefile.inc", 'w') as f:
f.write(makefile_inc)
\ No newline at end of file
......@@ -76,11 +76,8 @@ $(output_dir)/%.html: $(output_dir)/%.ipynb
$(output_dir)/%.slides.html: $(output_dir)/%.ipynb
$(call nbconvert,slides,$<) --reveal-prefix $(revealprefix)
$(output_dir)/$(course_title).tex: executed_notebooks $(template_dir)/book.tplx
cd $(output_dir) && python3 -m bookbook.latex --output-file $(course_title) --template $(template_dir)/book.tplx
$(output_dir)/$(course_title).pdf: $(executed_notebooks) $(template_dir)/book.tplx
cd $(output_dir) && python3 -m bookbook.latex --pdf --output-file $(course_title) --template $(template_dir)/book.tplx
cd $(output_dir) && python3 -m nbcourse --book $(course_title).pdf --config ../nbcourse.yml
$(output_dir)/%.zip: $(notebook_dir)/%.ipynb
zip -r $@ $< $(notebook_dir)/fig $(notebook_dir)/exos --exclude "*/\.*" "*__pycache__*"
......
course_title := nbcourse
config_file ?= nbcourse.yml
notebook_dir := notebooks
output_dir := build
theme_dir := theme/default
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment