Writing Like a Geek

A few peo­ple have asked me for more details on my writ­ing process so I fig­ured the eas­i­est thing is to doc­u­ment it here. This about the lit­er­al process of how I put togeth­er my projects.

Editor

Kate in action
Chap­ter 2 in kate

My main edi­tor these days is Kate. Kate is a plain text edi­tor but since it’s part of the KDE project it comes with a huge num­ber of slick fea­tures include vi mode (vi is an unbe­liev­ably pow­er­ful edi­tor once you make it past the learn­ing curve). I use LaTeX markup for every­thing (more on that lat­er).

Project Structure

Each project gets its own fold­er (cur­rent project is named “ham­mer” due to an old work work­ing title). Each chap­ter is split in a cou­ple files but how many depends on my mood when I worked on that par­tic­u­lar piece (you can see in the above screen­shot that the chap­ter is split in four files: one for each of the three scenes and a fourth to put them togeth­er). Files are named with a one-let­ter pre­fix based on the act (A, B, or C), a num­ber (the chap­ter in that act), and a short name describ­ing the point of that file. Each act has its own file that puts the chap­ters in order (named part-A.tex, part-B.tex, and part-C.tex).

Generating Output

LaTeX is a pain to work with direct­ly (it pol­lutes the work­ing direc­to­ry and has no depen­den­cy man­age­ment) but CMake solves both of these prob­lems. CMake doesn’t sup­port LaTeX out of the box, but I hacked togeth­er a mod­ule to man­age LaTeX projects.

create_target(wolf-A "${CMAKE_CURRENT_SOURCE_DIR}" "${tex_files_A}" FALSE)
create_target(wolf-B "${CMAKE_CURRENT_SOURCE_DIR}" "${tex_files_B}" FALSE)
create_target(wolf-C "${CMAKE_CURRENT_SOURCE_DIR}" "${tex_files_C}" FALSE)
create_target(wolf   "${CMAKE_CURRENT_SOURCE_DIR}" "${tex_files}"   TRUE)

create_target(wolf-pub   "${CMAKE_CURRENT_SOURCE_DIR}" "${tex_files}" FALSE)
create_target(wolf-lulu  "${CMAKE_CURRENT_SOURCE_DIR}" "${tex_files}" FALSE)
create_target(wolf-scrib "${CMAKE_CURRENT_SOURCE_DIR}" "${tex_files}" FALSE)

The first four lines let me pro­duce man­u­script-for­mat­ted out­put for either the whole nov­el or indi­vid­ual acts, the bot­tom three pro­duce type­set con­tent, type­set con­tent for a 6″ x 9″ page (per the require­ments on Lulu), and indi­vid­ual chap­ters (for post­ing to Scri­bophile). The main tar­gets I lever­age are the first four, most­ly because man­u­script for­mats build much faster than non-man­u­script for­mats.

Using LaTeX means I get lots of slick fea­tures when I gen­er­ate the type­set out­put, includ­ing kern­ing, hyphen­ation, lig­a­tures, old-style numer­als, and micro-typog­ra­phy (this adjusts things like the spac­ing with­in words and over­flow­ing into the mar­gins to get white­space that looks uni­form to the human eye). Both type­set and man­u­script forms lever­age LaTeX fea­tures like the csquotes pack­age (auto­mat­i­cal­ly man­ages quote match­ing across lan­guages, includ­ing nest­ed quotes).

Each tar­get can be built in pdf, html, or odt. I can also gen­er­ate “full” ver­sions which include some post-pro­cess­ing on the out­put, but that’s only required for the full man­u­script (required to gen­er­ate Spe­cial Char­ac­ters).

You can com­pare chap­ter 2 of The Howl of the Wolf in both man­u­script and type­set for­mats.

Tools

I use apsell for spellcheck­ing and inte­grate it with cmake using a cus­tom com­mand.

add_custom_target(spellcheck)
foreach   (file ${spellcheck_files})
    add_custom_command(TARGET spellcheck
                       COMMAND ${ASPELL} -t -p ${CMAKE_SOURCE_DIR}/aspell_dict check ${file})
endforeach(file)

If you don’t speak geek, this runs the entire project through aspell using a cus­tom dic­tio­nary iso­lat­ed to that project. My cur­rent plan is to delete the dic­tio­nary and run a clean spellcheck before pub­lish­ing (just in case I acci­den­tal­ly added a word by mis­take), but for now I can tol­er­ate a few spelling errors.

