#!/usr/bin/perl
#
# Woody to Blosxom integrator
#
######################### 
# $Id: woody2blosxom.pl 119 2004-07-15 05:05:52Z steve $
#########################
# $Log$
# Revision 1.1  2004/07/15 05:05:52  steve
# first version, works
#
#
#########################

use strict;
use Getopt::Std;
use XML::Twig;

my ($version) = '$Revision: 119 $' =~ /Revision:\s*(.+)\$/;

our ( $opt_h, $opt_V );
getopts("hV");

usage() if $opt_h;
usage() unless @ARGV == 2;

die "$0 version: $version\n" if $opt_V;

my $debug = 0;

#### end init


my $t = new XML::Twig();

my $woody_file = $ARGV[0];
my $xsl        = $ARGV[1];

$t->parsefile($woody_file);

# find all the special nodes
my @elts = $t->get_xpath( '//Node[@note =~ /^blosxom-path\:/]');

# check all the special nodes and see if they need updating, update if they do
foreach my $elt (@elts){

    if( $debug ){
	print "found a note at ".$elt->xpath()."\n";
	print "which points to file: ".$elt->att("note"). "\n";
    }

    my( $blosxom_path ) = $elt->att("note") =~ /^blosxom-path\:\s*(.+)/i;

    if( newer( $woody_file, $blosxom_path ) > 0 ){ 
	print "updating \"$blosxom_path\"...\n";
	filter_blosxom( $blosxom_path );
    }
}

exit;


#### helper subs

# runs the stylesheet, passing the blosxom filename in the parameter "path"
# then replaces the special comments in the blosxom file with the output 
sub filter_blosxom{
    my( $blosxom_file ) = @_;

    my $tempfile = `tempfile -p woody2blosxom`;

    chomp $tempfile;

    $tempfile = "/tmp/woody2blosxom.tmp" unless $tempfile;

    # touch the tempfile to make sure we can write to it
    open TMP, ">$tempfile" 
	or die "cannot create tempfile, \"$tempfile\": $!\n";
    close TMP;

    unless( system("xalan", 
		   "-q",
		   "-xsl", $xsl, 
		   "-in", "file:$woody_file", 
		   "-out", $tempfile, 
		   "-param", 'path', 
		   "'$blosxom_file'" ) == 0 ){

	die "error running xalan: $!\n";
    }

    # read in the converted file
    open TMP, "<$tempfile" 
	or die "cannot read from tempfile, \"$tempfile\": $!\n";
    my $html = join "", <TMP>;
    close TMP;

    unlink $tempfile;

    open BLOSX, "<$blosxom_file" 
	or die "cannot open blosxom file \"$blosxom_file\" for reading: $!\n";

    my $blosxom = join "", <BLOSX>;

    close BLOSX;
    
    # replace the special comments with the output, $html
    unless( $blosxom =~ s/(?<=\<!-- begin woody list --\>\n)(.+)(?=\<!-- end woody list --\>)/$html/isg ){
	unless( $blosxom =~ s/<!-- woody list --\>/<!-- begin woody list -->\n$html<!-- end woody list -->/isg ){
	    die "couldn't find any woody tags in $blosxom_file. Put \"<!-- woody list -->\" in it somewhere and try again\n";
	}
    }

    open BLOSX, ">$blosxom_file" 
	or die "cannot open blosxom file \"$blosxom_file\" for writing: $!\n";
    print BLOSX $blosxom;

    close BLOSX;
}

# determines which file was most recently changed
# returns -1 if $file_a is older than $file_b
#          0 if they're equal
#          1 if $file_a is newer than $file_b
sub newer{
    my( $file_a, $file_b ) = @_;

    return (stat $file_a)[9] <=> (stat $file_b)[9];
}

sub usage(){
    die <<USAGE;
usage: $0 [options] woody.xml output_style.xsl
 
options:
    -h          this help
    -V          print version information


This program takes input from the Woody outliner and applies a stylesheet
to it, replacing a special comment in a Blosxom file with the sylesheet\'s 
output.

To use:

  in the Woody file, for the parent node you care about:
      create a note that has the following:

blosxom-path: /path/to/the/blosxom/file/to/update.txt

  then in the Blosxom file, add the following:

<!-- woody list -->

  and everything should be automagic from there.

Note: make sure that the comment in the Blosxom file is exactly as it is
shown above.

Copyright(C) 2004 Steve Pomeroy <steve\@staticfree.info>
Licensed under the GNU GPL. See documentation for complete details.
USAGE

}

__END__

=head1 NAME

template - a general template for perl utilities

=head1 SYNOPSIS

B<template> S<[ B<-h> ]> I<file> S<[ I<files> ]>

=head1 DESCRIPTION

C<template>
a very general template for a perl utilitiy

=head1 OPTIONS

=over 8

=item B<-h>

This help

=back

=head1 ENVIRONMENT

No environment variables are used.

=head1 AUTHOR

Steve Pomeroy <steve@staticfree.info>
http://staticfree.info/

=head1 LICENSE

Copyright © 2004 Steve Pomeroy <steve@staticfree.info>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA

=head1 SEE ALSO

perl(1), xalan(1), XML::Twig

=head1 BUGS

this is a big hack. but it goes pretty well.

=cut
