Archive | August 2013

Distraction-free writing on Linux

With Vim and GNU Screen

I’ve been playing around with Vim recently, and I’ve found it to be surprisingly good for writing prose, once I had got over the differences from normal word processors and text editors and had a basic .vimrc set up. I mark up my text with markdown and then run it through pandoc to create appropriate output (in the case of this blog I have it output to HTML, which I redirect to xclip and then paste into WordPress’ HTML view).

I’ve also been interested in trying out a distraction-free writing environment; but I’ve grown so used to using Vim that I just can’t go back (I can’t! Ah bloo hoo ho).

Now of course it is entirely possible to just use a fullscreen terminal with Vim running in it; but then the lines would be extremely long, which I would find unpleasant.

A few hours of googling found me nothing useful – there are a lot of attempts at kludgy workarounds involving obscure Vim commands, but I couldn’t get them to work.

Finally, I just asked a question over on stackexchange. From that and from another question on superuser.com, I have learned how to get what I wanted with another program called GNU Screen (if you have a SE account, go ahead and give all those answers an upvote). Screen is mostly intended for sysadmins and so on to run multiple terminals in a single terminal, but it is also perfectly suited to this task.

First, make sure you have Vim and Screen installed. Then, put the following in a file called .screenrc in your $HOME (/home/evilsoup/.screenrc for me). These commands will be run whenever an instance of Screen is started:

focusminsize 75 25
split -v
focus
only
split -v
split -v
focus
caption string "%{= dd} "
sorendition "="

Most of these lines (up until the final ‘focus’) do the ‘centring’ – you will end up with a ‘page’ in the middle of the terminal with a width of 75 characters (perfect for readability). The last two lines get rid of the white lines that would otherwise be on the bottom and either side of the ‘page’, since they are horribly distracting, by turning them the same colour as your terminal’s background.

I also have the following in my .vimrc:

syntax on
set wrap
set linebreak
set spell spelllang=en_gb
map <f5> :set spell! spelllang=en_gb <enter>

That turn on syntax highlighting, sets Vim to wrap on words, sets the spellchecker on by default (with English-English as the language) and means that F5 toggles spellchecking. For the kind of writing I do, this is enough; you may want more (or even less! Maybe you could have spellcheck and syntax highlighting turned off by default, for an even more minimal environment. You could get rid of Vim’s linecount and so on…).

An advantage of this method is that it can be seamlessly used with any terminal-based text editor. GNU Emacs, Nano, whatever.

How to concatenate ODT files

(or anything else that libreoffice can read)

I recently found myself wanting to concatenate two ODT files. Now obviously, this is a very simple task with LibreOffice or OpenOffice (open them up —> copy from one —> paste to another), but being a massive nerd I wanted to see if this could be automated for batches of files. Well,

soffice --headless --convert-to html file1.odt file2.odt
pandoc file1.html file2.html -o output.odt

This requires LibreOffice (or OpenOffice) to convert the ODT files to HTML, and then pandoc (I cannot over-emphasise how great this tool is) to concatenate them properly and convert back to ODT. I wrote up a quick bash script to to it easily: save it somewhere in your $PATH as concat-odt and invoke it with concat-odt file1.odt file2.odt -o output.odt. This should work with any file format that LibreOffice can read, and will always output an ODT file, no matter the input:

#! /usr/bin/env bash
until [[ "$1" = '' ]]; do
  case "$1" in
    -o )  shift
      out="$1"
      ;;
    *  )  inputs+=("$1")
      ;;
  esac
  shift
done

soffice --headless --convert-to html --outdir /tmp "${inputs[@]}"
pandoc /tmp/"${inputs[@]%.*}".html -t odt -o "$out"

exit 0

Caveats

This method has caused me some trouble. Any blank lines in the document will be doubled, so

foo

bar

will become

foo


bar

I’m sure this is a solvable problem (and I’ll update this post if I ever get around to figuring out how to fix it), but for now it’s annoying. I think I may need to just run a regex through the intermediate HTML files and remove all <br>s, which seem to be placed wherever there’s an empty line by LibreOffice. That would cause it’s own problems, of course.

This method will also revert the documents to pandoc’s default styling. It will retain italics and bold and so on. This is, I think, a less easily solved problem; you could mitigate against it by using a custom template, if you don’t like 12 pt Times New Roman.

This method requires the creation of intermediate HTML files – in my script I brushed them out of the way and into /tmp – which isn’t a really big deal, but is something I personally find annoying. Oh well.

EDIT 17/07/2014: According to one of the comments, this will also break on anything containing tables. I wouldn’t exactly call that surprising – this whole thing was basically just me playing with a new toy, and I’m sure there are proper tools out there that can accomplish this task more cleanly and… well, better. So. Caveat emptor, I suppose. I’m sure there are dozens of other problems with this approach that I haven’t mentioned here (which I would like to hear about, but have no intention (or ability, really) of fixing).