Collaborative Book Authoring
4 min read
Will Puckett
When I used to use Atom, there was a great collaborative writing tool called Teletype. It allowed multiple people to be editing the same files at the same time. I've been working on a book lately and wanted to get another one in progress with a group of authors, so I tried to find something that would duplicate Teletype's functionality iThonically.
There weren't a lot of options. Both HackMD and StackEdit seemed decently put together, worked nicely in the browser, but I wanted a stand alone app that would load quickly so I could jot ideas on the train/bus as well as have longer sessions at home and on the go. I wanted to be able to collaboratively edit a bunch of Markdown documents and then build them into an ePub.
The only option was Apple Notes.
So, the Saturday morning before last, I sat around for a half an hour and patched a Pandoc build script together. This takes a folder of Notes and pulls it out of Apple Notes in plaintext, then makes a table of contents out of the Markdown chapters, then adds the front matter.
File and Directory Structure
You'll need to use a folder structure something like:
mybook/
templates/
gfm.template
epub.template
css/
fonts/
chapters/
publish.sh
I have modified Pandoc templates to control the Table of Contents Page, but you may or may not find that necessary. In case you do, here are the two templates I reference later in the publish script. Place them in the templates directory.
gfm.template
$if(titleblock)$
$titleblock$
$endif$
$for(header-includes)$
$header-includes$
$endfor$
$for(include-before)$
$include-before$
$endfor$
$if(toc)$
$if(toc-title)$
# $toc-title$
$endif$
$table-of-contents$
$endif$
$body$
$for(include-after)$
$include-after$
$endfor$
epub.template
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops"$if(lang)$ xml:lang="$lang$"$endif$>
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<title>$pagetitle$</title>
$if(highlighting-css)$
<style>
$highlighting-css$
</style>
$endif$
$for(css)$
<link rel="stylesheet" type="text/css" href="$css$" />
$endfor$
$for(header-includes)$
$header-includes$
$endfor$
</head>
<body$if(coverpage)$ id="cover"$endif$$if(body-type)$ epub:type="$body-type$"$endif$>
$if(coverpage)$
<div id="cover-image">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="100%" height="100%" viewBox="0 0 $cover-image-width$ $cover-image-height$" preserveAspectRatio="xMidYMid meet">
<image border="5" width="$cover-image-width$" height="$cover-image-height$" xlink:href="../media/$cover-image$" />
</svg>
</div>
$else$
$for(include-before)$
$include-before$
$endfor$
$body$
$for(include-after)$
$include-after$
$endfor$
$endif$
</body>
</html>
publish.sh
I like to place this script in the root of my project directory for easy access.
#!/bin/bash
# change to working directory
cd ~/icloud/mybook/chapters
# sanitize the directory from any previous runs
rm *.md
# bring in a fresh copy of chapters/front matter from Notes
osascript <<EOF
# get a list of all the chapters
tell application "Notes"
set myList to the name of every note of folder "mybook" of account "iCloud"
# Loop through the results
repeat with a from 1 to length of myList
set theCurrentListItem to item a of myList
# get title and content of each chapter
tell folder "mybook" of account "iCloud"
set myName to name of note theCurrentListItem
set myText to plaintext of note theCurrentListItem
end tell
# set textFile variable to the appropriate .md file
set textFile to "~/icloud/mybook/chapters/" & myName & ".md"
# export title and content to build directory
# (the awk command removes the heading line)
do shell script "echo " & quoted form of myText & " | awk '{if(NR>1)print}' > " & quoted form of textFile
end repeat
end tell
EOF
# stitch chapters and add TOC
/usr/local/bin/pandoc -s -t gfm --toc --toc-depth=2 -V toc-title:"Contents" --template=../templates/gfm.template ?hapter* > toc.chapters.md
# strip bullets from the table of contents (the $ in the sed
# command uses a string literal to pass the new line character)
# the rough syntax is:
# sed -e /start/,/end/$'s/find/replace'
sed -e /Contents/,/-----/$'s/ - \[/\\\n\[/' toc.chapters.md > debulleted.toc.chapters.md
# stitch title, front/back matters, and chapters
/usr/local/bin/pandoc -s --to=epub3 --template=../templates/epub.template --epub-embed-font='../fonts/*.otf' title.txt front-matter.md debulleted.toc.chapters.md > ../mybook.epub
# clean up the directory
rm *.md
With the build script in place, you're ready to assemble the Markdown you've written in Apple Notes into an epub. I like to make a Shortcut to run the build script and leave it in my shortcuts widget so I can just tap on it from the home screen of my iPad.