------------------------------------------------------------------------
Version 0.01    Date: 1997/04/29 12:09:47

* Original code migrated from previous Template::Base module.  

------------------------------------------------------------------------
Version 0.02    Date: 1997/04/29 12:12:07

* Cleaned up and optimised much of the existing Template::Base code.

* Added user-definable MAGIC tokens, including different tokens for 
  start/end of MetaText directive.

* Updated filter functions definition

* Added user-definable warning function (ERROR)

* Added user-definable debug function (DEBUG) providing multi-level
  reporting

* Replaced old-style typeglobs with FileHandles

* Modified _split_params() to recognise single parameters (e.g. "noprint")
  as flags rather than requiring a balanced "name = value".  Flags are 
  added thusly: $directive->{ PARAMS }->{ $flag } = 0;

* Further modified _split_params() to protect multi-word quoted 
  sequences that may be values to pass to a function without being
  interpreted as many individual flags.  i.e. "foo bar baz" should
  *not* be interpreted as ("foo", "bar", "baz").

* Added "noprint" flag to BLOCK definition to prevent inclusion of the
  BLOCK definition in the processed output.  This changes in V0.10 where
  the default behaviour becomes "noprint" and printing is activated with 
  the "print" flag.  

------------------------------------------------------------------------
Version 0.03    Date: 1997/04/30 08:20:12

* Added ROGUE option to indicate how unrecognised tokens should be 
  handled.

* Added primitive LOOP construct.

------------------------------------------------------------------------
Version 0.04    Date: 1997/04/30 14:34:03

* Fully implemented LOOP construct.   LOOP segments are defined between 
  %% LOOP %% and %% ENDLOOP %% and _pre-process()'d into the symbol table 
  as LOOP.name (name defaults to a unique zero-padded 5-digit number).
  This is a test state.  Ideally, looping constructs should be built 
  into INCLUDE directives.  Lo and behold!  See the next comment...

* Removed LOOP directive (ha!) and built functionality into the standard
  INCLUDE directive.  This now supports the "repeat" flag, with an
  optional value (i.e. "repeat = 5").  Without the value, the parameters
  supplied to the INCLUDE are split by a delimiter (comma, ',' by 
  default, but can be set with "delimiter = <string>") and the loop 
  repeats until all the data has been used.  In the case that the block
  loops more times than a given parameter has values (i.e. repeat=5
  data="10,15,20") then the last value is repeated.  NOTE: LOOP constructs
  have since been removed from MetaText.  They may return one day.

* Formalised case sensitivity.  Keywords and special directive variables
  (e.g. REPEAT, IF, etc) are forced to upper case, parameter names to 
  lower case.  Identifiers (which may reference a case-sensitive external
  file) and parameter values are left as found.  
  This changes again in version 0.5)

* Modified _parse_directive() to handle all special parameters in a 
  generic way.  Previously, a special function, _extract_conditional()
  was employed to identify "if=<condition>" statements.  This is no
  longer required.

------------------------------------------------------------------------
Version 0.05    Date: 1997/05/02 06:48:31

* Further enhanced ROGUE error reporting to re-insert cleaned-up version
  of original tag (default), delete the tag in entirety (delete) and
  in either case, warn about the bad token (warn).

* Changed case sensitivity handling (again).  I decided it was incorrect 
  to force all parameter names and identifiers to lower case.  Why not
  let the users deferentiate between "foo" and "FOO" if they want to?
  There is now a CASE configuration option.  If it evaluates true,
  MetaText runs in case-sensitive mode, preserving the case of all
  identifiers and parameters (except for directive control params such
  as REPEAT, DELIMITER etc. which are always forced to UPPER).  When
  CASE is false, all parameters and identifiers are converted to lower
  case.  This will cause problems if you try to INCLUDE an external
  file whose name is not fully lower case.  i.e. "INCLUDE Foo/Bar"
  becomes "INCLUDE foo/bar".  For this reason, case sensitive is the
  default mode.

