Home

You’re Doing That Wrong is a journal of various successes and failures by Dan Sturm.

"Send With Gmail" Service for OS X

Do you ever need to send an email, but hate the thought of opening Gmail and seeing an inbox full of expectations?

On this week’s episode of Systematic, Merlin told Brett how much he enjoys using Drafts on iOS to quickly send an emails to solve exactly that problem. He also mentioned there isn’t an easy way to achieve the same thing on the Mac. Since I wanted such a tool to exist, I decided to take a whack at it and see what I could come up with.

I thought the best fit for such a tool would be a system service. As much as I still enjoy using TextExpander to process text, copying the email content to the clipboard and typing a snippet is inelegant and leaves room for error. A system service can be called from pretty much any application with a quick keyboard shortcut of my choosing. Besides, I’ve never created a system service before and where’s the challenge if I don’t try something new?

How Does it Work

Like Drafts, it uses the first line of input as the subject of the email and lines three through the end for the body, assuming you’ll leave a blank line between the subject and body. Optionally, you can launch an empty Gmail message by using your key command with an empty selection [1].

The service uses Gmail’s URL syntax which allows fields to be prepopulated in the address bar. It’s the same idea behind the YouTube URL scheme that allows you to do things like link to a specific time in a video. For my purposes I would need the syntax for subject, body and opening the compose window in full screen [2]. As it happens, those URL parameters are as follows:

subject: su=
body: body=
full screen compose: fs=1

Just like YouTube, these parameters are concatenated with an ampersand, creating a URL that looks like this:

https://mail.google.com/mail/?view=cm&ui=2&fs=1&tf=1&su=SUBJECT&body=BODY

When using the service, you can compose your message in any application, then, when you’re ready to send it, select the text and hit your keyboard shortcut. As long as you’ve previously logged into Gmail in your browser, you’ll be taken directly to a full-screen compose window awaiting your recipient’s email address. And even better, after you hit send, you won’t be taken back to your inbox.

Limitations

This being the complete hack that it is, there are some limitations to the service.

First, it’s plain text only. Since the content of the message passes through the location bar of your browser, there’s no way (that I can tell) to pass rich text. My hope was to be able to write emails in Markdown and process the text before sending, but as of yet, I haven’t been able to figure out how to make that happen.

EDIT 2013-03-11: As luck would have it, it seems our friend Brett Terpstra, with the help of Tobias O'Leary, has solved this particular problem for us.

Second, and this is a big one, there is a limit on the length of the email. It may sound like a deal breaker, but in practice it’s not as inconvenient as you might imagine. Because this hack uses a URL to pass the email information, we’re limited by the maximum URL length supported by the browser. Yes, there is a maximum URL length.

In my testing, I found the maximum length of a working URL was 1465 characters. The result was the same for both Chrome and Safari. Since the service is adding extra characters to the email content in order to create a functioning URL, the length of the actual email content is limited to around 1350 characters.

It’s a bummer that this limitation exists, but if you’re writing a longer email and you’d still like to avoid your inbox, I suggest launching a blank Gmail message (as mentioned above) and composing your message in the browswer or using the service with only the subject line selected and pasting in the body text manually [3].

Download

Download: Send With Gmail service for OS X

The Code:

If you’d like to tweak the code or use it in another way, here it is.

#!/bin/python

import sys
import re
import subprocess
import urllib
from sys import stdin, stdout

tinput = stdin.read()

def subject_sel(s):
    line_list = re.split('\n', s)
    sub_final = line_list[0]
    return sub_final

def body_sel(b):
    line_list = re.split('\n', b)
    body_final = "\n".join(line_list[2:])
    return body_final

full_url = "open https://mail.google.com/mail/?view=cm&ui=1&fs=1&tf=1&su=" + urllib.quote(subject_sel(tinput)) + "&body=" + urllib.quote(body_sel(tinput))

process = subprocess.Popen(full_url.split(), stdout=subprocess.PIPE)
output = process.communicate()[0]

  1. You will need to be in a text field of some sort for the command to work. This can be in any location of any application that accepts text.  ↩

  2. It appears the full screen parameter is added automatically when creating an email with a prepopulated subject and body.  ↩

  3. Like an animal!  ↩

CMMA - A Panel Discussion on Stereography

Back in April of this year, I was asked to speak on a panel about Stereoscopic 3D production at the Communications Media Management Association's Spring Conference in Redmond, Washington.

The panel consisted of Adam Green from Avid Technology, Keith Vidger from Sony, Amir Stone from the Adobe AfterEffects development team, and myself.