I have a few scripts to help with analy­sis and file man­age­ment. The most obvi­ous exam­ple is word counts (split­ting chapters/acts across lots of files makes this hard).

sh ../chapwc.sh 
A-00  3015+1+0 (1/0/0/0) Total
A-01  3688+0+0 (1/0/0/0) Total
A-02  2920+0+0 (1/0/0/0) Total
A-03  2471+0+0 (1/0/0/0) Total
A-04  2412+0+0 (1/0/0/0) Total
A-05  2718+0+0 (1/0/0/0) Total
A-06  1401+0+0 (1/0/0/0) Total
A-07  1117+0+0 (1/0/0/0) Total
...

All changes are tracked using git.

Posting

Before post­ing any­thing to Scri­bophile I run it through Pro Writ­ing Aid to help with gram­mar and style. If you haven’t tried Pro Writ­ing Aid give it a shot, the site is amaz­ing (it found the exact same sen­tence being used twice in the same chap­ter; not sim­i­lar, the exact same). I usu­al­ly work through one report at a time, updat­ing my raw files and gen­er­at­ing new out­put as I go to make sure I don’t miss any­thing.

After going through Pro Writ­ing Aid I check for trou­ble­some words. When I’m done clean­ing those up I do one last check through spellcheck and Pro Writ­ing Aid to make sure I didn’t intro­duce new prob­lems.

Once the san­i­ty check is done I spit out the chap­ter in html (eas­i­er than deal­ing with copy/pasting through a pdf) and copy/paste in Scri­bophile.

Version Control for Fun and Profit

Keep­ing track of old ver­sions of your work is one of those things you don’t appre­ci­ate until you have it. Most peo­ple keep old ver­sions with a mish­mash of file names (novel.doc, novel-backup.doc, novel-backup2.doc, novel-backup-september-2015.doc, …) or using a ser­vice like Google Dri­ve or Drop­box. These solu­tions work but to say they’re lack­ing is an under­state­ment. Enter git.

Git is a piece of soft­ware used to track his­to­ry of source code. While it’s fine-tuned for this behav­ior it’s still phe­nom­e­nal at track­ing changes in projects that are struc­tured sim­i­lar to soft­ware. If your project has the fol­low­ing prop­er­ties git makes an excel­lent choice:

  • work is stored in plain text (i.e., non-bina­ry files)
  • files are small to medi­um-sized
  • files are human-read­able

Since I use LaTeX all these con­di­tions are met (most word proces­sors have an option to store con­tents in flat files which gets you most of the way here).

So how use­ful is git? Think about the back­ups spread across dif­fer­ent ser­vices and fold­ers with God-only-knows what names. Count how many you have and com­pare it to the his­to­ry of my project.

$ git log --oneline | wc -l
177

177 ver­sions at the time of this post, all of which are time-stamped with meta­da­ta about what actu­al­ly changed. The last two com­mits look like this:

commit 42bf73d45dfe7fea13996ef9e3b2cdd0e122dc0a
Author: K.P. Wayne
Date:   Sun Jan 29 20:02:52 2017 -0700

    Polish up first part of chapter 1 using Pro Writing Aid

commit 297b676edc97643f901be6f6d0f846546534f2d5
Author: K.P. Wayne
Date:   Sun Jan 29 18:54:26 2017 -0700

    Work in feedback from Scribophile

Not only is back­ing up off­site triv­ial, but each back­up con­tains the entire his­to­ry of the project. As of right now my entire repos­i­to­ry, mean­ing the full his­to­ry of my project, is a whop­ping 652 kilo­bytes; less than half the space of a flop­py disk.

You can also mark spe­cif­ic ver­sions with sym­bol­ic names (the git term for this is a tag). This makes it triv­ial to see what changed between two dif­fer­ent ver­sions.

git diff –col­or-words scrib-bk1-a01..master bk1/A-01mine.tex

In fair­ness git has a learn­ing curve and last time I checked most gui tools ranged from awful to bad (cowork­ers assure me this has changed). A sim­pler option is mer­cu­r­ial and Joel Spol­sky put togeth­er a sim­ple tuto­r­i­al for any­body unfa­mil­iar with ver­sion con­trol.

It’s not for every­body and I haven’t test­ed git with pop­u­lar tools Scriven­er but if it fits in your work­flow give it a go.