Plaintext Dock

Markdown, PlainText, Dropbox, and shell scripts

I am a big fan of Dropbox, the auto­matic folder sync­ing ser­vice that keeps a doc­u­ment folder syn­chro­nized across all of your com­put­ers and hand­held devices. I became a big­ger fan when I found iPhone apps like PlainText, which acts as a Dropbox-synchronized notepad. You can write notes on your desk­top, then see and update them on your phone and vice-versa. The files them­selves are just text files, not some weird pro­pri­etary for­mat, so you can work with them on the desk­top, too.

I’ve also started to get intrigued by Gruber’s Markdown “lan­guage” (for lack of a bet­ter word). It allows you to write text in a sim­ple and read­able way that can then be auto­mat­i­cally trans­lated to styl­ized and linked text. For instance, writ­ing some­thing *like this* will make it bold upon pub­li­ca­tion. Writing [Google]( will pro­duce a link to Google. Nested bul­let lists are sim­i­larly easy.

I have a few notes in PlainText that con­sist of lists and links. They trans­late quite eas­ily into Markdown, but I couldn’t find any great iPhone tools for view­ing or edit­ing Markdown across a Dropbox share. So I did what any self-respecting Unix admin would do: I wrote a shell script!

Specifically, the shell script looks for files in my Dropbox PlainText folder with the exten­sion “.md.txt”. This indi­cates it’s a text file in Markdown for­mat. If there’s no cor­re­spond­ing “.html” file or the .md.txt is newer than the .html file, then it gen­er­ates a new HTML file.

What this means is that I can edit a note on my iPhone or iPad (or from a short­cut in the dock of desk­top com­puter)...

Markdown Source

...and then when the script is run, a cor­re­spond­ing HTML file is avail­able:

Generated HTML (Browser)

Since I can­not (eas­ily) kick off a shell script from my phone, this is set up as a cron job on one of my desk­top machines. It runs every 5 min­utes, looks for miss­ing or out-of-date HTML files, then gen­er­ates what it needs to. I guess I could have made it run more fre­quently, but the sorts of notes I take rarely change and are mainly used as ref­er­ence every few days or weeks.

For those that are inter­ested, the script is repro­duced here:


find . -name '*.md.txt' > ${TMP}markdownlist.$$
exec 0<${TMP}markdownlist.$$
while read SRC
    DST=`echo $SRC | sed 's/.md.txt/.html/'`
    if [ ! -f "$DST" ]; then			# doesn't exist -> rebuild
    elif [ "$SRC" -nt "$DST" ]; then	# html older than Markdown -> rebuild
    if [ "$1" == "-force" ]; then
    if [ $REBUILD -eq 1 ]; then
        echo "$SRC -> $DST"
        echo '<html><head><title>' > $DST
        echo "$DST" | sed 's/.*\///' | sed 's/.html//' >> $DST
        echo '</title><body>' >> $DST
        cat "$SRC" | $MARKDOWN >> $DST
        echo '</body></html>' >> $DST
rm -f ${TMP}markdownlist.$$

I orig­i­nally tried to do this as a Makefile, but using make to process files with pos­si­ble spaces in their names proved to be more dif­fi­cult than expected. Make assumes space-delimited file­names in most places and the tricks to con­vert spaces to some­thing else, then back, did not mesh so well with wild­cards and file­names that are unknown at run­time.

Posted in: Code Dear Diary iPhone

Published by

Brian Enigma

Brian Enigma is a Portlander, manipulator of atoms & bits, minor-league blogger, and all-around great guy. He typically writes about the interesting “maker” projects he's working on, but sometimes veers off into puzzles, software, games, local news, and current events.

2 thoughts on “Markdown, PlainText, Dropbox, and shell scripts”

  1. Thanks, a few days ago made some­thing like it but sim­pler for Markdown, using Hazel, using your com­pi­la­tion code and today I came back to learn about the –nt oper­a­tor which is way use­ful! This time is for auto­matic LaTeX com­pi­la­tion :)

  2. You prob­a­bly know this by now but there is a pretty decent iOS text edi­tor called Nocs which has mark­down sup­port built in. I use it with Dropbox.

Leave a Reply

Your email address will not be published. Required fields are marked *