The audience, as you can see from the live polls at the beginning of the video, was essentially brand new to the topic of S3D, so the discussion ranged from a basic introduction to stereo nomenclature and workflow, to on-set learnings and insight (primarily my focus).

I think it turned out pretty well, and now it's online, so check it out.

Experiments in iSight Scripting

A week or two ago, a conversation with my girlfriend reminded me of this old video from the Defcon 18 Conference, in which a hacker by the name of Zoz recounts the tale of how he located and recovered his recently-stolen computer by way of some fancy Internet skills. In addition to being a great reminder about data safety and security, it’s a pretty damn funny story.

Re-watching the video reminded me I’ve always wanted to experiment with scripting the iSight camera on my MacBook Pro. Not necessarily for the purpose of having photo evidence in the event of a theft, but more as a fun exercise in scripting and automation. Maybe I’m easily entertained (rhetorical), but I found the process and results throughly enjoyable.

Command Line Tools

The first thing I needed was a command line interface to the iSight camera. Despite my best Googling efforts, I wasn’t able to find any native OS tools to fire the camera (I’m still not sure if there is one). But lucky for me, nearly every search I did pointed me to a free, no-longer-supported-but-still-functional CLI tool called iSightCapture. Installation is as simple as tossing it into /usr/local/bin.

Regarding syntax, here’s the pertinent information from the iSightCapture readme file:

isightcapture [-v] [-d] [-n frame-no] [-w width] [-h height] [-t jpg|png|tiff|bmp] output-filename

Options
-v output version information and exit
-d enable debugging messages. Off by default
-n capture nth-frame
-w output file pixel width. Defaults to 640 pixels.
-h output file pixel height. Defaults to 480 pixels.
-t output format - one of jpg, png, tiff or bmp. Defaults to JPEG.

Examples
$ ./isightcapture image.jpg
will output a 640x480 image in JPEG format

$ ./isightcapture -w 320 -h 240 -t png image.png
will output a scaled 320x240 image in PNG format

Triggering

I wanted the ability to remotely trigger the iSight camera from my phone, and have it run for a predefined interval of time. To do this, I’d use a watch folder and a trigger file, uploaded from my phone, to initiate the script. This would theoretically be the method I’d use to “gather photographic evidence” in the event my laptop is stolen.

As usual, to set this up, I turned to my trusty friend Dropbox. To keep things tidy, I needed a couple of folders. The directory structure looks like this:

  • iSight_backup
    • scripts
    • trigger

The photos taken by the script will be placed in the top level directory, iSight_backup. The script itself would be placed in the scripts folder, and the trigger folder remains empty, awaiting a text file to be uploaded via Dropbox on my phone.

The Script

Here’s the script, called isbackup_t.bash, and saved into my iSight_backup/scripts/ folder:

#!/bin/bash  

#   path to iSightCapture CLI tool  
APPP="/usr/local/bin/isightcapture"  

#   path to Dropbox folder to receive photos  
FPATH="/Path/To/Dropbox/iSight_backup/" 

#   path to trigger file  
TPATH="/Path/To/Dropbox/iSight_backup/trigger/"  

#   select photo filetype; jpg, png, tiff, or bmp  
XTN=".jpg"  

#   number of photos to take  
PNUM="24"  

#   interval between photos (seconds)  
PINT="300"  

for i in `seq 1 $PNUM`;  
    do
        DTS=$(date -u +"%F--%H-%M-%S")  
        $APPP "$FPATH$DTS$XTN"  
        sleep $PINT  
    done  

rm $TPATH*  

The Details

Each photo gets a date and time stamp added to the file name for easy sorting. Since the FPATH destination is set to a folder within my Dropbox, and each file is a 640x480 jpeg, approximately 25kb in size, I can see the resulting photos on my phone just seconds after their taken.

By setting PNUM to 24, and PINT to 300, the script will take a photo every 5 minutes, for the next 2 hours, then stop until I upload another trigger file. However, since the script itself lives in Dropbox, I can change the interval or duration variables from my iOS text editor at any time.

Tying The Room Together

All that’s left to complete our little project is to create a launchd task to keep an eye on our trigger folder, and fire up the script if anything lands inside. Since creating, modifying, or using launchd tasks via any method other than a GUI is currently beyond me, I turned to Lingon.

Here’s the resulting launchd task:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>isbackup triggered</string>
    <key>ProgramArguments</key>
    <array>
        <string>bash</string>
        <string>/Path/To/Dropbox/iSight_backup/scripts/isbackup_t.bash</string>
    </array>
    <key>QueueDirectories</key>
    <array>
        <string>/Path/To/Dropbox/iSight_backup/trigger</string>
    </array>
