Tools I'm using to write the book

Since I can't really share the book with you, I figured I could share some of the tools I'm using to write it. They're a pile of hacks as I tend to flounder outside of Perl, but they work and I figured geeks would get some useful stuff out of them.

First, I have an alias, book, which I type to start working. The alias is to:

screen -rx book || screen -c /Users/curtispoe/.screenrc.d/book

That starts a screen session with several panels, putting me in the "writing" panel to start. This is the file which overrides my standard .screenrc (thanks to Ævar Arnfjörð Bjarmason for a lot of this):

# show some info at the bottom
caption always "%{= kw}%-w%{= gW}%n %t%{-}%+w %-= %{= r}%H%{-} %{= g}%l%{-} %c:%s"

# Don't trap C-s and C-q
defflow off

# clear the screen properly when vim (et al) exits
altscreen on

# no visual bell, thanks
vbell off

# Unbind the `C-a x' password prompt which I keep accidentally bringing up
bind x meta

# Without this screen is unusable
nethack on

# Turn off the startup banner
startup_message off

# keep a long scroll buffer
defscrollback 10000

# leave window open after command is finished,
# destroy with 'd', resurrect with 'r'
zombie ar

sessionname book

screen -t console

screen -t Writing
stuff "cd ~/beginning_perl/^M"

screen -t glossary
stuff "perldoc perlglossary^M"

screen -t perlvar
stuff "perldoc perlvar^M"

screen -t perlop
stuff "perldoc perlop^M"

screen -t perlfunc
stuff "perldoc perlfunc^M"

screen -t perlsyn
stuff "perldoc perlsyn^M"

select 1

If you're not familiar with screen, you can switch to different panels with <ctrl-$panel_number>. You can exit the screens with <ctrl-A d>.

While writing the book, I simply use plain text with some custom markup (I couldn't be bothered to write a POD parser because there's no way I could format the output to Wrox's Word styles anyway). By using my own format, I could easily customize it on the fly. However, I wanted it syntax highlighted in my vim editor:

" Vim syntax file
" Language: Wrox Book text format
" Maintainer: Ovid
" Latest Revision: 17 Oct 2011
" http://vim.wikia.com/wiki/Creating_your_own_syntax_files
" autocmd! BufRead,BufNewFile drafts/*.txt setfiletype wroxbook

if version < 600
  syntax clear
elseif exists("b:current_syntax")
  finish
endif
syntax clear

" Properly syntax highlight Perl
syntax include @PERL syntax/perl.vim
syntax region bookHereDocPerl matchgroup=Statement start=+^\s*#\s*<<\s*Perl+ end=+^\s*#\s*Perl+ contains=@PERL

" Highlight overused words
syn keyword bookOverusedWords simply Simply I we We our Our We'll we'll above below following which
syn keyword bookOverusedWords this it etc

" We want "perldoc perl$foo" to be underlined
syn match   bookPerldoc       'perldoc\_s\+perl\w\+'

" Highlight comment lines
syn match   bookComment       "^\s*#-\+$"

" Don't use a period followed by two spaces to end a sentence
syn match   bookBadEOL        '^\w.*\.  '

" Wrote type="note|warning"
syn match   bookWarningOrNote '\s*#\s*\(NOTE\|WARNING\)'

" A leading space means the text should be rendered verbatim
syn match   bookVerbatim      '^\s.*\w'

" double words are usually an error
syn match   bookDoubleWords   '\(\<\w\+\>\)\_s*\1\>'

hi def link bookDoubleWords   Error
hi def link bookOverusedWords Error
hi def link bookBadEOL        Error
hi def link bookVerbatim      Statement
hi def link bookPerldoc       Underlined
hi def link bookWarningOrNote PreProc
hi def link bookComment       PreProc " because they change the output slightly"

An a simple Perl program to reformat my text document for pasting into Word:

#!/usr/bin/env perl

use strict;
use warnings;
use v5.14;

my $file = shift or die "Usage: $0 text_file";
open my $fh, '<', $file or die "Cannot open ($file) for reading; $!";

my $text = '';
my @paragraph;
my $in_para = 0;

my $last_was_paragraph;
while (<$fh>) {
    if (/^#/) {
        next unless $_ = process_comment($_);
    }
    $in_para = /^\S/ && !/^\*/;
    if ( $in_para ) {
        chomp;
        s/\s*$//;
        push @paragraph => $_;
        next;
    }
    if ( @paragraph ) {
        my $paragraph = join " " => @paragraph;
        $text .= "$paragraph\n";
        @paragraph = ();
        $last_was_paragraph = 1;
    }
    else {
        $last_was_paragraph = 0;
    }
    s/^ //; # only remove one space
    next if /^\s*$/ && $last_was_paragraph;
    $text .= $_;
}

print $text;

sub process_comment {
    my $comment = shift;
    given ($comment) {
        return qq{type="note"\n"}    when /#\s*note/i;
        return qq{type="warning"\n"} when /#\s*warning/i;
    }
    return;
}

Also, when I submit a chapter, I need to have a bunch of sample programs ready for download, but OS X has an annoying habit of adding .DS_Store files to directories, so I've created this bash function to zip up the code directories:

function zipdir {                                                                                                                         
    name="${1%/}"                                                                                                                         
    zip -vr $name.zip $name -x "*.DS_Store"                                                                                               
}

All of these tools will evolve over time, but for now, they're saving me a lot of time.

2 Comments

I understand the you need to provide your publisher with a Word file, but I was wondering if you considered using PseudoPod.

I'm not pitching PseudoPod to you :), I've just recently started using it and I'm still figuring it out, just curious if you looked at it, and if yes and you ended up rejecting it, if you could explain why.

Leave a comment

About Ovid

user-pic Have Perl; Will Travel. Freelance Perl/Testing/Agile consultant. Photo by http://www.circle23.com/. Warning: that site is not safe for work. The photographer is a good friend of mine, though, and it's appropriate to credit his work.