NAME
   Text::MetaText - Perl extension implementing meta-language for
   processing "template" text files.

SYNOPSIS
       use Text::MetaText;
       my $mt = new Text::MetaText;
       print $mt->process($filename, \%vardefs);

SUMMARY OF METATEXT DIRECTIVES
       %% DEFINE variable=value %%   # define variable(s)

       %% SUBST variable  %%         # insert variable value
       %% variable %%                # short form of above

       %% BLOCK blockname %%         # define a block 'blockname'
          block text...
       %% ENDBLOCK %%

       %% INCLUDE blockname %%       # include 'blockname' block text
       %% INCLUDE filename  %%       # include external file 'filename'

       %% INCLUDE file_or_block      # a more complete example...
          variable=value             # additional variable definition(s)
          if=condition               # conditional inclusion
          format=format_string       # printf-like format string with '%s'
          filter=fltname(params)     # post-process filter
       %%

       %% TIME                       # current system time, as per time(2)
          format=format_string       # display format, as per strftime(3C)
       %%

DESCRIPTION
   MetaText is a text processing and markup meta-language which can
   be used for processing "template" files. This module is a Perl 5
   extension implementing a MetaText object class which processes
   text files, interpreting and acting on the embedded MetaText
   directives within.

   Like a glorified pre-processor, MetaText can; include files,
   define and substitute variable values, execute conditional
   actions based on variables, call other perl functions or object
   methods and capture the resulting output back into the document,
   and more. It can format the resulting output of any of these
   operations in a number of ways. The objects, and inherently, the
   format and symantics of the MetaText langauge itself, are highly
   configurable.

   MetaText was originally designed to aid in the creation of html
   documents in a large web site. It remains well suited for this
   and similar tasks, being able to create web pages (dynamically
   or statically) that are consistent with each other, yet easily
   customisable:

   *   standard headers, footers and other elements can be defined in
       separate files and then inserted into web documents:

           %% INCLUDE header %%

   *   variables can be defined externally or from within a document,
       then can be substituted back into the text. This is useful
       for including your %% name %% or %% email %% address or any
       other variable, and for encoding URL's or file paths that
       can then be changed en masse. e.g.

           <img src="%% imgroot %%/foo/bar.gif">

   *   conditional actions can be made based on variable definitions,
       allowing easily and instantly customisable web pages. e.g

           %% INCLUDE higraphics/header if="higfx && userid != abw" %%

   *   blocks of text can be internally defined simplifying the
       creation of repetitive elements. e.g.

           %% BLOCK table_row %%
           <tr> <td>%% userid %%</td> <td>%% name %%</td> </tr>
           %% ENDBLOCK %%

           %% INCLUDE table_row userid=lwall  name="Larry Wall"         %%
           %% INCLUDE table_row userid=tomc   name="Tom Christiansen"   %%
           %% INCLUDE table_row userid=merlyn name="Randal L. Schwartz" %%

   *   in addition, the metapage utility is a script which can
       automatically traverse document trees, processing updated
       files to assist in web document management and other similar
       tasks.

PREREQUISITES
   MetaText requires Perl 5.004 or later. The Date::Format module
   should also be installed. This is available from CPAN (in the
   "TimeDate" distribution) as described in the following section.