</dict>
</plist>

And just like that, we’ve got a setup that will monitor our trigger folder, fire up our script when it sees anything inside, and save each file to our Dropbox.

Extra Credit

During my research for this project, I found a number of people using iSightCapture for things other than a makeshift security tool. Some, for example, used it to take a self portrait at login every day and auto-upload it to an online photo diary.

I thought that was a fun idea, so I wrote a second, shorter version of my script to automatically take a shot every 2 hours without the need for a trigger. For my version, however, I was most definitely not interested in auto-uploading the photos.

The script:

#!/bin/bash

APPP="/usr/local/bin/isightcapture"
FPATH="/Path/To/Dropbox/iSight_backup/"
DTS=$(date -u +"%F--%H-%M-%S")
XTN=".jpg"

$APPP "$FPATH$DTS$XTN"

And the launchd task:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Disabled</key>
    <false/>
    <key>KeepAlive</key>
    <false/>
    <key>Label</key>
    <string>IS Secuirty</string>
    <key>ProgramArguments</key>
    <array>
        <string>bash</string>
        <string>/Path/To/Dropbox/iSight_backup/scripts/isbackup.bash</string>
    </array>
    <key>QueueDirectories</key>
    <array/>
    <key>RunAtLoad</key>
    <true/>
    <key>StartInterval</key>
    <integer>7200</integer>
</dict>
</plist>

Since I typically use a multiple monitor setup when working, I almost never see the green light come on when the script runs and when I check the photo directory, usually the beginning of the next day, I’m treated to at least a couple hilarious images. Like these, for example:

Hi Merlin!

I may be asleep in this photo. I can't tell.

No, that's not my poster. My girlfriend got to decorate that side of the room.

Yes, It makes Skype calls awkward. Then again, so does that hair.

Cleanup

Despite the photos being almost inconsequentially small in file size, I really don’t need to be keeping a long-running historical record of my disheveled appearance. To keep things from getting unwieldy, I created a Hazel rule that deletes files older than 2 weeks. I see no reason I’d need to keep them any longer than that.

Why?

I don’t know if it’s because this little project was so different from my day to day work, or I thought it would be a genuinely useful security tool, or I’m a narcissist that loves seeing pictures of himself (again, rhetorical), but I had a blast playing around with this little project.

As with nearly everything on this blog, I learned some things, failed a few times, and came out the other side with a fun little script I can demo to people, making it absolutely certain they’ll never ask me anything about computers again.

Converting MultiMarkdown to HTML with TextExpander

If you’re here, reading this site, chances are pretty good that you use and love MultiMarkdown as much as I do. That, or you’re at least fairly curious and have a plenty of free time.

With more and more applications supporting Markdown natively, the need to convert the text to HTML is decreasing in frequency. However, the need isn’t completely gone. Sometimes you just need some good old fashioned HTML.

A Hammer For Every Season

(Or Some Other Metaphor That Actually Makes Sense)

There are almost as many ways to get your MultiMarkdown into HTML as there are applications that support Markdown.

I’ve created build systems for Sublime Text to convert MultiMarkdown documents to HTML files. I’ve got a build system that lets Marked do the heavy lifting for me. For the times I don’t need a full MultiMarkdown document, just a small snippet of text, I’ve got Brett Terpstra’s killer MultiMarkdown Service Tools.

It’s probably due to the myriad of tools at my disposal that I only recently discovered I’m unable to use Brett’s OS X Services in Sublime Text 2. I’ll admit, I didn’t try very hard, but after Control + Clicking, trying my keyboard shortcuts, and doing a bit of searching online, I quickly gave up and decided to build a tool I knew would work.

To TextExpander We Go!

When I need a system-wide tool that works in any application, activated by a few quick keys, the answer is almost always TextExpander. With its ability to act as an intermediary between text and scripts, TextExpander is the hammer that always gets the job done [1].

The snippet:

#!/bin/bash
pbpaste | /usr/local/bin/mmd

Just like my other text processing scripts, proper use involves selecting the text to be processed, copying it to the clipboard, and invoking the snippet, which I’ve bound to the command ;mmd. Now, any time I need to convert MultiMarkdown text into HTML, without the hassle of saving files and opening specific applications, I’ve got a quick, universal keyboard command I can use. Bringing me one step closer to an application agnostic workflow.

Hooray!


  1. Yes, I’m sticking with the hammer metaphor. I’m in too deep to turn back now.  ↩

Running Scripts with TextExpander

