NAME

LaTeX::Replicase - Perl extension implementing a minimalistic engine for filling real TeX-LaTeX files that act as templates.

SYNOPSIS

Activate the module:

use LaTeX::Replicase qw( replication );

or

use LaTeX::Replicase qw(:all);

Usage examples:

1. Using replication() with default options.

The following pseudo-code extract demonstrates this:

  • Fragment of the original (source) TeX file with fillable fields myParam, myTable_array, and myTable_hash:

    SPECIFY VALUE of myParam! %%%V: myParam -- substitutes Variable
    
    etc...
    
    \begin{tcolorbox}
    
    \rule{0mm}{4.5em}%%%VAR: myParam -- substitutes Variable as well
    ...
    ... SPECIFY VALUE of myParam!
    ...
    %%%END:
    
    \end{tcolorbox}
    
    
    \begin{tabular}{ccccc}
     column0 & column1 & column2 & column3 & column4 \\
     \toprule
    
    %%%VAR: myTable_array
      %%%ADD: %add " \n" at beginning of value in the 0th column without any conditions for all rows
    %%%CASE1: \midrule
    %%%CASE1: ... % continuation of CASE1
    %%%CASE2: ...
    %%%CASE3: ...
     SPECIFY VALUE 0! %%%V:0
    
     & %%%ADD: %add " &\n" at beginning of value in the 1st column without any conditions for all rows
    %%%CASE1: ...
    %%%CASE2: ...
    SPECIFY VALUE 1! %%%V:1
    
     & %%%ADD:
    %%%CASE1: ...
    %%%CASE2: ...
    SPECIFY VALUE 2! %%%V:2
    
     & %%%ADD:
    %%%CASE1: ...
    %%%CASE2: ...
    SPECIFY VALUE 3! %%%V:3
    
     & %%%ADD:
    SPECIFY VALUE 4! %%%V:4
    
    \\%%%ADD:
    \midrule%%%ADD:
    %%%CASE5: ...
    ...
    VALUE 0 & VALUE 1 & VALUE 2 & VALUE 3 & VALUE 4 % All of this will be replaced until %%%END:
    \\
    \midrule
    ...
    %%%END:
    
    \end{tabular}
    
    ...
    \begin{tabbing}
    %%%VAR: myTable_hash
    
    %%%SKIP: \\
       SPECIFY VALUE 'A'! %%%V: A
    
     \= %%%ADD:
       SPECIFY VALUE 'B'! %%%V: B
    
     \= %%%ADD:
       SPECIFY VALUE 'C'! %%%V: C
    
     \= %%%ADD:
       SPECIFY VALUE 'D'! %%%V: D
    
     \= %%%ADD:
       SPECIFY VALUE 'E'! %%%V: E
    
    %%%END:
    \end{tabbing}
  • Data to fill TeX file (see above):

    my $info = {
        data => { # mandatory data section
          myParam => 'Blah-blah blah-blah blah-blah',
          myTable_array => [ # custom user variable ARRAY-ARRAY
            [00, 01, 02, 03, 04,], # row 0
            [10, 11, 12, 13, 14,], # row 1
            [20, 21, 22, 23, 24,], # row 2
            [30, 31, 32, 33, 34,], # row 3
          ],
          myTable_hash => [ # custom user variable ARRAY-HASH
            {A=>00, B=>01, C=>02, D=>03, E=>04,}, # row 0
            {A=>10, B=>11, C=>12, D=>13, E=>14,}, # row 1
            {A=>20, B=>21, C=>22, D=>23, E=>24,}, # row 2
            {A=>30, B=>31, C=>32, D=>33, E=>34,}, # row 3
          ],
        },
    
        cases => { # optional auxiliary data section
          myTable_array => {
            0 => { # table row 0
              3 => [1, 2], # extract from document %%%CASE1: and %%%CASE2: for 3-rd table column
              #...
            },
            2 => { # table row 2
              0 => [1, 3], # extract %%%CASE1: and %%%CASE3: for 0-th column
              1 => 2, # extract only %%%CASE2: for 1-st column
              #...
              # '' -- empty parameter (without column idx)
              '' => 5, # extract only %%%CASE5: located at the very "tail" of row
            },
          },
          myTable_hash => {
            1 => { # table row 1
              B => 1, # extract %%%CASE1: for 'B' key (1-st position)
              A => [1, 3], # extract %%%CASE1: and %%%CASE3: for 'A' key (0-th position)
              #...
            },
            0 => { # table row 0
              B => 2, # extract %%%CASE2:
              C => [1, 2], # extract %%%CASE1: and %%%CASE2: for 'C' key (2-nd position)
              #...
            },
          },
    
        },
    
    };
    
    my $msg = replication( $file, $info );

