Differences between revisions 59 and 64 (spanning 5 versions)
Revision 59 as of 2008-07-27 10:21:44
Size: 36028
Comment:
Revision 64 as of 2009-08-28 00:49:29
Size: 216
Editor: Tigo190-102-206-48
Comment: 5
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
= Htag HOWTO =

This is a howto for the program [[http://www.earth.li/projectpurple/progs/htag.html|htag]] which should describe in some detail how to go about setting it up along with how it works.

<<TableOfContents(,1)>>

== How htag works ==

Before going into the depths of configuring htag, it is useful first to understand what it is doing. Hopefully this will make configuring it easier.

=== How htag is structured ===

htag is divided into three main parts:
 1. htag.pl
  * This is the program itself which uses the other parts
 1. Htag''''''Plugin.pm
  * This is the library which holds many useful functions shared between plugins and htag.pl
 1. plugins
  * These are the main meat of the program. They are run to perform actions which lead to eventual creation of the sig.

If this sounds like overkill then it is. This is the sledgehammer solution to signature generation. It's not fast but I like it and it does quite a few cool things for me with just a little extra Perl.

=== htag.pl ===

These are the steps htag.pl goes through in order to generate a sig. Some of this may not make sense just yet. You may want to skim this and then come back to this section later.

 1. It prints a banner announcing its version.
 1. It reads the [[#head-599d92199dc637c164bc1ac75ddcec1a0ab24b81|command line switches]] and sets up various variables. If you've not given it enough parameters it will complain at this point.
 1. It runs the [[#head-52816d85af30c05078109fff62f4b72119faeed1|configfile]]
 1. It checks to see if '''changeheaders''' is set.
  1. If it is, then it checks to see if any of the regular expressions match any of the headers. If they do it runs the extra config file specified. (See the [[#head-b17a0642355905bcd6f71b4c9561dee81510d95f|Multiple config file]] section)
 1. If at this stage (after having run all the chosen config files) you haven't got the '''plugindir''' option defined then it dies
 1. Otherwise it will run all the plugins in the plugindir.

=== plugins ===

The plugins are run from '''plugindir''' once htag.pl has checked all the settings from the configfiles. Here are some points about plugins.

 * Plugins '''MUST''' be named to match the Perl regular expression \d\d.+ which means two digits followed by something else.
 * The digits at the start are a sort of priority similar but not identical to SysV init script directories.
  * htag.pl runs plugins starting with the lowest priority and moving to the highest in order.
  * If two or more plugins have the '''same''' priority then '''one''' of them will be randomly picked and run before moving onto plugins of a higher number.

Plugins may return special values:
 * 255 means that the script wants to terminate htag.pl completely without waiting for anything. This should normally only be used by plugins that have asked the user to quit and the user has said yes.
 * 254 means that the script has reached a fatal condition and needs to die but wants to allow htag.pl to ask for a keypress through nicedie. Mostly unused since the scripts can just call htagdie themselves but hey TMTOWTDI.
 * Any other value means that htag.pl should set the priority to that number and go back and start from there again. This allows plugins to go backwards.

An example of this last value is probably a good idea. In the default plugin layout there are a number of plugins which each carry out their own specialised function. One picks a random tag, one picks a signature, one calculates uptime, one generates random letters and numbers and one merges all these parts together. Then we have a plugin (called asktag) which asks the user if the choice of tag is ok and if the user says no, then it returns the priority corresponding to an earlier pluging which picks a random tag and the process starts back from there. It will then reappear back at the asktag plugin and ask the user if the new tagline is suitable and so on and so forth until the user says yes, quits or heat death occurs.

== Config file options ==

If what has come before has confused you then you probably don't need to worry about it too much. Just keep going and once you look at configuring htag you'll see it's not all that evil.

=== Prerequisites ===

You require:
 * htag (well duh) ideally from the tarball or the debian package but other sources should be fine too.
 * perl - I have a feeling you need 5.005 or higher but since '''even''' Debian stable is shipping 5.005 that shouldn't be a problem
 * Imagination to create new signatures and taglines :)

The '''.htrc''' is where you should start configuring htag. You should really download the [[SampleHtagRC]] first (though you should have one in '''/usr/share/doc/htag/examples/sample.htrc.gz''' in Debian or in '''docs/sample-config/sample.htrc''' in the tarball)

=== Format of htrc ===

The '''.htrc''' file is actually parsed as Perl. Now if this scares you, please don't run away screaming just yet. You can get by without knowing Perl but with judicious use of cut and paste. If you do know Perl you can do cool stuff of your own invention in the .htrc without having to change htag.pl.

Basically the '''.htrc''' consists of lines which set up a hash called cfg. Most of the values are simple straightforward scalars (just normal variables if you don't know what a scalar is) some are array references (don't worry if you don't know what this means).

htag options may use ~ which will be expanded to /home/username.

=== Global configuration ===

There a few important global configuration options that are required by the default plugins:

{{{
$cfg{'plugindir'} = "~/perl/huggietag/current/plugins";
$cfg{'debug'} = 1;
$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
}}}

The single most important option ever is '''plugindir'''. It should be set to the directory containing the plugins from the htag tarball or package. In the Debian package the plugins are in '''/usr/share/htag/plugins''' otherwise if you're installing them locally you could just leave them wherever you unpacked the tarball say '''~/htag-0.0.19/plugins''' for the sake of argument.

'''debug''' is useful in order to get some form of trace of what htag is doing but once htag is well configured you may grow tired of seeing this output so you can set '''debug''' back to 0.

'''tmpdir''', '''tmpsigfile''' and '''tmptagfile''' are all related. They refer to options which are used by many of the default plugins. Basically each plugin is run separately and doesn't communicate with the others except by the files it creates, modifies or deletes. '''tmpdir''' should be a directory that is private to you and which is used exclusively by htag. '''tmpsigfile''' and '''tmptagfile''' should point at distinct files. It is easiest to just leave this as it is unless you change the directory component. You will however need to create this directory.

'''nicedie''' does exactly what the comment says it does. It requires the user to press a key if a plugin requests death or if any fatal error occurs. This is '''very''' useful for debugging purposes.

If you are following the sample configfile you'll notice that it next talks about [[#head-b17a0642355905bcd6f71b4c9561dee81510d95f|Multiple config file]] support. I'm going to skip over this and return to it later on.

=== catsig plugin options ===

{{{
$cfg{'asksig'} = 1;
$cfg{'sigdir'} = "~/.sigs/";
# AND/OR
$cfg['sigs'} = [ "~/.sigone", "/home/coolguy/funny/sig" ];

# 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.
}}}

'''asksig''' tells catsig to ask if you want to use a particular signature file at run time. This way you get to choose which signature you want. Otherwise it picks one at random for you.

'''sigdir''' specifies a directory full of signatures that you wish to use.

'''sigs''' is an array reference (i.e. you need to use the funny square brackets if you don't know Perl) of signature files. This is useful if you want to specify signature files which aren't all in one directory.

Personally I prefer to put them all in one directory. But, you say, I have lots of signature files and I don't want certain people to see my bizarre ones, so how can I pick certain ones out? Ah, well you can use '''sigmatch'''. If you just want a basic htag setup then you can ignore this. '''sigmatch''' is a Perl regular expression which is applied to all the files in turn in '''sigdir'''. Only the ones that match it are allowed through and added to the signature list.

If you specify ''' ''both'' sigdir''' and '''sigs''' then first all of '''sigs''' gets added to the list then any signatures in '''sigdir''' that match '''sigmatch'''. If '''sigmatch''' isn't defined then the whole of '''sigdir''' gets added.

If you are following the sample htrc then you will see sections for grep and dadadodo plugins which can safely be ignored - these are optional plugins which I describe at the end of this section.

=== marknlard plugin options ===

Inspired by the UK's BBC Radio 1 show by Mark and Lard who kept repeating "Is it foo, Mark? Sounds just like them.". You only have to define this if you want to add such quotes to your sig (as well as taglines)

{{{
$cfg{'attributions'} = "~/perl/huggietag/current/attributions";
}}}

Defines the path to the file of attributions. The file should be in the following format:
{{{
The Famous Five:them
Buzz Lightyear:him
Woody:him
}}}

that is name of person/band/thing and then pronoun that should be used in "Sounds just like them/him/it". Yes, this is a silly plugin. Er, what you thought taglines were serious?

=== uptime plugin options ===

{{{
$cfg{'uptime_time'} = 1;
}}}

This option cuts down the output from full uptime output to just "up 365 days, 23:59". Again only define it if you want to add uptimes to your sigfiles.

=== date plugin options ===

{{{
$cfg{'date_format'} = "%d/%m/%Y";
}}}

This option tells the date plugin what format to use. It's in the form strftime would use so see the strftime manpage. Again only defin it if you want to add the current date to your sigfiles.

=== simple plugin options ===

{{{
$cfg{'tagline_comment_char'} = '#';
$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";

$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';
}}}

'''tagline_comment_char''' defines the comment character used in tagfiles. i.e. if it's set to # then lines starting with # in tagfiles will be ignored.


'''tagfile''' specifies a single tagfile. It's deprecated since you can use '''tagfiles''' to do the same thing but it's there for backwards compatibility.

'''tagfiles''', '''tagdir''' and '''tagmatch''' work in exactly the same way as '''sigs''', '''sigdir''' and '''sigmatch''' (see [[#head-e00333a76482aa64e58c1617a080567a46ae2c25|catsig options]] above)

The simple plugin can also run fortune. It can either only pick taglines if the fortune options are undefined, only pick fortunes if the tagfile options are undefined or pick one or the other at random.

'''fortuneval''' specifies the probability that it will pick a fortune rather than a tagline when both fortune options and tagline options are defined.

'''fortune''' specifies the path to the fortune executable

'''fortuneargs''' is optional and specifies any extra arguments you want passed to fortune for instance a different fortune file.

=== merge plugin options ===

The merge plugin deals mostly with signature files that are not templated that is, have no @68C@ style macros in them. In this case, the tagline is merely appended to the sigfile after having been wrapped according to the following parameters.

{{{
$cfg{'maxlinelen'} = 76;
$cfg{'first'} = "... ";
$cfg{'leader'} = " ";
$cfg{'newline'} = 1;
}}}

'''maxlinelen''' is the maximum line length (including '''leader''' or '''first''') that is allowed before the tagline is wrapped.

'''first''' is the leader for the first line.

'''leader''' is the leader for second and subsequent lines.

What this ''means'' is that for a tagline wrapped with '''first''' equal to "****" and '''leader''' equal to "--''''''--" you get something like:
{{{
****Foo bar foo bar foo bar foo bar
----bar foo bar foo bar foo bar foo
----bar foo bar foo bar foo bar foo
}}}

Hopefully that makes sense now.

'''newline''' is how many newline characters to insert between the sigfile and the wrapped tagline. This really does depend on what you end your sigfile with. Play and then tune it.

Again, just a reminder that any of these parameters only apply to non-templated sigfiles.


=== asktag plugin options ===

{{{
$cfg{'asktag'} = 1;
}}}

'''asktag''' set to one means asktag will show you the currently merged signature with tagline and ask you if it is
ok. You can quit, say yes, go back to the beginning (to pick a new sig) or get a new tag. This option is
recommended if you're running interactively.

=== tearline plugin options ===

Tearlines are a Fidonet thing really. Still they were cute and perhaps some people are nostalgic. Basically they consist of a user defined leader, the text "Htag.pl" and its version, and an optional user defined random trailer.

{{{
$cfg{'tearline'} = "OFF";
$cfg{'pretear'} = "[+]";
$cfg{'randtear'} = [ "I'm a tree!",
                        "Boink!",
                        "Chocolate!",
                        "Fear not the penguins.",
                        "Huggable.",
                        "Kick the baby!",
                        ];
}}}

'''tearline''' can be OFF, LONG or SHORT. It's actually case insensitive anyway but hey. LONG includes the random trailer, SHORT does not, OFF omits altogether.

'''pretear''' is the leader

'''randtear''' is an array reference of random trailers.

So it goes: "PRETEAR Htag.pl 0.0.19 - RANDTEAR" for LONG and "PRETEAR Htag.pl 0.0.19" for SHORT.

Well I thought it was a nice idea at the time, ok?

=== header plugin options ===

{{{
$cfg{'randhead'} = [ "Hi \@F,\@B",
                     "Hiya \@F,\@B",
                     "Look! It's \@F!\@B",
                     "'ello \@F\@B",
                     "Salut \@F!\@B",
                   ];
}}}

The header plugin prints up customized headers if it can get at enough information to do so. It normally does it by parsing the To: header. It can make some annoying mistakes and there is no exception file but it works well in normal cases.

'''randhead''' specifies the headers, one of which will be chosen and placed at the top of the message but below any lines that look like message headers.

If you're wondering, the @F is replaced by the first name and @B by a carriage return. But we'll get to that later in the section of macros. You have to escape (preceed with a \) the @ symbol because it's in double quotes and otherwise Perl will interpret it as an array. You could put them in single quotes but then you'd have to do odd things with 'ello.

=== The Last Line ===

In spite of comments in the config file saying that the last line has to be "1;" it doesn't any more. Oops. I should fix this in the tarball.

=== grep plugin options ===

grep is an optional plugin that is in the example-scripts directory in the tarball. It checks the messagefile for words and counts their frequency and then makes a list of tags which match some of the more common words and picks one of them.

I ended up not liking it since it always seemed to pull out the same tags for messages to the same lists. I guess that's what it's meant to do but still...

=== dadadodo plugin options ===

dadadodo is an optional plugin that uses [[http://www.jwz.org/dadadodo/|dadadodo]] to generate random markov chains to use as taglines. It was fun for a while but people kept picking at my grammar ;-)

Fun to play with anyway. Read the source if you want to play with it. It's in the example-scripts directory of the tarball.

== Running htag ==

So you should now have enough knowledge to create your htag config file but how do you run it?

=== From an editor script ===

The most common way to run htag is from the following script:
{{{
#!/bin/sh

~/path/to/htag.pl -m $1
#2>&1 |tee ~/.htaglog
vim $1
}}}

The commented out line enables debugging information to be saved to a file called .htaglog which can be very useful for debugging purposes.

Basically you should run htag and then your editor or your editor and then htag depending on your point of view.

If you use mutt you can add:
{{{
set editor=~/bin/yourscript
}}}
where yourscript is the name of the script as created above.

=== How to test your config ===

If you wish to test your config however you should probably just run it from the command line so create a test message file with the following contents:
{{{
To: Simon Huggins <huggie-spam-me-harder@earth.li>

> This is a test message. Yadda yadda yadda.

Look here's my reply! And with a bit of luck htag will add my sig below!
}}}

Then run htag as follows and see what happens:
{{{
~/path/to/htag.pl -m ~/path/to/messagefile
}}}

If all went well then it will magically work so read on about how to create signatures, best use macros and use different config files for different people.

Otherwise:
 * If it complains that "Can't locate Htag''''''Plugin.pm in @INC" '''OR'''
 * If it complains that "Htag''''''Plugin version 0.5 required--this is only version 0.4" or similar
  * try adding a line that reads "use lib '/path/to/htag/Htag''''''Plugin';" to htag.pl before the "use Htag''''''Plugin 0.5;" line.
 * If it complains that it "couldn't do /home/huggie/.htrc" then check that you have created this file and that it is readable to you.
 * If it complains that it "Cannot open /home/huggie/htag/plugins/: No such file or directory" then you have specified the wrong '''plugindir''' in your config file.

It may give other Perl errors in which case your config file is not being parsed properly by Perl. Fix the error it gives you.

Other error messages come from the plugins. Common problems are:
 * "htag.pl: Cannot open foo: No such file or directory" i.e. your message file doesn't exist.
 * "No tagfile defined! I'm good but I'm not psychic. Did you configure me at all? Look at the sample.htrc" which means what it says really. No '''tagfile''', '''tagfiles''', '''tagdir''' or '''fortune''' options were defined.

When you run with $cfg{'debug'}=1; in your config file you will get a trace that looks a bit like what follows which may help you identify more specifically where the problem lies:
{{{
[snip]
Running "/home/huggie/perl/huggietag/current/plugins/06marknlard"
Running "/home/huggie/perl/huggietag/current/plugins/07sesame"
Running "/home/huggie/perl/huggietag/current/plugins/08uptime"
Running "/home/huggie/perl/huggietag/current/plugins/09date"
Running "/home/huggie/perl/huggietag/current/plugins/10simple"
Running "/home/huggie/perl/huggietag/current/plugins/13substtag"
[snip]
}}}

Other output is interpersed with this.

If you are still having problems then feel free to mail me: huggie-htag@earth.li

== Making signature files ==

Signature files are easy to make once you get a hang of the syntax. There are three types (since 0.0.20 type 2 exists):
 1. Trivial signature files have no special markup and htag just appends the tagline it chose to the end wrapping it according to [[#head-34ae98839985130ac84a36e14b6c879b35c738eb|merge plugin options]]
 1. Signature files with a `@NOTAG@` macro where other macros are substituted but no tagline is added.
 1. Normal signature files are templates which say where the various pieces should be slotted in.

=== Placement of signature files ===

This depends entirely on your [[#head-e00333a76482aa64e58c1617a080567a46ae2c25|catsig plugin options]] but I would recommend creating a separate directory for signatures and using it as the '''sigdir''' option.

If you name your signatures intelligently you can use '''sigmatch''' to good effect later when we examine how to change the configuration based on the headers of the message.

=== Trivial signature files ===

There really isn't a lot to say about them. A trivial signature file would be:
{{{
Simon

--
}}}

Producing:
{{{
Simon

--
... "The good thing about Unix is that it's very easy to create a child on
    the fly to tell you things like that (although it's not quite as much
    fun as in real life)." - Malcolm Beattie (linux-kernel)
}}}

To configure the first line leader (the "... ") and the second and subsequent leaders see the [[#head-34ae98839985130ac84a36e14b6c879b35c738eb|merge plugin options]]

=== Basic macros ===

Both types of signatures may contain basic macros:
|| Macro || Description || Output ||
|| @F || First name || Simon ||
|| @L || Last name || Huggins ||
|| @N || Full name || Simon James Huggins ||
|| @B || Line break || ||
|| @V || htag version || 0.0.19 ||
|| @NOTAG@ || Do not add a tag || ||

=== Templated signatures ===

Templated signatures come from the basic idea that you should be able to exactly specify where to put your tagline. Essentially you create a signature file but instead of leaving a gap at the end for your signature you can have it split over as many or as few gaps as you like.

Indeed you don't even need to limit this to taglines as some of the htag plugins provide their own template macros. So let's see how they work.

==== Basic principles of template macros ====

Template macros consist of:
 * an initial @ symbol
 * an optional letter - no letter means reformat the tagline, the other letters correspond to a plugin
  * a number representing the width of the field
  * ''OR'' an asterisk (*) meaning don't pad me.
 * an optional alignment character which can be L for left, R for right or C for centered. If not supplied then left is assumed.
 * a final @ symbol

Here are the letters that are currently defined:
|| Letter || Plugin || Output ||
|| D || Date || 20/04/2002 (but depends on '''date_format''' option) ||
|| M || Mark 'n Lard || Is it foo Mark? Sounds just like them. ||
|| S || Sesame street plugin || "the letter " then random letter then " and the number" and a random number ||
|| U || Uptime plugin || 365 days, 23:59 (but depends on '''uptime_time''' option) ||

When the replacement is made, any unused characters are padded with spaces. If a replacement doesn't fit then it will try to find one that does and failing that will fail and tell you.

Here are some examples:
|| Macro || Explanation ||
|| @68C@ || Replace with part of the tagline centered over these 68 characters ||
|| @D20@ || Replace with twenty characters of the date left aligned ||
|| @U50R@ || Replace with the uptime right aligned over 50 characters ||
|| @M*@ || Replace with the Mark and Lard plugin for however many characters it takes up without any padding ||

Multiple occurrences of macros are allowed and each plugin is run however many times a macro referencing it is found. i.e. having "@D20@ || @D20R@" would when substituted in result in the date twice once left aligned over 20 characters and once right aligned, split in the middle by " || ".

Tagline macros behave differently. There is only one tagline per sig and multiple tagline macros are interpreted as meaning split the tagline up over all of these different spaces.

==== Signature files and the reformat plugin ====

htag 0.0.21 and later have a reformat plugin which deals with tags such as `<CENTER76>Stuff</CENTER76>` and reformats them according to the number of characters specified after the position argument.

The reformat plugin requires the `Text::Balanced` module.

There are three positions, LEFT, RIGHT and CENTER.

For instance:
{{{
|<RIGHT10>21.34</RIGHT10>|<CENTER20>bar</CENTER20>| <RIGHT21>Thing</RIGHT21>
|<RIGHT10>1,987.99</RIGHT10>|<CENTER20>Stuff</CENTER20>| <RIGHT21><-- Look!</RIGHT21>
<CENTER76>And that was that then wasn't it</CENTER76>
<CENTER76>|<RIGHT10>21.34</RIGHT10>|<CENTER20>bar</CENTER20>|</CENTER76>
<CENTER76>|<RIGHT10>1,987.99</RIGHT10>|<CENTER20>Stuff</CENTER20>|</CENTER76>
}}}

Gives:
{{{
| 21.34| bar | Thing
| 1,987.99| Stuff | <-- Look!
                      And that was that then wasn't it
                     | 21.34| bar |
                     | 1,987.99| Stuff |
}}}

Reformat is called after merge and as such it will reformat bits of tags and macros that have already been substituted in to the signature.

A more relevant example is:

{{{
--
<CENTER68><CENTER31>huggie@earth.li</CENTER31>-+*+-<CENTER31>fou, con et anglais</CENTER31></CENTER68>
(_) @60C@ (_)
(_) @60C@ (_)
<RIGHT68>Brought to you by @S*@ at @D*@</RIGHT68>
}}}

{{{
--
        huggie@earth.li -+*+- fou, con et anglais
(_) "A l'attaque par Junon" "Aoh! Choquant. Ce ne sont pas (_)
(_) des gentils hommes" -- Astérix chez les Bretons. (_)
      Brought to you by the letter I and the number 47 at 03/06/2002
}}}

The starred form of macros is good when combined with the reformat plugin.

==== Example sig files ====

{{{
Simon.

--
@76R@
@76R@
htag.pl @M68R@
}}}

This is a very simple layout and it means:
 * Replace the @76R@ with right aligned portions of the tagline
 * Replace the @M68R@ with a right aligned Mark 'n Lard style quote

It results in the following look:
{{{
Simon.

--
    "Bizarre, right? That's what you get for knowing just enough Lisp to be
                       dangerous" -- The Camel Book (description of select)
htag.pl Is it Woody, Mark? Sounds just like him.
}}}

Here is a more interesting one:
{{{
Simon.

--
Just another wannabie | @30C@ | Just another fool
----------------------+ @30C@ +-------------------
This message was brought to you by @S30@.
htag.pl @V -- http://www.earth.li/projectpurple/progs/htag.html
}}}

This means:
 * Replace the @30C@ with centered portions of the tagline
 * Replace the @S30@ with left aligned bits from the sesame plugin
 * Replace the @V with the version of the running htag.pl

{{{
Simon.

--
Just another wannabie | "Cardinal Fang! Fetch... the | Just another fool
----------------------+ comfy chair!" - Monty Python +-------------------
This message was brought to you by the letter J and the number 21.
htag.pl 0.0.19 -- http://www.earth.li/projectpurple/progs/htag.html
}}}

Asterisks also work in tagline macros to mean just put the tag here with no reformatting. Normally this isn't what you want but it will work.

{{{
Simon.

--
@D*@ @*@
}}}

Will print out the date then the tagline without reformatting either.


You can of course be much more creative than I am :)

==== Special option for creating sigs ====

If you run ''htag -f sigfile'' htag will fill the sigfile with spaces where it would normally have filled it with a tagline or plugin text. This allows you to test the sigfile quickly without going through all the questions that htag may normally ask you. It is especially helpful to you when you want to line up some complex ASCII art.

== Multiple config file usage ==

htag has fairly good support for choosing different config file options based on the headers for a message. This can be used to:
 * not send rude taglines to your family
 * use sigs appropriate to your workplace when the mail is a reply to mail sent to your work address
 * use a different set of taglines say in a different language when you reply to a particular mailing list
 * use different random headers depending on the number of exclamation marks in the subject line

The multiple config file support is quite easy to understand I think but fairly flexible so it may be confusing at first. Basically htag always interprets the .htrc or the configfile you give to the -c option on the command line first. From there it checks the special variable '''changeheaders''' which is an array reference of array references. (Yes, I'm sick and twisted.)

Each array inside the array is a rule. It is a list of one or more regular expressions followed by a configfile name to use.
If all the regular expressions match, then htag will use that configfile. This means that the first array to match wins so more specific ones should be put earlier in the sequence to override less specific ones later on. The last one should probably be a catch all situation for consistency though if it isn't it will just not use that configfile.

The regular expression may contain brackets and the config file may contain $1 (only $1 however not $2 onwards) so that one rule may specify many config files easily. The example makes this clearer.

htag processes the .htrc first and then adds the extra config file specified in '''changeheaders''' on top. This is so that you can specify all the defaults in .htrc and then override the particular values which interest you in the extra config file.

=== Example changeheaders ===

Here's an example of '''changeheaders''':
{{{
$cfg{'changeheaders'} = [
        [ '^Foo: no','^From:.*?(\w+)@earth.li','~/.htagrc/$1' ],
        [ '^(From|Cc):.*@blackcatnetworks\.co\.uk','~/.htagrc/blackcat' ],
        [ '', '~/.htagrc/default' ],
        ];
}}}

The example is a little contrived I'm afraid but what the first array means is if the mail has a header "Foo: no" and a header that matches "From:" some random text then a word followed by "@earth.li" then use the config file "~/.htagrc/" appending the word preceeding the "@earth.li".

Confused? If you know Perl regular expressions then it probably isn't all that confusing. If not then try ignoring the "(\w+)" and the "$1" bits and imagine that it instead read:
{{{
[ '^Foo: no','^From:.*@earth.li','~/.htagrc/earthli' ],
}}}

This would simply mean for all messages with a "Foo: no" header and From someone with an email address at earth.li, use the ~/.htagrc/earthli config file.

The second line in the first example says any message which is from or CC'd to a blackcatnetworks.co.uk address should use the ~/.htagrc/blackcat configfile.

The last line is a catchall since all messages will match the empty string and it says to use ~/.htagrc/default.

=== Examples of configfiles ===

The configfiles I tend to use are centered around changing either the sigs or the taglines for those people.

For instance my default is:
{{{
$cfg{'tagdir'}="~/.tags/";
$cfg{'sigdir'} = "~/.sigs";

undef $cfg{'tagfile'};
undef $cfg{'tagfiles'};
undef $cfg{'tagmatch'};

undef $cfg{'fortune'};
# Probability 0 -> 1 of using fortune instead of tagline
undef $cfg{'fortuneval'};
undef $cfg{'fortuneargs'};

undef $cfg{'sigs'};
undef $cfg{'sigmatch'};
}}}

I also undef any other potentially conflicting variables that I may enable by mistake in my .htrc. This isn't necessary if your .htrc doesn't include those variables to start with but strikes me as more explicitly saying what I want plus it means I can just copy any of my .htagrc/* files and change the undef to actually defining it to get different behaviour instead of having to remember what the option is called. In the next examples I've missed out the undefs.

My blackcat file picks out only sigfiles that start with bc or blackcat:
{{{
$cfg{'sigmatch'} = '^/u2/huggie/\.sigs/(bc-.*|blackcat.*)$';
$cfg{'sigdir'} = "~/.sigs";
$cfg{'tagdir'}="~/.tags/";
}}}

=== Advanced magic with changeheaders ===

You can easily skip this if it scares you :)

The htrc file is really just Perl so you can effectively do anything with it. I have some friends who really aren't very technical and I have a tagfile which contains quotes from the linux-kernel mailing list so I use the following magic in my config file:
{{{
open(NOTECH, "$HOME/.htagrc/notech_addresses")
or nicedie "Could not open $HOME/.htagrc/notech_addresses: $!";
while (<NOTECH>) {
        chomp;
        next if ($_ =~ /^(?:#.*|\s*|)$/);
        $_ = quotemeta;
        $notech_addresses .= $_ . "|";
}
close(NOTECH);
$notech_addresses =~ s/\|$//;

$cfg{'changeheaders'} = [
        [ '(?x)^To:.*
                (?:'.$notech_addresses.
                ')','~/.htagrc/notech' ],
[snip]
}}}

This reads in .htagrc/notech_addresses, escapes any regular expression characters, and then combines them into one long regular expression which looks something like:
{{{
foo\.bar@hotmail\.com|foobar@earth\.li
}}}

The regular expression used in changeheaders uses the (?x) construct to allow splitting of the regular expression over several lines. It just checks to see if I'm sending mail to any of the addresses I've listed as not wanting to receive technical taglines and if so chooses the notech configfile which excludes that one tagfile from the list.

== Commandline options ==

|| Option || Description ||
|| -h || Show brief help summary (uses perldoc :) ) ||
|| -f sigfile || Fill sigfile with spaces for the alignment test ||
|| -t tagfile || Use tagfile as if it had been specified as $cfg{'tagfile'} (better to use configfile than this option) ||
|| -c configfile || Use configfile instead of .htrc ||
|| -m messagefile || This is the messagefile to be altered. Maybe "-" for standard input ||

== Other uses ==

Potentially the htag.pl program could run any set of plugins that did more or less anything to a file be it a mail file or something else though there are some specifics like '''changeheaders''' which require RFC 822 alike headers.

More realistically here are some ideas for plugins I haven't written or extensions which may improve htag:
 * Write a plugin to behave like the Mark 'n Lard, Sesame, and Date plugins for taglines. That is:
  * To check how many times taglines are asked for in the file probably with say @T68C for the 1st tagline then a random character for the second
  * To write out the different chunks into different files and correctly merge them not just one chunk into one space from one file, but all the chunks into the T spaces and all the chunks for the second tagline into the other spaces.
  * I'm not sure how useful this would actually be though.
 * Write an automated email address collection script that takes the To: and Cc: addresses and records them in an addressbook along with a timestamp. Then write a program to query that addressbook and to remind me to keep in touch with someone if I've not emailed them for a couple of months
 * Write a tagline stealing program which attempts to steal taglines from others signatures, asking for confirmation along the way.


== What did I miss? ==

Did I miss stuff? Probably. Comment here.
X0xYp6 <a href="http://ilhssgoilbgr.com/">ilhssgoilbgr</a>, [url=http://euugtqrmtjmu.com/]euugtqrmtjmu[/url], [link=http://mvegulayyoaq.com/]mvegulayyoaq[/link], http://aaqghqtunbhi.com/
----
CategoryRoleplaying

TheEarthWiki: HtagHowto (last edited 2009-12-12 09:13:40 by SimonHuggins)