I love that the Internet is full of smart people making and sharing awesome things. Like Dr. Drang and his Tidying Markdown Reference Links script. Seth Brown’s formd is another great tool I don’t know how I ever lived without. But, being the amateur that I am, I always struggle to figure out just how to use the scripts these amazing programmers have been kind enough to provide.

Lucky for me (and you), I’m able to play along with the help of everyone’s favorite writing tool, TextExpander. In the documentation for formd, Seth was gracious enough to spell it out for us laypersons[1].


To run formd with TextExpander, simply place the Markdown text to convert onto the clipboard and issue the appropriate TextExpander shortcut (I use fr or fi for referenced or inline, respectively).

It took longer than I’d like to admit, but eventually I realized this snippet could be tweaked to run any script I happen to download from a coder more skilled than myself. Additionally, since most of the scripts I want to use are built for processing text, the copy/paste activation generally works great.

#!/bin/bash
pbpaste | python /Path/To/Your/Script/script.py

With this short snippet, I can copy my text to be processed, invoke the script snippet of my choosing, and have the results immediately pasted back into my text editor, email, or wherever.

This particular snippet assumes you’re running a python script, but you can just as easily swap python for ruby or perl. Or you can omit the python call if you’re just running a standard Bash command. As long as it’s a valid command that would run in the Terminal[2], you can automate it this way. And, just as with formd, to use the snippet, you simply Copy the text to be processed, and invoke the snippet.

Boom. Done. Life is grand.

While none of this is new or revolutionary, connecting the dots between TextExpander and the Terminal is something I wish I’d have discovered long ago and, therefore, may be of interest to you.

Of course none of this would be possible without the amazing minds that write the scripts in the first place. So, along with this post, I offer a sincere Thank You to Dr. Drang and his site And now it’s all this, as well as Seth Brown and his site Dr. Bunsen.


  1. Layfolk? Laypeople? Missing the point?  ↩

  2. And frankly, I just start trying things in the Terminal until I find the correct command.  ↩

Fountain for Sublime Text

Jonathan Poritsky has created a great Fountain package for Sublime Text. It supports almost everything outlined in the Fountain syntax guide but, most importantly, gives us syntax highlighting.

While not everyone likes the idea of using colors to highlight elements in their screenplay, I most definitely do. For me, syntax highlighting is equivalent to the red squiggly line underneath a misspelled word. At a glance, I can see if I've made any errors and, to a lesser degree, I can recognize patterns of highlighted elements to quickly understand where I am in the overall document.

Another reason I want syntax highlighting is to ease my recent transition to full-time use of Fountain for screenwriting writing projects, replacing my roll-your-own MultiMarkdown screenplay syntax.

The Part Where I Ruin Everything

Hands down, my favorite part of Jonathan's Fountain package is its ability to be customized, like all Sublime Text packages. The default package theme does a good job of emulating the look of a screenplay, using layout settings like 15pt black Courier on a white background and centering the text within the document window, etc.

While I enjoy reading screenplays in their correct format, I really dislike that layout during the writing process. I much prefer to look at white text on a black document. More specifically, I use the Sunburst theme in Sublime Text while writing in MultiMarkdown. Since Fountain is designed specifically to be platform and application agnostic, I'm free to be as picky as I want about my writing environment.

So, I tweaked the theme that came with the Fountain package. The biggest thing I wanted to add was background highlighting for Scene Headings. It helps me quickly scan the document to find the beginning of a given scene.

I made all Scene Headings, Action, Character, and Dialogue elements white(ish), and Parentheticals, Sections, Synopses a dimmer grey color to help them fade into the background a bit. The only elements that use colored text are Transitions, Notes, and the Title Page, which uses the same color scheme as MultiMarkdown metadata in the Sunburst theme.

In Fountain.sublime-settings I removed the additional line padding, changed the font to Monaco 11, turned on line numbering, and turned off "draw_centered". What I'm left with is a document that looks nothing like a screenplay, just the way I like it.

Personally, I don't want to feel like I'm writing a screenplay. Writing a screenplay is hard and stressful. Conversely, writing words into a text editor is something I can do all day long. Maybe some day I won't be so particular or need to psych myself out in order to write, but for now, this feels right to me and I'm sticking with it.

If for some reason you would like to use my theme, download this file and drop it into the Fountain folder in your Sublime Text package directory. Once you've done that, open up Fountain.sublime-settings and make yours match mine:

