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,myArray,myHash,myTable_array, andmyTable_hash:%%%TDZ: -- beginning of The Dead Zone \documentclass[10pt,a4paper]{article} \usepackage[english]{babel} \usepackage{amsmath} \usepackage{color} \usepackage{url} \title{ChiTaRS-${}_{3.1}$-the enhanced chimeric transcripts and RNA-seq database etc...} \author{Alessandro Gorohovski, etc...} \begin{document} \maketitle %%%ENDZ: -- end of The Dead Zone 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}{% c %%%VAR: myArray l %%%ADD:% -- column "l" type will repeat as many times as myArray size, e.g. 'lll...l' lllll %%%END: } % head of table Expense item & %%%VAR: myArray %%%ADDX: & %-- eXcept 1st (0) row (record) \multicolumn{1}{c}{ %%%ADD:% -- there will be no line break 2020 %%%V:@% % there will be no line break also } %%%ADDE: -- final part of '@' variables & 2021 & 2022 & 2023 & 2024 & 2025 % All of this will be replaced until %%%END: %%%END: \\ \hline etc... \\ \hline HASH Summary %%%VAR: myHash & %%%ADD: 00000 %%%V: year0 & %%%ADD: 11111 %%%V: year1 & %%%ADD: 22222 %%%V: year2% & %%%ADD:% 33333 %%%V: year3 & 44444 & 55555 %%%END: %%%VAR: myTable_array \\ \hline %%%ADD: SPECIFY VALUE 0! %%%V:0 & %%%ADD: \multicolumn{1}{c}{ %%%ADD:% -- there will be no line break SPECIFY VALUES from 3 to last element of array! %%%V:3-% } %-- ' }' will be added to right of values } & %%%ADD:% SPECIFY VALUES 1 and 2 %%%V:1,2 & 22222 & 33333 & 44444 & 55555 %%%TDZ: -- beginning of The Dead Zone. Yes, you can use this instead of %%%END: \\ \hline \end{tabular} ... \begin{tabular}{ccc} column2 & column1 & column0 \\ \toprule %%%ENDZ: -- end of The Dead Zone %%%VAR: myTable_array & %%%ADDX:% % add " &" without line breaks ("\n"), except for the 1st SPECIFY VALUES 2, 1, and 0! %%%V: -3-% & VALUE 1 & VALUE 0 \\ %%%ADD: \midrule %%%ADD: % All of this will be replaced until %%%TDZ: (or %%%END:) ... VALUE 2 & VALUE 1 & VALUE 0 \\ \midrule ... %%%TDZ: -- beginning of The Dead Zone. \end{tabular} ... \begin{tabbing} %%%ENDZ: -- end of The Dead Zone %%%VAR: myTable_hash %%%ADDX: \\ SPECIFY VALUE 'A'! %%%V: A% \= %%%ADD:% SPECIFY VALUE 'B'! %%%V: B% \= %%%ADD:% SPECIFY VALUE 'C'! %%%V: C %%%ENDT: -- end of Template area (and myTable_hash also) \end{tabbing} etc... \end{document}Dataset to fill TeX file (see above):
my $info = { myParam => 'Blah-blah blah-blah blah-blah', myArray => [2024, 2025, 2026, 2027], myHash => {year0 => 123456, year1 => 789012, year2 => 345678, year3 => 901234}, 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 ], myTable_hash => [ # custom user variable ARRAY-HASH {A=>00, B=>01, C=>02, }, # row 0 {A=>10, B=>11, C=>12, }, # row 1 ], }; my $msg = replication( $file, $info );Ready (filled, completed) TeX file:
\documentclass[10pt,a4paper]{article} \usepackage[english]{babel} \usepackage{amsmath} \usepackage{color} \usepackage{url} \title{ChiTaRS-${}_{3.1}$-the enhanced chimeric transcripts and RNA-seq database etc...} \author{Alessandro Gorohovski, etc...} \begin{document} \maketitle Blah-blah blah-blah blah-blah %-- substitutes Variable etc... \begin{tcolorbox} \rule{0mm}{4.5em}Blah-blah blah-blah blah-blah \end{tcolorbox} \begin{tabular}{% c llll } % head of table Expense item & \multicolumn{1}{c}{2024} & \multicolumn{1}{c}{2025} & \multicolumn{1}{c}{2026} & \multicolumn{1}{c}{2027} \\ \hline etc... \\ \hline HASH Summary & 123456 & 789012 & 345678 & 901234 \\ \hline 00 & \multicolumn{1}{c}{ 03 } %-- ' }' will be added to right of values & \multicolumn{1}{c}{ 04 } %-- ' }' will be added to right of values & 01 & 02 \\ \hline 10 & \multicolumn{1}{c}{ 13 } %-- ' }' will be added to right of values & \multicolumn{1}{c}{ 14 } %-- ' }' will be added to right of values & 11 & 12 \\ \hline 20 & \multicolumn{1}{c}{ 23 } %-- ' }' will be added to right of values & \multicolumn{1}{c}{ 24 } %-- ' }' will be added to right of values & 21 & 22 \\ \hline \end{tabular} ... \begin{tabular}{ccc} column2 & column1 & column0 \\ \toprule 02 & 01 & 00 \\ \midrule 12 & 11 & 10 \\ \midrule 22 & 21 & 20 \\ \midrule \end{tabular} ... \begin{tabbing} 00 \= 01 \= 02 \\ 00 \= 01 \= 02 \end{tabbing} etc... \end{document}
A new TeX
base_filefrom the template$filefilled with data from$infowill be created in random subdirectory (its name is stored in$$variable) of current directory. File name of source$filecan be absolute, i.e. with a full path (include directories and subdirectories).base_filename is extracted (same) from source$file. Under no circumstances will source$filebe overwritten by newbase_file. - 2. Using
outdiroption: -
my $msg = replication( $file, $info, outdir => $target_dir );A new
$filewill be created in$target_dirdirectory. - 3. Using
ofileoption: -
my $msg = replication( $file, $info, ofile => $ofile );A new
$ofilewill be created.ofileoption suppresses (eliminates)outdiroption, i.e. file name of$ofilecan be absolute. Under no circumstances will source$filebe overwritten by new$ofile. - 4. Set the
$DEBUGpackage variable to enable debugging messages (global debug mode): -
$LaTeX::Replicase::DEBUG = 1;
LIMITATIONS
This module have reason only for SCALAR, REF, ARRAY, HASH, ARRAY.ARRAY, ARRAY.HASH, ARRAY.REF, ARRAY.ARRAY.ARRAY, ARRAY.HASH.ARRAY data with perl 5.10 and higher.
File and directory names and paths to them must not contain space characters.
In the names of %%%V: and %%%VAR: tags (keys and indexes), it is possible (preferably) to use only [a-zA-Z0-9_] symbols, since other symbols are currently or will be reserved in the future.
Currently, symbols: %, @, :, and / have a special purpose.
ABSTRACT
Replicase is minimalistic (ascetic) interpreter (uses only 3-4 basic control tags, like the system of 4 bases (nucleotides) and 3 codons, it is an optimal balance between diversity and stability) that can be used to process (fill) 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 conditionals (logic) and loops 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 or PostScript 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 basic "three pillars" (directives, tags):
%%%V: variable_nameis a short form of a regular (SCALAR) variable_name which replaces the text located to the left of it, in the line where it is located, e.g.Before blah, blah, \ldots blah. %%%V: myParamwill be replaced by contents of
myParamvariable. However, if there is text after this variable, it will be added to the right of its value:Before blah, blah, \ldots blah. %%%V: myParam After blah, \ldots blah.here 'After blah, \ldots blah.' will remain to the right of
myParamvalue in the line.This construct can be used as an ON or OFF switch, for example by setting
myParamto "~" (i.e. " ") or "%" the text 'After blah, \ldots blah.' will be present or absent in the finished PDF or PostScript document.If a
variable_nameends in%(i.e.variable_name%), a newline is suppressed. By default, a newline always occurs after value substitution and 'After blah, \ldots blah.' if it exists.In
variable_nameyou can use the special character "/", which denotes the "path" to the variable(s) in the passed dataset ($info) structure, e.g.%%%V: key/myParam,%%%V: key/index/myParam, etc.If this "path" to
variable_namebegins with "/", then it is absolute and the variable is searched for from the root (initial)$infostructure. Otherwise, the "path" is determined relative to the current global environment, previously established in the same way.For example, using this trick,
%%%V:/key/subkey, you can move (shift) the global environment of all subsequent (further down)%%%V:and%%%VAR:variables into the$info->{key}{subkey}area (scope). To return to the root (initial)$infoglobal environment of all variables, call%%%V: /.If this "path" ends with a regular (scalar) variable or a reference to one, then the global environment is not redefined, e.g.
%%%V: key/index/myParam, herekey/index"path" is exclusively the local environment ofmyParamvariable.%%%V:nested within the scope of%%%VAR:tag do not change the global environment, and the "/" character is not a separator in the "path". It is a normal character in thevariable_name.CONCLUSION: standalone
%%%V:tag (outside%%%VAR:scope) can be used to set the global variable lookup environment.%%%V:can be nested in an ARRAY or HASH%%%VAR:tag, but in SCALAR or REF%%%VAR:it will not work and will be discarded.There's a special
variable_name-@, which means to "use all elements of an ARRAY". Therefore, this only makes sense for ARRAY variables (see example above).Using
@for HASH variables is also acceptable. In this case, it is assumed that a key with this name exists in the hash, which stores a list (vector) of the keys of this hash in the order they are inserted into TeX template.%%%VAR: variable_nameis start of full form of regular (SCALAR) or complex (HASH, ARRAY)variable_name, preserving preceding TeX up to%%%VAR:but completely replacing everything up to first%%%END:(%%%ENDT:,%%%ENDZ:, or a new%%%VAR:, or%%%TDZ:) tag inclusive.Blah, blah, \ldots blah. %%%VAR: myParam Blah, blah, \ldots \ldots Blah, \ldots %%%END:Usually HASH and ARRAY variable_name are used in the template to create (fill) tables.
%%%VAR:tag is similar to%%%V:tag, where the variable name can be used to specify its search "path" using a special symbol, "/". However, this "path" does not affect the global environment. It only sets the local environment within the scope of%%%VAR:tag.Nested
%%%VAR:tags will not work and are treated as%%%END:tags, i.e. tags for early termination of the scope.There are three options for
%%%ENDxtags:- 1.
%%%END:is used to specify the end of%%%VAR:tag. -
BTW: if this tag is omitted and there are no further
%%%ENDT:,%%%ENDZ:,%%%VAR:, and%%%TDZ:tags, all text to the end of document will be replaced byvariable_namespecified in%%%VAR:tag. - 2.
%%%ENDZ:is used to mark the end of the%%%TDZ:tag. -
%%%TDZ:marks The Dead Zone in the template free from any tag searches. It can also be used to disable (deactivate) tags. - 3.
%%%ENDT:is used to mark the end of a template. -
It is typically applied to the bottom of a document to terminate tag searches and speed up processing. It can also be used to disable (deactivate) tags.
ATTENTION! Text (and newline) located in line with any
%%%END:,%%%ENDZ:, and%%%ENDT:tags will be discarded.- 1.
%%%TDZ:marks the start of The Dead Zone in the template free from any tag searches. This tag must start at the very beginning of the line and be single on the line.It can also be used to disable other tags.
The following tags can be located within the block limited by ARRAY and HASH %%%VAR: and any %%%ENDx, %%%TDZ:, or a new %%%VAR: tags:
%%%V: key|indexwith setting ofkey(in case of HASH%%%VAR:, i.e.%%%V: keyA,%%%V:keyB, etc.) orindex(in case ARRAY%%%VAR:, i.e.%%%V:0,%%%V:1,%%%V:2,%%%V:-7, etc.). Herekeysorindexesare columns (or positions) of the table (filled area) being created.indexcan also be specified as a comma-separated list of numbers (array indices, e.g., 1, -7, 3, 5, -9), or as a closed (0-7, 4-10), left-open (-3-), or right-open (0-) range of array indices. In this case, spaces are also not allowed.Negative values and left-open range indicate the reverse order of the array indices, i.e., counting from the end. For example, -1- means from -1,-2,-3,... to the initial element of the array (vector).
There's
@- a special name ofindexwhich means "to use all elements of an ARRAY". It's actually short for right-open range:0-. Therefore, this only makes sense for ARRAY variables.Using
@for HASH variables is also acceptable. In this case, it is assumed that a key with this name exists in the hash, which stores a list (vector) of the keys of this hash in the order they are inserted into TeX template.If a
key|indexends in%(e.g.keyA%,%%%V:0%,%%%V:@%, etc. ), a newline is suppressed. (By default, a newline always occurs after value substitution and 'After blah, ... blah.' if it exists).There are three options for
%%%ADDxtags:- 1.
%%%ADD:adds text 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, \ldotsthis text will be added here:
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, \ldotsthis text will be added here:
Tail blah, blah, \ldots.If the following
%%%V:tag is not present, then the text is output at the end of allkeysorindexes(columns) each table (filled area) row.BTW: By combining auxiliary parameters and the
deffacultative option (see below), which specifies discarding (ignoring)undefinedvalues and their associated%%%ADD:structures, you can create a logic scheme for disabling%%%ADD:tags. For example:%%%VAR: myTable \\ %%%ADD: % %%%V: head etc... \\ %%%ADD: \midrule %%%ADD: % %%%V: rule my $info = { myTable => [ {head =>'%', ... }, # 'rule' is undefined {rule =>'%', ... }, # 'head' is undefined ... ] ... }; my $msg = replication( $file, $info, def =>1 ); - 2.
%%%ADDE:is similar to%%%ADD:, but it differs in that text is added after variable specified in%%%V:tag. -
This
%%%ADDE:tag must follow immediately after%%%V:tag (i.e. there should not be%%%ADD:tag before it), otherwise it will also become a regular%%%ADD:tag, for example for the next%%%V:. - 3.
%%%ADDX:is similar to%%%ADD:for all lines (records) eXcept the first column (0) of first record (0) or after the last column of last record.
If any
%%%ADDx:ends in%(e.g.%%%ADD:%,%%%ADDE:%, or%%%ADDX:%), a newline is suppressed. (By default, a newline always occurs after adding text).- 1.
Only ONE tag can be located on ONE line of input $file (document).
Tag names must be in %%%UPPERCASE:.
SUBROUTINES
LaTeX::Replicase provides these subroutines:
replication( $file, $info [, %facultative_options ] );
tex_escape( $value [, '~'] );
replication( $file, $info [, %facultative_options ] )
Creates a new output file from the specified TeX $file, which is a template. $info HASH or ARRAY is used to fill template:
$info = { };
# or
$info = [ ];
File name of source $file can be absolute, i.e. with a full path (include directories and subdirectories). File and directory names and paths to them must not contain space characters.
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 $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
$filewill be created in$target_dirdirectory. File and directory names and paths to them must not contain space characters. ofile-
my $msg = replication( $file, $info, ofile => $ofile );A new
$ofilewill be created.ofileoption suppresses (eliminates)outdiroption, i.e. file name of$ofilecan be absolute. File and directory names and paths to them must not contain space characters. utf8-
This option specifies the template and output files' character encoding as utf8:
my $msg = replication( $file, $info, utf8 =>1 ); esc-
This option applies
tex_escape()subroutine to all incoming values to mask active TeX characters:&%$#_{}~^\.my $msg = replication( $file, $info, esc =>1 ); # or esc =>'~'BTW: if the value starts with the
%%%:tag, then this tag is removed (e.g.%%%:$\frac{12345}{67890}$is converted to$\frac{12345}{67890}$), and the value itself is not masked, it is skipped. def-
This option specifies discarding (ignoring)
undefinedvalues and associated structures (%%%ADD...), i.e. dictates that onlydefinedvalues be into account.my $msg = replication( $file, $info, def =>1 );This option is useful, for example, for creating merged cells in tables (using
\multicolumnLaTeX-command) and applies to all incoming data. Also this option can be used as an ON or OFF switch (see above). ignore-
This option specifies silently ignore undefined name|key|index of
%%%V:and%%%VAR:tags:my $msg = replication( $file, $info, ignore =>1 ); silent-
This option activates 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
$DEBUGpackage 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.
tex_escape( $value [, '~'] )
Masks (or replaces with equivalents) the active TeX characters & % $ # _ { } ^ \ to \& \% \$ \# \_ \{ \} \^{} \textbackslash in the input $value.
tex_escape( $value );
With the facultative (optional) option ~ you can additionally replace the character ~ with \texttt{\~{}}.
tex_escape( $value, '~');
If the $value starts with the %%%: tag, then this tag is removed (e.g. $value = '%%%:$\frac{12345}{67890}$' is converted to $value = '$\frac{12345}{67890}$'), and the value itself is not masked, it is skipped.
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, File::Compare, and Carp.
SEE ALSO
Perl modules that offer similar functionality:
Template::Latex, LaTeX::Easy::Templates
SUPPORT AND BUGS
You can find documentation for this module with the perldoc command.
perldoc LaTeX::Replicase
Please bug reports, comments or feature requests to: https://github.com/AlessandroGorohovski/LaTeX-Replicase
The original bug tracker can be found at: https://rt.cpan.org/Public/Dist/Display.html?Name=LaTeX-Replicase
AUTHOR
Alessandro N. Gorohovski, <an.gorohovski@gmail.com>
COPYRIGHT AND LICENSE
Copyright (C) 2010-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.