OBTAINING AND INSTALLING THE METATEXT MODULE
   The MetaText module is available from CPAN. As the 'perlmod' man
   page explains:

       CPAN stands for the Comprehensive Perl Archive Network.
       This is a globally replicated collection of all known Perl
       materials, including hundreds of unbunded modules.

       [...]

       For an up-to-date listing of CPAN sites, see
       http://www.perl.com/perl/ or ftp://ftp.perl.com/perl/ .

   Within the CPAN archive, MetaText is in the "Text::" group which
   forms part of the the category:

     *) String Processing, Language Text Processing,
        Parsing and Searching

   The module is available in the following directories:

       /modules/by-module/Text/Text-MetaText-<version>.tar.gz
       /authors/id/ABW/Text-MetaText-<version>.tar.gz

   For the latest information on MetaText or to download the latest
   pre-release/beta version of the module, consult the definitive
   reference, the MetaText Home Page:

       http://www.kfs.org/~abw/perl/metatext/

   MetaText is distributed as a single gzipped tar archive file:

       Text-MetaText-<version>.tar.gz

   Note that "<version>" represents the current MetaText Revision
   number, of the form "0.14". See the REVISION manpage below to
   determine the current version number for Text::MetaText.

   Unpack the archive to create a MetaText installation directory:

       gunzip Text-MetaText-<version>.tar.gz
       tar xvf Text-MetaText-<version>.tar

   'cd' into that directory, make, test and install the MetaText
   module:

       cd Text-MetaText-<version>
       perl Makefile.PL
       make
       make test
       make install

   The 't' sub-directory contains a number of small sample files
   which are processed by the test script (called by 'make test').
   See the README file in that directory for more information. A
   logfile (test.log) is generated to report any errors that occur
   during this process. Please note that the test suite is
   incomplete and very much in an 'alpha' state. Any further
   contributions here are welcome.

   The 'make install' will install the module on your system. You
   may need root access to perform this task. If you install the
   module in a local directory (for example, by executing "perl
   Makefile.PL LIB=~/lib" in the above - see `perldoc MakeMaker'
   for full details), you will need to ensure that the PERL5LIB
   environment variable is set to include the location, or add a
   line to your scripts explicitly naming the library location:

       use lib '/local/path/to/lib';

   The metapage utility is a script designed to automate MetaText
   processing of files. It can traverse directory trees, identify
   modified files (by comparing the time stamp of the equivalent
   file in both "source" and "destination" directories), process
   them and direct the resulting output to the appropriate file
   location in the destination tree. One can think of metapage as
   the MetaText equivalent of the Unix make(1S) utility.

   The installation process detailed above should install metapage
   in your system's perl 'installbin' directory (try `perl '-
   V:installbin'' to check this location). See the metapage
   documentation (`perldoc metapage') for more information on
   configuring and using metapage.

USING THE METATEXT MODULE
   To import and use the MetaText module the following line should
   appear in your Perl script:

       use Text::MetaText;

   MetaText is implemented using object-oriented methods. A new
   MetaText object is created and initialised using the
   Text::MetaText->new() method. This returns a reference to a new
   MetaText object.

       my $mt = Text::MetaText->new;

   A number of configuration options can be specified when creating
   a MetaText object. A reference to a hash array of options and
   their associated values should be passed as a parameter to the
   new() method.

       $my $mt = Text::MetaText->new( { 'opt1' => 'val1', 'opt2' => 'val2' } );

   The configurations options available are described in full
   below. All keywords are treated case-insensitively (i.e. "LIB",
   "lib" and "Lib" are all considered equal).

   LIB The INCLUDE directive causes the external file specified
       ("INCLUDE <file>") to be imported into the current document.
       The LIB option specifies one or more directories in which
       the file can be found. Multiple directories should be
       separated by a colon or comma. The current directory is also
       searched by default.

           my $mt = Text::MetaText->new( { LIB => "/tmp:/usr/metatext/lib" } );

   CASE
       The default behaviour for MetaText is to treat variable
       names and identifiers case insensitively. Thus, the
       following are treated identically:

           %% INCLUDE foo %%
           %% INCLUDE FOO %%

       Setting the CASE option to any non-zero value causes the
       document to be processed case sensitively.

           my $mt = Text::MetaText->new( { CASE => 1 } ); # case sensitive

       Note that the configuration options described in this
       section are always treated case insensitively regardless of
       the CASE setting.

   MAGIC
       MetaText directives are identifed in the document being
       processed as text blocks surrounded by special "magic"
       identifers. The default identifiers are a double percent
       string, "%%", for both opening and closing identifiers.
       Thus, a typical directive looks like:

           %% INCLUDE some/file %%

       and may be embedded within other text:

           normal text, blah, blah %% INCLUDE some/file %% more normal text

       The MAGIC option allows new identifiers to be defined. A
       single value assigned to MAGIC defines a token to be used
       for both opening and closing identifiers:

           my $mt = Text::MetaText->new( { MAGIC => '++' } );

           ++ INCLUDE file ++

       A reference to an array providing two values (elements 0 and
       1) indicates separate tokens to be used for opening and
       closing identifiers:

           my $mt = Text::MetaText->new( { MAGIC => [ '<!--', '-->' ] } );

           <!-- INCLUDE file -->

   CHOMP
       When MetaText processes a file it identifies directives and
       replaces them with the result of whatever magical process
       the directive represents (e.g. file contents for an INCLUDE,
       variable value for a SUBST, etc). Anything outside the
       directive, including newline characters, are left intact.
       Where a directive is defined that has no corresponding
       output (DEFINE, for example, which silently sets a variable
       value), the trailing newline characters can leave large
       tracts of blank lines in the output documents.

       For example:

         line 1
         %% DEFINE f="foo" %%
         %% DEFINE b="bar" %%
         line 2

       Produces the following output:

         line 1

         line 2

       This happens because the newline characters at the end of
       the second and third lines are left intact in the output
       text.

       Setting CHOMP to any true value will remove any newline
       characters that appear immediately after a MetaText
       directive. Any characters coming between the directive and
       the newline, including whitespace, will override this
       behaviour and cause the intervening characters and newline
       to be output intact.

       With CHOMP set, the following example demonstrates the
       behaviour:

         line 1
         %% DEFINE f="foo" %%
         %% DEFINE b="bar" %%<space>
         line 2

       Produces the following output (Note that "<space>" is
       intended to represent a single space character, not the
       string "<space>" itself, although the effect would be
       identical):

         line 1
         <space>
         line 2

   FILTER
       There may be times when you may want to INCLUDE a file or
       element in a document but want to filter the contents in
       some way. You may wish to escape (i.e. prefix with a
       backslash '\') certain characters such as quotes, search for
       certain text and replace with an alternative phrase, or
       perform some other post-processing task. The FILTER option
       allows you to define one or more code blocks that can be
       called as filter functions from an INCLUDE directive. Each
       code block is given a unique name to identify it and may
       have calling parameters (parenthesised and separated by
       commas) that can be specified as part of the directive. e.g.

           %% INCLUDE foo filter="slurp(prm1, prm2, ...)" %%

       Two default filters are pre-defined: escape() and sr().
       escape() takes as a parameter a perl-like regular expression
       pattern that indicates characters that should be 'escaped'
       (i.e. prefixed by a backslash '\') in the text. For example,
       to escape any of the character class `["'\]' you would
       specify the filter as:

           %% INCLUDE foo filter="escape([\"'\\])" %%

       The second filter, sr(), takes two arguments, a search
       string and a replace string. A simple substitution is made
       on the included text. e.g.

           %% INCLUDE foo filter="sr(spam, \"processed meat\")" %%

       Note that quotes and other special metacharacters should be
       escaped within the filter string as shown in the two
       examples above.

       Additional filters can be specified by passing a reference
       to a hash array that contains the name of the filter and the
       code itself in each key/value pair. Your filter function
       should be designed to accept the name of the function as the
       first parameter, followed by a line of text to be processed.
       Any additional parameters specified in the INCLUDE directive
       follow. The filter function is called for each line of an
       INCLUDE block and should return the modified text.

       Example:

           my $mt = Text::MetaText->new( {
               FILTER => {
                   'xyzzy' => sub {
                        my ($filtername, $text, @params) = @_;
                        $text = # do something here...
                        $text;  # return modified text
                   }
               }
           } );

           %% INCLUDE file1 filter="xyzzy(...)" %%

       A new FILTER definition will replace any existing filter
       with the same name.

   EXECUTE
       The SUBST directive performs a simple substitution for the
       value of the named variable. In the example shown below, the
       entire directive, including the surrounding 'magic' tokens
       '%%', is replaced with the value of the variable 'foo':

           %% SUBST foo %%  (or more succinctly, %% foo %%)

       If the named variable has not been defined, MetaText can
       interpret the variable as the name of an object method in
       the current class or as a function in the main package.

       If the EXECUTE flag is set to any true value, the MetaText
       processor will interpret the variable as an object method
       and attempt to apply it to its own object instance (i.e.
       $self->$method(...)). If the method is not defined, the
       processor fails quietly (but see ROGUE below to see what can
       happen next). This allows classes to be derived from
       MetaText that implement methods that can be called (when
       EXECUTE == 1) as follows:

           %% method1 ... %%       # calls $self->method1(...);
           %% method2 ... %%       # calls $self->method2(...);

       The text returned from the method is used as a replacement
       value for the directive.

       The following pseudo-code example demonstrates this:

           package MyMetaText;
           @ISA = qw( Text::MetaText );

           sub foo { "This is method 'foo'" }  # simple return string
           sub bar { "This is method 'bar'" }  # "        "         "

           package main;

           my $mt = MyMetaText->new( { EXECUTE => 1 } );
           print $mt->process("myfile");

       which, for the file 'myfile':

           %% foo %%
           %% bar %%

       generates the following output:

           This is method 'foo'
           This is method 'bar'

       If the EXECUTE flag is set to a value > 1 and the variable
       name does not correspond to a class method, the processor
       tries to interpret the variable as a function in the main
       package. Like the example above, the processor fails
       silently if the function is not defined (but see ROGUE
       below).

       The following pseudo-code extract demonstrates this:

           my $mt = Text::MetaText->new( { EXECUTE => 2 } );
           print $mt->processs("myfile");

           sub foo { "This is function 'foo'" }  # simple return string
           sub bar { "This is fucntion 'bar'" }  # "        "         "

       which, for the file 'myfile':

           %% foo %%
           %% bar %%

       generates the following output:

           This is function 'foo'
           This is function 'bar'

       Any additional parameters specified in the directive are
       passed to the class method or function as a hash array
       reference. The original parameter string is also passed.
       Note that the first parameter passed to class methods is the
       MetaText (or derivative) object reference itself.

       Example:

           %% foo name="Seuss" title="Dr" %%

       causes the equivalent of (when EXECUTE is any true value):

           $self->foo(                                  # implicit $self ref
               { 'name' => 'Seuss', 'title' => 'Dr' },  # hash ref of params
                 'name="Seuss" title="Dr"' );           # parameter string

       and/or (when EXECUTE > 1):

           &main::foo(
               { 'name' => 'Seuss', 'title' => 'Dr' },  # hash ref of params
                 'name="Seuss" title="Dr"' );           # parameter string

   ROGUE
       This configuration item determines how MetaText behaves when
       it encounters a directive it does not recognise. The ROGUE
       option may contain one or more of the ROGUE keywords
       separated by any non-word character. The keywords and their
       associated meanings are:

           warn    Issue a warning (via the ERROR function, if
                   specified) when the directive is encountered.

           delete  Delete any unrecognised directives.

       The default behaviour is to silently leave any unrecognised
       directive in the processed text.

       Example:

           my $mt = Text::MetaText->new( { ROGUE => "delete,warn" } );

   DELIMITER
       The DELIMITER item specifies the character or character
       sequence that is used to delimit lists of data. This is
       used, for example, by the "in" operator which can be used in
       evaluation conditions. e.g.

           %% INCLUDE hardenuf if="uid in abw,wrigley" %%

       In this case, the condition evaluates true if the uid
       variable contains the value "abw" or "wrigley". The default
       delimiter character is a comma.

       The example:

           my $mt = Text::MetaText->new( { DELIMITER => ":" } );

       would thus correctly process:

           %% INCLUDE hardenuf if="uid in abw:wrigley" %%

   ERROR
       The ERROR configuration item allows an alternative error
       reporting function to be specified for error handling. The
       function should expect a printf() like calling convention.

       Example:

           my $mt = Text::MetaText->new( {
               ERROR => sub {
                   my ($format, @params) = @_;
                   printf(STDERR "ERROR: $format", @params);
               }
           } );

   DEBUG
       The DEBUG item allows an alternative debug function to be
       provided. The function should expect a printf() like calling
       convention, as per the ERROR option described above. The
       default DEBUG function sends debug messages to STDERR,
       prefixed by a debug string: 'D> '.

   DEBUGLEVEL
       The DEBUGLEVEL item specifies which, if any, of the debug
       messages are displayed during the operation of the MetaText
       object. Like the ROGUE option described above, the
       DEBUGLEVEL value should be constructed from one or more of
       the following keywords:

           none      no debugging information (default)
           info      general processing information
           config    MetaText object configuration items
           preproc   pre-processing phase
           process   processing phase
           postproc  post-processing phase
           data      additional data parameters in debug messages
           content   content of pre-processed INCLUDE blocks
           function  list functions calls as executed
           evaluate  trace conditional evaluations
           test      used for any temporary test code
           all       all of the above (excluding "none", obviously)

       Example:

           my $mt = Text::MetaText->new( {
               DEBUGLEVEL => "preproc,process,data"
           } );

   MAXDEPTH
       It is possible for MetaText to become stuck in an endless
       loop if a circular dependancy exists between one or more
       files. For example:

           foo:
               %% INCLUDE bar %%

           bar:
               %% INCLUDE foo %%

       To detect and avoid such conditions, MetaText allows files
       to be nested up to MAXDEPTH times. By default, this value is
       32. If you are processing a file which has nested INCLUDE
       directives to a depth greater than 32 and MetaText returns
       with a "Maximum recursion exceeded" warning, set this
       confiuration item to a higher value. e.g.

           my $mt = Text::MetaText->new( { MAXDEPTH => 42 } );

PROCESSING TEXT
   The MetaText process() method is called to process a file,
   interpreting any MetaText directives embedded within it. The
   first parameter should be the name of the file which should
   reside in the current working directory or in one of the
   directories specified in the LIB configuration option. A
   filename starting with a slash '/' is considered to be an
   absolute path. The optional second parameter may be a reference
   to a hash array containing a number of variable/value
   definitions that should be pre-defined when processing the file.

       print $mt->process("somefile", { name => "Fred" });

   If "somefile" contains:

       Hello %% name %%

   then the output generated would be:

       Hello Fred

   Pre-defining variables in this way is equivalent to using the
   DEFINE directive (described below) at the start of the INCLUDE
   file

       %% DEFINE name="Fred" %%
       Hello %% name %%

   The process() function will continue until it reaches the end of
   the file or a line containing the pattern "__END__" by itself
   ("END" enclosed by double underscores, no other characters or
   whitespace on the line). Note that the pre-processor (a private
   method which is called by process(), so feel free to forget all
   about it) *does* scan past any __END__ marker. In practice, that
   means you can define blocks *after*, but use them *before*, the
   __END__ marker. e.g.

       Martin, %% INCLUDE taunt %%

       __END__                 << processor stops here and ignores
                                  everything following
       %% BLOCK taunt %%       << but the pre-processor has correctly
       you Camper!                continued and parsed this block so that
       %% ENDBLOCK %%             it can be included in the main body

   produces the output:

       Martin, you Camper!

   The process() function returns a string containing the processed
   file or block output.

       my $output = $mt->process("myfile");
       print $output;

METATEXT DIRECTIVES
   A MetaText directive is a block of text in a file that is
   enclosed by the MAGIC identifiers (by default '%%'). A directive
   may span multiple lines and may include blank lines within in.
   Whitespace within a directive is generally ignored except where
   quoted as part of a specific value.

       %% DEFINE
          name    = Yorick
          age     = 30
          comment = "A fellow of infinite jest"
       %%

   The first word of the directive indicates the directive type.
   Directives may be specified in upper, lower or mixed case,
   irrespective of the CASE sensitivity flag (which affects only
   variable names). The general convention is to specify the
   directive type in UPPER CASE to aid clarity.

   The MetaText directives are:

   DEFINE
       Define the values for one or more variables

   SUBST
       Substitute the value of a named variable

   INCLUDE
       Process and include the contents of the named file or block

   BLOCK
       Define a named block which can be subsequently INCLUDE'd

   ENDBLOCK
       Marks the end of a BLOCK definition

   To improve clarity and reduce excessive, unnecessary and
   altogether undesirable verbosity, a directive block that doesn't
   start with a recognised MetaText directive is assumed to be a
   'SUBST' variable substitution. Thus,

       %% SUBST foo %%

   can be written more succinctly as

       %% foo %%

   When MetaText processes directives, it is effectively performing
   a "search and replace". The MetaText directive block is replaced
   with whatever text is appropriate for the directive specified.
   Generally speaking, MetaText does not alter any text content or
   formatting outside of directive blocks. The only exception to
   this rule is when CHOMP is turned on (see the section on "USING
   THE METATEXT MODULE") and newlines immediately following a
   directive are subsequently deleted.

 DEFINE

   The DEFINE directive allows simple variables to be assigned
   values. Multiple variables may be defined in a single DEFINE
   directive.

       %% DEFINE
          name  = Caliban
          quote = "that, when I waked, I cried to dream again."
       %%

   Variables defined within a file or passed to the process()
   function as a hash array remain defined until the file or block
   is processed in entirety. Variable values will be inherited by
   any nested files or blocks INCLUDE'd into the file. Re-
   definitions of existing variables will persist within the file
   or block, masking any existing values, until the end of the file
   or block when the previous values will be restored.

   The following example illustrates this:

       foo:
           Hello %% name %%              # name assumes any predefined value
           %% DEFINE name=tom %%
           Hello %% name %%              # name = 'tom'
           %% INCLUDE bar name='dick' %% # name = 'dick' for "INCLUDE bar"
           Hello %% name %%              # name = 'tom'

       bar:
           Hello %% name %%              # name = 'dick'
           %% DEFINE name='harry' %%     # name = 'harry'
           Hello %% name %%

   Processing the file 'foo' as follows:

       print $mt->process('foo', { 'name' => 'nobody' });

   produces the following output (with explanatory comments added
   for clarity):

       Hello nobody                      # value from process() hash
       Hello tom                         # from foo
       Hello dick                        # from bar
       Hello harry                       # re-defined in bar
       Hello tom                         # restored to previous value in foo

 SUBST

   A SUBST directive performs a simple variable substitution. If
   the variable is defined, its value will be inserted in place of
   the directive.

   Example:

       %% DEFINE name=Jake %%
       Hello %% SUBST name %%

   generates the following output:

       Hello Jake

   The SUBST keyword can be omitted for brevity. Thus "%% name %%"
   is processed identically to "%% SUBST name %%".

   If the variable is undefined, the MetaText processor will,
   according to the value of the EXECUTE configuration value, try
   to execute a class method or a function in the main package with
   the same name as the SUBST variable. If EXECUTE is set to any
   true value, the processor will try to make a corresponding
   method call for the current object (that is, the current
   instantiation of the MetaText or derived class). If no such
   method exists and EXECUTE is set to any value greater than 1,
   the processor will then try to execute a function in the main
   package with the same name as the SUBST variable In either case,
   the text returned from the method or function is included into
   the current block in place of the SUBST directive (non-text
   values are automatically coerced to text strings). If neither a
   variable, method or function exists, the SUBST directive will
   either be deleted or left intact (and additionally, a warning
   may be issued), depending on the value of the ROGUE
   configuration item.

   See EXTENDING METATEXT below for more information on deriving
   MetaText classes and using EXECUTE to extend the meta-language.

   The "format" and "filter" options as described in the INCLUDE
   section below are applied to the processed SUBST result before
   being inserted back into the document.

   Some MetaText variables have a special meaning. Unless
   specifically defined otherwise, the variable(s) listed below
   generate the following output:

       TIME    The current system time in seconds since the epoch,
               00:00:00 Jan 1 1970.  Use the "format" option to
               specify a time/date format.

 INCLUDE

   The INCLUDE directive instructs MetaText to load and process the
   contents of the file or block specified. If the target is a
   file, it should reside in the current directory or a directory
   specified in the LIB configuration variable. Alternatively, the
   target may be a text block specified with BLOCK..ENDBLOCK
   directives (see below).

       %% INCLUDE chapter1 %%

   The target may also be a variable name and should be prefixed
   with a '$' to identify it as such. On evaluation, the value of
   the named variable will be used as the target:

   Example:

       %% DEFINE chapter=ch1 %%
       %% INCLUDE $chapter   %%

   is equivalent to:

       %% INCLUDE ch1 %%

   Additional variables may be defined for substitution within the
   file:

       %% INCLUDE chapter2 bgcolor=#ffffff title="Chapter 2" %%

   The contents of the file "chapter2":

       <html><head><title>%%title%%</title></head>
       <body bgcolor="%% bgcolor %">
         ...
       </body>

   would produce the output:

       <head><title>Chapter 2</title></head>
       <body bgcolor="#ffffff">
         ...
       </body>

   Defining variables in this way is equivalent to using the DEFINE
   directive. Variables remain in scope for the lifetime of the
   file being processed and then revert to any previously defined
   values (or undefined). Any additional files processed via
   further INCLUDE directives within the file will also inherit any
   defined variable values.

   Example:

         %% INCLUDE file1 name="World" %%

   for the files:

       file1:                   # name => "World" from INCLUDE directive
           %% INCLUDE file2 %%

       file2:                   # inherits "name" variable from file1
           %% INCLUDE file3 %%

       file3:                   # inherits "name" variable from file2
           Hello %% name %%

   produces the output:

       Hello World

   The output generated by INCLUDE and SUBST directives can be
   formatted using a printf-like template. The format string should
   be specified as a "format" option in the INCLUDE or SUBST
   directive. Each line of the included text is formatted and
   concatentated to create the final output. Within the format
   string, '%s' is used to represent the text.

   For example, the 'author' element below could be used to display
   details of the author of the current document.

       author:
           File:   %% file %%
           Author: %% name %%
           Date:   %% date %%

   For inclusion in an HTML document, the text can be encapsulated
   in HTML comment tags ("<!--" and "-->") using a format string:

       %% INCLUDE author
          file   = index.html
          name   = "Andy Wardley"
          date   = 19-Mar-1987
          format = "<!-- %-12s -->"
       %%

   Which produces the following output:

       <!-- File:   index.html   -->
       <!-- Author: Andy Wardley -->
       <!-- Date:   19-Mar-1987  -->

   Note that the print format is applied to each line of the
   included text. To encapsulate the element as a whole, simply
   apply the formatting outside of the INCLUDE directive:

       <!--
          %% INCLUDE author
          ...
          %%
       -->

   In these examples, the formatting is applied as if the
   replacement value/line is a character string. Any of the
   standard printf(3) format tokens can be used to coerce the value
   into a specific type.

   As mentioned in the SUBST section above, the TIME variable is
   used to represent the current system time in seconds since the
   epoch (see time(2)). The "format" option can also be employed to
   represent such values in a more user-friendly format. Any format
   string that does not contain a '%s' token is assumed to be a
   time-based value and is formatted using the time2str() function
   from the Date::Format module (distributed as part of the
   TimeDate package).

   Example:

       The date is %% TIME format="%d-%b-%y" %%

   Generates:

       The date is 19-Mar-98

   See `perldoc Date::Format' for information on the formatting
   characters available.

   The pragmatic token '%P' can be added to a format to override
   this behaviour and force the use of printf(). The '%P' token is
   otherwise ignored.

   Example:

       %% DEFINE foo=123456789  %%
       %% foo format="%d-%b-%y" %%  # "day-month-year" using time2str
       %% foo format="%d"       %%  # "day" using timestr
       %% foo format="%P%d"     %%  # decimal value using printf
       %% foo format="%s"       %%  # string value using printf

   Generates:

       29-Nov-73
       29
       123456789
       123456789

   Text that is inserted with an INCLUDE or SUBST directive can
   also be filtered. There are two default filters provided,
   'escape' which can be used to escape (prefix with a backslash
   '\') certain characters, and 'sr' which is used to perform
   simple search and replace actions. Other filters may be added
   with the FILTER option when creating the object (see the FILTER
   section in the section on "USING THE METATEXT MODULE", above).

   Like the 'format' option, output filters work on a line of text
   at a time. Any parameters required for the filter can be
   specified in parentheses after the filter name. The 'escape'
   filter expects a perl-style character class indicating the
   characters to escape. The 'sr' filter expects two parameters, a
   search pattern and a replacement string, separated by a comma.
   Note that parameters that include embedded spaces should be
   quoted. The quote characters themselves must also be escaped as
   they already form part of a quoted string (the filter text).
   (This way of representing parameters is admittedly far from
   ideal and may be improved in a future version.)

   Example:

       %% DEFINE text="Madam I'm Adam" %%
       %% SUBST  text filter="escape(['])"               %%
       %% SUBST  text filter="sr(Adam, \"Frank Bough\")" %%

   Generates:

       Madam I\'m Adam
       Madam I'm Frank Bough

   Conditional tests can be applied to INCLUDE blocks to determine
   if the block should evaluated or ignored. Variables and absolute
   values can be used and can be evaluated in the following ways:

       a == b       # a is equal to b
       a != b       # a is not equal to b
       a >  b       # a is greater than b
       a <  b       # a is less than b
       a => b       # a is greater than or equal to b
       a <= b       # a is less than or equal to b
       a =~ b       # a matches the perl regex pattern b
       a !~ b       # a does not match the perl regex pattern b
       a in b,c,d   # a appears in the list b, c, d (see DELIMITER)

   The items on the right of the evaluations can be absolute values
   or variable names which should be prefixed by a '$'. The items
   on the left of the evaluation are assumed to be variable names.
   There is no need to prefix these with a '$', but you can if you
   choose.

   The single equality, "a = b", is treated identically to a double
   equality "a == b" although the two traditionally represent
   different things (the first, an assignment, the second, a
   comparison). In this context, I consider the former usage
   confusing and would recommend use of the latter at all times.

   Variables without any comparison operator or operand are tested
   for a true/false value.

   Examples:

       %% INCLUDE foo if="name==fred"        %%
       %% INCLUDE foo if="$name==fred"       %%  # equivalent to above
       %% INCLUDE foo if="name==$goodguy"    %%
       %% INCLUDE foo if="hour > 10"         %%
       %% INCLUDE foo if="tonk =~ [Ss]pl?at" %%
       %% INCLUDE foo if="camper"            %%

   Multiple conditions can be joined using the following boolean
   operators

       a && b       # condition 'a' and 'b'
       a || b       # condition 'a' or  'b'
       a ^  b       # condition 'a' xor 'b'
       a and b      # same as "a && b" but with lower precedence
       a or  b      # same as "a || b" but with lower precedence
       a xor b      # same as "a ^  b" but with lower precedence

   Conditional equations are evaluated left to right and may
   include parentheses to explicitly set precedence.

   Examples:

       %% INCLUDE tonk
          if="hardenuf && uid in abw,wrigley"
       %%
       %% INCLUDE tapestry
          if="(girly && studly < 1) || uid == neilb"
       %%
       %% INCLUDE tapestry
          if="($girly && $studly < 1) || $uid == neilb"
       %%

   Note that the third example above is identical in meaning to the
   second, but explicitly prefixes variable names with '$'. This is
   optional for elements on the left hand side of comparison
   operators, but mandatory for those on the right that might
   otherwise be interpreted as absolute values.

 BLOCK..ENDBLOCK

   In some cases it is desirable to have a block of text available
   to be inserted via INCLUDE without having to define it in an
   external file. The BLOCK..ENDBLOCK directives allow this.

   A BLOCK directive with a unique identifier marks the start of a
   block definition. The block continues, including any valid
   MetaText directives, until an ENDBLOCK directive is found.

   A BLOCK..ENDBLOCK definition may appear anywhere in the file. It
   is in fact possible to INCLUDE the block before it has been
   defined as long as the block definition resides in the same
   file.

   Processing of a file stops when it encounters the __END__ marker
   on a line by itself. Blocks can be defined after this marker
   even though the contents of the file after __END__ are ignored
   by the processor.

       # include a block defined later
       %% INCLUDE greeting name=Prospero %%

       __END__
       %% BLOCK greeting %%
       Hello %% name %%
       %% ENDBLOCK %%

   This produces the following output:

       # include a block defined later
       Hello Prospero

   Additional variable definitions specified in an INCLUDE
   directive will be applied to blocks just as they would to
   external files.

   A BLOCK..ENDBLOCK definition that appears in the main part of a
   document (i.e. before, or in the absence of an __END__ line)
   will not appear in the processed output. A simple "print" flag
   added to the BLOCK directive overrides this behaviour, causing a
   copy of the BLOCK to appear in it's place:

       %% DEFINE name=Caliban %%

       %% BLOCK greeting print %%
       Hello %% name %%
       %% ENDBLOCK %%

       %% INCLUDE greeting name="Prospero" %%

   produces the following output:

       Hello Caliban

       Hello Prospero

   Conditions ("if" and "unless") can be applied to BLOCK
   directives, but they affect how and when the BLOCK itself is
   printed, rather than determining if the block gets defined or
   not. Conditionals have no effect on BLOCK directives that do not
   include a "print" flag.

EXTENDING METATEXT
   MetaText may be used as a base class for deriving other text
   processing modules. Any member function of a derived class can
   be called directly as a MetaText directive. See the EXECUTE
   configuration option for more details.

   Pseudo-code example:

       package MyMetaText;
       @ISA = qw( Text::MetaText );

       # define a new derived class method, get_name()
       sub get_name {
           my $self   = shift;
           my $params = shift;

           # return name from an ID hash, for example
           $self->{ PEOPLE }->{ $params->{'id'} } || 'nobody';
       }

       package main;

       # use the new derived class
       my $mmt = MyMetaText { EXECUTE => 1 };

       # process 'myfile'
       print $mmt->process('myfile');

   which, for a sample file, 'myfile':

       %% get_name id=foo %%
       %% get_name id=bar %%

   is equivalent to:

       print $mmt->get_name({ 'id' => 'foo' }), "\n";
       print $mmt->get_name({ 'id' => 'bar' }), "\n";

   Alternatively, a simple calling script can be written that
   defines functions that themselves can be called from within a
   document:

       my $mt = Text::MetaText->new( { EXECUTE => 2 } );

       print $mt->process("myfile");

       sub get_name {
           my $params = shift;
           $global_people->{ $params->{'id'} } || 'nobody';
       }

   Please note that the functionality provided by the EXECUTE
   option, and inherently, the extensibility possible by deriving
   MetaText sub-classes, relies in part on the operation of the
   AUTOLOAD method. Authors of derived MetaText classes should be
   aware of, and account for this, if re-defining the AUTOLOAD
   method.

WARNINGS AND ERRORS
   The following list indicates warning or error messages that
   MetaText can generate and their associated meanings.

   "Closing directive tag missing in %s"
       A MetaText directive was found that was not terminated
       before the end of the file. e.g. `%% INCLUDE something ...'
       The processor attempts to compensate, but check your source
       files and add any missing MAGIC tokens.

   "Invalid configuration parameter: %s"
       An invalid configuration parameter was identified in the
       hash array passed to Text::MetaText->new(). See the section
       on "USING THE METATEXT MODULE".

   "Invalid debug/error function"
       The debug or error handling routine specified for the ERROR
       or DEBUG configuration options was not a code reference. See
       the ERROR and/or DEBUG sections for more details.

   "Invalid debug option: %s"
       A token was specified for the DEBUGLEVEL configuration item
       which was invalid. See the DEBUGLEVEL section for a complete
       list of valid tokens.

   "Invalid roque option: %s"
       A token was specified for the ROGUE configuration item which
       was invalid. See the ROGUE section for a complete list of
       valid tokens.

   "Maximum recursion exceeded"
       The processed file had multiple INCLUDE directives that
       nested to a depth greater than MAXDEPTH (default: 32). Set
       MAXDEPTH higher to avoid this problem, or check your files
       for circular dependencies.

   "Missing directive keyword"
       A MetaText directive was identified that had no keyword or
       other content. e.g. `%% %%'

   "Text::MetaText->new expects a hash array reference"
       The new() method can accept a reference to a hash array as
       the first parameter which contains configuration variables
       and values. This error is generated if the parameter is not
       a hash array reference.

   "Unrecognise directive: %s"
       An internal error that should never happen. The pre-
       processor has identified a directive type that the processor
       then failed to recognise.

   "Unrecognised token: %s"
       A `%% SUBST <variable> %%' or `%% <variable> %%' directive
       was found for which there was no corresponding <variable>
       defined. This warning is only generated when the 'warn'
       token is set for the ROGUE option.

   "Unmatched parenthesis: %s"
       A conditional evaluation ("if" or "unless") for a directive
       is missing a closing parenthesis. e.g. `%% INCLUDE foobar
       if="(foo && bar || baz" %%'

   "%s: non-existant or invalid filter"
       An INCLUDE or SUBST directive included a "filter" option
       that refers to a non-existant filter. e.g. `%% INCLUDE foo
       filter=nosuchfilter() %%'

AUTHOR
   Andy Wardley <[email protected]>

   See also:

       http://www.kfs.org/~abw/
       http://www.kfs.org/~abw/perl/metatext/

   My thanks extend to the people who have used and tested
   MetaText. In particular, the members of the Peritas Online team;
   Simon Matthews, Simon Millns and Gareth Scott; who brutally
   tested the software over a period of many months and provided
   valuable feedback, ideas and of course, bug reports. I am also
   indebted to the members of the SAS Team at Canon Research Centre
   Europe Ltd; Tim O'Donoghue, Neil Bowers, Ave Wrigley, Martin
   Portman, Channing Walton and Gareth Rees; although I'm not yet
   sure why. :-)

   I welcome bug reports, enhancement suggestions, comments,
   criticisms (hopefully constructive) and patches related to
   MetaText. I would appreciate hearing from you if you find
   MetaText particularly useful or indeed if it *doesn't* do what
   you want, for whatever reason. Hopefully this will help me make
   MetaText help you more.

   It pains me to say that MetaText comes without guarantee or
   warranty of suitability for any purpose whatsoever. That doesn't
   mean it doesn't do anything good, but just that I don't want
   some scrupulous old git to sue me because they thought I implied
   it did something it doesn't. *<sigh>*

REVISION
   $Revision: 0.15 $

COPYRIGHT
   Copyright (c) 1996-1998 Andy Wardley. All Rights Reserved.

   This program is free software; you can redistribute it and/or
   modify it under the same terms as Perl itself.

SEE ALSO
   The metapage utility, the Date::Format module.