{  
    "extensions":  
    [  
    "fountain"  
    ],  
    "font_face": "Monaco",  
    // "font_face": "Courier Screenplay",  
    // "font_face": "Courier Final Draft",  
    "font_size": 11,  
    "color_scheme": "Packages/Fountain/Fountain Dan.tmTheme",  
    "word_wrap": true,  
    "wrap_width": 78,  
    // "line_padding_top": 5,  
    "draw_centered": false,  
    "spell_check": true,  
    "indent_subsequent_lines": false,  
    "trim_automatic_white_space": true,  
    "line_numbers": true,  
    "translate_tabs_to_spaces": true,  
    "auto_complete_commit_on_tab": true,  
    "auto_complete_with_fields": true  
}

Launching Marked from Sublime Text 2

I do pretty much all my MultiMarkdown writing anymore in Sublime Text 2. I’ve come to rely on Marked for previewing my files with a variety of custom CSS files, depending on the type of project I’m writing.

At the moment, the most annoying part of this workflow is the time it takes to open Marked and locate the MultiMarkdown file I’m currently working on in Sublime Text. I think I’ve been spoiled by the speed of using Sublime Text’s Goto Anything feature (Command + P) for opening files.

To speed things along, I wrote a new build system for Sublime Text that launches the active document in Marked. Now previewing my active file is as easy as invoking the build command which, for me, is still Command + B.

The (insanely simple) code [1]:

{  
"shell": "true",  
"cmd": ["open -a marked \"$file\""]  
}  

More non-rocket-science, but a big time saver in my world.


  1. This build system is only for OS X.  ↩

Automated FTP upload with Hazel via Bash

A couple weeks ago Macdrifter had a nice post about automating FTP uploads with Hazel, Dropbox, and Python. It’s a similar idea to the setup I’ve been using to automate my MultiMarkdown workflow, but the main reason it grabbed my interest was this line:

I really like Transmit for FTP, but it seemed a little heavy handed for Hazel automation.

He’s right. Using Transmit for the FTP portion of my process was a poor decision. It just happened to be the only way I knew how, and scripting the FTP upload didn’t even occur to me at the time (there’s a reason for the name of this site).

After reading his post, I decided to swap out the slow and clunky Transmit portion of my Hazel rule with some fancy code. One problem. I don’t know anything about Python[1], and the 3 hours I spent trying to get up to speed were futile and fruitless.

Since I’ve dabbled a bit with Bash, I decided to see if there was an equivalent way to accomplish the same tasks. After a bit of searching, and a lot of trial and error (again, read the name of the site), I came up with this:

HOST=ftp.DOMAIN.com  
USER=myUserName  
PASS=myPassword  

JNAME= \ basename $1\  

ftp -inv $HOST << EOF  

user $USER $PASS  

put "$1" "$JNAME"  

EOF  

echo "http://dansturm.com/$JNAME" >> /Users/PATH/Dropbox/PATH/UPLOADS_LOG_FILE.txt

It’s faster than the Transmit method. It works more often than the Transmit method. And it even records the URL of the uploaded file to a text file in my Dropbox (my favorite idea from the Macdrifter post). I also have the Hazel rule change the file name to all lowercase and swap spaces for underscores, something is already performed in my Text to HTML conversion rule, but now the FTP rule can be used stand-alone as well as in conjunction with the MultiMarkdown process.

It has no error reporting, and you can’t even really tell it’s running (save for the evidence in the log file), but it’s way better than what I was using. Many thanks to Macdrifter for this one.

But…

I’m happy I was able to improve my exiting tools, and learn a few things in the process, but now that I’ve migrated this blog to Squarespace, I’m not sure how much I’ll actually use them considering Squarespace doesn’t support FTP access, and my home site doesn’t need updating very often.


  1. Okay, I know some Python, but only enough to customize the interface in Nuke and build some basic gizmos and comp tools.  ↩

Creating Linked Images with TextExpander

I have a TextExpander snippet for creating Markdown links. I have one for creating Markdown images. Both pull a URL from the clipboard.

On occasion I’ve used them in combination to create images that are linked to the, usually larger, original images. I don’t know why it’s taken me this long to create a single snippet to do this one task, but a recent project filled with high-rez images necessitated such a tool.

For this particular project, I’ve also used a fill variable to add a description to the image. Not rocket science, but just another tool to save myself a lot of time and frustration.

The Snippet:

[![%fill:description%](%clipboard) %fill:description%](%clipboard)

SP-MMD Cheaters

Since Brett Terpstra gave us Cheaters, I’ve been populating the app with the various tools I use frequently.

I’ve finally gotten around to creating a cheat sheet for my MultiMarkdown Screenplay syntax. I expect it to be used by precisely one person. Me.

