So, I took myself off to the local AppleCentre Friday evening, just after 6pm, like a good fanboy. :) Unfortunately, family and social commitments (what sort of a geek am I?) prevented me from installng it until this morning, but now I’m in dashboard and spotlight bliss.
The Good
Apart from all the eye-candy goodness of dashboard, etc., the number one highlight so far is the built-in ability to map caps-lock to control. Which is just as well, because I pretty much can’t use a computer with out the control key where it’s meant to be, and my previous solution, uControl, doesn’t work with Tiger. Big thanks to Apple for making it standard.
The Bad
Alas, alak! Emacs (the aqua version) doesn’t work! The horror! Even a simple rebuild from source didn’t work either. And google didn’t help… So I’m creating this entry in a substandard editor until I find a solution…
I’ve been spending some time reorganising my blog and general revision
management. Part of this has been to bring it all into a Subversion
server, which went well, and to set up blosxom to statically render
(so I can just publish HTML files, rather than hit the CGI script for
every page view).
This presented a small problem: I use a Mac as my primary machine, but
I’m deploying to a linux host. I wanted to set up svn hooks to
actually do the render (rather than render locally and upload as a
separate step). This gives me a nice workflow for blogging, as I can
write away and work on stuff for as long as I like, and when I’m ready
to publish I just commit to svn and it automagically gets published on
the site.
Anyhow, the problem… because I want to (a) work in a svn-managed
directory locally, (b) view the site locally, which under Mac OS X
defaults to ~/Sites, and (c) publish to ~/public_html on the linux
box, I need to use symlinks. But this didn’t work with blosxom’s
static rendering. :(
It turns out that blosxom, or in my case the entries_index plugin,
uses File::Find, which defaults to not following symlinks. So
without further ado, herewith and henceforth, a patch to entries_index
to cause it to follow symlinks:
Index: plugins/entries_index
===================================================================
--- plugins/entries_index (revision 21)
+++ plugins/entries_index (working copy)
@@ -18,9 +18,39 @@
1;
}
+my(%files, %indexes);
+
+sub process_files {
+ my $d;
+ my $curr_depth = $File::Find::dir =~ tr[/][];
+ if ( $blosxom::depth and $curr_depth > $blosxom::depth ) {
+ $files{$File::Find::name} and delete $files{$File::Find::name};
+ return;
+ }
+
+ $File::Find::name =~ m!^$blosxom::datadir/(?:(.*)/)?(.+)\.$blosxom::file_extension$!
+ and $2 ne 'index' and $2 !~ /^\./ and (-r $File::Find::name)
+ # to show or not to show future entries
+ and (
+ $blosxom::show_future_entries
+ or stat($File::Find::name)->mtime <= time
+ )
+ and ( $files{$File::Find::name} || ++$reindex )
+ and ( $files{$File::Find::name} = $files{$File::Find::name} || stat($File::Find::name)->mtime )
+ # Static
+ and (
+ param('-all')
+ or !-f "$blosxom::static_dir/$1/index." . $blosxom::static_flavours[0]
+ or stat("$blosxom::static_dir/$1/index." . $blosxom::static_flavours[0])->mtime < stat($File::Find::name)->mtime
+ )
+ and $indexes{$1} = 1
+ and $d = join('/', (blosxom::nice_date($files{$File::Find::name}))[5,2,3])
+ and $indexes{$d} = $d
+ and $blosxom::static_entries and $indexes{ ($1 ? "$1/" : '') . "$2.$blosxom::file_extension" } = 1;
+}
+
sub entries {
return sub {
- my(%files, %indexes);
if ( open ENTRIES, "$blosxom::plugin_state_dir/.entries_index.index" ) {
my $index = join '', <ENTRIES>;
@@ -32,34 +62,7 @@
for my $file (keys %files) { -f $file or do { $reindex++; delete $files{$file} }; }
find(
- sub {
- my $d;
- my $curr_depth = $File::Find::dir =~ tr[/][];
- if ( $blosxom::depth and $curr_depth > $blosxom::depth ) {
- $files{$File::Find::name} and delete $files{$File::Find::name};
- return;
- }
-
- $File::Find::name =~ m!^$blosxom::datadir/(?:(.*)/)?(.+)\.$blosxom::file_extension$!
- and $2 ne 'index' and $2 !~ /^\./ and (-r $File::Find::name)
- # to show or not to show future entries
- and (
- $blosxom::show_future_entries
- or stat($File::Find::name)->mtime <= time
- )
- and ( $files{$File::Find::name} || ++$reindex )
- and ( $files{$File::Find::name} = $files{$File::Find::name} || stat($File::Find::name)->mtime )
- # Static
- and (
- param('-all')
- or !-f "$blosxom::static_dir/$1/index." . $blosxom::static_flavours[0]
- or stat("$blosxom::static_dir/$1/index." . $blosxom::static_flavours[0])->mtime < stat($File::Find::name)->mtime
- )
- and $indexes{$1} = 1
- and $d = join('/', (blosxom::nice_date($files{$File::Find::name}))[5,2,3])
- and $indexes{$d} = $d
- and $blosxom::static_entries and $indexes{ ($1 ? "$1/" : '') . "$2.$blosxom::file_extension" } = 1;
- }, $blosxom::datadir
+ { wanted => \&process_files, follow => 1 }, $blosxom::datadir
);
if ( $reindex ) {
Phew.
There’s probably a neater way to do that, but it Works For Me.
There’s a known problem with the Textile plugin for blosxom in static
rendering mode. http://groups.yahoo.com/group/blosxom/message/4052
I reproduce the relevant patch here:
--- plugins/1textile2 (revision 21)
+++ plugins/1textile2 (working copy)
@@ -51,6 +51,7 @@
# image_rel_base relative image filenames relative to this
sub blostile {
+ local $_;
my $str = shift @_;
my $ctx = shift @_;
if (!$textile) {
I have a bit of a thing about it. Crappy code. Or, more to the point,
crappy habits and attitudes towards writing code. I am trying to make
a career of helping organisations write better code, so below is a
description of what I mean by “code construction techniques” and why I
think it’s important.
You’ll hear a lot of people talk about process, methodologies and
software engineering. All that is great, and certainly necessary, but
it’s not what I’m talking about here. Beyond all the use cases,
requirements engineering, document control and repeatable processes,
at some point somebody’s got to sit down and write some code. And I
can assure you that I’ve seen some pretty badly written code, even on
projects that could well get their organisations CMM Level 5
certification.
My main workstation PC has two physical IDE hard disks. Since one of
them is about 60G (and I don’t have that many mp3s), I figured I may
as well install a few different operating systems on it.
At present, that consists of Debian r3.0 (woody), Debian unstable
(sid), FreeBSD 4.6, OpenBSD 3.2 and finally Debian GNU/Hurd. Phew.
Partitions
Below is the layout of partitions on the disks.
mira:~# fdisk -l /dev/hda /dev/hdb
Disk /dev/hda: 255 heads, 63 sectors, 1028 cylinders
Units = cylinders of 16065 * 512 bytes
Device Boot Start End Blocks Id System
/dev/hda1 1 1 8001 83 Linux
/dev/hda2 393 1028 5108670 5 Extended
/dev/hda3 2 262 2096482+ a5 FreeBSD
/dev/hda4 263 392 1044225 a6 OpenBSD
/dev/hda5 393 963 4586526 83 Linux
/dev/hda6 964 1028 522081 82 Linux swap
Partition table entries are not in disk order
Disk /dev/hdb: 255 heads, 63 sectors, 7476 cylinders
Units = cylinders of 16065 * 512 bytes
Device Boot Start End Blocks Id System
/dev/hdb1 1 4 32098+ 83 Linux
/dev/hdb2 5 7476 60018840 5 Extended
/dev/hdb5 5 490 3903763+ 83 Linux
/dev/hdb6 491 612 979933+ 83 Linux
/dev/hdb7 613 734 979933+ 83 Linux
/dev/hdb8 2006 7476 43945776 83 Linux
grub
This is the grub config I use to boot them all:
title Debian Woody GNU/Linux
root (hd1,4)
kernel /boot/vmlinuz-2.4.18 root=/dev/hdb5 ro
savedefault
title Debian Sid GNU/Linux
root (hd0,4)
kernel /boot/vmlinuz-2.4.17 root=/dev/hda5 ro
savedefault
title FreeBSD 4.6
root (hd0,a)
kernel /boot/loader
savedefault
title OpenBSD 3.2
root (hd0,3)
makeactive
chainloader +1
savedefault
title Debian GNU/Hurd
root (hd1,5)
kernel /boot/gnumach.gz root=hd1s6
module /boot/serverboot.gz
savedefault
Although I wouldn’t dream of doing it unless forced at knife-point (or
threatened with suspension of my beer allowance), you can also
convince grub to boot windows—against its better judgement.
Installation
If I really had any clue, I would have made careful notes as this
sytem came together, so I could reproduce exactly what I
did. Sigh. Anyhow, it started off with just the smaller hard disk
(/dev/hda) containing a single install of Debian. When I got the
groovy new 60Ger and decided to go nuts, I installed Debian Woody on
that, and allocated a decent chunk to my /home filesystem. I then
proceeded to carve up the original disk for various BSDs and Hurds.
A reasonable amount of research in the web before I started convinced
me that it would all end in disaster, and my four year old debian sid
install that started life as potato would be toast… but what the eh,
it’s all in the name of science. As it turned out, it was far less
traumatic than I thought—my biggest heart ache was discovering the
particular mysterious incantations that grub needed for each OS.
It’s probably important that the *BSDs live in primary
partitions—this will somewhat limit your flexibility in having six
thousand OSes on a single disk. Linux is not so particular, and hurd
would probably happily live in that little mat of fluff that gathers
in the cooling vents of your PC.
I’ve just installed the
Textile2
plug-in for Blosxom based on Brad Choate’s
Perl
implementation of
Dean Allen’s Textile text
markup language. (See how easy it makes gratuitous linking?)
Textile allows me to put simple markup in my blog files, and get it
automagically turned into nice HTML (HyperText Markup Language).
This is a long-ish paragraph containing single line-break characters,
so that it looks nice in my editor. Hopefully, Textile will not care
about these line breaks and still flow the whole block nicely into
HTML. [Time passes…] Unfortunately,
Textile did care, and I had to make a small, unapproved patch to
the Perl module to make it leave paragraphs alone:
diff -r1.1 Textile.pm
715c715,718
< $result .= $self->{line_close} ."\n";
---
> # ROWE HACK - we don't want paras split up with
> # break tags, damn it!
> #$result .= $self->{line_close} ."\n";
> $result .= "\n";
I don’t know yet (after exhaustively testing the change on, well, just
this entry) what else that will impact. But I can’t think of any
reason I’d want break tags anywhere else anyway, so it should be fine.
The ABC have announced plans to trial podcasting Radio National programmes. This is Good News. Up until now, they have
provided live and “on demand” Real Audio streams of many programs, but
this hasn’t helped those of us that wanted to listen while offline
(e.g. on the train, or on a portable media player). It also forced
you to use the godawful Real player.
But soon, there will be MP3s! It sounds like they are planning to
provide both downloadable MP3s and an RSS “podcast” feed. Way
cool!
Upgrade of moin in debian sid is not quite as smooth as it could
be… so, apart from running the backup and migrate scripts as
described in /usr/share/doc/moin/README.migration.gz, I had to:
copy /usr/share/moin/server/moin.cgi to /home/www/wiki/
create a /etc/moin/mywiki.py (from /etc/moin/moinmaster.py)
and customise it more or less like the existing
/home/www/wiki/moin_config.py
add an entry to /etc/moin/farmconfig.py for the new config file
It just occurred to me today… PHP is the new VB!
…
Not that you can’t write good PHP code, of course. For all I know,
maybe it’s even possible to write good VB code. But the trouble is, by
lowering the barrier to entry you end up with all sorts of morons
convinced they can be programmers too.
Markdown looks like it
might be nicer than textile…
And now, for some formating tests.
A Heading
Below is a blockquote (from DaringFireball):
Markdown is intended to be as easy-to-read and easy-to-write as is feasible.
Readability, however, is emphasized above all else. A
Markdown-formatted document should be publishable as-is, as plain
text, without looking like it’s been marked up with tags or
formatting instructions. While Markdown’s syntax has been influenced
by several existing text-to-HTML filters, the single biggest source
of inspiration for Markdown’s syntax is the format of plain text
email.
A Smaller Heading
Arbitrary HTML tags can also be used, such as span
tags to set colours. Not that I’d do that of course.
- This is an item
- This is another item
A Really Small Heading
And these are:
- the first item
- the second item, and
- the third item