Build Novel
I wrote this code to manage the publication of the Knowing Mars Novella in coordination with the build system that I use for tychogaren.com and Critical Futures, but this script just prepares multiple versions of the story for different kinds of readers, and prepares the content for proper rendering.
Many aspects of this script will need to be modified to be able to process other texts, but the main concepts are generalizable. Additionally, despite potential inefficiencies with the method used for this program (blunt force with text files and shell operations) the script runs in a few seconds.
For your consideration:
#!/bin/bash
# build-novel
# Copyright (c) 2010 Sam Kleinman
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the 'Software'), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
######################################################################
#
# The following array, is itterated over at several points, and is
# basically a list of allowable chapters. The scirpt assumes that all
# of the source files are named `$CHAPTER.mdwn` and that they should
# end up in directories that are `$CHAPTER/index.mdwn`.
#
CHAPTERS="01 02 03 04 05 06 07 08 09 10"
#
# Paths and other constituents that are used in filenames.
#
SRCDIR=~/bin/knowing-mars
DESTDIR=~/sites/tychoish/mars
NOVELSLUG=knowing-mars
#
# The following values control special text which is inserted at
# several points in the text of the novel. Mostly at the beginning of
# the fulltext-html edition that *isn't* styled to match the rest of
# the site.
#
MDWN_BYLINE="by [tycho garen](http://www.tychogaren.com/mars/)"
MDWN_TITLE="# KNOWING MARS, A NOVELLA"
CHAPTERHEADLINE="# Chapter"
#
# The following values specify text which are added to the YAML
# forematter which Jeykll uses in template publication
#
META_CCLICENSE="http://creativecommons.org/licenses/by-nc-sa/3.0/"
META_LINK="http://tychogaren.com/mars/"
META_AUTHOR="Sam Kleinman"
META_BYLINE="tycho garen"
META_TITLE="Knowing Mars"
META_SECTION="a novella"
META_LAYOUT="mars"
META_LAYOUT_STYLED="mars-full-styled"
META_LAYOUT_PLAIN="mars-text"
#
# Beyond the following point should require minimal (if any)
# modification if you want to use this script for a similar project of
# your own. The only thing that's hardcoded is the use of the
# extension `.mdwn` for markdown files and `.txt` for text files. You
# may also discover that your deployment requires additional meta
# tags.
#
######################################################################
migrate-from-source (){
for i in $CHAPTERS; do
mkdir -p $DESTDIR/$i
cp $SRCDIR/$i.mdwn $DESTDIR/$i/index.mdwn
echo "Chapter $i Moved to Publication"
done
}
build-chapters-plain-text(){
for i in $CHAPTERS; do
MDWNCHAPTER=$DESTDIR/$i/index.mdwn
TXTCHAPTER=$DESTDIR/$i/index.txt
cp $MDWNCHAPTER $TXTCHAPTER
sed -i 's/layout: '$META_LAYOUT'/layout: '$META_LAYOUT_PLAIN'/' $TXTCHAPTER
cat >> $TXTCHAPTER <<EOF
---
link: $META_LINK
license: $META_CCLICENSE
byline: $META_BYLINE
author: $META_AUTHOR
---
EOF
done
}
###################################
build-full-simple(){
MDWNSIMPLE=$DESTDIR/$NOVELSLUG-simple.mdwn
cat > $MDWNSIMPLE <<EOF
---
title: $META_TITLE
byline: $META_BYLINE
author: $META_AUTHOR
license: $META_CCLICENSE
---
$MDWN_TITLE
$MDWN_BYLINE
EOF
for ch in $CHAPTERS; do
echo $CHAPTERHEADLINE `echo $ch | sed s/^0//` >> $MDWNSIMPLE
cat $DESTDIR/$ch/index.mdwn | sed '1d;2d;3d;4d;5d;6d;7d;8d;9d' >> $MDWNSIMPLE
done
sed -i '7d' $MDWNSIMPLE
cat >> $MDWNSIMPLE <<EOF
---
license: $META_CCLICENSE
byline: $META_BYLINE
author: $META_AUTHOR
---
EOF
cp $MDWNSIMPLE $DESTDIR/$NOVELSLUG.txt
}
###################################
build-full-styled(){
MDWNSTYLED=$DESTDIR/$NOVELSLUG.mdwn
cat > $MDWNSTYLED <<EOF
---
title: $META_TITLE
section: $META_SECTION
byline: $META_BYLINE
author: $META_AUTHOR
license: $META_CCLICENSE
layout: $META_LAYOUT_STYLED
---
EOF
for ch in $CHAPTERS; do
echo >> $MDWNSTYLED
echo $CHAPTERHEADLINE `echo $ch | sed s/^0//` >> $MDWNSTYLED
cat $DESTDIR/$ch/index.mdwn | sed '1d;2d;3d;4d;5d;6d;7d;8d;9d' >> $MDWNSTYLED
done
}
###################################
backport-changes(){
for ch in $CHAPTERS; do
PUBFILE=$DESTDIR/$ch/index.mdwn;
SRCFILE=$SRCDIR/$ch.mdwn
cp $PUBFILE $SRCFILE
echo "Changes From Chapter $ch Moved to $SRCFILE"
done
}
######################################################################
main(){
migrated=0
if [ ! -e $DESTDIR/$NOVELSLUG.mdwn ]; then
migrate-from-source
migrated=1
fi
build-full-simple
build-chapters-plain-text
build-full-styled
if [ ! $migrated -eq 1 ]; then
backport-changes
fi
}
main;
echo "Success! $META_TITLE built.