However I’m posting it here to serve as a shorter explanation of the way I write, to spare you from reading the whole back story. It uses the same modified CSS file I created for the Fountain cheet sheet.

Here’s the SP-MMD Cheaters page.

And here’s the cheat sheet in a web-friendly view for curious passers-by.

My Hazel CMS

It should be no surprise to anyone familiar with the app, that Noodlesoft’s Hazel is amazing. Today I setup an automated system using Dropbox, Automator, and Hazel to process MultiMarkdown documents into HTML, give them web-ready filenames, and upload them to my website.

Everything on this site starts as a MultiMarkdown text file. I preview the page in Marked, and when its ready to go live, I save a copy of the file in a folder called _1_ready_, which has 3 Hazel rules applied.

Ready

First things first, the text file needs to be converted to an HTML document. I’ve used the Run Shell Script action to call the mmd command.

Pretty straight forward. To add some flexibility, the second Hazel rule for the _1_ready_ folder checks for changes to preexisting text files, and processes them using the same bash script. That saves me from having to delete and re-copy a file to make an update.

The last rule for the _1_ready_ folder renames the HTML file, making it entirely lowercase, replaces the spaces with underscores, and moves the new file to a folder called _2_go_.

It’s important to make sure the name element in the with patern: section is set to lowercase, and the replace text dialog is used to swap the spaces for underscores.

Go

The _2_go_ folder automatically uploads any file it finds to the root of my site. As with _1_ready_, the final files are left in the folder to more easily make changes later. Additionally, I keep a copy of my Blog index page and rss XML in the _2_go_ folder so I can quickly update the main page with links to the new posts.

To upload the files, the Hazel rule calls an Automator Workflow that uses the Transmit [1] upload action to log into my site (stored as a favorite), and drop everything in the root folder, overwriting files if necessary.

Dropbox

The best part about this whole workflow is Dropbox. Both the _1_ready_ and _2_go_ folders are in my Dropbox, giving me the ability to drop in files from my iPhone, iPad, etc. With apps like TextExpander and Nebulous Notes, there’s no reason I can’t create, and post entirely from an iOS device. Obviously I’ll need a Mac, running and online, but the flexibility of this workflow is well worth the cost of a dedicated system.

Needless to say, I’m incredibly excited to have this new capability, and I can’t wait to see what other workflow magic I can create with Hazel


  1. Many thanks to Macdrifter for recommending Transmit. I love this app.  ↩

Update: I've since revised my upload method to use a Bash script, rather than Transmit. It's much faster and more efficient, so if this idea interests you, you should definitely check it out.

MultiMarkdown Build Systems for Sublime Text 2

When I started using Sublime Text 2 as my primary text editor, last year sometime, I created a build system to more quickly process my MultiMarkdown files. Since I couldn’t find a preexisting MultiMarkdown build system in the Sublime Text forum, it’s probably a safe bet that others might find it useful for me to post mine.

Since all of my writing is based on MultiMarkdown and varying CSS files, I use the same build system for screenplays, blog posts, presentations, etc. When I created the initial build system I was doing the majority of my writing on a Windows 7 machine. Since that time, I have retired all of my Windows computers [1] and created a new build system for OS X (10.7.3).

Here are both build systems:

OS X

{
"shell": "true",
"path": "/usr/local/bin",
"cmd": ["mmd \"$file\""]
}

Windows

{
"shell": "true",
"cmd": "multimarkdown -b \"$file\"",
"cmd": "\"\"${file/\\.txt/\\.html/}\"\""
}

The last line in the Windows build system is a launch command that will open the processed document in your default HTML application. Since I have Marked on my Mac, I decided to omit the launch command from the OS X version and pick my viewer on a per-file basis.


  1. For a number of reasons, I’m still required to use a VM of Win 7 on my Mac via Parallels.  ↩

Fountain for Cheaters

Fountain for Cheaters

Earlier today Brett Terpstra posted Cheaters, a “customizable cheat sheet system”. It’s easy to use, super helpful, and just all around awesome.

I had a little time this afternoon so I whipped up a Fountain syntax guide, pulled from the fountain.io syntax page. Here are links to the Fountain sheet and the modified CSS file. Follow Brett’s instructions to customize your own cheatsheet.

I plan on adding my SP-MMD syntax to my cheatsheet, as well as my still-in-development MultiMarkdown sildeshow presentation tool.

FYI, since I’m strictly an amateur, I make no guarantees that this will work as well for you as it does for me.

A huge thanks to Brett for this insanely useful tool.

