The previous example did not have any arguments, so let's
try one with an argument. The mydate package
described above is now going to be
modified so that it defines the command \monthname which
takes one argument--the number of the current month
(from 1 to 12.)
The command \today will be modified so that it
uses the month name instead of a number. The LaTeX code
in mydate.sty now looks like:
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{mydate}
\newcommand{\monthname}[1]{%
\ifcase#1
\or January%
\or February%
\or March%
\or April%
\or May%
\or June%
\or July%
\or August%
\or September%
\or October%
\or November%
\or December%
\fi}
\renewcommand{\today}{%
\number\year-\monthname{\month}-\number\day}
\endinput
LaTeX2HTML defines the array @Monthname="@Month,sort=Month,description=The
month names in the currect language are stored in this array.
Note that $Month[0] is empty, so subscripts effectively
start from 1.@Month which contains
the month names in the currently defined language, so the
&do_cmd_monthname subroutine
can use this, but first it needs to determine the
month number which is passed as the argument.
Recall
that braces are replaced by markups with unique identifiers
in the form $OPn$CP.
This means that you need to search for these identifiers
at the start of the string passed to the
&do_cmd_monthname subroutine. Rather than having to
remember the form of these
identifiers, you can use the variable $next_pair_pr_rxname=$next_pair_pr_rx,sort=nextpairprrx,description=Regular expression used to extract the group at the
start of $_ delimited by
$OPn$CP. The contents of the group is
given by $2, the unique identifier belonging to
that group is given by
$1.$next_pair_pr_rx which provides the correct regular expression, where $1
will contain the unique identifier, and $2 will
contain the text found inside the set of braces corresponding
to that identifier.
For example, suppose your LaTeX code looked something like:
\documentclass[a4paper]{article}
\usepackage{mydate}
\begin{document}
\monthname{1} is a very chilly month
in Britain.
\end{document}
then the argument passed to &do_cmd_monthname
will be the string
<#4#>1<#4#> is a very chilly month in Britain.The Perl code
s/$next_pair_pr_rx/$month=$2;''/eo;will set $month equal to $2, which in this case is simply 1. The value of the identifier in this instance is not necessary, but if you wanted to know it for some reason, you can add
$id=$1. Note that
if a match is found, the empty string '' will be
substituted, which means the substring <#4#>1<#4#> will
be removed from $_.
It is possible that the user may have omitted the braces
around the argument to the command (e.g. \monthname 1),
in which case you need to get the first character, and warn
about the missing braces. This can be done using the
&missing_bracesname=&missing_braces,sort=missingbraces,description=Generate a warning message and extract first character
from $_.&missing_braces subroutine:
unless (s/$next_pair_pr_rx/$month=$2;''/eo)
{
$month = &missing_braces;
}
or more succinctly:
$month = &missing_braces unless s/$next_pair_pr_rx/$month=$2;''/eo;So the whole subroutine should look like:
sub do_cmd_monthname{
local($_) = @_;
local($month);
$month = &missing_braces unless
s/$next_pair_pr_rx/$month=$2;''/eo;
$Month[$month] . $_;
}
The subroutine &do_cmd_today can now be modified
so that it uses the \monthname command:
sub do_cmd_today{
local($_) = @_;
local($sec,$min,$hr,$day,$month,$year) = localtime(time);
$year += 1900;
$month++;
local($id) = ++$global{'max_id'};
join('-',
$year,
"\\monthname${OP}${id}${CP}$month${OP}${id}${CP}",
$day) . $_;
}
Of course, it would be even easier to use $Month[$month]name="@Month,sort=Month,description=The
month names in the currect language are stored in this array.
Note that $Month[0] is empty, so subscripts effectively
start from 1.$Month[$month]
instead of
\\monthname${OP}${id}${CP}$month${OP}${id}${CP}
but this way illustrates the use of $OP, $CP
and $global{'max_id'}name=$global{'max_id'},sort=global,description=This
is the maximum number of unique
identifiers.$global{'max_id'}.
The basic principle can be extended to commands with
more than one argument. Each argument is dealt with in
the same way. For example, suppose you have a command called,
say \fmtdate that formats a specific date in a certain
way, then this command would need to take three arguments
representing the day, month and year. The LaTeX code
might look something like:
\newcommand{\fmtdate}[3]{#3-#2-#1}
The Perl subroutine &do_cmd_fmtdate would then
look something like:
sub do_cmd_fmtdate{
local($_) = @_;
local($day,$month,$year);
$day = &missing_braces unless
s/$next_pair_pr_rx/$day=$2;''/eo;
$month = &missing_braces unless
s/$next_pair_pr_rx/$month=$2;''/eo;
$year = &missing_braces unless
s/$next_pair_pr_rx/$year=$2;''/eo;
join('-', $year, $month, $day) . $_;
}