htag-0.0.24/0000755000175000017500000000000011016622572012024 5ustar huggiehuggiehtag-0.0.24/build_util/0000755000175000017500000000000007505133422014157 5ustar huggiehuggiehtag-0.0.24/build_util/license-head0000644000175000017500000000127407505133422016427 0ustar huggiehuggie# 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 htag-0.0.24/build_util/addlicense.sh0000644000175000017500000000155607505133422016615 0ustar huggiehuggie#!/bin/sh # 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 # Yes, yes I know it's written in sh and I advocate perl but... # Wheee! Of course you can run it on itself. cat $1 | sed -e '2r license-head' >$1.new mv $1.new $1 htag-0.0.24/htag.pl0000755000175000017500000002743711016622572013324 0ustar huggiehuggie#!/usr/bin/perl -w use strict; # htag.pl - a tagline generator, sig manager and over engineered program. # Copyright (C) 1999-2003 Project Purple, Simon Huggins # Simon Huggins # http://www.earth.li/projectpurple/progs/htag.html # For ChangeLog and Known Bugs see HISTORY and BUGS. # 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; version 2 of the License only # # 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 # FIXME Check for UNIX first? if ($< == 0 or $> == 0 or $( == 0 or $) == 0) { die "UID/GID or effective UID/GID is 0\n". "Htag is no doubt not safe for use when run as root\n"; } # If the "use HtagPlugin 0.5;" line causes problems due to older versions of # HtagPlugin lying around the system then uncomment the following with the # path to your local copy of HtagPlugin # use lib '/home/huggie/perl/huggietag/htag-0.0.24/HtagPlugin'; use HtagPlugin 0.6; use Getopt::Long; use POSIX qw/tcgetpgrp/; use vars qw(%cfg); my %override; my $package_num=0; # Controls "Doing config filename" messages. my $cfgdebug=0; # $infinity is how many times we are allowed to loop in run_plugins # That is how many times a plugin is allowed to call back to earlier ones. # The counter is only increased in this case so keep it fairly small but # increase this if you need to and mail huggie@earth.li to say you did so I # know what is a sane magic number for future releases. # Did that make sense? my $infinity = 80; ### Defines $override{'VERSION'} = $cfg{'VERSION'} = "0.0.24"; $override{'HOME'} = $cfg{'HOME'} = $ENV{"HOME"} || $ENV{"LOGDIR"} || (getpwuid($<))[7]; $cfg{'nicedie'} = 1; # srand(time() ^ ($$ + ($$ << 15) )); # Since 5.004 not required sub print_header { print STDERR "Htag.pl $cfg{'VERSION'} - Simon Huggins Released under GPL\n"; print STDERR "Copyright (C) 1999-2002 Project Purple. http://www.earth.li/projectpurple/\n\n"; } sub process_options { $cfg{'basecfgfile'}=$cfg{'HOME'} . "/.htrc"; $cfg{'debug'} = 0; # default. Can be overriden in cfgfile # For process_configfile/undef %cfg logic. $override{'basecfgfile'} = $cfg{'basecfgfile'}; my %getopt=( "tagfile=s" => \$override{'tagfile'}, "t=s" => \$override{'tagfile'}, "cfgfile=s" => \$override{'basecfgfile'}, "c=s" => \$override{'basecfgfile'}, "fillsig=s" => \$cfg{'fillsig'}, "f=s" => \$cfg{'fillsig'}, "help" => \$cfg{'help'}, "h" => \$cfg{'help'}, "msgfile=s" => \$cfg{'msgfile'}, "m=s" => \$cfg{'msgfile'}); if (not &GetOptions(%getopt)) { print STDERR <<'EOF'; htag.pl - tagline and general sig adder. Usage: htag.pl -t tagfile -c cfgfile -m msgfile htag.pl -h gives perldoc htag.pl -f sigfile Fills a sig with spaces to check your @nn@ bits line up (or don't depending what you are trying to achieve). Believe me this is useful. EOF nicedie "\n"; } if (defined $cfg{'fillsig'}) { fillsig($cfg{'fillsig'}); exit; } if (defined $cfg{'help'}) { exec "perldoc $0"; die "Could not run perldoc.\nPlease less $0 and read the (lack of) documentation at the end\n"; } if (not defined $cfg{'msgfile'}) { print STDERR "No message file?\n"; nicedie "Sorry you need to give me a message file to add to (or a new filename or -)\n"; } # For process_configfile/undef %cfg logic. $override{'msgfile'} = $cfg{'msgfile'}; $cfg{'basecfgfile'} = $override{'basecfgfile'}; } sub expand_home_scalar_or_ref($); # suppress warning about unknown prototype # for the calls to itself inside itself. sub expand_home_scalar_or_ref($) { my $foo = shift; return if not defined $foo; if (ref($foo) eq 'ARRAY') { foreach (@{$foo}) { $_ = expand_home_scalar_or_ref($_); } } elsif (ref($foo) eq 'HASH') { foreach my $key (keys %{$foo}) { $foo->{$key} = expand_home_scalar_or_ref($foo->{$key}); } } else { $foo =~ s#^~/#$cfg{'HOME'}/#o; } return $foo; } sub process_configfile { my @list = ($cfg{'basecfgfile'},$cfg{'extracfgfile'}); undef %cfg; # nicedie controls whether to ask for keypress when dying (useful when # normally called by mutt or tin etc.) # Default to on until cfgfile read. After all if there is a problem before # then we want the user to know about it. $cfg{'nicedie'} = 1; foreach my $cfgfile (@list) { print STDERR "Doing $cfgfile\n" if $cfgdebug and defined $cfgfile; next if not defined $cfgfile; unless (my $retval = do "$cfgfile") { warn "couldn't parse $cfgfile: $@" if $@; warn "couldn't do $cfgfile: $!" unless defined $retval; warn "couldn't run $cfgfile" unless $retval; nicedie "Problem with $cfgfile! Aborting"; } } foreach (keys %override) { $cfg{$_} = $override{$_} if defined $override{$_}; } foreach my $key (keys %cfg) { if (defined $cfg{$key}) { $cfg{$key} = expand_home_scalar_or_ref($cfg{$key}); } } } sub run_plugin($) { my $program = shift; if (-f $program) { print STDERR "Running \"$program\"\n" if $cfg{'debug'}; my ($lines,$rc); $rc=0; # Plugins are allowed to scribble over %cfg but %cfg holds values that must # be reset (generally) before a second run of the same plugin will work # (the print "\n" while $cfg{'newline'}--; hit this) # Plugins can change $cfg{'basecfgfile'} themselves. This is considered a # feature. (Stop laughing at the back there). # To ensure that plugins written in other languages see the changes to %cfg # this is done for both forks of the if. process_configfile(); open(H,"<$program"); $lines = ; if ($lines =~ m&^#!/[a-zA-Z/.-]+perl .*$&) { { # Otherwise $/ is undef in eval. Mucho ick. local $/; undef $/; $lines .= ; close(H); } # I tried to use Safe to do this but it fouls up when using modules. $package_num++; $program =~ s/.*?([^\/]+)$/$1/; my $eval_code = "package HtagPlugin::$package_num;". 'local $SIG{\'__WARN__\'} = sub { (my $mess = $_[0])'. " =~ s/\\(eval[^)]*\\)/$program/g; ". ' $mess =~ s/(HtagPlugin::)\d+::([^ ]*)/$1$2/; '. ' warn $mess; }; '. "my \$rc = eval {$lines}; ". 'die $@ if $@; $rc;'; $_ = "HtagPlugin::$package_num"; { no strict 'refs'; *{$_.'::cfg'} = \%cfg; *{$_.'::htagdie'} = \&nicedie; *{$_.'::subst_macros'} = \&subst_macros; *{$_.'::scansigfile'} = \&scansigfile; *{$_.'::process_msgbody'} = \&process_msgbody; *{$_.'::process_configfile'} = \&process_configfile; *{$_.'::chunksizealign'} = \&chunksizealign; *{$_.'::reg_deletion'} = \®_deletion; } $rc = eval $eval_code; $override{'notag'} = $cfg{'notag'} if defined $cfg{'notag'}; if ($@) { $@ =~ s/\(eval[^)]*\)/$program/g; nicedie "$program: $@"; } if (not defined $rc) { $rc = 253; } } else { # if not perl construct arg list my @args = ($cfg{'msgfile'},$cfg{'basecfgfile'}, $cfg{'VERSION'}); close(H); $rc = 0xffff & system($program,@args); $rc >>= 8; } if ($rc == 254) { my $msg=""; $msg = "Plugin control, plugin $program requesting clearance to die...\n" if $cfg{'debug'}; nicedie $msg; # Ensure we wait on a keypress if asekd to } elsif ($rc == 255) { my $msg=""; $msg = "User requested death... Complying.\n" if $cfg{'debug'}; die $msg; } return $rc unless $rc == 253; } else { # XXX Don't die? nicedie "$program does not exist!\n"; } return; } sub pick_rand(\@) { my $ref = shift; return @{$ref}[rand scalar @{$ref}]; } sub run_plugins($) { my $dir = shift; my (@plugins,%plugins,$program); opendir(DIR, $dir) or nicedie "Cannot open $dir: $!\n"; @plugins = grep { -f $_ } map { $dir . $_ } grep { ! /^\./ } readdir(DIR); closedir(DIR); foreach my $plugin (@plugins) { if ($plugin !~ m#/(\d\d).+$#) { nicedie "Found unexpected $plugin\n"; } else { push @{$plugins{$1}}, $plugin; } } my @order = sort keys %plugins; my (@trueorder,$infinite_loop); $infinite_loop=0; @trueorder = @order; while (my $num = shift @order) { $program = pick_rand(@{$plugins{$num}}); if (my $back = run_plugin($program)) { my @redo=@trueorder; while ($redo[0] < $back) { shift @redo; } @order = @redo; $infinite_loop++; if ($infinite_loop > $infinity) { nicedie "Purple Alert! This is not a daffodil! Too much recursion\n". "This probably happened because your taglines are too short compared to the\n". "space left in the sig chosen.\n"; } } } } sub fillsig($) { my $sigfile = shift; my ($sig,$len,$type); open(HANDLE, $sigfile) or nicedie "Could not open $sigfile!: $!"; while () { $sig .= $_; } close(HANDLE); while ($sig =~ /@[A-Za-z]?[1-9][0-9]*[RC]?@/) { $sig =~ s/@[A-Za-z]?([1-9][0-9]*)[RC]?@/" "x$1/e; } $sig =~ s/\@V/$cfg{'VERSION'}/g; print $sig; } sub choose_configfile() { process_configfile(); # Pick up the changeconf stuff. return $cfg{'basecfgfile'} if not defined $cfg{'changeheaders'}; my $file; if (defined $cfg{'changeheaders'}) { my (@headers,$match,@l); if (open(HANDLE, $cfg{'msgfile'})) { while (my $line = ) { last if ($line =~ /^$/); # end of headers push @headers, $line; } close(HANDLE); } foreach (@{$cfg{'changeheaders'}}) { $file = pop; foreach (@$_) { eval { "" =~ /$_/; }; nicedie "Pattern \"$_\" would have killed me if I'd tried to run it.\nPerl said: $@" if $@; } } # Ugh. # There must be a nicer way to implement this? CH: foreach (@{$cfg{'changeheaders'}}) { @l = @$_; $match=0; $file = pop @l; foreach my $line (@headers) { PAT: foreach my $pattern (@l) { if ($line =~ /$pattern/) { my $temp = $1; $file =~ s/\$1/$temp/e if defined $temp; $match++; last PAT; } } if ($match == @l or $l[0] eq "") { $override{'extracfgfile'} = $cfg{'extracfgfile'} = $file; last CH; } } if (not @headers and $l[0] eq "") { $override{'extracfgfile'} = $cfg{'extracfgfile'} = $file; last CH; } } } } ### START HERE { print_header; process_options; choose_configfile; process_configfile; if (not defined $cfg{'plugindir'}) { nicedie "Sorry, \$cfg{'plugindir'} was not defined in your config file.\n"; } if ($cfg{'plugindir'} !~ m#/$#) { $cfg{'plugindir'} .= "/"; } run_plugins($cfg{'plugindir'}); } END { &delete_tmpfiles; } __END__ =head1 NAME htag.pl - Add taglines and sigs to email, news and fidonet messages. =head1 SYNOPSIS htag.pl [I<-t> tagfile I<-c> cfgfile] I<-m> msgfile htag.pl I<-f> sigfile htag.pl I<-h> =head1 DESCRIPTION B is a sigmonster. It is designed to be extendable in many different ways through its use of plugins. It might be getting a little bit too sentient in its old age though. It can be used like this: htag.pl -m $1 $EDITOR $1 For information on configuration see the B file To create signature files, it is tedious to have to work out what will and won't line up. This is why the I<-f> option exists. Feed it a sigfile and it will replace the @[0-9]+[RC]?@ bits with required number of spaces so you can see if you got it right or not. (You could even run it from your favourite editor e.g. C<:! htag.pl -f %> for vim on the current file.) =head1 BUGS Inserting a tagline containing C<@[0-9]+[RC]?@> has interesting results. This documentation is useless. Use The Source Luke. =head1 FILES =over 4 =item ~/.htrc Config file =back =head1 SEE ALSO http://www.earth.li/progs/htag.html =head1 AUTHOR Simon Huggins =cut htag-0.0.24/contrib/0000755000175000017500000000000007505133422013463 5ustar huggiehuggiehtag-0.0.24/contrib/README0000644000175000017500000000021607505133422014342 0ustar huggiehuggieSend me stuff and get it included here for all to see. (Or included in ../plugins if it's truely wonderful). Simon Huggins htag-0.0.24/example-scripts/0000755000175000017500000000000007505133422015143 5ustar huggiehuggiehtag-0.0.24/example-scripts/10grep0000644000175000017500000000560607505133422016173 0ustar huggiehuggie#!/usr/bin/perl -w # Copyright (C) 2001 Simon Huggins # 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 use strict; my (@tags,%words,%blacklist); if (defined $cfg{'grep_debug'} and $cfg{'grep_debug'}) { open(DEBUG, ">$cfg{'grep_debugfile'}"); } open(HANDLE, "<$cfg{'tagfile'}") or htagdie "Could not open $cfg{'tagfile'}: $!\n"; @tags=; close(HANDLE); while() { chomp; s/\s+//g; $blacklist{$_}++; } open(MSG, "<$cfg{'msgfile'}"); while() { s/[\s\t\n]+/ /g; tr/A-Za-z0-9 //dc; # delete non-alphanumeric s/\b\d+\b//g; $_ = lc $_; my @words = split; foreach (@words) { next if length($_)>9; $words{$_}++ if not exists $blacklist{$_}; } } close(MSG); my @goodtags; my $count=0; foreach my $key (sort { $words{$b} <=> $words{$a} } keys %words) { print DEBUG "$key occurred $words{$key} times\n" if $cfg{'grep_debug'}; my @foundtags = grep { /\b$key\b/i } @tags; push @goodtags,@foundtags; # Tags with more than one matching word will get # pushed on more than one time print DEBUG join "\n",@foundtags if $cfg{'grep_debug'}; $count++; last if $count >20; } open(OUT, ">$cfg{'tmptagfile'}") or htagdie "$0: Could not open $cfg{'tmptagfile'}: $!\n"; reg_deletion("$cfg{'tmptagfile'}"); if (@goodtags) { print OUT $goodtags[rand(@goodtags)]; } else { exit(5); } END { close(OUT); if ($cfg{'grep_debug'}) { close(DEBUG); } } __DATA__ a about again all am an and another any apr are arent as at aug be because been before being but by can cant cat could dec did do doesnt dont down ehlo esmtp even every feb for fri from gmt go great had hadnt has have he her here hers herself him himself his how however i id if im in instead into is it its itself ive jan jul jun know like lots mar may maybe me might might mine mon more must my near need new no not nov now oct of off oh on or ought ours out over please quite received said same sat seem seemed seems sep she should should smtp so some such sun than that thats the their theirs them then there theres these they this thu to tom too tue up us very want was we wed well went were what when which while who why will with wont would would yes yet you your youre yours youve htag-0.0.24/example-scripts/README0000644000175000017500000000103507505133422016022 0ustar huggiehuggieSimon Huggins Perhaps one day I'll put useful stuff here. These might not work depending on whatever version you have of htag.pl fish.pl - Tag generation which just, erm, writes "Fish" to the tag file. dadadodo.pl - Interface to dadadodo (A Markov Chain generator) written by jwz. Could be changed to run dadadodo on the message file we are passed. grep.pl - Greps tagline file for words that appear in the message. These plugins are not really maintained. Sorry. I vaguely updated them on the 21/1/2001 htag-0.0.24/example-scripts/10fish0000644000175000017500000000164107505133422016162 0ustar huggiehuggie#!/usr/bin/perl -w # Copyright (C) 2001 Simon Huggins # 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 use strict; open(OUT, ">$cfg{'tmptagfile'}") or htagdie "$0: Could not open $cfg{'tmptagfile'}: $!\n"; reg_deletion("$cfg{'tmptagfile'}"); print OUT "Fish!"; close(OUT); htag-0.0.24/example-scripts/10dadadodo0000644000175000017500000000251607505133422016772 0ustar huggiehuggie#!/usr/bin/perl -w # Copyright (C) 2001 Simon Huggins # 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 use strict; if (not $cfg{'dadadodo_file'}) { htagdie "\$cfg{'dadadodo_file'} was not specified.\n"; } # Or we could use the message file... my $cmdline = "dadadodo -c 1 $cfg{'dadadodo_file'}"; my $tag; # Unsafe open but if this is ever SUID then the person to do it needs shooting. open(HANDLE, "$cmdline|") or htagdie "$cmdline failed: $!\n"; while () { $tag .= $_; } close(HANDLE) or htagdie "$cmdline failed: $!\n"; open(OUT, ">$cfg{'tmptagfile'}") or htagdie "$0: Could not open $cfg{'tmptagfile'}: $!\n"; reg_deletion("$cfg{'tmptagfile'}"); chomp $tag; print OUT $tag; close(OUT); htag-0.0.24/HtagPlugin/0000755000175000017500000000000011015273116014061 5ustar huggiehuggiehtag-0.0.24/HtagPlugin/HtagPlugin.pm0000644000175000017500000001010207674161570016473 0ustar huggiehuggie# HtagPlugin.pm # (C) Copyright 2000-2003 Simon Huggins # 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 package HtagPlugin; use vars qw($VERSION %cfg); use Carp; # This version is the version of this module and not the version of htag. # Plugins using functions only in new modules should really check the # version. $VERSION = '0.6'; # Do magic exporter stuff per mjd sub import { my $caller = caller; *{$caller . '::nicedie'} = \&nicedie; *{$caller . '::subst_macros'} = \&subst_macros; *{$caller . '::process_msgbody'} = \&process_msgbody; *{$caller . '::cfg'} = \%cfg; *{$caller . '::scansigfile'} = \&scansigfile; *{$caller . '::chunksizealign'} = \&chunksizealign; *{$caller . '::reg_deletion'} = \®_deletion; *{$caller . '::delete_tmpfiles'} = \&delete_tmpfiles; } sub nicedie($) { my $msg = shift; warn $msg; if ($cfg{'nicedie'}) { warn "Press to continue\n"; my $throwaway=; } # not die for the case when it's a plugin that calls this from the eval exit; } sub subst_macros($) { my $text=shift; if (defined $cfg{'fname'}) { $text =~ s/\@F/$cfg{'fname'}/g; } if (defined $cfg{'name'}) { $text =~ s/\@N/$cfg{'name'}/g; } if (defined $cfg{'lname'}) { $text =~ s/\@L/$cfg{'lname'}/g; } $text =~ s/\@B/\n/g; $text =~ s/\@V/$cfg{'VERSION'}/g; return $text; } sub assign_names($) { my $match = shift; if ($match =~ /^(.*), (.*)$/) { $match = "$2 $1"; } $cfg{'fname'} = $cfg{'name'} = $cfg{'lname'} = $match; if ($cfg{'name'} =~ /\s/) { $cfg{'fname'} =~ s/^([^ ]+)\s.*/$1/; $cfg{'lname'} =~ s/.*\s([^ ]+)$/$1/; } } sub process_msgbody($) { my $msgfile = shift; if ($msgfile ne "-") { open(HANDLE,$msgfile) or nicedie "$0: Cannot open $msgfile: $!\n"; while () { if (/^To:\s+\"?([^"']*)\"?\s+\<.*\>$/) { # To: "anything here"
assign_names($1); last; } elsif (/^To:\s+[a-zA-Z_.-]+\@[a-zA-Z.-]+\s+\((.*)\)$/) { # To: me@here.com (Blah) assign_names($1); last; } elsif (/^$/) { # end of headers last; } } close(HANDLE); } } # Scan the sigfile for the character passed looking for @X[0-9][RC]?@ where # X is the argument. # Return LoL of what found, size, align. sub scansigfile($) { my (@found,$sig); my $char = shift; if (length $char > 1) { nicedie "You passed $char to scansigfile! Must only be one character"; } open(SIG, "<$cfg{'tmpsigfile'}") or nicedie "$0: Could not open $cfg{'tmpsigfile'}: $!\n"; while() { $sig .= $_; } close(SIG); while ($sig =~ s/(\@$char(\*|(?:[1-9][0-9]*))([RC]?)\@)//) { my @array = ($1,$2); push @array, defined($3) ? $3 : "L"; push @found, \@array; } return @found; } sub chunksizealign($$$) { my ($chunk,$size,$align) = @_; if (defined $align and $align eq 'R') { # Right $chunk=sprintf("%$size" . "s",$chunk); } elsif (defined $align and $align eq 'C') { # Centered # There must be a better way to do this... my ($lspc,$rspc); $lspc=(($size - length($chunk))/2); ### Repeat after me thou shalt not use = when thou meanest == if (not $lspc == int($lspc)) { # Odd number of chars. $rspc=" " x ($lspc + 1); } else { $rspc=" " x $lspc; } $lspc=" " x $lspc; $chunk=$lspc . $chunk . $rspc; } else { $chunk=sprintf("%-$size" . "s",$chunk); # Left } } { my %delete; sub reg_deletion($) { my $file = shift; $delete{$file}++; } sub delete_tmpfiles() { return if not %delete; foreach (keys %delete) { unlink if -f; } } } 1; htag-0.0.24/plugins/0000755000175000017500000000000011015274134013501 5ustar huggiehuggiehtag-0.0.24/plugins/02catsig0000644000175000017500000000746007674161615015066 0ustar huggiehuggie#!/usr/bin/perl -w # Copyright (C) 2000-2003 Simon Huggins # catsig deals with choosing a sig # 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 # You can either specify sigs with # $cfg{'sigs'} # An arrayref to an array of filenames of sigs. # $cfg{'sigdir'} # A scalar containing a directory of all your sig files. # $cfg{'sigmatch'} # A scalar containing a pattern to match the files in sigdir # (full path) against. # # So specifying sigdir without sigmatch takes all the files in that # directory that don't start with a fullstop (period) and specifying # it with sigmatch only takes those that match. # Note that if you specify sigs *AND* sigdir you'll get all of sigs # and anything that sigdir/sigmatch matches. # The program dies if after trying to match it comes up with nothing. use strict; if (defined $cfg{'sigdir'}) { opendir(DIR, $cfg{'sigdir'}) or htagdie "Could not open directory $cfg{'sigdir'}: $!\n"; if (not defined $cfg{'sigmatch'}) { push @{$cfg{'sigs'}}, map { $cfg{'sigdir'} . "/" . $_ } grep { ! /^\./ } readdir(DIR); } else { # Check regexp wouldn't kill us exec { "" =~ $cfg{'sigmatch'};} htagdie "sigmatch contained bad pattern. perl said: $@" if $@; push @{$cfg{'sigs'}}, grep { m,$cfg{'sigmatch'}, } map { $cfg{'sigdir'} . "/" . $_ } readdir(DIR); print STDERR "Got sigmatch == $cfg{'sigmatch'}\n"; } closedir(DIR); } htagdie <$cfg{'tmpsigfile'}") or htagdie "Couldn't open $cfg{'tmpsigfile'}"; print OUT $sig; close(OUT); open(OUT, ">$cfg{'tmpsigfile'}.old") or htagdie "Couldn't open $cfg{'tmpsigfile'}.old"; print OUT $sig; close(OUT); } sub choose_sig { ### Choose a sig and read it into $sig for grepping for @72@ or whatever. my ($sigfile,@oldsiglist,@siglist,$num,$sig); @oldsiglist = @siglist = @{$cfg{'sigs'}}; do { $sig=""; if (@siglist) { # Find and delete $sigfile=splice(@siglist,rand(@siglist),1); } elsif (-r "$cfg{'HOME'}/.sig") { print STDERR "Falling back on ~/.sig\n" if $cfg{'debug'}; $sigfile="$cfg{'HOME'}/.sig"; } else { print STDERR "No sigs specified and no ~/.sig! Using simple tag method\n"; } if (not $sigfile) { $sig=""; write_sig($sig); return; } print STDERR "Using $sigfile\n" if $cfg{'debug'}; open(HANDLE, "<$sigfile") or htagdie "Could not open $sigfile: $!\n"; while() { $sig .= $_ }; close(HANDLE); if ($cfg{'asksig'}) { print STDERR $sig . "\nUse this sig? ([y]/n/q)"; $_ = ; if ($_ =~ /q(?:uit)?/i) { return &quit; } if (not @siglist and $_ =~ /no?/i) { print STDERR "That was the last sig. Reset siglist or quit? ([r]/q)"; $_ = ; if ($_ =~ /q(?:uit)?/i) { return &quit; } @siglist = @oldsiglist; $_ = 'n'; } } } while ($cfg{'asksig'} and $_ !~ /y(?:es)?/i and $_ !~ /^\n$/); write_sig($sig); return; } reg_deletion($cfg{'tmpsigfile'}); reg_deletion("$cfg{'tmpsigfile'}.old"); &choose_sig; htag-0.0.24/plugins/35tearline0000644000175000017500000000266007674162013015413 0ustar huggiehuggie#!/usr/bin/perl -w # Copyright (C) 2000-2003 Simon Huggins # tearline is a hang over from Fidonet days where tagline adding programs # had tearlines. It's probably no longer used by anyone anywhere but well I # live in hope that Fidonet will be reborn... # 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 use strict; my $sig; open(SIG, "<$cfg{'tmpsigfile'}") or htagdie "$0: Cannot open $cfg{'tmpsigfile'}: $!\n"; while() { $sig .= $_; } close(SIG); my @tears = @{$cfg{'randtear'}}; if ($_ = $cfg{'tearline'}) { /short/i and $sig .= "$cfg{'pretear'} Htag.pl $cfg{'VERSION'}"; /long/i and $sig .= "$cfg{'pretear'} Htag.pl $cfg{'VERSION'} - $tears[rand(@tears)]"; open(SIG, ">$cfg{'tmpsigfile'}") or htagdie "$0: Cannot open $cfg{'tmpsigfile'}: $!\n"; print SIG $sig; close(SIG); } return; htag-0.0.24/plugins/01checksigsep0000644000175000017500000000243607674161606016101 0ustar huggiehuggie#!/usr/bin/perl -w # Copyright (C) 2000-2003 Simon Huggins # checksigsep checks for an existing sigsep and allows you to quit without # adding a new sig. # 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 use strict; return if ($cfg{'msgfile'} eq "-"); my $msg=""; open(MSG, "<$cfg{'msgfile'}") or return; while() { $msg .= $_; } close(MSG); if (grep { /\n-- \n/ } $msg) { my $oldmsg = $msg; print STDERR "Looks like this message already has an unquoted sigsep:\n"; $oldmsg =~ s/.*(-- $)/$1/ms; print STDERR $oldmsg; print STDERR "\n\nAdd another? ([N]o/(y)es)\n"; $_ = ; return 255 if /^q(?:uit)?$/i; return 255 if /^(?:no?|\n)$/i; } htag-0.0.24/plugins/06marknlard0000644000175000017500000000375407674161621015572 0ustar huggiehuggie#!/usr/bin/perl -w # Copyright (C) 2000-2003 Simon Huggins # marknlard outputs Mark 'n Lard style attributions # 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 # Outputs attribution to tmpdir/M # Therefore replaces @M... in sigs via merge. use strict; return if not defined $cfg{'attributions'}; my @found = scansigfile("M"); return if not @found; my (@attributions); # srand( time() ^ ($$ + ($$ << 15) )); # Since 5.004 not required open(HANDLE, "<$cfg{'attributions'}") or htagdie "Could not open $cfg{'attributions'}: $!\n"; @attributions=; close(HANDLE); open(OUT, ">$cfg{'tmpdir'}/M") or htagdie "$0: Could not open $cfg{'tmpdir'}/M: $!\n"; reg_deletion("$cfg{'tmpdir'}/M"); foreach my $f (@found) { my @f = @{$f}; my $recursion = 0; while ($recursion < 30) { $recursion++; my $attr = pickone(); if ($f[1] eq "*") { print OUT $attr,"\n"; $recursion = 255; } elsif (length $attr <= $f[1]) { print OUT chunksizealign($attr, $f[1], $f[2]),"\n"; $recursion = 255; } } if ($recursion != 255) { htagdie "Recursed too much trying to find attribution <= $f[1].\nPerhaps your attributions aren't short enough?\n"; } } close(OUT); return; sub pickone { my $attribution = $attributions[rand(@attributions)]; chomp $attribution; my ($who,$gender) = split(":",$attribution); return "Is it $who, Mark? Sounds just like $gender."; } htag-0.0.24/plugins/09date0000644000175000017500000000347307674161650014537 0ustar huggiehuggie#!/usr/bin/perl -w # Copyright (C) 2000-2003 Simon Huggins # date just calls date. You may pass in a strftime compatible formatting # string. # 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 # Outputs date to tmpdir/D # Therefore replaces @D... in sigs via merge. use integer; use strict; use POSIX qw(strftime); my @found = scansigfile("D"); return if not @found; # srand( time() ^ ($$ + ($$ << 15) )); # Since 5.004 not required open(OUT, ">$cfg{'tmpdir'}/D") or htagdie "$0: Could not open $cfg{'tmpdir'}/D: $!\n"; reg_deletion("$cfg{'tmpdir'}/D"); foreach my $f (@found) { my @f = @{$f}; my $date = strftime($cfg{'date_format'} ? $cfg{'date_format'} : "%a %b %e %H:%M:%S %Y", localtime); if ($f[1] eq "*") { print OUT $date,"\n"; } elsif (length $date <= $f[1]) { print OUT chunksizealign($date, $f[1], $f[2]),"\n"; } else { my $diemsg = "Can't fit your chosen date format ("; if (defined $cfg{'date_format'}) { $diemsg .= $cfg{'date_format'}; } else { $diemsg .= "%a %b %e %H:%M:%S %Y"; } $diemsg .= ") in <= $f[1].\nPerhaps your space isn't big enough.\nAlternatively modify this script to give less information.\n"; htagdie $diemsg; } } close(OUT); return; htag-0.0.24/plugins/10simple0000644000175000017500000000567507674161656015117 0ustar huggiehuggie#!/usr/bin/perl -w # Copyright (C) 2000-2003 Simon Huggins # simple just chooses a random tagline in the simplest possible way # or uses fortune(1) # 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 use strict; my (@tags); # srand( time() ^ ($$ + ($$ << 15) )); # Since 5.004 not required. my $sig=""; open(SIG, "<$cfg{'tmpsigfile'}") or htagdie "$0: Could not open $cfg{'tmpsigfile'}: $!\n"; while() { $sig .= $_; } close(SIG); if (grep { /\@NOTAG\@/ } $sig) { $cfg{'notag'}=1; return 15; } htagdie < rand()) { my $cmd = $cfg{'fortune'}; $cmd .= " ".$cfg{'fortuneargs'} if defined $cfg{'fortuneargs'}; $tag = `$cmd`; htagdie "fortune died: $!" if $?; } else { foreach (@{$cfg{'tagfiles'}}) { open(HANDLE, "<$_") or htagdie "Could not open $_: $!\n"; push @tags, ; close(HANDLE); } if ($cfg{'tagline_comment_char'}) { @tags = grep { ! /^$cfg{'tagline_comment_char'}/ } @tags; } $tag = $tags[rand(@tags)]; } open(OUT, ">$cfg{'tmptagfile'}") or htagdie "$0: Could not open $cfg{'tmptagfile'}: $!\n"; reg_deletion("$cfg{'tmptagfile'}"); chomp $tag; print OUT $tag; close(OUT); return; htag-0.0.24/plugins/15merge0000644000175000017500000001364011015274104014672 0ustar huggiehuggie#!/usr/bin/perl -w # Copyright (C) 2000-2008 Simon Huggins # merge merges the sig and the tag but also merges the sig and the new style # plugin things (i.e. all those silly files in $cfg{'tmpdir'} # 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 use strict; use Text::Wrap; use Encode; $Text::Wrap::columns=defined $cfg{'maxlinelen'} ? $cfg{'maxlinelen'} : 72; $cfg{'first'} ||= ""; $cfg{'leader'} ||= ""; # Work out the correct locale to use if there is one otherwise we assume # UTF-8 which shouldn't kill ascii people and anyone else should have # correctly set locale. my $fromcharset = 'UTF-8'; my $tocharset = 'UTF-8'; my @all_encodings = Encode->encodings(":all"); my $locale; if (defined $ENV{'LC_ALL'}) { $locale = $ENV{'LC_ALL'}; } elsif (defined $ENV{'LC_CTYPE'}) { $locale = $ENV{'LC_CTYPE'}; } elsif (defined $ENV{'LANG'}) { $locale = $ENV{'LANG'}; } if ($locale) { $locale =~ s/.*\.//; $locale = lc $locale; foreach (@all_encodings) { if ($locale eq lc $_) { $tocharset = $fromcharset = $_; last; } } } my $anal_merge_debug=0; sub remove_space($) { my $text=shift; # Remove whitespace at the end of lines but not newlines themselves. # And don't remove the space if it comes directly after a -- which is # anchored at the beginning of a line. $text =~ s/(? 0) { $chunk = ; $count--; } $plugins{$plugin} = $count+1; $chunk = ; chomp $chunk; return $chunk; } } { my ($tag,$sig,$newsig); open(SIG, "<$cfg{'tmpsigfile'}") or htagdie "$0: Could not open $cfg{'tmpsigfile'}: $!\n"; while() { $sig .= decode($fromcharset, $_); } close(SIG); my $ret = 0; if (grep { /\@NOTAG\@/ } $sig) { $tag=""; $ret=26; $sig =~ s/\@NOTAG\@\n//; } else { open(TAG, "<$cfg{'tmptagfile'}") or htagdie "$1: Could not open $cfg{'tmptagfile'}: $!\n"; while() { $tag .= decode($fromcharset, $_); } close(TAG); } if (defined $sig and $sig =~ /@[A-Za-z]?\*|(?:[1-9][0-9]*)[RC]?@/) { $sig = merge($tag,$sig); } else { my $formatted_tag = Text::Wrap::wrap($cfg{'first'},$cfg{'leader'},$tag); $sig .= $formatted_tag; $sig = &remove_space($sig); $cfg{'notag'} = 0; } if (defined $sig) { $sig = encode($tocharset, $sig); open(SIG, ">$cfg{'tmpsigfile'}") or htagdie "$0: Could not open $cfg{'tmpsigfile'}: $!\n"; print SIG "\n" while $cfg{'newline'}--; print SIG $sig; close(SIG); return $ret; } else { return(10); } } htag-0.0.24/plugins/07sesame0000644000175000017500000000346307674161624015075 0ustar huggiehuggie#!/usr/bin/perl -w # Copyright (C) 2000-2003 Simon Huggins # Sesame Street style brought to you "by the letter X and the number 1" # 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 # Outputs Sesame Street "Brought to you..." to tmpdir/S # Therefore replaces @S... in sigs via merge. use integer; use strict; my @found = scansigfile("S"); return if not @found; #srand( time() ^ ($$ + ($$ << 15) )); # Since 5.004 not required open(OUT, ">$cfg{'tmpdir'}/S") or htagdie "$0: Could not open $cfg{'tmpdir'}/S: $!\n"; reg_deletion("$cfg{'tmpdir'}/S"); foreach my $f (@found) { my @f = @{$f}; my $recursion = 0; while ($recursion < 30) { $recursion++; my $attr = pickone(); if ($f[1] eq "*") { print OUT $attr,"\n"; $recursion = 255; } elsif (length $attr <= $f[1]) { print OUT chunksizealign($attr, $f[1], $f[2]),"\n"; $recursion = 255; } } if ($recursion != 255) { htagdie "Recursed too much trying to find chunk <= $f[1].\nPerhaps your space isn't big enough.\n"; } } close(OUT); return; sub pickone { my $letter = ("A" .. "Z")[rand(26)]; my $number = rand(50)+1; $number = " $number" if $number < 10; return "the letter $letter and the number $number"; } htag-0.0.24/plugins/08uptime0000644000175000017500000000320607674161630015114 0ustar huggiehuggie#!/usr/bin/perl -w # Copyright (C) 2000-2003 Simon Huggins # uptime merely calls uptime. You can influence the output a bit. # 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 # Outputs `uptime` to tmpdir/U # Therefore replaces @U... in sigs via merge. use integer; use strict; my @found = scansigfile("U"); return if not @found; #srand( time() ^ ($$ + ($$ << 15) )); # Since 5.004 not required open(OUT, ">$cfg{'tmpdir'}/U") or htagdie "$0: Could not open $cfg{'tmpdir'}/U: $!\n"; reg_deletion("$cfg{'tmpdir'}/U"); my $uptime = `uptime`; chomp $uptime; $uptime =~ s/^.*?(up (?:[0-9]+ days?,)?[^,]+),.*$/$1/ if $cfg{'uptime_time'}; $uptime =~ s/[ ]+/ /g; foreach my $f (@found) { my @f = @{$f}; if ($f[1] eq "*") { print OUT $uptime,"\n"; } elsif (length $uptime <= $f[1]) { print OUT chunksizealign($uptime, $f[1], $f[2]),"\n"; } else { htagdie "Can't fit uptime in <= $f[1].\nPerhaps your space isn't big enough.\nAlternatively modify this script to give less information.\n"; } } close(OUT); return; htag-0.0.24/plugins/25asktag0000644000175000017500000000306307674162003015056 0ustar huggiehuggie#!/usr/bin/perl -w # Copyright (C) 2000-2003 Simon Huggins # asktag chooses a tag like catsig chooses a sig. # 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 use strict; return if $cfg{'notag'}; return unless $cfg{'asktag'}; open(SIG, "<$cfg{'tmpsigfile'}") or htagdie "$0: Could not open $cfg{'tmpsigfile'}: $!\n"; my @sig=; close(SIG); chomp $sig[-1]; print STDERR @sig; print STDERR "\n\nOK? ([Y]es/(n)ew Tag/(b)ack to start/(q)uit)\n"; $_ = ; return 255 if /^q(?:uit)?/i; return 2 if /^b(?:ack)?/i; return if /^(?:y(?:es)?|\n)/i; # Remove sig, and copy old sig (unmerged copy) back over the top unlink($cfg{'tmpsigfile'}) or htagdie "Could not remove $cfg{'tmpsigfile'}: $!\n"; open(OLD, "$cfg{'tmpsigfile'}.old") or htagdie "Could not open old sigfile: $!\n"; my @oldsig = ; close(OLD); open(NEW, ">$cfg{'tmpsigfile'}") or htagdie "Can't write to sigfile: $!\n"; print NEW @oldsig; close(NEW); return 10; htag-0.0.24/plugins/80header0000644000175000017500000000273407674162017015046 0ustar huggiehuggie#!/usr/bin/perl -w # Copyright (C) 2000-2003 Simon Huggins # header adds headers to messages like "Hi @F" # 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 use strict; my ($sig); sub add_heading($) { my $msgfile = shift; my @msg; return if (not defined $cfg{'randhead'}); open(HANDLE,$msgfile) or htagdie "$0: Cannot open $msgfile: $!\n"; @msg = ; close(HANDLE); my $head = @{$cfg{'randhead'}}[rand scalar @{$cfg{'randhead'}}]; $head = subst_macros($head); my $i; for ($i=0; $i$msgfile") or htagdie "$0: Cannot open $msgfile: $!\n"; print HANDLE @msg; close(HANDLE); } process_msgbody $cfg{'msgfile'}; add_heading $cfg{'msgfile'} if defined $cfg{'name'}; return; htag-0.0.24/plugins/98append0000644000175000017500000000203607674162022015065 0ustar huggiehuggie#!/usr/bin/perl -w # Copyright (C) 2000-2003 Simon Huggins # Just appends the sig onto the message file # 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 use strict; open(IN, "<$cfg{'tmpsigfile'}") or htagdie "$0: Cannot open $cfg{'tmpsigfile'}: $!\n"; open(OUT, ">>$cfg{'msgfile'}") or htagdie "$0: Cannot open $cfg{'msgfile'}: $!\n"; while () { print OUT $_; } close(OUT); close(IN); return; htag-0.0.24/plugins/22reformat0000644000175000017500000000474707674161675015450 0ustar huggiehuggie#!/usr/bin/perl -w # Copyright (C) 2000-2003 Simon Huggins # reformats longer lengths after the substitutions have taken place # 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 use strict; use vars qw($nomod); BEGIN { unless (eval "use Text::Balanced qw(gen_extract_tagged);1;") { print STDERR "Text::Balanced not available, reformat plugin will not work\n"; $nomod=1; } } return if $nomod; sub remove_space($) { my $text=shift; # Remove whitespace at the end of lines but not newlines themselves. # And don't remove the space if it comes directly after a -- which is # anchored at the beginning of a line. $text =~ s/(?', undef, '(?s).*(?=<(?:CENTER|RIGHT|LEFT)\d+>)', {reject => ['<(?:CENTER|RIGHT|LEFT)\d+>']} ); while (1) { ($stuff, $end, $beg, $otag, $ext, $ctag) = &$process($text); if (not defined $stuff) { if ($text =~ /<(?:CENTER|RIGHT|LEFT)\d+>/) { nicedie($@->{'error'}); } } last if !$stuff; my $size = $otag; $size =~ s/<(?:CENTER|RIGHT|LEFT)//; $size =~ s/>//; my $align = $otag; $align =~ s/^.(.).*$/$1/; my $c = chunksizealign($ext, $size, $align); $stuff=quotemeta($stuff); $text =~ s/$stuff/$c/; } return $text; } my ($tag,$sig,$newsig); open(SIG, "<$cfg{'tmpsigfile'}") or htagdie "$0: Could not open $cfg{'tmpsigfile'}: $!\n"; while() { $sig .= $_; } close(SIG); if (defined $sig) { $sig = reformat($sig); $sig = remove_space($sig); if (defined $sig) { open(SIG, ">$cfg{'tmpsigfile'}") or htagdie "$0: Could not open $cfg{'tmpsigfile'}: $!\n"; print SIG $sig; close(SIG); return; } else { return(10); } } htag-0.0.24/plugins/20substsig0000644000175000017500000000222107674161672015450 0ustar huggiehuggie#!/usr/bin/perl -w # Copyright (C) 2000-2003 Simon Huggins # substsig substitutes parts of signatures # 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 use strict; my ($sig); process_msgbody($cfg{'msgfile'}); open(SIG, "<$cfg{'tmpsigfile'}") or htagdie "$0: Cannot open $cfg{'tmpsigfile'}: $!\n"; while() { $sig .= $_; } close(SIG); if (defined $sig) { $sig=subst_macros($sig); open(SIG, ">$cfg{'tmpsigfile'}") or htagdie "$0: Cannot open $cfg{'tmpsigfile'}: $!\n"; print SIG $sig; close(SIG); } return; htag-0.0.24/plugins/13substtag0000644000175000017500000000217507674161661015451 0ustar huggiehuggie#!/usr/bin/perl -w # Copyright (C) 2000-2003 Simon Huggins # substtag performs substitutions on the tagline. # 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 use strict; my ($tag); process_msgbody($cfg{'msgfile'}); open(TAG, "<$cfg{'tmptagfile'}") or htagdie "$0: Cannot open $cfg{'tmptagfile'}: $!\n"; while() { $tag .= $_; } close(TAG); $tag=subst_macros($tag); open(TAG, ">$cfg{'tmptagfile'}") or htagdie "$0: Cannot open $cfg{'tmptagfile'}: $!\n"; print TAG $tag; close(TAG); return; htag-0.0.24/README0000644000175000017500000000027507674161362012722 0ustar huggiehuggieThe real README and so on are in the docs/ subdir. Note if you package this please package all the files in the docs/ subdir. Simon Huggins Wed Jun 18 23:08:46 BST 2003 htag-0.0.24/docs/0000755000175000017500000000000011015274566012761 5ustar huggiehuggiehtag-0.0.24/docs/TODO0000644000175000017500000000211607505133422013443 0ustar huggiehuggiehuggie@earth.li Sat Aug 19 09:56:49 BST 2000 These aren't in priority. If you want to do one, please do and please mail me diffs or plugins or docs etc. * Reformat whole lines I want to be able to say: @MAGIC@ On @D@, this message was brought to you by @S30@ @MAGIC@ And have the MAGIC do things like center or right align or possibly even put over two lines if it is needed. * Write more plugins that do random stuff as examples of what can be done. * Keep updating the Wiki with more docs. * Fix bugs * Add more cunning things here. * Add an installer or very explicit Installation documentation. (paddy may do this) * Allow searching for taglines by regexp and choosing them that way Done ==== * I wrote some docs! http://the.earth.li/~huggie/cgi-bin/moin/HtagHowto * Add docs on how to install a module if you are not the sysadmin (request from fudge) * Add a way (probably in a plugin) to differentiate between which plugins are used for which email. I don't want to reply to work email with trivial tags. Or dadadodo on the message etc. == Multiple Config Choosing Support htag-0.0.24/docs/Changelog.htag0000644000175000017500000002056611015274566015526 0ustar huggiehuggieHISTORY 2008-05-22 Fix 15merge to use Encode and deal with UTF-8 taglines and signatures correctly. 2003-06-18 Oops, 25asktag always asked for a tag regardless of $cfg{'asktag'} Thanks to Jasper Spaans for pointing that out. 2002-06-04 Various bugfixes and cleanups. Added a working 22reformat instead of just the template which has been around for a while. 2002-06-01 Add Noodles' patch from a while back to add an option to skip back to asking about a sig from the asktag plugin. A few miscellaneous cleanups. Wrote a HOWTO which is at: http://the.earth.li/~huggie/cgi-bin/moin/HtagHowto Made @M*@ and so on work to insert things /without/ worrying about their length. This means they won't be padded and so is primarily useful for the extra plugins and not taglines and allows you to put text right up against them without worrying about extra spaces. It does also work with taglines so @*@ inserts the tag but with /no/ formatting. (Request from Alex Walker) Added @NOTAG@ to stop any tagline being added. Macros still get expanded as do non-tag plugins. (Request from Alex Walker) Added plugin to check for existing unquoted sigsep and allow user to quit. (Request from Alex Walker) 2001-06-04 s/.pl$// in plugins and chmod 644 plugins/* since they don't really make sense separately from htag. Created TROUBLESHOOTING file. Move all the files around a bit to get the docs out from under the rest and to show that there are some. Move other docs out of subdirectories and into the docs/ dir. Move the sample config stuff into one place too. 2001-05-27 Change version number in HtagPlugin.pm to one that perl can check automagically and add a version to my use HtagPlugin line. 2001-05-25 Fixed up the cases where either the configfile has an error (always set $override{'nicedie'}) or the plugins do htagdie. htagdie has now disappeared in favour of nicedie so I've bumped the versioning in HtagPlugin.pm and nicedie has moved to HtagPlugin.pm 2001-05-09 Changed s/|$// to s/\|$// in sample.htrc Doh! 2001-04-30 - 0.0.18 Yes, I should definitely have released 0.0.18 by now. Ho hum. Added check of patterns used in changeheaders so if someone puts one that would kill us in we tell them nicely. Rolled tarball - probably won't be uploaded til 2nd May. 2001-04-16 Oops, shouldn't I have released 0.0.18 by now? Checked status of 0.0.18 and cleaned it up a little. Made multiple config file docs reflect the changes. Note that changes to the multiple config stuff mean that there is no more default directory for these scripts and the full path must be given. Also if you relied on the blank filename implied just $1 before you'll need to use $1 now although this probably means you need to add the path beforehand too. Setting $cfg{'tagline_comment_char'} to for instance '#' makes simple.pl ignore lines that start with that character. Improve error reporting from eval'd scripts some more. Support for multiple tagfiles using the tagfiles variable means (with the much saner multiple config support) that it's a lot easier to pick tagline files per recipient. I might even have to start using the multiconfig stuff now :) Support for fortune(1) as wanted by "The Big Nose" and Lim Swee Tat. It does have a probability value (adjust so that you get the right mix of fortunes and taglines) and an arguments parameter so you can point it at your own fortune files. It doesn't do anything clever with reformatting them and they don't fit easily in small sigs. It also doesn't parse the .dat files it just runs fortune(1) which is fairly icky really but hey. 2001-02-02 Feedback (oh my God other people use this? :)) led to a few changes: Change the cfgfile interface stuff so we eval just one file (~/.htrc or the file specified on the commandline with -c) then eval another that changes this default file in the changeheader stuff. Remove all the paranoia checks about symlinks for multiple config cases because they didn't really help and just caused config problems really. 2001-01-22 Check for UID/GID 0 before running. 2000-11-28 - 0.0.17 Put 01changeconf.pl into htag.pl instead. Tried to think about the idea of having dependencies instead of just a plugin dir or indeed a plugin list instead but gave up simply because I can't be arsed. I want to run all the plugins. This is the idea. Anyway, patches/ideas accepted. 2000-11-27 Fixed a strange bug due to a regexp in merge that meant that @B in a tagline wasn't expanding correctly sometimes. 2000-11-13 Fixed some of the eval code so it reports fatal errors. Made merge.pl remove spaces if there were only spaces between it and the end of the line. Retrigger the "-- " => "--" bug by using a quick fix and gave in and used a negative look behind assertion in my regexp. Requires perl 5.005 or higher I think. 2000-11-09 Upgraded to perl 5.6.0 and um didn't realise and ran htag.pl It seems to work with 5.6.0 :) 2000-10-27 Moved substtag.pl so it was called *after* the tag had been chosen. Oops. I should have more tags with substable bits in, yes. 2000-10-11 - 0.0.16 Fixed merge so that it works if a sig doesn't have any tagline bits. And so that multiple elements of the same plugin will work (e.g. having two separate @Uxx@ lines works now). Fixed Multiple Config stuff to work with more than one header cumulatively. Wrote README.Multiple_Config (referenced below but not written til now!) Moved 05* to 14* so that in the case where the tag doesn't fit and we have to go back we only go back one. 2000-10-08 - 0.0.16-pre-going-to-release-soon-honest (Eurostar :)) Implemented a "read and eval" parser for the plugins if they are in perl. This may well break things. Let me know if it does. Moved plugin_util to HtagPlugin. (tab completion works better now so I'm less annoyed so I'll be more productive. Or summat :)) 2000-09-24 - 0.0.16-pre Changed htag.pl and all plugins not to call srand because since perl 5.004 this is done automatically and uses a better random seed than I was giving it. Added documentation (in INSTALL) about how to create your local perl module dir and get all the plugins to use it. Created plugins/01changeconf (thus moved 01catsig to 02catsig). It allows multiple configs based on headers finally! See README.Multiple_Config 2000-08-15 - 0.0.15 Changed HtagPlugin to only require three arguments (Message file, Cfg file and VERSION) which all need to come from htag.pl Created plugin_util/HISTORY. Changed protocol of HtagPlugin to 0.0.2 Made new plugin system so that other plugins can substitute in easily. See marknlard.pl for an example. Added some new plugins (sesame, date, uptime) using this system. 2000-07-29 - 0.0.14 Changed HtagPlugin to return 254 when htagdie is called. Made htag.pl ask for keypress if exited with 254 but NOT if exited with 255 (i.e. user requested exit). Improved behaviour when command line options failed. Now we set $cfg{'nicedie'} from the beginning and nicedie everywhere then read in the config files which may turn it off. Added the "Mark 'n Lard" plugin. Added protocol version number and checking for same. 2000-06-28 - 0.0.13 Changed HtagPlugin to cope with "Lastname, Firstname" 2000-06-18 - 0.0.12 Fixed the subst* plugins to use the To: address not the From: address. (Doh.) Put more common code into the HtagPlugin module. 2000-06-06 - 0.0.11 Early in the morning. Released the new one properly. ... Converted to an init style plugins-invoked-in-order-of-number type thing to allow more flexibility. 2000-04-05 - 0.0.8 Allowed plugins to return the number to go back to... Infinite loops are protected against. exiting with 255 means quit htag.pl 2000-03-31 - 0.0.7 Made it like init. (Runs plugins in numerical order randomly picks ones with same order). 2000-03-24 - 0.0.6 Backends for - choosing tags. 2000-02-07 - 0.0.5 Fixed '-- ' thing. 2000-01-03 - 0.0.4 Fixed length "feature" of 0.0.3 Will now only use tags that fit the sigs' @[0-9]+@ bits. 1999-12-19 Released to the unsuspecting world... Started 6/10/1999 Realised that in 23 lines (of perl) you can actually do what huggietag 0.0.1 did in 39 (of C) and that implementing this shouldn't be *too* tricky. 3 hours to an almost working one. Scary. Ancient history: Switched to linux didn't find a good tagline program so tried to write one in C. Got quite far with it but decided C isn't a good language for string handling. htag-0.0.24/docs/LICENSE0000644000175000017500000004311007505133422013757 0ustar huggiehuggie GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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 Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. htag-0.0.24/docs/MACRO_DESCRIPTION0000644000175000017500000000174607505133422015412 0ustar huggiehuggieReserved plugin letters ----------------------- Used in @x24R@ constructs where x is: D - date plugin. M - Mark 'n lard plugin. S - Sesame Street plugin. U - uptime plugin. Macros ------ Used in @x constructs where x is: B - Newline (think Break line) F - First name L - Last name N - Full name V - Version in the form x.y.z @NOTAG@ is special and means that no tagline is to be appended to this sig but that it will still be parsed and have macros substituted etc. The name variants are only available if htag is passed a message with headers like "To: Simon Huggins ". Magic Reformatting ------------------ This isn't supported yet but I think it's what I want. I just need to be able to match nested constructs but I think there is a module for this. Hmm. Need more CFT. Used in @x24@ constructs where x is: CENTER - Center over line width RIGHT - Right align LEFT - Left align with padding Without a following length the operations are done over the line width. htag-0.0.24/docs/AUTHORS0000644000175000017500000000133107505133422014021 0ustar huggiehuggieSimon Huggins Lots of input for the C version and complaints about this version from: Jonathan McDowell Thanks to all the nice fluffy people who make up Project Purple, to paddy for threatening to write documentation and to fudge for making me add the section about use lib to the docs. Thanks to the person known only to me as "The Big Nose" and an email address who poked me a bit to do more work on it and to Lim Swee Tat who did likewise and also sent a patch which I rewrote to provide fortune support. Thanks to Jonathan McDowell again for packaging this up for Debian. Thanks to Alex Walker for installing it and sending me lots of mail about useful stuff he wanted to see in it. htag-0.0.24/docs/Changelog.htagplugin0000644000175000017500000000227307505133422016732 0ustar huggiehuggieHISTORY - HtagPlugin.pm 01/06/2002 - 0.6 Changed scansigfile to cope with @M*@ style macros. 27/05/2001 - 0.5 Change to use perl style version number so it can be verified with "use HtagPlugin.pm 0.5;" Use nicedie as htagdie now and move it from htag.pl to here. 09/11/2000 - 0.0.4 Added reg_deletion and delete_tmpfiles. 15/08/2000 - 0.0.3 Modified so that it evals perl plugins. Lots of things could have gone wrong here. I think I've got rid of most of the problems but let me know if you find any. 15/08/2000 - 0.0.2 Only passes the three arguments which you cannot obtain elsewhere to all plugins. (Message file, config file and VERSION) Added the cunning "plugins may substitute just like tags can" code. Pick an unused letter between A-Z and a-z and then get users to use @X10R@ style things (where X is your letter). Call scansigfile("X") and parse the results generating one line per returned array element which merge.pl will merge in for you. See marknlard for the first sample plugin to use this. Register your letter with me to avoid disappointment. See LETTERS for the official list of reserved letters. 29/07/2000 - 0.0.1 Made all plugins check for version of HtagPlugin.pm htag-0.0.24/docs/INSTALL0000644000175000017500000000520411015274501014000 0ustar huggiehuggiehtag-0.0.24 22nd May 2008 1. Plugins ========== Htag.pl works on a plugin system. All the plugins are in the (originally named) plugins directory. They should be moved somewhere sensible and the path to them should be put in the $cfg{'plugindir'} variable in your ~/.htrc If you're installing for the whole box put them in /usr/local/share/huggietag/plugins or some such. A system tagfile could live in /usr/local/share/huggietag too for instance. If you're installing for yourself you can just leave them in the htag-x.y.z directory. 2. Module ========= htag.pl requires a perl module so I suggest: cp HtagPlugin/HtagPlugin.pm /usr/local/lib/site_perl or somewhere sensible that looks like a site_perl dir and is in the list given by: perl -e 'print join "\n", @INC;' If you want to make your own local perl directory (or you have no choice because you are not root on the machine you're installing it on), then make a directory, copy the module there, and add a line like: use lib '/home/huggie/.perllibs/'; to the top of htag.pl which is the only file which uses this module since the advent of eval of plugins (Hooray!). NOTE: This must be an absolute path if you're going to call it from random locations. If I write an install script it will do this for you. 3. Config file ============== Copy the sample.htrc to ~/.htrc and edit it lots. See http://the.earth.li/~huggie/cgi-bin/moin/HtagHowto for more information. 4. Signatures ============= Create your own sigs. You can use some of the sigs I provide as templates. See http://the.earth.li/~huggie/cgi-bin/moin/HtagHowto for more information. 5. Using it =========== To call htag from mutt and tin I use a script which I've called msg which contains: #!/bin/sh ~/perl/huggietag/current/htag.pl -m $1 2>&1 # |tee ~/.htaglog # Uncomment the pipe to tee for debugging vim $1 It assumes your mail/newsreader will pass the message file in as the first argument. If you wanted to you could modify it to do clever things based on the contents of the arguments passed (e.g. if tin passes <+line number> then you could detect that and pass it on to your editor). I don't do that because I have vim macros that do some elementary cleaning up and cursor positioning before I actually type anything in mail/news but you might want to. If you create anything you think others might find useful then mail it to me. (a version of my current vimrc might be at http://www.earth.li/~huggie/mutt/ but it might well not be when you read this :)) Enjoy. I hope you find this useful and if you do mail me and let me know what didn't work right, what you use it for, what plugins you wrote or how it Just Works :) htag-0.0.24/docs/README0000644000175000017500000000315211015274512013631 0ustar huggiehuggiehtag.pl 0.0.24 Simon Huggins Description =========== htag is a tagline and signature adder but it has now been so over engineered that it will also do anything you want it to[0], do lots of stuff I want it to[1], and do stuff it wants to[2]. See the INSTALL file for basic usage. See the TODO file for some stuff that I need help with and stuff that will appear soon. You will probably find the other docs useful (in order of usefulness): README - This file! INSTALL - how to install htag for those not using a binary package. sample-config - a bunch of sample config files useful to base yours on. But really most of the docs are now at: http://the.earth.li/~huggie/cgi-bin/moin/HtagHowto Other docs are: TROUBLESHOOTING - how to troubleshoot your own problems. MACRO_DESCRIPTION - the reference for all the magic in sigs and tags. Changelog.htag - the changes between versions of htag. Changelog.htagplugin - the changes between versions of the HtagPlugin module. URL - URL of homepage. BUGS - list of known bugs and what to do if you find one. TODO - list of outstanding tasks. AUTHORS - list of contributors. LICENSE - the license. Please mail me if you: * have written some cool/useful plugins * want to write an installer * think it's good * want to show off your tags and sigs :) I'm interested in anyone running this successfully under windows. I imagine it should work with a bit of hackery. [0] If you write the plugins to do it. [1] that should be there already or should appear in future releases. [2] Well ok that's just a blatent lie. Simon Huggins htag-0.0.24/docs/sample-config/0000755000175000017500000000000007674161276015516 5ustar huggiehuggiehtag-0.0.24/docs/sample-config/sample.htrc0000644000175000017500000002040207505133422017640 0ustar huggiehuggie#!/does/not/exist/but/fools/vim/perl # Htag.pl 0.0.18 - config file # This file is parsed as Perl by perl. ### Global options $cfg{'debug'} = 1; $cfg{'plugindir'} = "~/perl/huggietag/current/plugins"; $cfg{'tmpdir'} = "~/.htag/"; $cfg{'tmpsigfile'} = "~/.htag/sig"; $cfg{'tmptagfile'} = "~/.htag/tag"; $cfg{'nicedie'} = 1; # Wait until return pressed if going to die from # htag.pl ##################################################################### ### Multiple Config File support (see docs) ### ##################################################################### # This is my magic to take email addresses out of a file called # ~/.htagrc/notech_addresses and put them into a pattern called # $notech_addresses with "|" between each. # Note that it's not very efficient since it's executed between every # plugin. #my $notech_addresses; #my $HOME = $ENV{"HOME"} || $ENV{"LOGDIR"} || (getpwuid($<))[7]; #open(NOTECH, "$HOME/.htagrc/notech_addresses") #or htagdie "Could not open $HOME/.htagrc/notech_addresses: $!"; #while () { # next if ($_ =~ /^(?:#.*|\s*)$/); # chomp; # $_ = quotemeta; # $notech_addresses .= $_ . "|"; #} #close(NOTECH); #$notech_addresses =~ s/\|$//; # Some random config stuff for multiple configs #$cfg{'changeheaders'} = [ # [ '^Foo: no','^From:.*?(\w+)@earth.li','~/.htagrc/$1' ], # [ '(?x)^To:.* # (?:'.$notech_addresses. # ')','~/.htagrc/notech' ], # [ '^From:.*@blackcatnetworks\.co\.uk','~/.htagrc/blackcat' ], # [ '^Cc:.*@blackcatnetworks\.co\.uk','~/.htagrc/blackcat' ], # [ '', '~/.htagrc/default' ], # ]; ##################################################################### ### plugins/02catsig.pl ### ### Simple Signature output ### ##################################################################### $cfg{'asksig'} = 1; # I define my sig stuff (sigs or sigdir) in the various changeheaders files # - see sample.htrc.changeheaders.default. If you don't use changeheaders # you can define your sigs/sigdir here. # To add a random signature at the end of the message define the file(s) # containing it here. # @{cfg{'sigs'}} = ( "~/.htsig", "~/.htsig1" ); # $cfg{'sigdir'} = "~/.sigs/"; # sigmatch allows you to restrict the sigs in sigdir to all those in the dir # that match sigmatch # e.g. # $cfg{'sigdir'} = "~/.sigs/"; # $cfg{'sigmatch'} = '^/home/huggie/\.sigs/(bc-.*|blackcat.*)$'; # matches all the sigs in /home/huggie/.sigs/ which start with bc- or # blackcat. ##################################################################### ### plugins/10grep.pl ### ### Choosing a tagline by grepping the messge file ### ##################################################################### #$cfg{'grep_debug'} = 0; #$cfg{'grep_debugfile'} = "~/perl/huggietag/grep_debug"; ##################################################################### ### examples/10dadadodo.pl ### ### Choosing a tagline by using dadadodo by jwz ### ### NB copy to plugins directory first ### ##################################################################### #$cfg{'dadadodo_file'} = "~/Docs/funny/darwin-awards"; ##################################################################### ### plugins/06marknlard.pl ### ### Is it x Mark? Sounds just like y. ### ##################################################################### # attributions file format: # x:y # e.g.: # Buzz Lightyear:him => Is it Buzz Lightyear Mark? Sounds just like him. #$cfg{'attributions'} = "~/perl/huggietag/current/attributions"; ##################################################################### ### plugins/08uptime.pl ### ### Give uptime ### ##################################################################### $cfg{'uptime_time'} = 1; # Just give "up 365 days, 23:59" not full output. ##################################################################### ### plugins/09date.pl ### ### Print date in any format ### ##################################################################### # Format of strftime #$cfg{'date_format'} = "%a %b %e %H:%M:%S %Y"; # Default $cfg{'date_format'} = "%d/%m/%Y"; ##################################################################### ### plugins/10simple.pl ### ### Pick a tagline from a textfile or use fortune(1) ### ##################################################################### # Allows lines that begin with the following character (well regexp if you # *really* like) to be comments and thus ignored. $cfg{'tagline_comment_char'} = '#'; # As for the sigs I set these items in the individual changeheaders configs # that come afterwards - see sample.htrc.changeheaders.default for details # or if you don't use changeheaders set one of these: # Where is your tagfile? #$cfg{'tagfile'} = "/usr/local/share/huggietag/taglines.tag"; $cfg{'tagfile'} = "~/taglines.tag"; #$cfg{'tagfiles'} = ["~/taglines.tag","~/others"]; # You can also use tagdir to specify a directory of taglines, and tagmatch # to restrict the tagfiles to those that match. # The example below includes all files in /home/huggie/.tags/ except # /home/huggie/.tags/tech #$cfg{'tagmatch'} = '^/home/huggie/.tags/(?!tech$)'; #$cfg{'tagdir'} = "~/.tags"; # Provided by individual configs per message header or by the default. #$cfg{'fortune'} = '/usr/games/fortune'; # Probability 0 -> 1 of using fortune instead of tagline #$cfg{'fortuneval'} = 0.3; #$cfg{'fortuneargs'} = #'/home/huggie/Scratch/fortunes/matrixfortunes-0.1.0/matrix'; ##################################################################### ### plugins/15merge.pl ### ### Merge signature and Tagline ### ##################################################################### # This *INCLUDES* the length of leader and so should be the width of your # screen minus a few characters $cfg{'maxlinelen'} = 76; # LEADER is put before every line. # FIRST prefixes the first line # FIRST must be one less character than leader. # E.g. # FIRST tagline tagline tagline tagline tagline # LEADERtagline tagline tagline tagline $cfg{'first'} = "... "; $cfg{'leader'} = " "; # How many newlines to insert before putting the tag. # Depends on your sig really. $cfg{'newline'} = 1; ##################################################################### ### plugins/25asktag.pl ### ### Ask if you want this tagline ### ##################################################################### # Do you want to be prompted as to whether you want this tag or just choose # the first one that fits? $cfg{'asktag'} = 1; ##################################################################### ### plugins/35tearline.pl ### ### Simple Tearline output ### ##################################################################### # A tearline is the last line written out by HuggieTag # If you want to disable it then set it to OFF (no quotes) # SHORT is the prefix (PRETEAR) then HuggieTag and it's version # LONG includes (a random) RANDTEAR after that and " - " # if TEARLINE is OFF then PRETEAR and RANDTEAR may be omitted # if RANDTEAR is omitted and LONG is specified it will default to SHORT # PRETEAR must be three characters long $cfg{'tearline'} = "OFF"; $cfg{'pretear'} = "[+]"; @{$cfg{'randtear'}} = ( "I'm a tree!", "Boink!", "Chocolate!", "Fear not the penguins.", "Huggable.", "Kick the baby!", ); # To add a random header at the start of messages define it here: @{$cfg{'randhead'}} = ( "Hi \@F,\@B", "Hiya \@F,\@B", "Look! It's \@F!\@B", "'ello \@F\@B", "Salut \@F!\@B", ); ##################################################################### ### Leave the 1; below or it'll all die horribly :) ### ##################################################################### 1; htag-0.0.24/docs/sample-config/attributions0000644000175000017500000000006207505133422020147 0ustar huggiehuggieThe Famous Five:them Buzz Lightyear:him Woody:him htag-0.0.24/docs/sample-config/sample.htrc.changeheaders.default0000644000175000017500000000161007505133422024043 0ustar huggiehuggie#!/does/not/exist/but/fools/vim's/syntax/highlighting/perl # Htag.pl 0.0.18 - config file # This file is parsed as Perl by perl. # # My defaults when all else has failed. # All tagfiles but "fluffybunnies" # See comments about tagmatch/tagdir/tagfile in sample.htrc undef $cfg{'tagfile'}; undef $cfg{'tagfiles'}; $cfg{'tagmatch'} = '^/home/huggie/.tags/(?!fluffybunnies$)'; $cfg{'tagdir'} = "~/.tags"; # No fortunes (remove vars just through paranoia really since they aren't # defined in .htrc but they could be if someone doesn't have a separate # default config but uses .htrc as the default) undef $cfg{'fortune'}; undef $cfg{'fortuneval'}; undef $cfg{'fortuneargs'}; # All sigs in ~/.sigs that start with bc- or blackcat # See comments about sigs/sigmatch/sigdir in sample.htrc undef $cfg{'sigs'}; $cfg{'sigmatch'} = '^/home/huggie/\.sigs/(bc-.*|blackcat.*)$'; $cfg{'sigdir'} = "~/.sigs"; 1; htag-0.0.24/docs/sample-config/taglines.tag0000644000175000017500000000037607505133422020010 0ustar huggiehuggieThis is a test tagline. Un train peut en cacher un autre. "Thanks, and THIS time it really is fixed. I mean, how many times can we get it wrong? At some point, we just have to run out of really bad ideas.." -- Linus This tagline was personalised for @N. htag-0.0.24/docs/sample-config/sigs/0000755000175000017500000000000007505133422016444 5ustar huggiehuggiehtag-0.0.24/docs/sample-config/sigs/bubbly-big0000644000175000017500000000013207505133422020401 0ustar huggiehuggieSimon. -- oOoOo @60C@ oOoOo oOoOo @58C@ oOoOo oOoOo @56C@ oOoOo oOoOo @54C@ oOoOo htag-0.0.24/docs/sample-config/sigs/blackcat0000644000175000017500000000022607505133422020133 0ustar huggiehuggieSimon. -- Black Cat Networks -( @35C@ )- UK domain, email and web hosting -( @35C@ )- http://www.blackcatnetworks.co.uk -( @35C@ )- htag-0.0.24/docs/sample-config/sigs/brackets0000644000175000017500000000015007505133422020161 0ustar huggiehuggie-- ----------( @48C@ )---------- Simon ----( @48C@ )---- Nomis Htag.pl @V htag-0.0.24/docs/sample-config/sigs/oneliner0000644000175000017500000000002507505133422020177 0ustar huggiehuggieSimon. -- [ @68@ ] htag-0.0.24/docs/sample-config/sigs/brackets-big0000644000175000017500000000020607505133422020722 0ustar huggiehuggie-- ----------( @48C@ )---------- ----------( @48C@ )---------- Simon ----( @48C@ )---- Nomis Htag.pl @V htag-0.0.24/docs/sample-config/sigs/simple0000644000175000017500000000001307505133422017652 0ustar huggiehuggieSimon -- htag-0.0.24/docs/sample-config/sigs/slanty0000644000175000017500000000017407505133422017703 0ustar huggiehuggie-- Simon [ huggie@earth.li ] *\ @37R@ \** ****** ]-+-+-+-+-+-+-+-+-[ **\ @37R@ \* ****** [ Htag.pl @V ] ***\ @37R@ \ htag-0.0.24/docs/sample-config/sigs/bc-short0000644000175000017500000000012507505133422020106 0ustar huggiehuggieSimon. -- [ @68@ ] Black Cat Networks. http://www.blackcatnetworks.co.uk/ htag-0.0.24/docs/sample-config/sigs/blackcat-slanty0000644000175000017500000000034007505133422021440 0ustar huggiehuggieSimon. -- UK based domain, email and web hosting ***/ @28R@ /* http://www.blackcatnetworks.co.uk/ **/ @28R@ /** sales@blackcatnetworks.co.uk */ @28R@ /*** Black Cat Networks / @28R@ /**** htag-0.0.24/docs/sample-config/sigs/bubbly0000644000175000017500000000010507505133422017642 0ustar huggiehuggieSimon. -- oOoOo @60C@ oOoOo oOoOo @58C@ oOoOo oOoOo @56C@ oOoOo htag-0.0.24/docs/sample-config/sigs/big0000644000175000017500000000004007505133422017122 0ustar huggiehuggieSimon. -- @76@ @76@ @76@ @76@ htag-0.0.24/docs/BUGS0000644000175000017500000000064507505133422013443 0ustar huggiehuggie* Adding taglines with any of the magic macros @xx[RC] in them may have unexpected effects. Well they will have unexpected effects unless you have a really twisted mind :) Bonus points will be awarded to the first person to use this feature for a useful purpose. Mail me with any you find. Pints of beer available to people who write documentation (if they come and visit me). Simon Huggins htag-0.0.24/docs/TROUBLESHOOTING0000644000175000017500000000262107505133422015166 0ustar huggiehuggieOkie, you're trying desperately to install htag and it's all going wrong. If after reading this you really can't solve it or you now have a patch then please mail me huggie@earth.li Here are some hints: 1. Turn on all the debugging options. $cfgdebug in htag.pl (copy locally if it's installed sitewide) $cfg{'nicedie'} = 1; as the first thing in your .htrc 2. If perl says something like: HtagPlugin version 0.5 required--this is only version 0.4 at ./htag.pl line 40. BEGIN failed--compilation aborted at ./htag.pl line 40. Then your HtagPlugin.pm is too old and isn't the one required by htag.pl. I distribute them all together in the htag tarball but you might be hitting a problem with multiple copies of HtagPlugin.pm. Fix: put use lib '/path/to/HtagPlugin/'; at the top of htag.pl (copy it locally if it's installed sitewide). 3. You use htag in a script which replaces your editor but nicedie isn't working or for some unknown reason it's not stopping. You can log the whole output of htag to a file if nicedie isn't working for some reason (please report this to me if it isn't), using tee something like: htag.pl -m $1 |tee htaglog $EDITOR $1 4. If you're having problems with the merge plugin then you can define anal_merge_debug in that file (copy the plugins locally if it's sitewide and change your plugin dir). Beware that it really *is* anal debugging though and is very verbose. htag-0.0.24/docs/URL0000644000175000017500000000006207505133422013336 0ustar huggiehuggiehttp://www.earth.li/projectpurple/progs/htag.html