My MultiMarkdown SPMD Workflow

MultiMarkdown and SPMD

Back in August when Stu Maschwitz proposed Screenplay Markdown (formerly SPMD, now Fountain), I got very excited. After giving Stu way more input than he needed, I decided I wanted to use something like SPMD sooner rather than later.

Due to my lack of any real programming skills, I decided the quickest way to get something usable was to continue writing in MultiMarkdown and use simple CSS to transform my output into something that looked like a screenplay.

My solution is in no way as robust or polished as Stu’s SPMD proposal, but having used it for a few months now I find it suits my needs pretty well. You can find my SP-MMD(?) CSS file here.

Why MultiMarkdown?

There are a few reasons I chose to use MultiMarkdown instead of standard Markdown syntax. The first reason is it’s inclusion of metadata and the ability to create a “complete document” rather than just an HTML “snippit”.

From the MultiMarkdown user guide:

If you include metadata in your document (with two exceptions), then you will generate a complete document. If you don’t include metadata, then you will instead generate a “snippet.” The snippet will just include the relevant portion of HTML, but will not include the <head> or <body> elements.

The metadata features give me a nice looking header to all my text files and, more importantly, creates a complete HTML document that’s ready for the web. You may be asking, “But why does it need to be ready for the web? It’s a screenplay.” As much as I love writing in my text editor, eventually I will need to preview the final output of the properly formatted document.

Previewing

Ideally to view the final document I’d use something like Brett Terpstra’s awesome Marked app. But, unfortunately, I do the majority of my writing on a Windows 7 machine (please don’t email me [1] ). Regardless of the operating system on the machine itself, I like the idea of doing my previewing in a browser for two reasons. First, let’s face it, any computer you sit down at these days is going to have at least one browser installed, and that’s just one less app I need to worry about installing for my workflow to function properly. The second reason I user the browser for previewing is print support. MultiMarkdown supports some great text to pdf conversion tools through LaTeX, but the simpler solution is simply to print to PDF directly from the browser preview.

Another benefit of creating an HTML document from my text file is the ability to quickly upload it to my website and send a link to people. Having that online backup saves my ass when I’m away from a computer and someone who has lost their copy needs to read my script ASAP. Of course I always have my iPhone with me and I can easily resend the PDF via Dropbox, but that takes longer than just emailing or texting a URL.

CSS

The other huge advantage to using MultiMarkdown is the CSS metadata key. While Markdown is capable of using standard HTML code within the document, I much prefer the cleanliness and simplicity of the MultiMarkdown implementation.

Example. To link my CSS file in a standard Markdown file, I can use the line:

<style type="text/css"> <!-- @import url("http://dansturm.com/ds_script.css"); -->    </style>

Not exactly something I love to see at the top of all of my text files. With MultiMarkdown it’s as simple as:

CSS: http://dansturm.com/ds_script.css

Much better. And being that it’s cleaner to read, if I want to switch to a different CSS file for different formatting, I can more quickly and easily modify the URL.

My SP-MMD Syntax

The next problem MultiMarkdown solved was the fact that I would simply be using existing Markdown syntax elements in ways they were never intended, rather than creating my own language from the ground up. MultiMarkdown solves that problem by having additional syntax features not found in Markdown.

Standard MultiMarkdown *italics* and **bold** syntax is preserved. There is currently no support for underline text.

Basic Action elements of the script have no additional syntax associated with them (just as in Stu’s SPMD) and only required basic margin adjustments to the <p> tag to create the correct looking format.

For other elements of a screenplay I need the ability to have things left, center, and right justified. I appropriated the H1, H2, and H3 tags for this purpose. Examples:

For things like scene headings (left justified via H1), I write:

# Int. Coffee Shop - Day

Since scene headings should be written in CAPS, we can use the magic of CSS and the text-transform: uppercase command to automatically capitalize the line. It may not seem like a big deal, but it’s automating small things like this that allow me to keep my mind on the words and not the formatting.

Elements needing center alignment like the script’s title (NOT characters or dialog), use the H2 tag:

## Fancy Screenplay
## By Dan Sturm

Centered text is different from left or right justified text in that it is not subject to auto capitalization. I felt it’s content needed to be flexible.

And, as expected, right aligned text is written as:

### Cut to

Now for dialog. I needed control over both Character and Dialog elements separately, but I didn’t want each to require different syntax modifiers. As luck would have it, MultiMarkdown’s support for Definition Lists fit this need perfectly. To write dialog the syntax is:

Dan
: Is this guy completely insane?

