Thursday, August 26, 2010

Vim wnext, and Macros for Multiple Files

I have finished the pages for the home section. Yipee!, praise God! Almost done.
But while I did these pages I found a few things I needed to change on all the other cards. The first two were warnings from the validator:
  1. My XHTML namespace declaration was invalid because I hadn't stated which language I was using. I needed to delete the whole line and insert a declaration that included xml:lang to denote the primary language of the page.
  2. Most of the tooltips had a space at the end of the title's value, just before the closing quote. I needed to delete them all.
  3. I needed to add a copyright notice on every page.
This meant at least two changes on every one of 988 files.... but thanks to Vim the whole thing took under an hour.

First I made two files and put them in the home directory:

lang.txt was
<html xmlns="" lang="en" xml:lang="en">

And copy.txt:
<p>© Copyright 2010 Bruce Thompson</p>

Then I moved into a section (eg. Diseases with 202 pages) and in the console:
gvim *.html

This started Vim editing all 202 html files in the directory and displayed the first file. I then recorded the following macro "@A":
/<html xml^Mddk:read ../lang.txt^MG?div^Mk:read ../copy.txt^M:%s/ ">/">/ge^M

/<html xml^Mdd Find the present namespace declaration (^M is Enter - didn't type it, just pressed Enter) and delete the line
k:read ../lang.txt^M - Move up one line and read the lang.txt file
G?div^M - Move to the end of the file and search backwards for the last closing div
k:read ../copy.txt^M - Move up a line (to where the copyright needed to be) and read in the copy.txt file.
:%s/ ">/">/ge^M - Substitute the attribute ending with the space for one without a space. The "g" flag means that it will substitute all the occurrences on the line but the "e" flag is essential in a multifile macro because this doesn't report an error when there is no occurence in a particular file (and therefore stop the macro repeating).

After I checked the file and validated it. I made a new macro "@B":
:wnext^M/<html xml^Mddk:read ../lang.txt^MG?div^Mk:read ../copy.txt^M:%s/ ">/">/ge^M

:wnext - Wrote the file and moved to the next file in the series then repeated what I had done in previous macro, "@A".

When this file validated correctly, I issued the following command

This repeated the "@b" macro on the remaining 200 files in the directory.

I repeated this for each of the remaining three sections and had it all done in under an hour. So it is now finished... I've only got to find a place to host it.