]> the.earth.li Git - htag.git/commitdiff
Import Upstream version 0.0.19
authorJonathan McDowell <noodles@earth.li>
Fri, 26 Jul 2019 13:10:01 +0000 (10:10 -0300)
committerJonathan McDowell <noodles@earth.li>
Fri, 26 Jul 2019 13:10:01 +0000 (10:10 -0300)
52 files changed:
HtagPlugin/HtagPlugin.pm [new file with mode: 0644]
README [new file with mode: 0644]
build_util/addlicense.sh [new file with mode: 0755]
build_util/license-head [new file with mode: 0644]
contrib/README [new file with mode: 0644]
docs/AUTHORS [new file with mode: 0644]
docs/BUGS [new file with mode: 0644]
docs/Changelog.htag [new file with mode: 0644]
docs/Changelog.htagplugin [new file with mode: 0644]
docs/INSTALL [new file with mode: 0644]
docs/LICENSE [new file with mode: 0644]
docs/MACRO_DESCRIPTION [new file with mode: 0644]
docs/README [new file with mode: 0644]
docs/README.Multiple_Configs [new file with mode: 0644]
docs/TODO [new file with mode: 0644]
docs/TROUBLESHOOTING [new file with mode: 0644]
docs/URL [new file with mode: 0644]
docs/WRITING_SIGS [new file with mode: 0644]
docs/sample-config/attributions [new file with mode: 0644]
docs/sample-config/sample.htrc [new file with mode: 0644]
docs/sample-config/sample.htrc.changeheaders.default [new file with mode: 0644]
docs/sample-config/sigs/bc-short [new file with mode: 0644]
docs/sample-config/sigs/big [new file with mode: 0644]
docs/sample-config/sigs/blackcat [new file with mode: 0644]
docs/sample-config/sigs/blackcat-slanty [new file with mode: 0644]
docs/sample-config/sigs/brackets [new file with mode: 0644]
docs/sample-config/sigs/brackets-big [new file with mode: 0644]
docs/sample-config/sigs/bubbly [new file with mode: 0644]
docs/sample-config/sigs/bubbly-big [new file with mode: 0644]
docs/sample-config/sigs/oneliner [new file with mode: 0644]
docs/sample-config/sigs/simple [new file with mode: 0644]
docs/sample-config/sigs/slanty [new file with mode: 0644]
docs/sample-config/taglines.tag [new file with mode: 0644]
example-scripts/10dadadodo [new file with mode: 0644]
example-scripts/10fish [new file with mode: 0644]
example-scripts/10grep [new file with mode: 0644]
example-scripts/README [new file with mode: 0644]
htag.pl [new file with mode: 0755]
plugins/02catsig [new file with mode: 0644]
plugins/06marknlard [new file with mode: 0644]
plugins/07sesame [new file with mode: 0644]
plugins/08uptime [new file with mode: 0644]
plugins/09date [new file with mode: 0644]
plugins/10simple [new file with mode: 0644]
plugins/13substtag [new file with mode: 0644]
plugins/15merge [new file with mode: 0644]
plugins/20substsig [new file with mode: 0644]
plugins/22reformat [new file with mode: 0644]
plugins/25asktag [new file with mode: 0644]
plugins/35tearline [new file with mode: 0644]
plugins/80header [new file with mode: 0644]
plugins/98append [new file with mode: 0644]