Using just a colon before the dialog (and no spaces following the character) gives the character name the <dt> tag, and the dialog receives the associated <dd> tag. Again, by way of the text-transform: uppercase command, our character name is automatically capitalized. Two script elements defined by a single syntax character. Just what I was looking for.

To add a parenthetical to a line of dialog, I used the code-block designation of surrounding the line with backticks. I wish additional syntax wasn’t necessary for parentheticals, but at the moment this is the best way I could get the result I needed. Example:

Dan
`(pointing)`
: Is this guy completely insane?

Since there’s really no built in tool for pagination of HTML files, I felt a need to create a tool to force page breaks. A horizontal rule is all that’s required to force a page break. The forced page breaks are only visible when the document is sent to print, but I think the horizontal rule does a decent enough job of communicating the page break in the browser.

Known Issues

Since I put this little project together in a couple hours one night, when it reached the point of being “usable”, I stopped working on the code and went back to writing my script. As expected, there are a few known issues that may or may not be deal breakers for you.

The first issue is related to margins. When printing from the browser, I cannot print all the way to the edge of the paper. If there’s a way to create a full bleed PDF from a browser, I haven’t found it yet. Why is this a problem? My CSS originally assumed a full 8.5“ x 11” piece of paper from which to base it’s margin adjustments for each element. Printing from the browser scales that full size image down to something closer to 8“ x 10.5” ruining the rest of the formatting. I’ve attempted to compensate for those margins, but since I’m not 100% sure how large the margins the browser is adding actually are, it’s just guesswork. I plan to revisit this problem in the next rev of the CSS.

The next issue is one that doesn’t really affect me in the writing I personally do, but may be an issue for others. When creating parentheticals within a line of dialog (i.e. not immediately after the character and immediately before the dialog) the resulting margin is incorrect. Since I don’t currently have a method for determining where in the dialog the parenthetical occurs, there is no workaround for this issue. Example of writing that creates a problem:

Dan
: Is this guy completely insane?
`(pointing)`
: Or is he just full of it?

Again, something I plan on revisiting in the future.

Currently Unsupported

In my implementation there is currently no support for the following screenplay elements:

  • Dual Dialog
  • Sections and Synopses
  • Underlined Text

Pain Vs Flexibility

If you still think this whole idea is crazy and way more painful than the associated benefit, allow me to share a few tips and benefits.

As any good writing nerd, I use TextExpander (and Breevy on the PC) to alleviate some of the pain of the syntax. Page breaks via horizontal rules are added by typing “hhrl”, which creates 5 asterisks. I use “iint” to create “# INT. (FILL-BOX) - (FILL-BOX)”. I have about a dozen snippets that automate frequently used screenplay syntax (and correct typos). Another great benefit of using TextExpander is the ability to have a snippet turn CAPS on and off as needed. And if I somehow manage to override the CAPS on any particular line, the CSS will correct my mistake for me. Again, another small tool that helps keep my mind on the words.

Another reason I love this process may be a bit of blasphemy to many of you, but since it makes my life easier, it may do the same for some of you. At the very bottom of my scripts is usually a page break (horizontal rule) followed by a list of links to other relevant files the customer may need to see. Here I add links to storyboards, budgets, video reference, etc. And since it follows a page break, it’s easy enough to leave out of the printed version by designating a page range in the print dialog box. I love having a linked list of important files directly attached to the screenplay because, frankly it’s one less email I have to receive from the customer who loses their copy of those associated files.

No, I’m Not Crazy

In summary, yes, this is a really weird way to write a script and yes, it probably seems like more work that it’s worth, but I really believe the benefits and flexibility of MultiMarkdown and CSS greatly outweigh the hassles, even if my current implementation is far from ideal. If you think this mess will work for you, feel free to use, copy, steal, or modify my CSS file. And I’ll be sure to let you know if I ever get around to making v0.02.

To close, here’s how a sample script would look in my SP-MMD format.

Title: Fancy Script
Author: Dan Sturm
Date:
CSS: http://dansturm.com/ds_script.css

## FANCY SCRIPT
## By Dan Sturm

* * * * *

# EXT. GAS STATION - DAY

A bright hot day. A truck pulls up to the pump. The DRIVER steps out and heads inside.

The PASSENGER lights a cigarette and waits.

Eventually, the DRIVER bursts out the gas station door, GUN in one hand, MONEY in the other.

Driver
: Start the car!

Passenger
`(under his breath)`
: No shit.

### CUT TO:

# INT. NEXT SCENE - DAY

And Here’s what the above script looks like when formatted


  1. Borrowed, with love, from the great Marco Arment.  ↩