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} \endinputLaTeX2HTML 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) . $_; }