A new TeX base_file from the template $file filled with data from $info will be created in random subdirectory (its name is stored in $$ variable) of current directory. File name of source $file can be absolute, i.e. with a full path (include directories and subdirectories). base_file name is extracted (same) from source $file. Under no circumstances will source $file be overwritten by new base_file.

2. Using outdir option:
my $msg = replication( $file, $info, outdir => $target_dir );

A new $file will be created in $target_dir directory.

3. Using ofile option:
my $msg = replication( $file, $info, ofile => $ofile );

A new $ofile will be created. ofile option suppresses (eliminates) outdir option, i.e. file name of $ofile can be absolute. Under no circumstances will source $file be overwritten by new $ofile.

4. Set the $DEBUG package variable to enable debugging messages (global debug mode):
$LaTeX::Replicase::DEBUG = 1;

LIMITATIONS

This module have reason only for perl 5.10 and higher.

ABSTRACT

Replicase is minimalistic (ascetic) interpreter (uses only 6 control tags) which can be used for processing (filling) real TeX-LaTeX files that act as templates.

DESCRIPTION

This module is a Perl 5 extension implementing Replicase subroutines which processes TeX-LaTeX files, interpreting and executing built-in control directives (tags) of Replicase.

Replicase can: define and substitute variable values, execute conditional actions and capture the resulting output into a new document. Replicase was originally designed for creating programmatically configurable TeX-LaTeX documents.

Unlike other template engines, here the logic and cycles are completely separated from TeX-LaTeX document and are moved to your Perl program using this module. It's well suited for this and similar tasks, allowing you to dynamically create PDF documents that are consistent with each other, yet easily customisable.

Replicase is a standalones, safe as a TeX-LaTeX, and fast template engine with remarkable features. All markup is based on following "three pillars" (directives, tags):

  • %%%V: variable_name is a short form of a regular (SCALAR) variable_name that completely replaces the string in which it is located, e.g.

    Blah, blah, \ldots blah. %%%V: myParam

    will be completely replaced by contents of myParam variable.

    It can be nested in an ARRAY or HASH %%%VAR: tag, but in SCALAR %%%VAR: it will not work and will be discarded.

  • %%%VAR: variable_name is start of full form of regular (SCALAR) or complex (ARRAY, HASH) variable_name, preserving preceding TeX up to %%%VAR: but completely replacing everything up to first %%%END: tag inclusive.

    Blah, blah, \ldots blah. %%%VAR: myParam
    Blah, blah, \ldots
    \ldots
    
    Blah, \ldots %%%END:

    Usually ARRAY and HASH variable_name are used in the template to create (fill) tables.

    CONCLUSION: Nested %%%VAR: tags will not work and will be discarded.

  • %%%END: is used to specify the end of %%%VAR: tag. Text located in line with %%%END: will be discarded.

    BTW: If this tag is omitted, all text to the end of document will be replaced by variable_name specified in %%%VAR: tag.