diff --git a/HtagPlugin/HtagPlugin.pm b/HtagPlugin/HtagPlugin.pm
new file mode 100644 (file)
index 0000000..4610874
--- /dev/null
@@ -0,0 +1,170 @@
+# HtagPlugin.pm
+# (C) Copyright 2000-2001 Simon Huggins <huggie@earth.li>
+
+# 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.5';
+
+# 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'}           = \&reg_deletion;
+       *{$caller . '::delete_tmpfiles'}        = \&delete_tmpfiles;
+}
+
+sub nicedie($) {
+       my $msg = shift;
+       warn $msg;
+       if ($cfg{'nicedie'}) {
+               warn "Press <RETURN> to continue\n";
+               my $throwaway=<STDIN>;
+       }
+# 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 (<HANDLE>) {
+                       if (/^To:\s+\"?([^"']*)\"?\s+\<.*\>$/) {
+                               # To: "anything here" <address>
+                               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>) {
+               $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;
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..82944e5
--- /dev/null
+++ b/README
@@ -0,0 +1,6 @@
+The 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 <huggie@earth.li>
+Mon,  4 Jun 2001 22:18:35 +0200
diff --git a/build_util/addlicense.sh b/build_util/addlicense.sh
new file mode 100755 (executable)
index 0000000..9079929
--- /dev/null
@@ -0,0 +1,22 @@
+#!/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
+
diff --git a/build_util/license-head b/build_util/license-head
new file mode 100644 (file)
index 0000000..5a6afa1
--- /dev/null
@@ -0,0 +1,14 @@
+# 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
+
diff --git a/contrib/README b/contrib/README
new file mode 100644 (file)
index 0000000..6292a2d
--- /dev/null
@@ -0,0 +1,4 @@
+Send me stuff and get it included here for all to see.
+(Or included in ../plugins if it's truely wonderful).
+
+Simon Huggins <huggie@earth.li>
diff --git a/docs/AUTHORS b/docs/AUTHORS
new file mode 100644 (file)
index 0000000..425ca37
--- /dev/null
@@ -0,0 +1,14 @@
+Simon Huggins <huggie@earth.li>
+
+Lots of input for the C version and complaints about this version from:
+Jonathan McDowell <noodles@earth.li>
+
+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.
diff --git a/docs/BUGS b/docs/BUGS
new file mode 100644 (file)
index 0000000..32168db
--- /dev/null
+++ b/docs/BUGS
@@ -0,0 +1,13 @@
+* 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.
+* There isn't enough documentation
+
+
+Mail me with any you find.
+Pints of beer available to people who write documentation (if they come and
+visit me).
+
+Simon Huggins <huggie@earth.li>
diff --git a/docs/Changelog.htag b/docs/Changelog.htag
new file mode 100644 (file)
index 0000000..272207d
--- /dev/null
@@ -0,0 +1,213 @@
+HISTORY
+
+
+04/06/2001
+       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.
+
+27/05/2001
+       Change version number in HtagPlugin.pm to one that perl can check
+       automagically and add a version to my use HtagPlugin line.
+
+25/05/2001
+       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
+
+09/05/2001
+       Changed s/|$// to s/\|$// in sample.htrc  Doh!
+
+30/04/2001 - 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.
+
+16/04/2001
+       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.
+
+02/02/2001
+       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.
+
+22/01/2001
+       Check for UID/GID 0 before running.
+
+28/11/2000 - 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.
+
+27/11/2000
+       Fixed a strange bug due to a regexp in merge that meant that @B in a
+       tagline wasn't expanding correctly sometimes.
+
+13/11/2000
+       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.
+
+09/11/2000
+       Upgraded to perl 5.6.0 and um didn't realise and ran htag.pl
+       It seems to work with 5.6.0 :)
+
+27/10/2000
+       Moved substtag.pl so it was called *after* the tag had been chosen.
+       Oops.  I should have more tags with substable bits in, yes.
+       
+11/10/2000 - 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.
+
+08/10/2000 - 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 :))
+
+24/09/2000 - 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
+
+15/08/2000 - 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.
+
+29/07/2000 - 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.
+
+28/06/2000 - 0.0.13
+       Changed HtagPlugin to cope with "Lastname, Firstname"
+
+18/06/2000 - 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.
+
+06/06/2000 - 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.
+
+05/04/2000 - 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
+
+31/03/2000 - 0.0.7
+       Made it like init.  (Runs plugins in numerical order randomly picks
+       ones with same order).
+
+24/03/2000 - 0.0.6
+       Backends for    - choosing tags.
+
+07/02/2000 - 0.0.5
+       Fixed '-- ' thing.
+
+03/01/2000 - 0.0.4
+       Fixed length "feature" of 0.0.3
+       Will now only use tags that fit the sigs' @[0-9]+@ bits.
+
+19/12/1999
+       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.
diff --git a/docs/Changelog.htagplugin b/docs/Changelog.htagplugin
new file mode 100644 (file)
index 0000000..53f5a2d
--- /dev/null
@@ -0,0 +1,26 @@
+HISTORY - HtagPlugin.pm
+
+
+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
diff --git a/docs/INSTALL b/docs/INSTALL
new file mode 100644 (file)
index 0000000..bcacdc3
--- /dev/null
@@ -0,0 +1,83 @@
+htag-0.0.18
+16th April 2000
+
+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
+
+NOTE: Systemwide installation will get better.  Honest.
+
+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. 
+
+When I write an install script it will do this for you.
+
+3. Config file
+==============
+
+Copy the sample.htrc to ~/.htrc and edit it lots.
+If you want multiple config files then read README.Multiple_Config
+
+4. Signatures
+=============
+
+Create your own sigs.  You can use some of the sigs I provide as templates.
+You may find htag.pl -f useful when creating sigs with @xx[RC] macros since
+it will replace these just with spaces allowing you to get the spacing right
+as you're trying to line them up.
+
+Make sure you add at least one sig to the config file.
+
+Look in sigs for some of mine.
+
+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 <message file>
+<+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 :)
diff --git a/docs/LICENSE b/docs/LICENSE
new file mode 100644 (file)
index 0000000..d60c31a
--- /dev/null
@@ -0,0 +1,340 @@
+                   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.
+\f
+                   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.)
+\f
+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.
+\f
+  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.
+\f
+  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
+\f
+           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.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    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.
+
+  <signature of Ty Coon>, 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.
diff --git a/docs/MACRO_DESCRIPTION b/docs/MACRO_DESCRIPTION
new file mode 100644 (file)
index 0000000..e733e8f
--- /dev/null
@@ -0,0 +1,39 @@
+Reserved 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
+
+The name variants are only available if htag is passed a message with
+headers like "To: Simon Huggins <huggie@earth.li>".
+
+
+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.
diff --git a/docs/README b/docs/README
new file mode 100644 (file)
index 0000000..4ec3153
--- /dev/null
@@ -0,0 +1,51 @@
+htag.pl 0.0.18
+Simon Huggins <huggie@earth.li>
+
+Description
+===========
+
+       htag is a tagline 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 and use.
+README.Multiple_Configs        - How to use multiple config files (you probably
+                         want to use this to get any use of the
+                         power/configurability of htag)
+sample-config          - a bunch of sample config files useful to base
+                         yours on.
+WRITING_SIGS           - tips for writing your own signatures.
+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 docs
+* want me to write docs
+* 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 <huggie@earth.li>
diff --git a/docs/README.Multiple_Configs b/docs/README.Multiple_Configs
new file mode 100644 (file)
index 0000000..c8903a7
--- /dev/null
@@ -0,0 +1,65 @@
+Multiple Config Support
+=======================
+
+Please read the README/INSTALL before reading this document.
+
+In 0.0.18 this changed to eval your per header configs *after* the main
+config file as opposed to only evaluating one config file making it easier
+to see what is different about a particular config but breaking backward
+compatibility for those that used Multiple Config File support.  Sorry.
+Complain at me.
+
+Multiple Config Support allows that you can reply to different people or
+different newsgroups with different plugins.
+
+This is what htag.pl does when it starts up wrt configfiles:
+       - checks to see if one is specified on the commandline
+       - if not defaults the basecfgfile to ~/.htrc
+       - evaluates the basecfgfile
+       - checks to see if $cfg{'changeheaders'} is defined and if so checks
+         whether those patterns match the headers it has for the message.
+         If they match it runs this extra config file.
+
+So to get this working you just need to create one config file with your
+defaults and your changeheaders patterns and extra config file names.  Then
+create the extra config files you've mentioned in changeheaders.
+
+changeheaders syntax is something like:
+$cfg{'changeheaders'} = [
+       [ 'pattern_to_match', 'more optional patterns', 'config filename' ],
+       one or more lines like above
+       ];
+
+The patterns are ANDed together.  If you want OR just create multiple lines.
+
+$cfg{'changeheaders'} = [
+       [ '^From:.*support\@blackcatnetworks.co.uk', '~/.htagrc/support' ], 
+       [ '^Newsgroups:.* fr\.', 'From:.*huggie\@foo.com',
+         '~/.htagrc/fr-foo.com' ]
+       ];
+
+The first example matches all messages which I send out with a From: line of
+support@blackcatnetworks.co.uk so that I can append reassuring signatures to
+our customers - I don't actually do this ... yet :)
+The second is a contrived example which matches a Newsgroup line which has
+somewhere a group that starts with "fr." and where the From: line contains
+huggie@foo.com
+
+There is a way of having a config per address but still only having one
+rule.  Put a rule which has an empty config file and at least one rule which
+should (if it matches) produce the config file name in $1 (the first
+parenthesized match).
+e.g.
+       [ '^From:.*?(\w+)@earth.li','~/.htagrc/earth-li-$1' ],
+
+Then for every mail sent from something@earth.li it will use the config
+"~/.htagrc/earth-li-something".
+
+This could be used for instance to have a different config per From: address
+(i.e. when you send from company From: addresses, and from personal From:
+addresses and want to have different configs per address).
+
+This documentation was written when I hadn't had enough sleep.  Sorry.
+Corrections/clarifications/rewrites/chocolate welcomed.
+
+Simon Huggins <huggie@earth.li>
diff --git a/docs/TODO b/docs/TODO
new file mode 100644 (file)
index 0000000..897b721
--- /dev/null
+++ b/docs/TODO
@@ -0,0 +1,28 @@
+huggie@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.
+* Write documentation
+* Fix bugs
+* Add more cunning things here.
+* Add an installer or very explicit Installation documentation. (paddy may
+  do this)
+
+Done
+====
+
+* 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
+
diff --git a/docs/TROUBLESHOOTING b/docs/TROUBLESHOOTING
new file mode 100644 (file)
index 0000000..305a693
--- /dev/null
@@ -0,0 +1,36 @@
+Okie, 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.
+
diff --git a/docs/URL b/docs/URL
new file mode 100644 (file)
index 0000000..0db77a9
--- /dev/null
+++ b/docs/URL
@@ -0,0 +1 @@
+http://www.earth.li/projectpurple/progs/htag.html
diff --git a/docs/WRITING_SIGS b/docs/WRITING_SIGS
new file mode 100644 (file)
index 0000000..4b952aa
--- /dev/null
@@ -0,0 +1,100 @@
+Simon Huggins <huggie@earth.li>
+
+Sigs are essentially just text files with special characters inside them.
+
+There are two (ish) types of special characters:
+       - those that just get substituted
+       - those that get padded and aligned
+
+For a full definition of reserved letters and macros that can exist please
+read MACRO_DESCRIPTION.  Yeah, I know there is overlap but this file is
+meant to help you write sigs and MACRO_DESCRIPTION is meant to be an
+authoritative reference file.
+
+See the end for the examples which are probably more interesting.
+
+Straight substitutions
+======================
+
+       Becomes
+@B     A newline.  This is a bit pointless for sigs - why have a macro to
+       insert a newline when you can just put one in yourself?
+       It's useful for taglines.
+@F     First name of person in To: line.
+@L     Last name of person in To: line.
+@N     Whole name of person in To: line.
+@V     Version of htag.pl (format x.y.z i.e. 0.0.17)
+
+Padding and Aligning
+====================
+
+Ok, substitutions of this sort are done to a set number of characters.
+
+They are of the form:
+@[A-Za-z]?[1-9][0-9]*[RC]?@
+
+That is:
+       - An @ symbol
+       - An optional letter
+               * If it's not there it means insert a bit of the tagline
+                 you've selected (multiple ones of these are replaced with
+                 multiple sections of tagline)
+               * If it does exist it means insert a bit of the plugin that
+                 deals with that particular letter (multiple ones of these
+                 are replaced each time with a new line from the plugin)
+       - A number
+               * This is the exact number of characters that will be
+                 inserted.
+       - An optional alignment
+               * R for right padded with spaces
+               * C for centered padded with spaces
+               * Nothing for left aligned padded with spaces on the right.
+       - An @ symbol
+
+
+What this all means
+===================
+
+It's probably best shown with examples:
+
+@40@ means insert 40 characters of the tagline chosen left aligned.
+@64R@ means right align over 64 characters part of the tagline.
+
+
+@20R@ @20@ means right align 20 characters of tagline and then put a space
+and then left align another 20.
+
+With letters:
+
+@U20@ means print in 20 characters the output of the uptime plugin
+(depending on the settings in htrc this is normally of the form:
+up 23 days, 3:41)
+
+@U1@ means give me an error message because I didn't give it enough space to
+put the uptime in.
+
+Here is one of my sigs:
+
+-- 
+UK based domain, email and web hosting ***/ @28R@ /*
+http://www.blackcatnetworks.co.uk/     **/ @28R@ /**
+sales@blackcatnetworks.co.uk           */ @28R@ /***
+Black Cat Networks                     / @28R@ /****
+
+It just sticks the tagline inside the slanty bit right aligned.
+
+And another:
+
+-- 
+Just another wannabie | @30C@ |  Just another fool
+----------------------+ @30C@ +-------------------
+This message was brought to you @S30@.
+htag.pl @V -- http://www.earth.li/projectpurple/progs/htag.html
+
+This puts the tagline in the middle over two lines and centers it.  It
+replaces S30 with by the letter A and the number 1 where A and 1 are
+randomly chosen letters using the sesame plugin and it replaces @V with the
+current version of htag.pl
+
+Hope that helped a bit.
+Send me any good sigs that you write :)
diff --git a/docs/sample-config/attributions b/docs/sample-config/attributions
new file mode 100644 (file)
index 0000000..3924cb8
--- /dev/null
@@ -0,0 +1,3 @@
+The Famous Five:them
+Buzz Lightyear:him
+Woody:him
diff --git a/docs/sample-config/sample.htrc b/docs/sample-config/sample.htrc
new file mode 100644 (file)
index 0000000..d0eb453
--- /dev/null
@@ -0,0 +1,237 @@
+#!/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 (<NOTECH>) {
+#      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;
diff --git a/docs/sample-config/sample.htrc.changeheaders.default b/docs/sample-config/sample.htrc.changeheaders.default
new file mode 100644 (file)
index 0000000..267628b
--- /dev/null
@@ -0,0 +1,30 @@
+#!/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;
+
diff --git a/docs/sample-config/sigs/bc-short b/docs/sample-config/sigs/bc-short
new file mode 100644 (file)
index 0000000..5acbe11
--- /dev/null
@@ -0,0 +1,5 @@
+Simon.
+
+-- 
+[ @68@ ]
+        Black Cat Networks.  http://www.blackcatnetworks.co.uk/
diff --git a/docs/sample-config/sigs/big b/docs/sample-config/sigs/big
new file mode 100644 (file)
index 0000000..f875b22
--- /dev/null
@@ -0,0 +1,7 @@
+Simon.
+
+-- 
+@76@
+@76@
+@76@
+@76@
diff --git a/docs/sample-config/sigs/blackcat b/docs/sample-config/sigs/blackcat
new file mode 100644 (file)
index 0000000..efd40a9
--- /dev/null
@@ -0,0 +1,6 @@
+Simon.
+
+-- 
+        Black Cat Networks        -( @35C@ )-
+UK domain, email and web hosting  -( @35C@ )-
+http://www.blackcatnetworks.co.uk -( @35C@ )-
diff --git a/docs/sample-config/sigs/blackcat-slanty b/docs/sample-config/sigs/blackcat-slanty
new file mode 100644 (file)
index 0000000..a08c5cb
--- /dev/null
@@ -0,0 +1,7 @@
+Simon.
+
+-- 
+UK based domain, email and web hosting ***/ @28R@ /*
+http://www.blackcatnetworks.co.uk/     **/ @28R@ /**
+sales@blackcatnetworks.co.uk           */ @28R@ /***
+Black Cat Networks                     / @28R@ /****
diff --git a/docs/sample-config/sigs/brackets b/docs/sample-config/sigs/brackets
new file mode 100644 (file)
index 0000000..14945e4
--- /dev/null
@@ -0,0 +1,4 @@
+-- 
+----------( @48C@ )----------
+Simon ----( @48C@ )---- Nomis
+                             Htag.pl @V
diff --git a/docs/sample-config/sigs/brackets-big b/docs/sample-config/sigs/brackets-big
new file mode 100644 (file)
index 0000000..fbf5029
--- /dev/null
@@ -0,0 +1,5 @@
+-- 
+----------( @48C@ )----------
+----------( @48C@ )----------
+Simon ----( @48C@ )---- Nomis
+                             Htag.pl @V
diff --git a/docs/sample-config/sigs/bubbly b/docs/sample-config/sigs/bubbly
new file mode 100644 (file)
index 0000000..27e924a
--- /dev/null
@@ -0,0 +1,6 @@
+Simon.
+
+-- 
+oOoOo @60C@ oOoOo
+ oOoOo @58C@ oOoOo
+  oOoOo @56C@ oOoOo
diff --git a/docs/sample-config/sigs/bubbly-big b/docs/sample-config/sigs/bubbly-big
new file mode 100644 (file)
index 0000000..bb3b2c5
--- /dev/null
@@ -0,0 +1,7 @@
+Simon.
+
+-- 
+oOoOo @60C@ oOoOo
+ oOoOo @58C@ oOoOo
+  oOoOo @56C@ oOoOo
+   oOoOo @54C@ oOoOo
diff --git a/docs/sample-config/sigs/oneliner b/docs/sample-config/sigs/oneliner
new file mode 100644 (file)
index 0000000..f2ff11e
--- /dev/null
@@ -0,0 +1,4 @@
+Simon.
+
+-- 
+[ @68@ ]
diff --git a/docs/sample-config/sigs/simple b/docs/sample-config/sigs/simple
new file mode 100644 (file)
index 0000000..b801777
--- /dev/null
@@ -0,0 +1,3 @@
+Simon
+
+-- 
diff --git a/docs/sample-config/sigs/slanty b/docs/sample-config/sigs/slanty
new file mode 100644 (file)
index 0000000..3a0f01c
--- /dev/null
@@ -0,0 +1,4 @@
+-- 
+Simon  [ huggie@earth.li ] *\ @37R@  \**
+****** ]-+-+-+-+-+-+-+-+-[ **\ @37R@  \*
+****** [  Htag.pl @V  ] ***\ @37R@  \
diff --git a/docs/sample-config/taglines.tag b/docs/sample-config/taglines.tag
new file mode 100644 (file)
index 0000000..3c3ffd2
--- /dev/null
@@ -0,0 +1,4 @@
+This 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.
diff --git a/example-scripts/10dadadodo b/example-scripts/10dadadodo
new file mode 100644 (file)
index 0000000..b46ede2
--- /dev/null
@@ -0,0 +1,42 @@
+#!/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 (<HANDLE>) {
+       $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);
diff --git a/example-scripts/10fish b/example-scripts/10fish
new file mode 100644 (file)
index 0000000..ffa58e7
--- /dev/null
@@ -0,0 +1,26 @@
+#!/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);
diff --git a/example-scripts/10grep b/example-scripts/10grep
new file mode 100644 (file)
index 0000000..9ebf069
--- /dev/null
@@ -0,0 +1,248 @@
+#!/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=<HANDLE>;
+close(HANDLE);
+
+while(<DATA>) {
+       chomp;
+       s/\s+//g;
+       $blacklist{$_}++;
+}
+
+open(MSG, "<$cfg{'msgfile'}");
+while(<MSG>) {
+       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 
diff --git a/example-scripts/README b/example-scripts/README
new file mode 100644 (file)
index 0000000..dbe4547
--- /dev/null
@@ -0,0 +1,14 @@
+Simon Huggins <huggie@earth.li>
+
+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
diff --git a/htag.pl b/htag.pl
new file mode 100755 (executable)
index 0000000..235afef
--- /dev/null
+++ b/htag.pl
@@ -0,0 +1,475 @@
+#!/usr/bin/perl -w
+
+use strict;
+
+# htag.pl - a tagline generator, sig manager and over engineered program.
+# Copyright (C) 1999-2001 Simon Huggins
+
+# Simon Huggins <huggie@earth.li>
+# 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; 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
+
+# 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/htag/';
+
+use HtagPlugin         0.5;
+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.19";
+$override{'HOME'} = $cfg{'HOME'} = $ENV{"HOME"} || $ENV{"LOGDIR"}
+       || (getpwuid($<))[7];
+
+# srand(time() ^ ($$ + ($$ << 15) )); # Since 5.004 not required
+
+#sub nicedie($) {
+#      my $msg = shift;
+#      warn $msg;
+#      if ($cfg{'nicedie'}) {
+#              warn "Press <RETURN> to continue\n";
+#              my $throwaway=<STDIN>;
+#      }
+#      die "\n";
+#}
+
+sub print_header {
+       print STDERR "Htag.pl $cfg{'VERSION'} -  Simon Huggins <huggie\@earth.li>  Released under GPL\n";
+       print STDERR "Copyright (C) 1999-2001 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 <<'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 = <H>;
+               if ($lines =~ m&^#!/[a-zA-Z/.-]+perl .*$&) {
+                       { # Otherwise $/ is undef in eval.  Mucho ick.
+                       local $/;
+                       undef $/;
+                       $lines .= <H>;
+                       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'}
+                                               = \&reg_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 (<HANDLE>) {
+               $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'}) {
+               open(HANDLE, $cfg{'msgfile'});
+               my (@headers,$match,@l);
+               while (my $line = <HANDLE>) {
+                       last if ($line =~ /^$/); # end of headers
+                       push @headers, $line;
+               }
+               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;
+
+                       }
+               }
+               close(HANDLE);
+       }
+}
+
+### 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<htag.pl> 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<sample.htrc> 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 <huggie@earth.li>
+
+=cut
diff --git a/plugins/02catsig b/plugins/02catsig
new file mode 100644 (file)
index 0000000..62c5b72
--- /dev/null
@@ -0,0 +1,130 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2000-2001 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 <<EOF if (not defined $cfg{'sigs'} or scalar @{$cfg{'sigs'}} == 0);
+No signatures found.  Either you didn't specify sigs, or there weren't any
+files in sigdir or your sigmatch didn't match anything.
+EOF
+
+sub quit() {
+       return 255;
+}
+
+sub write_sig($) {
+       my $sig = shift;
+
+       open(OUT, ">$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(<HANDLE>) { $sig .= $_ };
+               close(HANDLE);
+
+               if ($cfg{'asksig'}) {
+                       print STDERR $sig . "\nUse this sig? ([y]/n/q)";
+                       $_ = <STDIN>;
+                       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)";
+                               $_ = <STDIN>;
+                               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;
diff --git a/plugins/06marknlard b/plugins/06marknlard
new file mode 100644 (file)
index 0000000..a6c9c82
--- /dev/null
@@ -0,0 +1,64 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2000-2001 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=<HANDLE>;
+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 (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.";
+}
diff --git a/plugins/07sesame b/plugins/07sesame
new file mode 100644 (file)
index 0000000..c532bf3
--- /dev/null
@@ -0,0 +1,56 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2000-2001 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 (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";
+}
diff --git a/plugins/08uptime b/plugins/08uptime
new file mode 100644 (file)
index 0000000..ffa34f6
--- /dev/null
@@ -0,0 +1,46 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2000-2001 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 (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;
diff --git a/plugins/09date b/plugins/09date
new file mode 100644 (file)
index 0000000..d62eaf9
--- /dev/null
@@ -0,0 +1,52 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2000-2001 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 (length $date <= $f[1]) {
+               print OUT chunksizealign($date, $f[1], $f[2]);
+       } 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;
diff --git a/plugins/10simple b/plugins/10simple
new file mode 100644 (file)
index 0000000..46825d6
--- /dev/null
@@ -0,0 +1,92 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2000-2001 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.
+
+
+htagdie <<EOF if (not defined $cfg{'tagfile'} and not defined $cfg{'tagfiles'} and not defined $cfg{'fortune'} and not defined $cfg{'tagdir'}); 
+No tagfile defined!  I'm good but I'm not psychic
+Did you configure me at all?  Look at the sample.htrc
+EOF
+
+htagdie <<EOF if ($cfg{'tagfiles'} && $cfg{'tagfile'});
+You have defined both \$cfg{'tagfile'} and \$cfg{'tagfiles'} in your config
+file(s).  Please use one or the other.
+EOF
+
+if (defined $cfg{'tagfile'}) {
+       push @{$cfg{'tagfiles'}}, $cfg{'tagfile'};
+}
+
+if (defined $cfg{'tagdir'}) {
+       opendir(DIR, $cfg{'tagdir'})
+               or htagdie "Could not open directory $cfg{'tagdir'}: $!\n";
+       if (not defined $cfg{'tagmatch'}) {
+               push @{$cfg{'tagfiles'}},
+                       map  { $cfg{'tagdir'} . "/" . $_ }
+                       grep { ! /^\./ }
+                       readdir(DIR);
+       } else {
+               # Check regexp wouldn't kill us
+               exec { "" =~ $cfg{'tagmatch'};}
+               htagdie "tagmatch contained bad pattern.  perl said: $@" if $@;
+               push @{$cfg{'tagfiles'}},
+                       grep { m,$cfg{'tagmatch'}, }
+                       map  { $cfg{'tagdir'} . "/" . $_ }
+                       readdir(DIR);
+htagdie <<EOF if (not @{$cfg{'tagfiles'}});
+tagdir didn't match anything and you had no tagfiles defined.
+EOF
+
+       }
+       closedir(DIR);
+}
+
+my $tag;
+
+if ($cfg{'fortune'} && $cfg{'fortuneval'} && $cfg{'fortuneval'} > 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, <HANDLE>;
+               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;
diff --git a/plugins/13substtag b/plugins/13substtag
new file mode 100644 (file)
index 0000000..2110db0
--- /dev/null
@@ -0,0 +1,34 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2000-2001 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>) {
+       $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;
diff --git a/plugins/15merge b/plugins/15merge
new file mode 100644 (file)
index 0000000..7b48711
--- /dev/null
@@ -0,0 +1,183 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2000-2001 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;
+
+$Text::Wrap::columns=defined $cfg{'maxlinelen'} ? $cfg{'maxlinelen'} : 72;
+$cfg{'first'}  ||= "";
+$cfg{'leader'} ||= "";
+
+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/(?<!^--)[    ]*$//mg;
+
+# Remove any newlines from the very end of the string.
+       $text =~ s/\n*$//;
+        return $text;
+}
+
+sub merge($$) {
+       my ($tag,$sig) = @_;
+       my $chunk;
+       my $notag=1;
+
+       chomp($tag);
+       $tag =~ s/\t/ /g;
+       
+       my ($plugin,$len,$align,$wascr);
+       $wascr=0;
+
+       while ($sig =~ /@([A-Za-z]?)([1-9][0-9]*)([RC]?)@/) {
+               # Ick.
+               if (defined $3) {
+                       $plugin = $1;
+                       $len    = $2;
+                       $align  = $3;
+               } elsif (not defined $2) {
+                       $len    = $1;
+                       $plugin = "";
+                       $align  = "L";
+               } elsif ($2 =~ /^[RC]$/) {
+                       $plugin = "";
+                       $len    = $1;
+                       $align  = $2;
+               } else {
+                       $plugin = $1;
+                       $len    = $2;
+                       $align  = "L";
+               }
+                       
+print STDERR "plugin,len,type = #$plugin#,#$len#,#$align#\n" if $anal_merge_debug;
+               if ($plugin ne "") {
+                       $chunk = getplugin($plugin);
+                       print STDERR "Got plugin $plugin and $chunk\n"
+                               if $anal_merge_debug;
+                       $sig =~ s/\@$plugin$len[RC]?@/$chunk/;
+                       print STDERR "Sig is now:\n$sig" if $anal_merge_debug;
+                       $chunk = "";
+               } else {
+                       my $extra;
+                       $notag=0;
+                       $chunk =  substr $tag, 0, $len;
+print STDERR "chunk,tag = #$chunk#,#$tag#".length($tag)." ".length($chunk)."\n"
+       if $anal_merge_debug;
+                       if ($chunk =~ s/^([^\n]+)\n+(.*)$/$1/s) {
+                               $extra = $2;
+                               print STDERR "\$extra = [$extra]\n"
+                                       if $anal_merge_debug;
+                       }
+                       if (length($chunk) < $len) {
+                               print STDERR "length(chunk) < $len\n"
+                                       if $anal_merge_debug;
+                               $chunk=&chunksizealign($chunk,$len,$align);
+                               print STDERR "chunk = #$chunk#\n"
+                                       if $anal_merge_debug;
+                       }
+                       if (length($tag) < $len + 1) {
+                               $tag= $extra ? $extra : "";
+print STDERR "length(tag) < $len + 1, tag now = #$tag#(extra = #$extra#)\n"
+       if $anal_merge_debug;
+                       } elsif (substr $tag, 0,  $len + 1 eq ' ') {
+                               $tag=substr $tag, $len + 1;
+                               $tag=$extra . $tag if defined $extra;
+print STDERR "substr tag, 0, $len + 1 was a space.  tag now = #$tag#\n"
+       if $anal_merge_debug;
+                       } else {
+                               $tag=substr $tag, $len;
+                               ### Back up a word in $chunk
+                               $tag=$extra . $tag if defined $extra;
+print STDERR "didn't break at space.  Backing up word.  tag now = #$tag#\n"
+       if $anal_merge_debug;
+                               if ($chunk =~ s/(.*) (.*)$/$1/) {
+                                       $tag=$2 . $tag;
+                                       $chunk=&chunksizealign($chunk,$len,$align);
+                               }
+print STDERR "If space in chunk then change chunk and add word to tag.".
+"Reformat chunk now = #$chunk# (tag = #$tag#)\n" if $anal_merge_debug;
+                       }
+                       $sig =~ s/\@$plugin$len[RC]?@/$chunk/;
+               }
+       }
+       $sig =~ s/@([0-9]+)[RC]?@/" " x $1/eg;
+       $cfg{'notag'} = $notag;
+       if ($tag and not $notag) {
+               return undef;
+       }
+       return &remove_space($sig);
+}
+
+{
+my %plugins;
+sub getplugin($) {
+       my $plugin = shift;
+
+       my $count = 0;
+       $count = $plugins{$plugin} if defined $plugins{$plugin};
+       open(IN, "$cfg{'tmpdir'}/$plugin") or htagdie "$0: Could not open $cfg{'tmpdir'}/$plugin: $!\n";
+       my $chunk;
+       while ($count > 0) {
+               $chunk = <IN>;
+               $count--;
+       }
+       $plugins{$plugin} = $count+1;
+       $chunk = <IN>;
+       chomp $chunk;
+       return $chunk;
+}
+}
+
+{
+my ($tag,$sig,$newsig);
+open(SIG, "<$cfg{'tmpsigfile'}") or htagdie "$0: Could not open $cfg{'tmpsigfile'}: $!\n";
+while(<SIG>) {
+       $sig .= $_;
+}
+close(SIG);
+open(TAG, "<$cfg{'tmptagfile'}") or htagdie "$1: Could not open $cfg{'tmptagfile'}: $!\n";
+while(<TAG>) {
+       $tag .= $_;
+}
+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) {
+       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;
+} else {
+       return(10);
+}
+}
diff --git a/plugins/20substsig b/plugins/20substsig
new file mode 100644 (file)
index 0000000..d870b10
--- /dev/null
@@ -0,0 +1,36 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2000-2001 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>) {
+       $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;
diff --git a/plugins/22reformat b/plugins/22reformat
new file mode 100644 (file)
index 0000000..910c768
--- /dev/null
@@ -0,0 +1,74 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2000-2001 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
+
+return;
+
+use strict;
+use Text::Wrap;
+
+$Text::Wrap::columns=defined $cfg{'maxlinelen'} ? $cfg{'maxlinelen'} : 72;
+$cfg{'first'}  ||= "";
+$cfg{'leader'} ||= "";
+
+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/(?<!^--)[    ]*$//mg;
+
+# Remove any newlines from the very end of the string.
+       $text =~ s/\n*$//;
+        return $text;
+}
+
+sub reformat($) {
+       my $sig = shift;
+# LRC
+#$chunk=&chunksizealign($chunk,$len,$align);
+       while ($sig =~ /\@(CENTER|RIGHT|LEFT)(\d+)?\@/) {
+       }
+
+       return $sig;
+}
+
+my ($tag,$sig,$newsig);
+open(SIG, "<$cfg{'tmpsigfile'}")
+       or htagdie "$0: Could not open $cfg{'tmpsigfile'}: $!\n";
+while(<SIG>) {
+       $sig .= $_;
+}
+close(SIG);
+if (defined $sig) {
+       $sig =  reformat($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);
+       }
+}
diff --git a/plugins/25asktag b/plugins/25asktag
new file mode 100644 (file)
index 0000000..8ee45f6
--- /dev/null
@@ -0,0 +1,45 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2000-2001 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'};
+
+open(SIG, "<$cfg{'tmpsigfile'}") or htagdie "$0: Could not open $cfg{'tmpsigfile'}: $!\n";
+my @sig=<SIG>;
+close(SIG);
+
+chomp $sig[-1];
+print STDERR @sig;
+print STDERR "\n\nOK? ([Y]es/(n)ew Tag/(q)uit)\n";
+$_ = <STDIN>;
+return 255 if /^q(?:uit)?/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 = <OLD>;
+close(OLD);
+
+open(NEW, ">$cfg{'tmpsigfile'}") or htagdie "Can't write to sigfile: $!\n";
+print NEW @oldsig;
+close(NEW);
+
+return 10;
diff --git a/plugins/35tearline b/plugins/35tearline
new file mode 100644 (file)
index 0000000..ef10d8f
--- /dev/null
@@ -0,0 +1,40 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2000-2001 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>) {
+       $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;
diff --git a/plugins/80header b/plugins/80header
new file mode 100644 (file)
index 0000000..5f9c52a
--- /dev/null
@@ -0,0 +1,54 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2000-2001 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 = <HANDLE>;
+       close(HANDLE);
+       
+       my $head =  @{$cfg{'randhead'}}[rand scalar @{$cfg{'randhead'}}];
+       $head    =  subst_macros($head);
+       
+       my $i;
+       for ($i=0; $i<scalar @msg; $i++) {
+               next if $msg[$i] =~ /^.*:/;
+               next if $msg[$i] =~ /^[         ]/;
+               last;
+       }
+
+       $msg[$i] = $msg[$i] . $head . "\n";
+
+       open(HANDLE, ">$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;
diff --git a/plugins/98append b/plugins/98append
new file mode 100644 (file)
index 0000000..f9f3661
--- /dev/null
@@ -0,0 +1,29 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2000-2001 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 (<IN>) {
+       print OUT $_;
+}
+close(OUT);
+close(IN);
+return;