* Modified _split_params() to allow single quotes ''' to be used to 
  encompass multi-word values in addition to the usual double quotes '"'.
  Cleaned up the regex code considerably, pre-defining various elements
  to make the final expression readable and easily understandable <gasp!>

* Modified _split_params() to allow variables to reference other 
  variables (e.g. alias = $name).  Added _interpolate_tags() to
  interpolate all these values before passing them to process(), 
  _substitute() and _evaluate.  Modified _evaluate() to understand and
  account for references and cleaned up much of the evaluation code.
  (This changes in version 0.6)
  
* Added DELIMITER option, allowing the user to specify the default 
  DELIMITER for splitting strings.  Specific delimiters can still be
  specified within individiual operations.

* Added some extra characters to the characters class that can delimit
  directories in a DIRECTORY or DATADIR string.  Currently [|;,:].

------------------------------------------------------------------------
Version 0.06    Date: 1997/05/02 14:43:18

* Fixed a minor bug in _tidy() that was stripping quotes from quoted
  parameter lists.

* Shifted lower case conversion (if $self->{ CASE }) out of 
  _split_params() and put it into _parse_directive() to allow slightly
  more flexibility in parameter parsing.

* Removed variable interpolation from basic block parameters.  It was 
  getting very complicated to track what was what.  Despite coding a
  reasonably elegant solution, I decided that it made the code more
  complex for very little gain.  Condition statements (if="<condition>")
  may include variable references as may INCLUDE identifiers, e.g.
  %% INCLUDE $name %%

------------------------------------------------------------------------
Version 0.07    Date: 1997/05/06 16:04:45

* Added generic _interpolate() function for expanding variable values
  within a string.  Block idetifiers are now passed through this function
  to permit directives such as "%% INCLUDE $name %%".  Ambiguous names
  can be resolved by surrounding the variable name in braces, as per the
  Unix shell syntax.  e.g. "foo${bar}baz".

* Modified _evaluate() to use hash array to reference anonymous code
  subs to do comparisons (==, !=, <=, etc) and boolean operations 
  (and, or, xor, etc).  

* Quotes are implicitly removed from around absolute values in 
  conditional equations.  e.g. with the following conditional: 
  if="name=\"John Doe\"" the variable 'name' is implictly changed from
  '"John Doe"' to 'John Doe'.  The original escaped quotes *ARE* 
  required to quote the whitespace within the variable value.
   
* Added regex matching (=~ and !~) to _evaluate() function for 
  conditionals.

* Relaxed valid/invalid variable checking within _evaluate() to allow
  the simple expression 'if="$variable"' to simply return 0 if 
  $variable isn't defined rather than bleat about it.

------------------------------------------------------------------------
Version 0.08    Date: 1997/05/08 08:34:41

* Fixed bug where surrounding quotes weren't being stripped from if=""
  values in all cases.

* Changed _evalute() to evaluate parameter values (as well as parameter 
  names) case-insensitively unless CASE sensitive flag is set.
 
* Added "in" comparator in _evaluate() to determine if a value is in a 
  given list.  e.g. "$name in \"fred,tom,harry\"".  Uses the current
  DELIMITER value (or the default) to delimit the list.

* Changed name of debug function from _debug() to _DEBUG() to enhance 
  readability.

------------------------------------------------------------------------
Version 0.09    Date: 1997/05/15 09:13:00

* Added an "UNLESS" option to INCLUDE directives for convenience, 
  effectively giving the opposite to the "IF" directive.  An INCLUDE 
  directive may contain both an IF and an UNLESS statement in which 
  case, the IF is evaluated first, and the UNLESS second.  If the
  IF condition fails, the UNLESS will not be evaulated.  If the UNLESS
  evaluates true, the INCLUDE will be skipped, even if the IF condition
  returned TRUE. 

* Added INDEX directive to build a list of INCLUDE directives within a
  block.  This is removed in a later version, not least of all because
  it proved to be unwieldy and of limited use.

* Optimised and tidied up the main _process() loop.

------------------------------------------------------------------------
Version 0.10    Date: 1997/05/19 08:37:05

* Made a couple of minor changes to get Perl 5.004 running -w without 
  warnings.

* Enhanced _index() to only index INCLUDE directives whose identifiers
  match the "element=<regex>,<regex>..." pattern specified in the INDEX
  directive.  Case sensitivity to the pattern match depends on 
  $self->{ CASE }.

* Changed the rather generic "DIRECTORY" configuration option to 
  "ELEMPATH" (element path) which more accurately describes what it
  actually refers to.

* Finally fixed and rationalised the handling of carriage returns at
  the end of lines.  The problem was, particularly with DEFINE 
  directives, where the directive was removed during processing 
  leaving a blank line it it's place.  A number of DEFINE directives 
  on subsequent lines (as is quite common) leaves a great big chunk of 
  whitespace.  The solution is to ignore any carriage return that 
  occurs immediately after the closing directive magic token.  Any 
  trailing characters after the directive, including whitespace, will 
  get a carriage return added to it.  The original carriage return 
  gets eaten by the regex, in case you wondered what happened to it.

* Changed the "print" INCLUDE option (in which the print format could
  be specified) to be "format" which makes more sense, IMHO.

* Removed the print format and filter code out of process() and into
  it's own function, _post_process().  This has several advantages.
  Firstly, it means that the code can conveniently be called for other
  directives apart from INCLUDE (SUBST now passes it's output through
  the printf filter as well).  Secondly, the directive object itself 
  can be passed to _post_process() meaning that the "filter" and 
  "format" options can now be stored as internal directive values
  rather than entries in the tags table.

* Changed the print format code to attempt to recognise the difference
  between a printf() format and a time2str() format.  A format that
  matches "%[^s]" is passed through time2str() from Date::Format. Other
  formats containing no other marker than "%s" are assumed to be 
  printf() formats.  A special "%P" marker in the format is ignored, 
  but silently invokes the printf() option regardless. "%s" is handled
  identically be either printf() or time2str().

* Modified _substitute() slightly to look for certain tag(s) before 
  attempting to call the tag as a function.  The tag(s) and their 
  associated return values are: 

    TIME       Returns current system time in seconds sinch the epoch 

* Changed AUTOLOAD to return undef if the original (unresolvable)
  directive should be left as is.  The value is passed up through 
  _substitute() to the relevant SUBST block in _process().  The 
  original directive is reconstructed here and the _post_process()
  step is bypassed.

* Added POD documentation.

------------------------------------------------------------------------
Version 0.11    Date: 1997/07/22 10:18:15

* Fixed fix in AUTOLOAD that was keeping directives from being deleted 
  when ROGUE=delete was defined.

* Fixed bug in process() which was returning an output list rather than
  concatenating the contents when __END__ was detected.  The usual 
  return point had been changed some time ago.

* Added CHOMP configuration item which allows the user to specify the
  end-of-line processing behaviour.  With CHOMP defined to any true value, 
  a newline immediately following a directive will be chomped off.  
  Modified _pre_process() to handle this.

* Corrected, enhanced and added further POD documentation.

* Added 'postproc' debug flag for examining _post_process() activity
  and data.

------------------------------------------------------------------------
Version 0.12    Date: 1997/11/28 07:56:24

* Replaced the DEBUGLEVEL constant sub-routines for the new "use constant...";

* Updated the tests (a little).

* Added the EXECUTE configuration option to control how the processor 
  attempts to resolve unknown identifiers.  With EXECUTE true, the 
  _substitute() method tried to run it as a package method.  With EXECUTE
  set > 1, it will also try to run it as a function in the main package, 
  assuming that the previous method call failed.

* Added PRINT as a special directive parameter (for BLOCK) rather than have
  it as just another parameter.

* Re-organised the code a little, listing methods roughly in the order in
  which they're used.

* Replaced the "ELEMPATH" configuration variable with "LIB".

* Moved the revision history (this list) and the bugs/future enhancements
  lists into separate files: "Changes" and "Todo", respectively.

* Changes _parse_params() to unescape any escaped characters, rather than
  just quotes.

------------------------------------------------------------------------
Version 0.13    Date: 1997/12/05 15:58:02

* Modified Makefile.PL to install metapage as well.

* Updated and completed documentation for module.

------------------------------------------------------------------------
Version 0.14    Date: 1998/01/30 15:50:37

* Fixed some significant bugs in the _evaluate() method and added 'eval'
  script to test general evaluation conditions.

* Fixed regex comparitor match bug in _evaluate() which was causing the 
  simple evaluation 'if="variable"' to fail.

* Fixed a number of typos and made a few enhancements to the
  Text::MetaText documentation.

* Added documentation to metapage utility.

------------------------------------------------------------------------
Version 0.15    Date: 1998/02/04 08:57:14

* Added 'ignore' and 'accept' options to metapage (1.06)

* First public beta release.