The following tags can be located within the block limited by ARRAY and HASH %%%VAR: and %%%END: tags:

  • %%%V: key|index with setting of key (in case of HASH %%%VAR:, i.e. %%%V: keyA, %%%V:keyB, etc.) or index (in case ARRAY %%%VAR:, i.e. %%%V:0, %%%V:1, %%%V:2, etc.). Here keys or indexes are columns (or positions) of the table (filled area) being created.

  • %%%ADD: without any conditions adds text before (or after) all %%%CASE: tags (if exists) and before variable specified in %%%V: tag. The added text is taken from the beginning of the line to the beginning of %%%ADD: (i.e. text located on the left), e.g.

    Head blah, blah, \ldots blah. %%%ADD: Tail blah, blah, \ldots

    this text will be added: Head blah, blah, \ldots blah.

    Or, if %%%ADD: is located at the very beginning of line, then after it to the end of line (i.e. text located on the right), e.g.

    %%%ADD: Tail blah, blah, \ldots

    this text will be added: Tail blah, blah, \ldots.

    If the following %%%V: tag is not present, then the text is output at the end of all keys or indexes (columns) each table row, before (or after) text-blocks of all %%%CASE: tags (if exists).

  • %%%SKIP: similar to %%%ADD: for all lines (records) except the first column of first record or after the last column of last record (if exists).

  • %%%CASE0:, %%%CASE1:, ... %%%CASE[\d+]: conditionally adds text before variable specified in %%%V: tag. This tag is triggered if its [\d+] index is specified for the corresponding row(s) in additional settings cases hash.

    Similar to %%%ADD:, here the added text is taken from the beginning of the line to the beginning of %%%CASE[\d+]: (i.e. text located on the left) or, if %%%CASE[\d+]: is located at the very beginning of line, then after it to the end of line (i.e. text located on the right).

    There can be as many %%%CASE[\d+]: tags as you like.

    If %%%CASE[\d+]: tags within the same %%%V: have the same [\d+] index, their texts are merged.

    %%%CASE[\d+]: tags are only valid when following %%%V: tag exists and is defined in the input data.

    If there is no following %%%V: tag, text is output at the end of all keys or indexes (columns) each table row. In the additional settings cases hash these %%%CASE[\d+]: must correspond to key with a name of zero length, i.e ''.

Only ONE tag can be located on ONE line of input $file (document).

Tag names must be in %%%UPPERCASE:.

SUBROUTINES

LaTeX::Replicase provides this subroutine:

replication( $file, $info [, %facultative_options ] );

replication( $file, $info [, %facultative_options ] )

Creates a new output file from the specified TeX $file, which is a template. $info hash is used to fill template.

File name of source $file can be absolute, i.e. with a full path (include directories and subdirectories).

The output file name is extracted (the same) from the source $file. Under no circumstances will source $file be overwritten by the new one.

When replication processes a $file it identifies tags and replaces them with the result of whatever the tag represents (e.g. variable value for %%%V: or from %%%VAR: to %%%END:). Anything outside the tag(s), including newline characters, are left intact.

The following %facultative_options can be used when calling replication:

outdir:
my $msg = replication( $file, $info, outdir => $target_dir );

A new $file will be created in $target_dir directory.

ofile:
my $msg = replication( $file, $info, ofile => $ofile );

A new $ofile will be created. ofile option suppresses (eliminates) outdir option, i.e. file name of $ofile can be absolute.

utf8

This option specifies the template and output files' character encoding as utf8:

my $msg = replication( $file, $info, utf8 =>1 );
def

This option specifies discarding (ignoring) undefined values and associated structures (%%%CASEn: and %%%ADD:), i.e. take into account only defined values.

my $msg = replication( $file, $info, def =>1 );

This option is useful, for example, for creating merged cells in tables (using \multicolumn LaTeX-command). This option applies to all incoming data.

ignore

This option specifies silently ignore undefined name|key|index of %%%V: and %%%VAR: tags:

my $msg = replication( $file, $info, ignore =>1 );
silent silent mode of operation:
my $msg = replication( $file, $info, silent =>1 );
debug

This option sets local debug mode:

my $msg = replication( $file, $info, debug =>1 );
if( ! $msg ) {
  say 'Ok';
}
else {
  say for @$msg;
}

Another way is to set the $DEBUG package variable to enable debugging messages (global debug mode).

$LaTeX::Replicase::DEBUG = 1;

replication returns undef or a reference to an error (and/or debug) message(s) array.

EXPORT

LaTeX::Replicase exports nothing by default. Each of the subroutines can be exported on demand, as in

use LaTeX::Replicase qw( replication );

and the tag all exports them all:

use LaTeX::Replicase qw( :all );

DEPENDENCIES

LaTeX::Replicase is known to run under perl 5.10.0 on Linux. The distribution uses File::Basename, File::Path, and Carp.

SEE ALSO

Perl modules that offer similar functionality:

Template::Latex, LaTeX::Easy::Templates

AUTHOR

Alessandro N. Gorohovski, <an.gorohovski@gmail.com>

COPYRIGHT AND LICENSE

Copyright (C) 2025 by Alessandro N. Gorohovski

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.10.0 or, at your option, any later version of Perl 5 you may have available.