Novel Makefile
Background
This makefile-based build system provides a bit of extra gloss/configuration for using Sphinx and sffms to build conventional manuscripts and websites for novel-like hypertexts.
Usage Notes
This makefile is derives from the default Sphinx makefile, with a number of tweaks that I've been making to this configuration:
-
The PDF build system is much abbreviated, and included in the main makefile. This is a bit less conservative than the default for this file, but it works just as well in most situations. The output is also much less verbose.
-
The build is a lot less noisy. Errors are still printed, which makes it great for automated build systems (i.e. continuous integration.)
-
Sphinx will build two sites, one, in an
outline/
directory would store the outline and working notes of a story, while the other in asource/
directory would store the actual text of the novel. *In practice, I also seem to keep anothernotes/
directory around for less formal and more early stage note taking. -
There's a post-processing script for sffms that makes section headers work right for my usual structure. Tweak or remove at your discretion.
-
You must install Sphinx and sffms and have them accessible to the build process.
Code
File: makefile
SPHINXOPTS = -c ./
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = build
SFFMS_CLEANUP = bin/sffms-cleanup
TITLE = name.title-of-book.pdf
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -q -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS)
.PHONY: html sffms dirhtml singlehtml ms outline outline-single outline-pdf help
.DEFAULT_GOAL = help
help:
@echo "A build system for generating novels and outlines using 'Sphinx' and 'sffms.'"
@echo "All build products are located within '$(BUILDDIR).' Some related scritps are in,"
@echo "'bin/'. See <http://tychoish.com/code/novel-makefile/> for more information."
@echo ""
@echo "Targets:"
@echo ""
@echo " outline - builds an html website of the outline."
@echo " outline-single - builds a single html page version of the outline."
@echo " outline-pdf - builds a pdf of the outline using Sphinx's LaTeX builder."
@echo ""
@echo " html - builds a html site of the text, with each page in its own file."
@echo " dirhtml - builds a html site with each page an index.html, in a directory."
@echo " singlehtml - builds the text in a single page."
@echo ""
@echo " ms - builds an sffms styled manuscript PDF named $(TITLE)"
@echo " ms-tex - builds and processes a sffms TeX file."
@echo ""
@echo " clean - removes $(BUILDDIR)/"
#
# Outline Generation
#
outline:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) outline $(BUILDDIR)/outline
@echo "[OUTLINE] (html) build complete."
outline-single:
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) outline $(BUILDDIR)/outline-single
@echo "[OUTLINE] (single-html) build complete."
outline-pdf:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) outline $(BUILDDIR)/outline-pdf
@echo "[OUTLINE] pdf build complete."
#
# Sphinx (HTML) Build System - Novel
#
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) source $(BUILDDIR)/html
@echo "[HTML] build complete."
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) source $(BUILDDIR)/dirhtml
@echo "[DIR] build complete."
singlehtml:
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) source $(BUILDDIR)/singlehtml
@echo "[SINGLE] build complete."
#
# Manuscript Build System - Novel
#
SFFMS_CLEANUP = bin/sffms-cleanup
$(BUILDDIR)/sffms/index.tex:sffms
@$(SFFMS_CLEANUP) $(BUILDDIR)/sffms/*tex
@echo "[SFFMS] tex santized."
$(BUILDDIR)/sffms/$(TITLE):$(BUILDDIR)/sffms/index.pdf
@mv $< $@
@echo "[SFFMS] pdf renamed. See: $@"
sffms:
$(SPHINXBUILD) -b sffms $(ALLSPHINXOPTS) source $(BUILDDIR)/sffms
@echo "[SFFMS] tex generated."
ms:$(BUILDDIR)/sffms/$(TITLE)
ms-tex:$(BUILDDIR)/sffms/index.tex
#
# PDF Build System
#
PDFLATEXCOMMAND = TEXINPUTS=".:$(BUILDDIR)/sffms/:" pdflatex --interaction batchmode --output-directory $(BUILDDIR)/sffms/
%.pdf:%.tex
@$(PDFLATEXCOMMAND) $(LATEXOPTS) '$<' >|$@.log
@echo "[PDF]: (1/3) pdflatex $<"
# @makeindex -s $(BUILDDIR)/latex/python.ist '$(basename $<).idx' >>$@.log 2>&1
# @echo "[PDF]: (2/3) Indexing: $(basename $<).idx"
@$(PDFLATEXCOMMAND) $(LATEXOPTS) '$<' >>$@.log
@echo "[PDF]: (2/3) pdflatex $<"
@$(PDFLATEXCOMMAND) $(LATEXOPTS) '$<' >>$@.log
@echo "[PDF]: (3/3) pdflatex $<"
@echo "[PDF]: see '$@.log' for a full report of the pdf build process."
#
# Meta
#
clean:
rm -rf build
The following file, used above, does a little bit of post-processing that makes using sffms with longer more structured works possible. Use, or not, as you wish:
File: bin/sffms-cleanup
#!/bin/zsh
if [ "`uname`" = "Linux" ]; then
SED_ARGS='-i -r'
elif [ "`uname`" = "Darwin" ]; then
SED_ARGS='-i "" -E'
else
echo "You're probably using an unsupported system. Do some testing, edit this file, and try again."
exit 1
fi
SFFMS_FILE=$1
while [ `pcregrep -c -M "^.chapter(.*)\{(.*)\}\n+.newscene" $SFFMS_FILE` -gt 0 ]; do
sed $SED_ARGS ':a;N;$!ba;s@(.)chapter.*\{(.*)\}\n{2}.newscene@\1chapter{\2}@m' $SFFMS_FILE
done