tychoish, a wiki

tychoish/code/ Build Novel

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.