% \iffalse meta-comment
%
% Copyright (C) 2003-2024 Scott Pakin <scott+pt@pakin.org>
% --------------------------------------------------------
%
% This file may be distributed and/or modified under the conditions of
% the LaTeX Project Public License, either version 1.3c of this license
% or (at your option) any later version.  The latest version of this
% license is in:
%
%    http://www.latex-project.org/lppl.txt
%
% and version 1.3c or later is part of all distributions of LaTeX
% version 2006/05/20 or later.
%
% \fi
%
% \iffalse
%<*driver>
\ProvidesFile{perltex.dtx}
%</driver>
%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
%<package>\ProvidesPackage{perltex}
%<*package>
    [2024/12/03 v2.3 LaTeX macros for use with PerlTeX]
%</package>
%
%<*driver>
\documentclass{ltxdoc}
\makeatletter
  \def\plmac@tag{FakingBeingRunFromPerlTeX}
  \def\plmac@tofile{\jobname.topl}
  \def\plmac@fromfile{\jobname.frpl}
  \def\plmac@toflag{\jobname.tfpl}
  \def\plmac@fromflag{\jobname.ffpl}
  \def\plmac@doneflag{\jobname.dfpl}
  \def\plmac@pipe{\jobname.pipe}
\makeatother
\usepackage{perltex}
\usepackage{varioref}
\usepackage{flafter}
\usepackage{textcomp}
\usepackage{graphicx}
\usepackage{hyperref}
\hypersetup{%
  hyperindex=false,
  bookmarksopen,
  pdftitle={PerlTeX: Defining LaTeX macros in terms of Perl code},
  pdfauthor={Scott Pakin, scott+pt@pakin.org},
  pdfsubject={Using Perl to define LaTeX macros},
  pdfkeywords={programming, LaTeX, macros, Perl}
}
\EnableCrossrefs
\CodelineIndex
\RecordChanges
\setcounter{IndexColumns}{2}
\begin{document}
  \DocInput{perltex.dtx}
\end{document}
%</driver>
% \fi
%
% \CheckSum{622}
%
% \CharacterTable
%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%   Digits        \0\1\2\3\4\5\6\7\8\9
%   Exclamation   \!     Double quote  \"     Hash (number) \#
%   Dollar        \$     Percent       \%     Ampersand     \&
%   Acute accent  \'     Left paren    \(     Right paren   \)
%   Asterisk      \*     Plus          \+     Comma         \,
%   Minus         \-     Point         \.     Solidus       \/
%   Colon         \:     Semicolon     \;     Less than     \<
%   Equals        \=     Greater than  \>     Question mark \?
%   Commercial at \@     Left bracket  \[     Backslash     \\
%   Right bracket \]     Circumflex    \^     Underscore    \_
%   Grave accent  \`     Left brace    \{     Vertical bar  \|
%   Right brace   \}     Tilde         \~}
%
%
% \changes{v1.0}{2003/07/13}{Initial version}
% \changes{v1.2}{2004/10/07}{Renamed \texttt{perlmacros.sty} to
%   \texttt{perltex.sty} for consistency.}
%
% \GetFileInfo{perltex.sty}
%
% \DoNotIndex{\$, \', \(, \), \., \\, \{, \}, \^, \", \@}
% \DoNotIndex{\@empty, \@ifnextchar, \@ifundefined, \@makeother, \@ne}
% \DoNotIndex{\@permittedops}
% \DoNotIndex{\A, \active, \advance}
% \DoNotIndex{\b, \begin, \begingroup, \bgroup, \btrapped}
% \DoNotIndex{\catcode, \csname}
% \DoNotIndex{\d, \def, \documentclass}
% \DoNotIndex{\E, \edef, \egroup, \else, \end, \endcsname, \endgroup}
% \DoNotIndex{\expandafter}
% \DoNotIndex{\fi}
% \DoNotIndex{\gdef, \global}
% \DoNotIndex{\ifeof, \ifnum, \ifx, \immediate}
% \DoNotIndex{\let, \loop}
% \DoNotIndex{\makeatletter, \makeatother, \MessageBreak}
% \DoNotIndex{\n, \newcommand, \newcount, \newenvironment, \newif}
% \DoNotIndex{\newread, \newtoks, \newwrite}
% \DoNotIndex{\noexpand, \number}
% \DoNotIndex{\obeyspaces}
% \DoNotIndex{\ProcessOptions, \protect}
% \DoNotIndex{\Q}
% \DoNotIndex{\r, \relax, \repeat}
% \DoNotIndex{\s, \space, \string}
% \DoNotIndex{\TeX, \the}
% \DoNotIndex{\W}
%
% \newcommand{\indexpkg}[1]{^^A               ^^A  Index a package name
%   \index{#1=\textsf{#1} (package)}^^A
%   \index{packages>#1=\textsf{#1}}^^A
% }
% \newcommand{\pkgname}[1]{^^A                ^^A  Name of an arbitrary package
%   \textsf{#1}^^A
%   \indexpkg{#1}^^A
% }
% \newcommand{\PerlTeX}{Perl\TeX{}}           ^^A  Name of the complete system
% \newcommand{\perltex}{\texttt{perltex.pl}}  ^^A  Name of the Perl script
% \newcommand{\perlmac}{^^A                   ^^A  Name of the LaTeX package
%   \texttt{perltex.sty}^^A
%   \indexpkg{perltex}^^A
% }
% \newcommand{\noperlmac}{\texttt{noperltex.sty}} ^^A  Name of the alternate LaTeX package
% \newcommand{\XeTeX}{^^A                     ^^A  Name of the typesetting system
%   X\lower0.5ex\hbox{\kern-0.15em\reflectbox{E}}\kern-0.1667em\TeX^^A
% }
% \newcommand{\signal}[1]{^^A                 ^^A  Signal handler
%   \lowercase{\textsc{sig#1}}^^A
%   \index{SIG#1=\lowercase{\textsc{sig#1}}}^^A
% }
%
% ^^A  Typeset package options.
% \newcommand{\DescribeOption}[1]{^^A
%   \marginpar{\raggedleft\PrintDescribeEnv{#1}}}
% \newcommand{\pkgoption}[1]{^^A
%   \texttt{#1}^^A
%   \index{#1=\texttt{#1} (package option)}^^A
%   \index{package options>#1=\texttt{#1}}^^A
% }
%
%
% ^^A  Define an environment just like macro but for Perl subroutines
% \makeatletter
% \newenvironment{perlsub}{^^A
%   \begingroup
%     \catcode`\_=11
%     \def\PrintMacroName##1{\strut\MacroFont\string##1\ }^^A
%     \def\SpecialIndex@##1##2{^^A
%       \@bsphack
%       \special@index{\string##1\actualchar
%         \string\verb\quotechar*\verbatimchar##1\verbatimchar##2}^^A
%       \@esphack
%     }^^A
%     \begin{macro}^^A
% }{^^A
%     \end{macro}^^A
%   \endgroup
% }
% \makeatother
%
% ^^A  Define an environment just like macro but for Perl scalars or lists.
% \makeatletter
% \newenvironment{perlvar}{^^A
%   \begingroup
%     \catcode`\_=11
%     \def\PrintMacroName##1{\strut\MacroFont\string##1\ }^^A
%     \def\SpecialIndex@##1##2{^^A
%       \@bsphack
%       \special@index{\expandafter\@gobble\string##1\actualchar
%         \string\verb\quotechar*\verbatimchar\string##1\verbatimchar##2}^^A
%       \@esphack
%     }^^A
%     \begin{macro}^^A
% }{^^A
%     \end{macro}^^A
%   \endgroup
% }
% \makeatother
%
% \title{\PerlTeX: \\ Defining \LaTeX{} macros in terms of Perl code^^A
%   \thanks{This document corresponds to \PerlTeX~\fileversion, dated
%   \filedate.}}
% \author{Scott Pakin \\ \texttt{scott+pt@pakin.org}}
%
% \maketitle
% \sloppy
%
% \begin{abstract}
%   \PerlTeX{} is a combination Perl script (\perltex) and \LaTeXe{}
%   style file (\perlmac) that, together, give the user the ability to
%   define \LaTeX{} macros in terms of Perl code.  Once defined, a Perl
%   macro becomes indistinguishable from any other \LaTeX{} macro.
%   \PerlTeX{} thereby combines \LaTeX's typesetting power with Perl's
%   programmability.
% \end{abstract}
%
% \section{Introduction}
%
% \TeX{} is a professional-quality typesetting system.  However, its
% programming language is rather hard to use for anything but the most
% simple forms of text substitution.  Even \LaTeX, the most popular
% macro package for \TeX, does little to simplify \TeX{} programming.
%
% Perl is a general-purpose programming language whose forte is in text
% manipulation.  However, it has no support whatsoever for typesetting.
%
% \PerlTeX's goal is to bridge these two worlds.  It enables the
% construction of documents that are primarily \LaTeX-based but contain
% a modicum of Perl.  \PerlTeX{} seamlessly integrates Perl code into a
% \LaTeX{} document, enabling the user to define macros whose bodies
% consist of Perl code instead of \TeX{} and \LaTeX{} code.
%
% As an example, suppose you need to define a macro that reverses a set
% of words.  Although it sounds like it should be simple, few \LaTeX{}
% authors are sufficiently versed in the \TeX{} language to be able to
% express such a macro.  However, a word-reversal function is easy to
% express in Perl: one need only |split| a string into a list of words,
% |reverse| the list, and |join| it back together.  The following is how
% a |\reversewords| macro could be defined using \PerlTeX:
%
% \begin{verbatim}
%    \perlnewcommand{\reversewords}[1]{join " ", reverse split " ", $_[0]}
% \end{verbatim}
%
% \noindent
% Then, executing ``\texttt{\string\reversewords\string{Try doing this
% without Perl!\string}}'' in a document would produce the text ``Perl!
% without this doing Try''.  Simple, isn't it?
%
% As another example, think about how you'd write a macro in \LaTeX{} to
% extract a substring of a given string when provided with a starting
% position and a length.  Perl has an built-in |substr| function and
% \PerlTeX{} makes it easy to export this to \LaTeX:
%
% \begin{verbatim}
%    \perlnewcommand{\substr}[3]{substr $_[0], $_[1], $_[2]}
% \end{verbatim}
%
% |\substr| can then be used just like any other \LaTeX{} macro---and as
% simply as Perl's |substr| function:
%
% \bigskip
%
% \noindent|   |^^A
% \begin{tabular}{@{}l@{}}
%    |\newcommand{\str}{superlative}| \\
%    |A sample substring of ``\str'' is ``\substr{\str}{2}{4}''.| \\[1ex]
%    \multicolumn{1}{@{}c@{}}{\Huge$\Downarrow$} \\[2ex]
%    \multicolumn{1}{@{}c@{}}{A sample substring of ``superlative'' is ``perl''.}
% \end{tabular}
%
% \bigskip
%
% To present a somewhat more complex example, observe how much
% easier it is to generate a repetitive matrix using Perl code than
% ordinary \LaTeX{} commands:
%
% \begin{verbatim}
%    \perlnewcommand{\hilbertmatrix}[1]{
%      my $result = '
%    \[
%    \renewcommand{\arraystretch}{1.3}
%    ';
%      $result .= '\begin{array}{' . 'c' x $_[0] . "}\n";
%      foreach $j (0 .. $_[0]-1) {
%        my @row;
%        foreach $i (0 .. $_[0]-1) {
%          push @row, ($i+$j) ? (sprintf '\frac{1}{%d}', $i+$j+1) : '1';
%        }
%        $result .= join (' & ', @row) . " \\\\\n";
%      }
%      $result .= '\end{array}
%    \]';
%      return $result;
%    }
%
%    \hilbertmatrix{20}
% \end{verbatim}
%
% \begin{center}
% {\Huge$\Downarrow$}
% \end{center}
%
% \[
% \renewcommand{\arraystretch}{1.3}
% \begin{array}{ccccccccccccccc}
% 1 & \frac{1}{2} & \frac{1}{3} & \frac{1}{4} & \frac{1}{5} & \frac{1}{6} & \frac{1}{7} & \frac{1}{8} & \frac{1}{9} & \frac{1}{10} & \frac{1}{11} & \frac{1}{12} & \frac{1}{13} & \frac{1}{14} & \frac{1}{15} \\
% \frac{1}{2} & \frac{1}{3} & \frac{1}{4} & \frac{1}{5} & \frac{1}{6} & \frac{1}{7} & \frac{1}{8} & \frac{1}{9} & \frac{1}{10} & \frac{1}{11} & \frac{1}{12} & \frac{1}{13} & \frac{1}{14} & \frac{1}{15} & \frac{1}{16} \\
% \frac{1}{3} & \frac{1}{4} & \frac{1}{5} & \frac{1}{6} & \frac{1}{7} & \frac{1}{8} & \frac{1}{9} & \frac{1}{10} & \frac{1}{11} & \frac{1}{12} & \frac{1}{13} & \frac{1}{14} & \frac{1}{15} & \frac{1}{16} & \frac{1}{17} \\
% \frac{1}{4} & \frac{1}{5} & \frac{1}{6} & \frac{1}{7} & \frac{1}{8} & \frac{1}{9} & \frac{1}{10} & \frac{1}{11} & \frac{1}{12} & \frac{1}{13} & \frac{1}{14} & \frac{1}{15} & \frac{1}{16} & \frac{1}{17} & \frac{1}{18} \\
% \frac{1}{5} & \frac{1}{6} & \frac{1}{7} & \frac{1}{8} & \frac{1}{9} & \frac{1}{10} & \frac{1}{11} & \frac{1}{12} & \frac{1}{13} & \frac{1}{14} & \frac{1}{15} & \frac{1}{16} & \frac{1}{17} & \frac{1}{18} & \frac{1}{19} \\
% \frac{1}{6} & \frac{1}{7} & \frac{1}{8} & \frac{1}{9} & \frac{1}{10} & \frac{1}{11} & \frac{1}{12} & \frac{1}{13} & \frac{1}{14} & \frac{1}{15} & \frac{1}{16} & \frac{1}{17} & \frac{1}{18} & \frac{1}{19} & \frac{1}{20} \\
% \frac{1}{7} & \frac{1}{8} & \frac{1}{9} & \frac{1}{10} & \frac{1}{11} & \frac{1}{12} & \frac{1}{13} & \frac{1}{14} & \frac{1}{15} & \frac{1}{16} & \frac{1}{17} & \frac{1}{18} & \frac{1}{19} & \frac{1}{20} & \frac{1}{21} \\
% \frac{1}{8} & \frac{1}{9} & \frac{1}{10} & \frac{1}{11} & \frac{1}{12} & \frac{1}{13} & \frac{1}{14} & \frac{1}{15} & \frac{1}{16} & \frac{1}{17} & \frac{1}{18} & \frac{1}{19} & \frac{1}{20} & \frac{1}{21} & \frac{1}{22} \\
% \frac{1}{9} & \frac{1}{10} & \frac{1}{11} & \frac{1}{12} & \frac{1}{13} & \frac{1}{14} & \frac{1}{15} & \frac{1}{16} & \frac{1}{17} & \frac{1}{18} & \frac{1}{19} & \frac{1}{20} & \frac{1}{21} & \frac{1}{22} & \frac{1}{23} \\
% \frac{1}{10} & \frac{1}{11} & \frac{1}{12} & \frac{1}{13} & \frac{1}{14} & \frac{1}{15} & \frac{1}{16} & \frac{1}{17} & \frac{1}{18} & \frac{1}{19} & \frac{1}{20} & \frac{1}{21} & \frac{1}{22} & \frac{1}{23} & \frac{1}{24} \\
% \frac{1}{11} & \frac{1}{12} & \frac{1}{13} & \frac{1}{14} & \frac{1}{15} & \frac{1}{16} & \frac{1}{17} & \frac{1}{18} & \frac{1}{19} & \frac{1}{20} & \frac{1}{21} & \frac{1}{22} & \frac{1}{23} & \frac{1}{24} & \frac{1}{25} \\
% \frac{1}{12} & \frac{1}{13} & \frac{1}{14} & \frac{1}{15} & \frac{1}{16} & \frac{1}{17} & \frac{1}{18} & \frac{1}{19} & \frac{1}{20} & \frac{1}{21} & \frac{1}{22} & \frac{1}{23} & \frac{1}{24} & \frac{1}{25} & \frac{1}{26} \\
% \frac{1}{13} & \frac{1}{14} & \frac{1}{15} & \frac{1}{16} & \frac{1}{17} & \frac{1}{18} & \frac{1}{19} & \frac{1}{20} & \frac{1}{21} & \frac{1}{22} & \frac{1}{23} & \frac{1}{24} & \frac{1}{25} & \frac{1}{26} & \frac{1}{27} \\
% \frac{1}{14} & \frac{1}{15} & \frac{1}{16} & \frac{1}{17} & \frac{1}{18} & \frac{1}{19} & \frac{1}{20} & \frac{1}{21} & \frac{1}{22} & \frac{1}{23} & \frac{1}{24} & \frac{1}{25} & \frac{1}{26} & \frac{1}{27} & \frac{1}{28} \\
% \frac{1}{15} & \frac{1}{16} & \frac{1}{17} & \frac{1}{18} & \frac{1}{19} & \frac{1}{20} & \frac{1}{21} & \frac{1}{22} & \frac{1}{23} & \frac{1}{24} & \frac{1}{25} & \frac{1}{26} & \frac{1}{27} & \frac{1}{28} & \frac{1}{29} \\
% \end{array}
% \]
%
% \bigskip
%
% In addition to |\perlnewcommand| and |\perlrenewcommand|, \PerlTeX{}
% supports |\perlnewenvironment| and |\perlrenewenvironment| macros.
% These enable environments to be defined using Perl code.  The
% following example, a |spreadsheet| environment, generates a |tabular|
% environment plus a predefined header row.  This example would have
% been much more difficult to implement without \PerlTeX:
%
% \begin{verbatim}
% \newcounter{ssrow}
% \perlnewenvironment{spreadsheet}[1]{
%   my $cols = $_[0];
%   my $header = "A";
%   my $tabular = "\\setcounter{ssrow}{1}\n";
%   $tabular .= '\newcommand*{\rownum}{\thessrow\addtocounter{ssrow}{1}}' . "\n";
%   $tabular .= '\begin{tabular}{@{}r|*{' . $cols . '}{r}@{}}' . "\n";
%   $tabular .= '\\multicolumn{1}{@{}c}{} &' . "\n";
%   foreach (1 .. $cols) {
%     $tabular .= "\\multicolumn{1}{c";
%     $tabular .= '@{}' if $_ == $cols;
%     $tabular .= "}{" . $header++ . "}";
%     if ($_ == $cols) {
%       $tabular .= " \\\\ \\cline{2-" . ($cols+1) . "}"
%     }
%     else {
%       $tabular .= " &";
%     }
%     $tabular .= "\n";
%   }
%   return $tabular;
% }{
%   return "\\end{tabular}\n";
% }
%
% \begin{center}
%   \begin{spreadsheet}{4}
%     \rownum &  1 &  8 & 10 & 15 \\
%     \rownum & 12 & 13 &  3 &  6 \\
%     \rownum &  7 &  2 & 16 &  9 \\
%     \rownum & 14 & 11 &  5 &  4
%   \end{spreadsheet}
% \end{center}
% \end{verbatim}
%
% \begin{center}
% {\Huge$\Downarrow$}
% \end{center}
%
% \DeleteShortVerb{\|}
% \begin{center}
%   \begin{tabular}{@{}r|*{4}{r}@{}}
%     \multicolumn{1}{@{}c}{} &
%     \multicolumn{1}{c}{A} &
%     \multicolumn{1}{c}{B} &
%     \multicolumn{1}{c}{C} &
%     \multicolumn{1}{c@{}}{D} \\ \cline{2-5}
%     1 &  1 &  8 & 10 & 15 \\
%     2 & 12 & 13 &  3 &  6 \\
%     3 &  7 &  2 & 16 &  9 \\
%     4 & 14 & 11 &  5 &  4
%   \end{tabular}
% \end{center}
% \MakeShortVerb{\|}
%
%
% \section{Usage}
%
% There are two components to using \PerlTeX\@.  First, documents must
% include a ``|\usepackage{perltex}|'' line in their preamble in
% order to define |\perlnewcommand|, |\perlrenewcommand|,
% |\perlnewenvironment|, and |\perlrenewenvironment|.  Second, \LaTeX{}
% documents must be compiled using the \perltex{} wrapper script.
%
% \subsection{Defining and redefining Perl macros}
%
% \DescribeMacro{\perlnewcommand}
% \DescribeMacro{\perlrenewcommand}
% \DescribeMacro{\perlnewenvironment}
% \DescribeMacro{\perlrenewenvironment}
% \DescribeMacro{\perldo}
% \perlmac{} defines five macros: |\perlnewcommand|,
% |\perlrenewcommand|, |\perlnewenvironment|, |\perlrenewenvironment|,
% and |\perldo|.  The first four of these behave exactly like their
% \LaTeXe{} counterparts---|\newcommand|, |\renewcommand|,
% |\newenvironment|, and |\renewenvironment|---except that the macro
% body consists of Perl code that dynamically generates \LaTeX{} code.
% \perlmac{} even includes support for optional arguments and the
% starred forms of its commands (i.e.~|\perlnewcommand*|,
% |\perlrenewcommand*|, |\perlnewenvironment*|, and
% |\perlrenewenvironment*|).  |\perldo| immediately executes a block of
% Perl code without (re)defining any macros or environments.
%
% A \PerlTeX-defined macro or environments is converted to a Perl
% subroutine named after the macro/environment but beginning with
% ``|latex_|''.  For example, a \PerlTeX-defined \LaTeX{} macro called
% |\myMacro| internally produces a Perl subroutine called
% |latex_myMacro|.  Macro arguments are converted to subroutine
% arguments.  A \LaTeX{} macro's |#1| argument is referred to as |$_[0]|
% in Perl; |#2| is referred to as |$_[1]|; and so forth.
%
% Any valid Perl code can be used in the body of a macro.  However,
% \PerlTeX{} executes the Perl code within a secure sandbox.  This means
% that potentially harmful Perl operations, such as |unlink|, |rmdir|,
% and |system| will result in a run-time error.  (It is possible to
% disable the safety checks, however, as is explained in
% Section~\ref{sec:perltex-man}.)  Having a secure sandbox implies that
% it is safe to build \PerlTeX{} documents written by other people
% without worrying about what they may do to your computer system.
%
% A single sandbox is used for the entire |latex| run.  This means that
% multiple macros defined by |\perlnewcommand| can invoke each other.
% It also means that global variables persist across macro calls:
%
% \bigskip
%
% \noindent|   |^^A
% \begin{tabular}{@{}l@{}}
%    |\perlnewcommand{\setX}[1]{$x = $_[0]; return ""}| \\
%    |\perlnewcommand{\getX}{'$x$ was set to ' . $x . '.'}| \\
%    |\setX{123}| \\
%    |\getX| \\
%    |\setX{456}| \\
%    |\getX| \\
%    |\perldo{$x = 789}| \\
%    |\getX| \\[1ex]
%    \multicolumn{1}{@{}c@{}}{\Huge$\Downarrow$} \\[2ex]
%    \multicolumn{1}{@{}c@{}}{^^A
%      $x$ was set to 123.  $x$ was set to 456.  $x$ was set to 789.^^A
%    } \\
% \end{tabular}
%
% \bigskip
%
% Macro arguments are expanded by \LaTeX{} before being passed to Perl.
% Consider the following macro definition, which wraps its argument
% within |\begin{verbatim*}|\dots\linebreak[0]|\end{verbatim*}|:
%
% \begin{verbatim}
%     \perlnewcommand{\verbit}[1]{
%       "\\begin{verbatim*}\n$_[0]\n\\end{verbatim*}\n"
%     }
% \end{verbatim}
%
% \noindent
% An invocation of
% ``|\verbit{\TeX}|'' would therefore typeset the \emph{expansion} of
% ``|\TeX|'', namely ``|T\kern| |-.1667em\lower| |.5ex\hbox| |{E}\kern|
% |-.125emX\spacefactor| |\@m|'', which might be a bit unexpected.  The
% solution is to use |\noexpand|:
% |\verbit{\noexpand\TeX}|~$\Rightarrow$ |\TeX|\@.  ``Robust'' macros as
% well as |\begin| and |\end| are implicitly preceded by |\noexpand|.
%
%
% \subsection{Making \perltex\ optional}
% \label{sec:perltex-opt}
%
% Normally, \perlmac\ issues a \texttt{Document must be compiled using
%   perltex} error if a document specifies |\usepackage{perltex}| but is
% not compiled using \perltex.  However, sometimes \PerlTeX\ may be
% needed merely to enhance a document's formatting without being
% mandatory for compiling the document.  For such cases, the
% \DescribeOption{optional}
% \pkgoption{optional} package option instructs \perlmac\ only to note
% that \texttt{Document was compiled without using the perltex script}
% without aborting the compilation.
% \DescribeMacro{\ifperl}
% The author can then use the |\ifperl| macro to test if \perltex\ is
% being used and, if not, provide alternative definitions for macros and
% environments defined with |\perlnewcommand| and |\perlnewenvironment|.
%
% See Section~\ref{sec:complete-example} for a large \PerlTeX\ example
% that uses \pkgoption{optional} and |\ifperl| to define an environment
% one way if \perltex\ is detected and another way if not.  The text
% preceding the example also shows how to enable a document to compile
% even if \perlmac\ is not even installed.
%
%
% \subsection{Invoking \perltex}
% \label{sec:perltex-man}
%
% The following pages reproduce the \perltex{} program documentation.
% Key parts of the documentation are excerpted when \perltex{} is
% invoked with the |--help| option.  The various Perl
% |pod2|\meta{something} tools can be used to generate the complete
% program documentation in a variety of formats such as \LaTeX, HTML,
% plain text, or Unix man-page format.  For example, the following
% command is the recommended way to produce a Unix man page from
% \perltex:
%
% \enlargethispage{4ex}
% \begin{verbatim}
%   pod2man --center=" " --release=" " perltex.pl > perltex.1
% \end{verbatim}
%
% \clearpage
% \begingroup
% \def\index#1{}
% \def\section#1{}
% \let\subsection=\subsubsection
%
% ^^A  ***************************************************************
% ^^A  * The following was generated using pod2latex and touched up  *
% ^^A  * slightly to make it better match the rest of this document. *
% ^^A  ***************************************************************
%
% \def\C++{{\rm C\kern-.05em\raise.3ex\hbox{\footnotesize ++}}}
% \def\underscore{\leavevmode\kern.04em\vbox{\hrule width 0.4em height 0.3pt}}
% \setlength{\parindent}{0pt}
%
% \section{PERLTEX.PL}%
% \index{PERLTEX.PL}
%
% \subsection*{NAME}
% perltex --- enable \LaTeX{} macros to be defined in terms of Perl code
%
% \subsection*{SYNOPSIS}
% perltex
% [\textbf{--help}]
% [\textbf{--latex}=\textit{program}]
% [\textbf{--}[\textbf{no}]\textbf{safe}]
% [\textbf{--permit}=\textit{feature}]
% [\textbf{--makesty}]
% [\textit{latex options}]
%
% \subsection*{DESCRIPTION}
% \LaTeX---through the underlying \TeX{} typesetting system---produces
% beautifully typeset documents but has a macro language that is
% difficult to program.  In particular, support for complex string
% manipulation is largely lacking.  Perl is a popular general-purpose
% programming language whose forte is string manipulation.  However, it
% has no typesetting capabilities whatsoever.
%
% \bigskip
%
% Clearly, Perl's programmability could complement \LaTeX's typesetting
% strengths.  \textbf{perltex} is the tool that enables a symbiosis
% between the two systems.  All a user needs to do is compile a \LaTeX\
% document using \textbf{perltex} instead of \textbf{latex}.
% (\textbf{perltex} is actually a wrapper for \textbf{latex}, so no
% \textbf{latex} functionality is lost.)  If the document includes a
% \texttt{\string\usepackage\{perltex\}} in its preamble, then
% \texttt{\string\perlnewcommand} and \texttt{\string\perlrenewcommand}
% macros will be made available.  These behave just like \LaTeX's
% \texttt{\string\newcommand} and \texttt{\string\renewcommand} except
% that the macro body contains Perl code instead of \LaTeX\ code.
%
% \subsection*{OPTIONS}%
% \index{OPTIONS}
%
% {\bf perltex} accepts the following command-line options:
%
% \begin{description}
%
%
% \item[{\textbf{-{}-help}}] \mbox{}
%
% Display basic usage information.
%
%
% \item[{\textbf{-{}-latex}=\textit{program}}] \mbox{}
%
% Specify a program to use instead of \textbf{latex}.  For example,
% \texttt{--latex=pdflatex} would typeset the given document using
% \textbf{pdflatex} instead of ordinary \textbf{latex}.
%
%
% \item[{\textbf{-{}-}[\textbf{no}]\textbf{safe}}] \mbox{}
%
% Enable or disable sandboxing.  With the default of \textbf{-{}-safe},
% \textbf{perltex} executes the code from a
% \texttt{\string\perlnewcommand} or \texttt{\string\perlrenewcommand}
% macro within a protected environment that prohibits ``unsafe''
% operations such as accessing files or executing external programs.
% Specifying \textbf{-{}-nosafe} gives the \LaTeX\ document \textit{carte
% blanche} to execute any arbitrary Perl code, including that which can
% harm the user's files.  See \emph{Safe} for more information.
%
% \item[{\textbf{-{}-permit}=\textit{feature}}] \mbox{}
%
% Permit particular Perl operations to be performed.  The
% \textbf{-{}-permit} option, which can be specified more than once on
% the command line, enables finer-grained control over the
% \textbf{perltex} sandbox.  See \emph{Opcode} for more information.
%
%
% \item[{\textbf{-{}-makesty}}] \mbox{}
%
% Generate a \LaTeX\ style file called \emph{noperltex.sty}.  Replacing
% the document's \texttt{\string\usepackage\{perltex\}} line with
% \texttt{\string\usepackage\{noperltex\}} produces the same output
% but does not require \PerlTeX, making the document suitable for
% distribution to people who do not have \PerlTeX\ installed.  The
% disadvantage is that \emph{noperltex.sty} is specific to the document
% that produced it.  Any changes to the document's \PerlTeX\ macro
% definitions or macro invocations necessitates rerunning
% \textbf{perltex} with the \textbf{-{}-makesty} option.
%
% \end{description}
%
% These options are then followed by whatever options are normally
% passed to \textbf{latex} (or whatever program was specified with
% \texttt{--latex}), including, for instance, the name of the
% \emph{.tex} file to compile.
%
% \subsection*{EXAMPLES}
%
% In its simplest form, \textbf{perltex} is run just like \textbf{latex}:
%
% \begin{verbatim}
%     perltex myfile.tex
% \end{verbatim}
%
%
% To use \textbf{pdflatex} instead of regular \textbf{latex}, use the
% \textbf{-{}-latex} option:
%
% \begin{verbatim}
%     perltex --latex=pdflatex myfile.tex
% \end{verbatim}
%
%
% If \LaTeX\ gives a ``\texttt{trapped by operation mask}'' error and
% you trust the \emph{.tex} file you're trying to compile not to execute
% malicious Perl code (e.g., because you wrote it yourself), you can
% disable \textbf{perltex}'s safety mechansisms with
% \textbf{-{}-nosafe}:
%
% \begin{verbatim}
%     perltex --nosafe myfile.tex
% \end{verbatim}
%
%
% The following command gives documents only \textbf{perltex}'s default
% permissions (\texttt{:browse}) plus the ability to open files and invoke the
% \texttt{time} command:
%
% \begin{verbatim}
%     perltex --permit=:browse --permit=:filesys_open
%       --permit=time myfile.tex
% \end{verbatim}
%
%
% \subsection*{ENVIRONMENT}
%
% \textbf{perltex} honors the following environment variables:
%
% \begin{description}
%
% \item[{PERLTEX}] \mbox{}
%
% Specify the filename of the \LaTeX\ compiler.  The \LaTeX\ compiler
% defaults to ``\texttt{latex}''.  The \texttt{PERLTEX} environment
% variable overrides this default, and the \textbf{-{}-latex}
% command-line option (see \textsf{OPTIONS}) overrides that.
%
% \end{description}
%
%
% \subsection*{FILES}
%
% While compiling \emph{jobname.tex}, \textbf{perltex} makes use of the
% following files:
%
% \begin{description}
%
% \item[{\emph{jobname.lgpl}}] \mbox{}
%
% log file written by Perl; helpful for debugging Perl macros
%
%
% \item[{\emph{jobname.topl}}] \mbox{}
%
% information sent from \LaTeX\ to Perl
%
%
% \item[{\emph{jobname.frpl}}] \mbox{}
%
% information sent from Perl to \LaTeX\
%
%
% \item[{\emph{jobname.tfpl}}] \mbox{}
%
% ``flag'' file whose existence indicates that \emph{jobname.topl} contains
% valid data
%
%
% \item[{\emph{jobname.ffpl}}] \mbox{}
%
% ``flag'' file whose existence indicates that \emph{jobname.frpl} contains
% valid data
%
%
% \item[{\emph{jobname.dfpl}}] \mbox{}
%
% ``flag'' file whose existence indicates that \emph{jobname.ffpl} has been
% deleted
%
%
% \item[{\emph{noperltex-\#.tex}}] \mbox{}
%
% file generated by \emph{noperltex.sty} for each \PerlTeX\ macro invocation
%
% \end{description}
%
%
% \subsection*{NOTES}
%
% \textbf{perltex}'s sandbox defaults to what \emph{Opcode} calls
% ``\texttt{:browse}''.
%
%
% \subsection*{SEE ALSO}
%
% latex(1), pdflatex(1), perl(1), Safe(3pm), Opcode(3pm)
%
%
% \subsection*{AUTHOR}
%
% Scott Pakin, \textit{scott+pt@pakin.org}
%
%
% ^^A  ***********************************
% ^^A  * End of generated pod2latex text *
% ^^A  ***********************************
% \endgroup
% \clearpage
%
%
% \subsection{A large, complete example}
% \label{sec:complete-example}
%
% Suppose we want to define a |linkwords| environment that exhibits the
% following characteristics:
%
% \begin{enumerate}
%   \item All words that appear within the environment's body are
%     automatically hyperlinked to a given URL that incorporates the
%     lowercase version of the word somewhere within that URL\@.
%
%   \item The environment accepts an optional list of stop~words that
%     should not be hyperlinked.
%
%   \item Paragraph breaks, nested environments, and other
%     \LaTeX\ markup are allowed within the environment's body.
% \end{enumerate}
%
% Because of the reliance on text manipulation (parsing the
% environment's body into words, comparing each word against the list of
% stop~words, distinguishing between text and \LaTeX\ markup, etc.),
% these requirements would be difficult to meet without \PerlTeX\@.
%
% We use three packages to help define the |linkwords| environment:
% \pkgname{perltex} for text manipulation, \pkgname{hyperref} for
% creating hyperlinks, and \pkgname{environ} for gathering up the body
% of an environment and passing it as an argument to a macro.  Most of
% the work is performed by the \PerlTeX\ macro |\dolinkwords|, which
% takes three arguments: a URL template that contains ``|\%s|'' as a
% placeholder for a word from the text, a mandatory but possibly empty
% space-separated list of lowercase stop~words, and the input text to
% process.  |\dolinkwords| first replaces all sequences of the form
% |\|\meta{letters}, |\begin{|\meta{letters}|}|, or
% |\end{|\meta{letters}|}| with dummy alphanumerics but remembers which
% dummy sequence corresponds with each original \LaTeX\ sequence.  The
% macro then iterates over each word in the input text, formatting each
% non-stop-word using the URL template.  Contractions (words containing
% apostrophes) are ignored.  Finally, |\dolinkwords| replaces the dummy
% sequences with the corresponding \LaTeX\ text and returns the result.
%
% The |linkwords| environment itself is defined using the |\NewEnviron|
% macro from the \pkgname{environ} package.  With |\NewEnviron|'s help,
% |linkwords| accumulates its body into a |\BODY| macro and passes that
% plus the URL template and the optional list of stop~words to
% |\dolinkwords|.
%
% As an added bonus,
% |\ifperl|\dots\linebreak[0]|\else|\dots\linebreak[0]|\fi| is used to
% surround the definition of the |\dolinkwords| macro and |linkwords|
% environment.  If the document is not run through \perltex, |linkwords|
% is defined as a do-nothing environment that simply typesets its body
% as~is.  Note that \perlmac\ is loaded with the \pkgoption{optional}
% option to indicate that the document can compile without \perltex.
% However, the user still needs \perlmac\ to avoid getting a
% \texttt{File `perltex.sty' not found} error from \LaTeX\@.  To produce
% a document that can compile even without \perlmac\ installed, replace
% the |\usepackage[optional]{perltex}| line with the following
% \LaTeX\ code:
%
% \begin{samepage}
% \begin{verbatim}
%    \IfFileExists{perltex.sty}
%                 {\usepackage[optional]{perltex}}
%                 {\newif\ifperl}
% \end{verbatim}
% \end{samepage}
%
% A complete \LaTeX\ document is presented below.  This document, which
% includes the definition and a use of the |linkwords| environment, can be
% extracted from the \PerlTeX\ source code into a file called
% |example.tex| by running
%
% \begin{verbatim}
%    tex perltex.ins
% \end{verbatim}
%
% In the following listing, line numbers are suffixed with ``X'' to
% distinguish them from line numbers associated with \PerlTeX's source
% code.
%
% \bigskip
%
% ^^A  We want the doc package to number and index the lines in our
% ^^A  code listing, but we want to keep line numbers and index entries
% ^^A  distinct from those of the PerlTeX package code.  The following
% ^^A  machinations temporarily append an "X" to line numbers in the
% ^^A  code listing and in the index.
% \makeatletter
% \let\theOldCodelineNo=\theCodelineNo
% \def\theCodelineNo{\reset@font\scriptsize \arabic{CodelineNo}X}
% \def\appendX#1{#1X}
% \def\codeline@wrindex@ex#1{\if@filesw
%   \immediate\write\@indexfile
%   {\string\indexentry{#1\encapchar appendX}^^A
%   {\number\c@CodelineNo}}\fi}
% \ifcodeline@index
%   \let\special@index=\codeline@wrindex@ex
% \fi
% \makeatother
% \iffalse
%<*example>
% \fi
%
%    \begin{macrocode}
\documentclass{article}
\usepackage[optional]{perltex}
\usepackage{environ}
\usepackage{hyperref}

\ifperl

  \perlnewcommand{\dolinkwords}[3]{
      # Preprocess our arguments.
      $url = $_[0];
      $url =~ s/\\\%s/\%s/g;
      %stopwords = map {lc $_ => 1} split " ", $_[1];
      $stopwords{""} = 1;
      $text = $_[2];

      # Replace LaTeX code in the text with placeholders.
      $placeholder = "ABCxyz123";
      %substs = ();
      $replace = sub {$substs{$placeholder} = $_[0]; $placeholder++};
      $text =~ s/\\(begin|end)\s+\{[a-z]+\}/$replace->($&)/gse;
      $text =~ s/\\[a-z]+/$replace->($&)/gse;

      # Hyperlink each word that's not in the stop list.
      $newtext = "";
      foreach $word (split /((?<=[-\A\s])[\'a-z]+\b)/i, $text) {
          $lcword = lc $word;
          if (defined $stopwords{$lcword} || $lcword =~ /[^a-z]/) {
              $newtext .= $word;
          }
          else {
              $newtext .= sprintf "\\href{$url}{%s}", $lcword, $word;
          }
      }

      # Restore original text from placeholders and return the new text.
      while (($tag, $orig) = each %substs) {
          $newtext =~ s/\Q$tag\E/$orig/gs;
      }
      return $newtext;
  }

  \NewEnviron{linkwords}[2][]{\dolinkwords{#2}{#1}{\BODY}}{}

\else

  \newenvironment{linkwords}[2][]{}{}

\fi

\begin{document}

\newcommand{\stopwords}{a an the of in am and or but i we me you us them}

\begin{linkwords}[\stopwords]{http://www.google.com/search?q=define:\%s}
\begin{verse}
  I'm very good at integral and differential calculus; \\
  I know the scientific names of beings animalculous:  \\
  In short, in matters vegetable, animal, and mineral, \\
  I am the very model of a modern Major-General.
\end{verse}
\end{linkwords}

\end{document}
%    \end{macrocode}
%
% \iffalse
%</example>
% \fi
% \makeatletter
% \ifcodeline@index
%   \let\special@index=\codeline@wrindex
% \fi
% \let\theCodelineNo=\theOldCodelineNo
% \makeatother
%
%
% \StopEventually{^^A
%   \section{License agreement}
%   \label{sec:license}
%
%   Copyright \textcopyright{} 2003--2024 Scott Pakin \texttt{<scott+pt@pakin.org>}
%
%   \providecommand{\url}[1]{\texttt{##1}}
%
%   \bigskip
%   \noindent
%   These files may be distributed and/or modified under the conditions of
%   the \LaTeX{} Project Public License, either version~1.3c of this
%   license or (at your option) any later version.  The latest version of
%   this license is in \url{http://www.latex-project.org/lppl.txt} and
%   version~1.3c or later is part of all distributions of \LaTeX{} version
%   2006/05/20 or later.
%
%
%   \section*{Acknowledgments}
%   \label{sec:acknowledgments}
%
%   Thanks to Andrew Mertz for writing the first draft of the code that
%   produces the \PerlTeX-free \noperlmac\ style file and for testing the
%   final draft; to Andrei Alexandrescu for providing a few bug fixes; to
%   Nick Andrewes for identifying and helping diagnose a problem running
%   \PerlTeX\ with \XeTeX\ and to Jonathan Kew for suggesting a
%   workaround; to Linus K\"allberg for reporting and helping diagnose
%   some problems with running \PerlTeX\ on Windows; and to Ulrike Fischer
%   for reporting and helping correct a bug encountered when using
%   \noperlmac\ with newer versions of \LaTeX\@.  Also, thanks to the many
%   people who have sent me fan mail or submitted bug reports,
%   documentation corrections, or feature requests.  (The
%   \texttt{\string\perldo} macro and the \texttt{--makesty} option were
%   particularly popular requests.)
%
%   \PrintChanges
%   \PrintIndex
% }
%
% \section{Implementation}
% \label{sec:implementation}
%
% Users interested only in \emph{using} \PerlTeX{} can skip
% Section~\ref{sec:implementation}, which presents the complete
% \PerlTeX{} source code.  This section should be of interest primarily
% to those who wish to extend \PerlTeX{} or modify it to use a language
% other than Perl.
%
% Section~\ref{sec:implementation} is split into two main parts.
% Section~\ref{sec:perlmacros} presents the source code for \perlmac,
% the \LaTeX{} side of \PerlTeX, and Section~\ref{sec:perltex} presents
% the source code for \perltex, the Perl side of \PerlTeX\@.
% \makeatletter
% \@ifundefined{perlmaclines}{}{^^A
%   \newcount\perltex@lines
%   \perltex@lines=\perltexlines
%   \advance\perltex@lines by -\perlmaclines
%   In toto, \PerlTeX{} consists of a relatively small amount of code.
%   \perlmac{} is only \perlmaclines{} lines of \LaTeX{} and \perltex{}
%   is only \the\perltex@lines{} lines of Perl.
% }
% \makeatother
% \perltex{} is fairly straightforward Perl code and shouldn't be too
% difficult to understand by anyone comfortable with Perl programming.
% \perlmac, in contrast, contains a bit of \LaTeX{} trickery and is
% probably impenetrable to anyone who hasn't already tried his hand at
% \LaTeX{} programming.  Fortunately for the reader, the code is
% profusely commented so the aspiring \LaTeX{} guru may yet learn
% something from it.
%
% After documenting the \perlmac{} and \perltex{} source code, a few
% suggestions are provided for porting \PerlTeX{} to use a backend
% language other than Perl (Section~\ref{sec:porting}).
%
% \subsection{\perlmac}
% \label{sec:perlmacros}
%
% \iffalse
%<*package>
% \fi
%
% Although I've written a number of \LaTeX{} packages, \perlmac{} was
% the most challenging to date.  The key things I needed to learn how to
% do include the following:
%
% \begin{enumerate}
%   \item storing brace-matched---but otherwise not valid \LaTeX---code
%   for later use
%
%   \item iterating over a macro's arguments
% \end{enumerate}
%
% Storing non-\LaTeX{} code in a variable involves beginning a group in
% an argumentless macro, fiddling with category codes, using
% |\afterassignment| to specify a continuation function, and storing the
% subsequent brace-delimited tokens in the input stream into a token
% register.  The continuation function, which also takes no arguments,
% ends the group begun in the first function and proceeds using the
% correctly |\catcode|d token register.  This technique appears in
% |\plmac@haveargs| and |\plmac@havecode| and in a simpler form
% (i.e.,~without the need for storing the argument) in
% |\plmac@write@perl| and |\plmac@write@perl@i|.
%
% Iterating over a macro's arguments is hindered by \TeX's requirement
% that ``|#|'' be followed by a number or another ``|#|''.  The
% technique I discovered (which is used by the Texinfo source code) is
% first to |\let| a variable be |\relax|, thereby making it
% unexpandable, then to define a macro that uses that variable followed
% by a loop variable, and finally to expand the loop variable and |\let|
% the |\relax|ed variable be ``|#|'' right before invoking the macro.
% This technique appears in |\plmac@havecode|.
%
% I hope you find reading the \perlmac{} source code instructive.
% Writing it certainly was.
%
%
% \subsubsection{Package initialization}
% \label{sec:package-init}
%
% \begin{macro}{\ifplmac@required}
% \begin{macro}{\plmac@requiredtrue}
% \begin{macro}{\plmac@requiredfalse}
% The |optional| package option lets an author specify that the document
% can be built successfully even without \PerlTeX\@.  Typically, this
% means that the document uses |\ifperl| to help define
% reduced-functionality equivalents of any document-defined
% \PerlTeX\ macros and environments.  When |optional| is not specified,
% \perlmac\ issues an error message if the document is compiled without
% using \perltex.  When |optional| is specified, \perlmac\ suppresses
% the error message.
% \changes{v1.8}{2009/03/26}{Introduced an \texttt{optional} package
%   option to suppress the ``must be compiled using perltex'' error
%   message}
%    \begin{macrocode}
\newif\ifplmac@required
\plmac@requiredtrue
\DeclareOption{optional}{\plmac@requiredfalse}
\ProcessOptions\relax
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \PerlTeX{} defines six macros that are used for communication between
% Perl and \LaTeX\@.  |\plmac@tag| is a string of characters that should
% never occur within one of the user's macro names, macro arguments, or
% macro bodies.  \perltex{} therefore defines |\plmac@tag| as a long
% string of random uppercase letters.  |\plmac@tofile| is the name of a
% file used for communication from \LaTeX{} to Perl.  |\plmac@fromfile|
% is the name of a file used for communication from Perl to \LaTeX.
% |\plmac@toflag| signals that |\plmac@tofile| can be read safely.
% |\plmac@fromflag| signals that |\plmac@fromfile| can be read safely.
% |\plmac@doneflag| signals that |\plmac@fromflag| has been deleted.
% Table~\ref{tbl:variables} lists all of these variables along with the
% value assigned to each by \perltex.
%
% \begin{table}[htbp]
%   \centering
%   \caption{Variables used for communication between Perl and \LaTeX}
%   \label{tbl:variables}
%   \begin{tabular}{@{}lll@{}}
%     \hline
%     Variable & Purpose & \perltex{} assignment \\
%     \hline
%
%     |\plmac@tag| & |\plmac@tofile| field separator &
%     (20 random letters) \\
%
%     |\plmac@tofile| & \LaTeX{} $\rightarrow$ Perl communication &
%     |\jobname.topl| \\
%
%     |\plmac@fromfile| & Perl $\rightarrow$ \LaTeX{} communication &
%     |\jobname.frpl| \\
%
%     |\plmac@toflag| & |\plmac@tofile| synchronization &
%     |\jobname.tfpl| \\
%
%     |\plmac@fromflag| & |\plmac@fromfile| synchronization &
%     |\jobname.ffpl| \\
%
%     |\plmac@doneflag| & |\plmac@fromflag| synchronization &
%     |\jobname.dfpl| \\
%
%     \hline
%   \end{tabular}
% \end{table}
%
% \begin{macro}{\ifperl}
% \begin{macro}{\perltrue}
% \begin{macro}{\perlfalse}
% The following block of code checks the existence of each of the
% variables listed in Table~\ref{tbl:variables} plus |\plmac@pipe|, a
% Unix named pipe used for to improve performance.  If any variable is
% not defined, \perlmac{} gives an error message and---as we shall see
% on page~\pageref{page:define-dummies}---defines dummy versions of
% |\perl|[|re|]|newcommand| and |\perl|[|re|]|newenvironment|.
% \changes{v2.2}{2019/09/14}{Let-bind \cs{plmac@tag} to \cs{relax} if
%   \cs{plmac@tag} is undefined.  This corrects a problem when
%   \noexpand\texttt{noperltex} is used with newer versions of
%   \noexpand\LaTeX}
%    \begin{macrocode}
\newif\ifperl
\perltrue
\@ifundefined{plmac@tag}{\perlfalse\let\plmac@tag=\relax}{}
\@ifundefined{plmac@tofile}{\perlfalse}{}
\@ifundefined{plmac@fromfile}{\perlfalse}{}
\@ifundefined{plmac@toflag}{\perlfalse}{}
\@ifundefined{plmac@fromflag}{\perlfalse}{}
\@ifundefined{plmac@doneflag}{\perlfalse}{}
\@ifundefined{plmac@pipe}{\perlfalse}{}
\ifperl
\else
  \ifplmac@required
    \PackageError{perltex}{Document must be compiled using perltex}
      {Instead of compiling your document directly with latex, you need
       to\MessageBreak use the perltex script.  \space perltex sets up
       a variety of macros needed by\MessageBreak the perltex
       package as well as a listener process needed for\MessageBreak
       communication between LaTeX and Perl.}
    \else
      \bgroup
        \obeyspaces
        \typeout{perltex: Document was compiled without using the perltex script;}
        \typeout{         it may not print as desired.}
      \egroup
  \fi
\fi
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \subsubsection{Defining Perl macros}
% \label{sec:perl-mac}
%
% \PerlTeX{} defines five macros intended to be called by the author.
% Section~\ref{sec:perl-mac} details the implementation of two of them:
% |\perlnewcommand| and |\perlrenewcommand|.
% (Section~\ref{sec:perl-env} details the implementation of the next
% two, |\perlnewenvironment| and |\perlrenewenvironment|; and,
% Section~\ref{sec:perl-run} details the implementation of the final
% macro, |\perldo|.)  The goal is for these two macros to behave
% \emph{exactly} like |\newcommand| and |\renewcommand|, respectively,
% except that the author macros they in turn define have Perl bodies
% instead of \LaTeX{} bodies.
%
% The sequence of the operations defined in this section is as follows:
%
% \begin{enumerate}
%   \item The user invokes |\perl|[|re|]|newcommand|, which stores
%   |\|[|re|]|newcommand| in |\plmac@command|.  The
%   |\perl|[|re|]|newcommand| macro then invokes |\plmac@newcommand@i|
%   with a first argument of ``|*|'' for |\perl|[|re|]|newcommand*| or
%   ``|!|'' for ordinary |\perl|[|re|]|newcommand|.
%
%   \item |\plmac@newcommand@i| defines |\plmac@starchar| as ``|*|'' if
%   it was passed a ``|*|'' or \meta{empty} if it was passed a ``|!|''.
%   It then stores the name of the user's macro in |\plmac@macname|, a
%   |\write|able version of the name in |\plmac@cleaned@macname|, and
%   the macro's previous definition (needed by |\perlrenewcommand|) in
%   |\plmac@oldbody|.  Finally, |\plmac@newcommand@i| invokes
%   |\plmac@newcommand@ii|.
%
%   \item |\plmac@newcommand@ii| stores the number of arguments to the
%   user's macro (which may be zero) in |\plmac@numargs|.  It then
%   invokes |\plmac@newcommand@iii@opt| if the first argument is
%   supposed to be optional or |\plmac@newcommand@iii@no@opt| if all
%   arguments are supposed to be required.
%
%   \item |\plmac@newcommand@iii@opt| defines |\plmac@defarg| as the
%   default value of the optional argument.
%   |\plmac@newcommand@iii@no@opt| defines it as \meta{empty}.  Both
%   functions then call |\plmac@haveargs|.
%
%   \item |\plmac@haveargs| stores the user's macro body (written in
%   Perl) verbatim in |\plmac@perlcode|.  |\plmac@haveargs| then invokes
%   |\plmac@havecode|.
%
%   \item By the time |\plmac@havecode| is invoked all of the
%   information needed to define the user's macro is available.  Before
%   defining a \LaTeX{} macro, however, |\plmac@havecode| invokes
%   |\plmac@write@perl| to tell \perltex{} to define a Perl subroutine
%   with a name based on |\plmac@cleaned@macname| and the code contained
%   in |\plmac@perlcode|.  Figure~\ref{fig:tofile-define} illustrates
%   the data that |\plmac@write@perl| passes to \perltex.
%
% \begin{figure}[htbp]
%   \centering
%   \DeleteShortVerb\|
%   \begin{tabular}{|l|}
%     \hline
%     \verb|DEF|                    \\ \hline
%     \verb|\plmac@tag|             \\ \hline
%     \verb|\plmac@cleaned@macname| \\ \hline
%     \verb|\plmac@tag|             \\ \hline
%     \verb|\plmac@perlcode|        \\ \hline
%   \end{tabular}
%   \MakeShortVerb\|
%   \caption{Data written to \texttt{\string\plmac@tofile} to define a
%     Perl subroutine}
%   \label{fig:tofile-define}
% \end{figure}
%
%   \item |\plmac@havecode| invokes |\newcommand| or |\renewcommand|, as
%   appropriate, defining the user's macro as a call to
%   |\plmac@write@perl|.  An invocation of the user's \LaTeX{} macro
%   causes |\plmac@write@perl| to pass the information shown in
%   Figure~\ref{fig:tofile-use} to \perltex.
%
% \begin{figure}[htbp]
%   \centering
%   \DeleteShortVerb\|
%   \begin{tabular}{|l|}
%     \hline
%     \verb|USE|                    \\ \hline
%     \verb|\plmac@tag|             \\ \hline
%     \verb|\plmac@cleaned@macname| \\ \hline
%     \verb|\plmac@tag|             \\ \hline
%     \verb|#1|                     \\ \hline
%     \verb|\plmac@tag|             \\ \hline
%     \verb|#2|                     \\ \hline
%     \verb|\plmac@tag|             \\ \hline
%     \verb|#3|                     \\ \hline
%     \multicolumn{1}{c}{$\vdots$}  \\ \hline
%     \verb|#|\meta{last}           \\ \hline
%   \end{tabular}
%   \MakeShortVerb\|
%   \caption{Data written to \texttt{\string\plmac@tofile} to invoke a
%     Perl subroutine}
%   \label{fig:tofile-use}
% \end{figure}
%
%   \item Whenever |\plmac@write@perl| is invoked it writes its argument
%   verbatim to |\plmac@tofile|; \perltex{} evaluates the code and
%   writes |\plmac@fromfile|; finally, |\plmac@write@perl| |\input|s
%   |\plmac@fromfile|.
% \end{enumerate}
%
% An example might help distinguish the myriad macros used internally by
% \perlmac.  Consider the following call made by the user's
% document:\label{text:example-cmd}
%
% \begin{center}
% |\perlnewcommand*{\example}[3][frobozz]{join("---", @_)}|
% \end{center}
%
% \noindent
% Table~\ref{tbl:example-cmd} shows how \perlmac{} parses that command
% into its constituent components and which components are bound to
% which \perlmac{} macros.
%
% \begin{table}[htbp]
%   \centering
%   \caption{Macro assignments corresponding to an sample
%     \texttt{\string\perlnewcommand*}}
%   \label{tbl:example-cmd}
%   \begin{tabular}{@{}lll@{}}
%     \hline
%     Macro & \multicolumn{2}{l@{}}{Sample definition} \\
%     \hline
%     |\plmac@command|          & |\newcommand|                    \\
%     |\plmac@starchar|         & |*|                              \\
%     |\plmac@macname|          & |\example|                       \\
%     |\plmac@cleaned@macname|  & |\example| & (catcode~11)        \\
%     |\plmac@oldbody|          & |\relax| & (presumably)          \\
%     |\plmac@numargs|          & |3|                              \\
%     |\plmac@defarg|           & |frobozz|                        \\
%     |\plmac@perlcode|         & |join("---", @_)| & (catcode~11) \\
%     \hline
%   \end{tabular}
% \end{table}
%
% \bigskip
%
% \begin{macro}{\perlnewcommand}
% \begin{macro}{\perlrenewcommand}
% \begin{macro}{\plmac@command}
% \begin{macro}{\plmac@next}
% |\perlnewcommand| and |\perlrenewcommand| are the first two commands
% exported to the user by \perlmac.  |\perlnewcommand| is analogous to
% |\newcommand| except that the macro body consists of Perl code instead
% of \LaTeX{} code.  Likewise, |\perlrenewcommand| is analogous to
% |\renewcommand| except that the macro body consists of Perl code
% instead of \LaTeX{} code.  |\perlnewcommand| and |\perlrenewcommand|
% merely define |\plmac@command| and |\plmac@next| and invoke
% |\plmac@newcommand@i|.
%    \begin{macrocode}
\def\perlnewcommand{%
  \let\plmac@command=\newcommand
  \let\plmac@next=\relax
  \@ifnextchar*{\plmac@newcommand@i}{\plmac@newcommand@i!}%
}
%    \end{macrocode}
%    \begin{macrocode}
\def\perlrenewcommand{%
  \let\plmac@next=\relax
  \let\plmac@command=\renewcommand
  \@ifnextchar*{\plmac@newcommand@i}{\plmac@newcommand@i!}%
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\plmac@newcommand@i}
% \begin{macro}{\plmac@starchar}
% \begin{macro}{\plmac@macname}
% \begin{macro}{\plmac@oldbody}
% \begin{macro}{\plmac@cleaned@macname}
% If\label{page:newcommand-i} the user invoked
% |\perl|[|re|]|newcommand*| then |\plmac@newcommand@i| is passed a
% ``|*|'' and, in turn, defines |\plmac@starchar| as ``|*|''.  If the
% user invoked |\perl|[|re|]|newcommand| (no ``|*|'') then
% |\plmac@newcommand@i| is passed a ``|!|'' and, in turn, defines
% |\plmac@starchar| as \meta{empty}.  In either case,
% |\plmac@newcommand@i| defines |\plmac@macname| as the name of the
% user's macro, |\plmac@cleaned@macname| as a |\write|able
% (i.e.,~category code~11) version of |\plmac@macname|, and
% |\plmac@oldbody| and the previous definition of the user's macro.
% (|\plmac@oldbody| is needed by |\perlrenewcommand|.)  It then invokes
% |\plmac@newcommand@ii|.
%    \begin{macrocode}
\def\plmac@newcommand@i#1#2{%
  \ifx#1*%
    \def\plmac@starchar{*}%
  \else
    \def\plmac@starchar{}%
  \fi
  \def\plmac@macname{#2}%
  \let\plmac@oldbody=#2\relax
  \expandafter\def\expandafter\plmac@cleaned@macname\expandafter{%
    \expandafter\string\plmac@macname}%
  \@ifnextchar[{\plmac@newcommand@ii}{\plmac@newcommand@ii[0]}%]
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\plmac@newcommand@ii}
% \begin{macro}{\plmac@numargs}
% |\plmac@newcommand@i| invokes |\plmac@newcommand@ii| with the number
% of arguments to the user's macro in brackets.  |\plmac@newcommand@ii|
% stores that number in |\plmac@numargs| and invokes
% |\plmac@newcommand@iii@opt| if the first argument is to be optional or
% |\plmac@newcommand@iii@no@opt| if all arguments are to be mandatory.
%    \begin{macrocode}
\def\plmac@newcommand@ii[#1]{%
  \def\plmac@numargs{#1}%
  \@ifnextchar[{\plmac@newcommand@iii@opt}
               {\plmac@newcommand@iii@no@opt}%]
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\plmac@newcommand@iii@opt}
% \begin{macro}{\plmac@newcommand@iii@no@opt}
% \begin{macro}{\plmac@defarg}
% Only one of these two macros is executed per invocation of
% |\perl|[|re|]|newcommand|, depending on whether or not the first
% argument of the user's macro is an optional argument.
% |\plmac@newcommand@iii@opt| is invoked if the argument is optional.
% It defines |\plmac@defarg| to the default value of the optional
% argument.  |\plmac@newcommand@iii@no@opt| is invoked if all arguments
% are mandatory.  It defines |\plmac@defarg| as |\relax|.  Both
% |\plmac@newcommand@iii@opt| and |\plmac@newcommand@iii@no@opt| then
% invoke |\plmac@haveargs|.
%    \begin{macrocode}
\def\plmac@newcommand@iii@opt[#1]{%
  \def\plmac@defarg{#1}%
  \plmac@haveargs
}
%    \end{macrocode}
%    \begin{macrocode}
\def\plmac@newcommand@iii@no@opt{%
  \let\plmac@defarg=\relax
  \plmac@haveargs
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\plmac@perlcode}
% \begin{macro}{\plmac@haveargs}
% Now things start to get tricky.  We have all of the arguments we need
% to define the user's command so all that's left is to grab the macro
% body.  But there's a catch: Valid Perl code is unlikely to be valid
% \LaTeX{} code.  We therefore have to read the macro body in a
% |\verb|-like mode.  Furthermore, we actually need to \emph{store} the
% macro body in a variable, as we don't need it right away.
%
% The approach we take in |\plmac@haveargs| is as follows.  First, we
% give all ``special'' characters category code~12 (``other'').  We then
% indicate that the carriage return character (control-M) marks the end
% of a line and that curly braces retain their normal meaning.  With the
% aforementioned category-code definitions, we now have to store the
% next curly-brace-delimited fragment of text, end the current group to
% reset all category codes to their previous value, and continue
% processing the user's macro definition.  How do we do that?  The
% answer is to assign the upcoming text fragment to a token register
% (|\plmac@perlcode|) while an |\afterassignment| is in effect.  The
% |\afterassignment| causes control to transfer to |\plmac@havecode|
% right after |\plmac@perlcode| receives the macro body with all of the
% ``special'' characters made impotent.
%    \begin{macrocode}
\newtoks\plmac@perlcode
%    \end{macrocode}
%    \begin{macrocode}
\def\plmac@haveargs{%
  \begingroup
    \let\do\@makeother\dospecials
    \catcode`\^^M=\active
    \newlinechar`\^^M
    \endlinechar=`\^^M
    \catcode`\{=1
    \catcode`\}=2
    \afterassignment\plmac@havecode
    \global\plmac@perlcode
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% Control is transfered to |\plmac@havecode| from |\plmac@haveargs|
% right after the user's macro body is assigned to |\plmac@perlcode|.
% We now have everything we need to define the user's macro.  The goal
% is to define it as ``|\plmac@write@perl{|\meta{contents of
% Figure~\ref{fig:tofile-use}}|}|''.  This is easier said than done
% because the number of arguments in the user's macro is not known
% statically, yet we need to iterate over however many arguments there
% are.  Because of this complexity, we will explain |\plmac@perlcode|
% piece-by-piece.
%
% \begin{macro}{\plmac@sep}
% Define a character to separate each of the items presented in
% Figures~\ref{fig:tofile-define} and~\ref{fig:tofile-use}.  Perl will
% need to strip this off each argument.  For convenience in porting to
% languages with less powerful string manipulation than Perl's, we
% define |\plmac@sep| as a carriage-return character of category code~11
% (``letter'').
%    \begin{macrocode}
{\catcode`\^^M=11\gdef\plmac@sep{^^M}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\plmac@argnum}
% Define a loop variable that will iterate from |1| to the number of
% arguments in the user's function, i.e.,~|\plmac@numargs|.
%    \begin{macrocode}
\newcount\plmac@argnum
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\plmac@havecode}
% Now comes the final piece of what started as a call to
% |\perl|[|re|]|newcommand|.  First, to reset all category codes back to
% normal, |\plmac@havecode| ends the group that was begun in
% |\plmac@haveargs|.
% \changes{v1.1}{2004/02/24}{Added a \texttt{\string\string\string\plmac@next}
%   hook to support \PerlTeX's new environment-defining macros}
%    \begin{macrocode}
\def\plmac@havecode{%
  \endgroup
%    \end{macrocode}
%
% \begin{macro}{\plmac@define@sub}
% We invoke |\plmac@write@perl| to define a Perl subroutine named after
% |\plmac@cleaned@macname|.  |\plmac@define@sub| sends Perl the
% information shown in Figure~\vref{fig:tofile-define}.
%    \begin{macrocode}
  \edef\plmac@define@sub{%
    \noexpand\plmac@write@perl{DEF\plmac@sep
      \plmac@tag\plmac@sep
      \plmac@cleaned@macname\plmac@sep
      \plmac@tag\plmac@sep
      \the\plmac@perlcode
    }%
  }%
  \plmac@define@sub
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\plmac@body}
% The rest of |\plmac@havecode| is preparation for defining the user's
% macro.  (\LaTeXe's |\newcommand| or |\renewcommand| will do the actual
% work, though.)  |\plmac@body| will eventually contain the complete
% (\LaTeX) body of the user's macro.  Here, we initialize it to the
% first three items listed in Figure~\vref{fig:tofile-use} (with
% intervening |\plmac@sep|s).
%    \begin{macrocode}
  \edef\plmac@body{%
    USE\plmac@sep
    \plmac@tag\plmac@sep
    \plmac@cleaned@macname
  }%
%    \end{macrocode}
%
% \begin{macro}{\plmac@hash}
% Now, for each argument |#1|, |#2|,~\dots, |#\plmac@numargs| we append
% a |\plmac@tag| plus the argument to |\plmac@body| (as always, with a
% |\plmac@sep| after each item).  This requires more trickery, as \TeX{}
% requires a macro-parameter character (``|#|'') to be followed by a
% literal number, not a variable.  The approach we take, which I first
% discovered in the Texinfo source code (although it's used by \LaTeX{}
% and probably other \TeX-based systems as well), is to |\let|-bind
% |\plmac@hash| to |\relax|.  This makes |\plmac@hash| unexpandable, and
% because it's not a ``|#|'', \TeX{} doesn't complain.  After
% |\plmac@body| has been extended to include |\plmac@hash1|,
% |\plmac@hash2|,~\dots, |\plmac@hash\plmac@numargs|, we then
% |\let|-bind |\plmac@hash| to |##|, which \TeX{} lets us do because
% we're within a macro definition (|\plmac@havecode|).  |\plmac@body|
% will then contain |#1|, |#2|,~\dots, |#\plmac@numargs|, as desired.
%    \begin{macrocode}
  \let\plmac@hash=\relax
  \plmac@argnum=\@ne
  \loop
    \ifnum\plmac@numargs<\plmac@argnum
    \else
      \edef\plmac@body{%
        \plmac@body\plmac@sep\plmac@tag\plmac@sep
        \plmac@hash\plmac@hash\number\plmac@argnum}%
      \advance\plmac@argnum by \@ne
  \repeat
  \let\plmac@hash=##%
%    \end{macrocode}
%
% \begin{macro}{\plmac@define@command}
% We're ready to execute a |\|[|re|]|newcommand|.  Because we need to
% expand many of our variables, we |\edef| |\plmac@define@command| to
% the appropriate |\|[|re|]|newcommand| call, which we will soon
% execute.  The user's macro must first be |\let|-bound to |\relax| to
% prevent it from expanding.  Then, we handle two cases: either all
% arguments are mandatory (and |\plmac@defarg| is |\relax|) or the
% user's macro has an optional argument (with default value
% |\plmac@defarg|).
%    \begin{macrocode}
  \expandafter\let\plmac@macname=\relax
  \ifx\plmac@defarg\relax
    \edef\plmac@define@command{%
      \noexpand\plmac@command\plmac@starchar{\plmac@macname}%
      [\plmac@numargs]{%
        \noexpand\plmac@write@perl{\plmac@body}%
      }%
  }%
  \else
    \edef\plmac@define@command{%
      \noexpand\plmac@command\plmac@starchar{\plmac@macname}%
      [\plmac@numargs][\plmac@defarg]{%
        \noexpand\plmac@write@perl{\plmac@body}%
      }%
  }%
  \fi
%    \end{macrocode}
%
% The final steps are to restore the previous definition of the user's
% macro---we had set it to |\relax| above to make the name
% unexpandable---then redefine it by invoking |\plmac@define@command|.
% Why do we need to restore the previous definition if we're just going
% to redefine it?  Because |\newcommand| needs to produce an error if
% the macro was previously defined and |\renewcommand| needs to produce
% an error if the macro was \emph{not} previously defined.
%
% |\plmac@havecode| concludes by invoking |\plmac@next|, which is a
% no-op for |\perlnewcommand| and |\perlrenewcommand| but processes the
% end-environment code for |\perlnewenvironment| and
% |\perlrenewenvironment|.
%    \begin{macrocode}
  \expandafter\let\plmac@macname=\plmac@oldbody
  \plmac@define@command
  \plmac@next
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
% \subsubsection{Defining Perl environments}
% \label{sec:perl-env}
%
% \changes{v1.1}{2004/02/24}{Added new
%   \texttt{\string\string\string\perlnewenvironment} and
%   \texttt{\string\string\string\perlrenewenvironment} macros}
%
% Section~\ref{sec:perl-mac} detailed the implementation of
% |\perlnewcommand| and |\perlrenewcommand|.  Section~\ref{sec:perl-env}
% does likewise for |\perlnewenvironment| and |\perlrenewenvironment|,
% which are the Perl-bodied analogues of |\newenvironment| and
% |\renewenvironment|.  This section is significantly shorter than the
% previous because |\perlnewenvironment| and |\perlrenewenvironment| are
% largely built atop the macros already defined in
% Section~\ref{sec:perl-mac}.
%
% \begin{macro}{\perlnewenvironment}
% \begin{macro}{\perlrenewenvironment}
% \begin{macro}{\plmac@command}
% \begin{macro}{\plmac@next}
% |\perlnewenvironment| and |\perlrenewenvironment| are the remaining
% two commands exported to the user by \perlmac.  |\perlnewenvironment|
% is analogous to |\newenvironment| except that the macro body consists
% of Perl code instead of \LaTeX{} code.  Likewise,
% |\perlrenewenvironment| is analogous to |\renewenvironment| except
% that the macro body consists of Perl code instead of \LaTeX{} code.
% |\perlnewenvironment| and |\perlrenewenvironment| merely define
% |\plmac@command| and |\plmac@next| and invoke
% |\plmac@newenvironment@i|.
%
% The significance of |\plmac@next| (which was let-bound to |\relax| for
% |\perl|[|re|]|newcommand| but is let-bound to |\plmac@end@environment|
% here) is that a \LaTeX{} environment definition is really two macro
% definitions: |\|\meta{name} and |\end|\meta{name}.  Because we want to
% reuse as much code as possible the idea is to define the ``begin''
% code as one macro, then inject---by way of |plmac@next|---a call to
% |\plmac@end@environment|, which defines the ``end'' code as a second
% macro.
%    \begin{macrocode}
\def\perlnewenvironment{%
  \let\plmac@command=\newcommand
  \let\plmac@next=\plmac@end@environment
  \@ifnextchar*{\plmac@newenvironment@i}{\plmac@newenvironment@i!}%
}
%    \end{macrocode}
%    \begin{macrocode}
\def\perlrenewenvironment{%
  \let\plmac@command=\renewcommand
  \let\plmac@next=\plmac@end@environment
  \@ifnextchar*{\plmac@newenvironment@i}{\plmac@newenvironment@i!}%
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\plmac@newenvironment@i}
% \begin{macro}{\plmac@starchar}
% \begin{macro}{\plmac@envname}
% \begin{macro}{\plmac@macname}
% \begin{macro}{\plmac@oldbody}
% \begin{macro}{\plmac@cleaned@macname}
% The |\plmac@newenvironment@i| macro is analogous to
% |\plmac@newcommand@i|; see the description of
% |\plmac@newcommand@i|~\vpageref{page:newcommand-i} to understand the
% basic structure.  The primary difference is that the environment name
% (|#2|) is just text, not a control sequence.  We store this text in
% |\plmac@envname| to facilitate generating the names of the two macros
% that constitute an environment definition.  Note that there is no
% |\plmac@newenvironment@ii|; control passes instead to
% |\plmac@newcommand@ii|.
%    \begin{macrocode}
\def\plmac@newenvironment@i#1#2{%
  \ifx#1*%
    \def\plmac@starchar{*}%
  \else
    \def\plmac@starchar{}%
  \fi
  \def\plmac@envname{#2}%
  \expandafter\def\expandafter\plmac@macname\expandafter{\csname#2\endcsname}%
  \expandafter\let\expandafter\plmac@oldbody\plmac@macname\relax
  \expandafter\def\expandafter\plmac@cleaned@macname\expandafter{%
    \expandafter\string\plmac@macname}%
  \@ifnextchar[{\plmac@newcommand@ii}{\plmac@newcommand@ii[0]}%]
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\plmac@end@environment}
% \begin{macro}{\plmac@next}
% \begin{macro}{\plmac@macname}
% \begin{macro}{\plmac@oldbody}
% \begin{macro}{\plmac@cleaned@macname}
% Recall that an environment definition is a shortcut for two macro
% definitions: |\|\meta{name} and |\end|\meta{name} (where \meta{name}
% was stored in |\plmac@envname| by |\plmac@newenvironment@i|).  After
% defining |\|\meta{name}, |\plmac@havecode| transfers control to
% |\plmac@end@environment| because |\plmac@next| was let-bound to
% |\plmac@end@environment| in |\perl|[|re|]|newenvironment|.
%
% |\plmac@end@environment|'s purpose is to define |\end|\meta{name}.
% This is a little tricky, however, because \LaTeX's
% |\|[|re|]|newcommand| refuses to (re)define a macro whose name begins
% with ``|end|''.  The solution that |\plmac@end@environment| takes is
% first to define a |\plmac@end@macro| macro then (in |plmac@next|)
% let-bind |\end|\meta{name} to it.  Other than that,
% |\plmac@end@environment| is a combined and simplified version of
% |\perlnewenvironment|, |\perlrenewenvironment|, and
% |\plmac@newenvironment@i|.
%    \begin{macrocode}
\def\plmac@end@environment{%
  \expandafter\def\expandafter\plmac@next\expandafter{\expandafter
    \let\csname end\plmac@envname\endcsname=\plmac@end@macro
    \let\plmac@next=\relax
  }%
  \def\plmac@macname{\plmac@end@macro}%
  \expandafter\let\expandafter\plmac@oldbody\csname end\plmac@envname\endcsname
  \expandafter\def\expandafter\plmac@cleaned@macname\expandafter{%
    \expandafter\string\plmac@macname}%
  \@ifnextchar[{\plmac@newcommand@ii}{\plmac@newcommand@ii[0]}%]
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
% \subsubsection{Executing top-level Perl code}
% \label{sec:perl-run}
%
% The macros defined in Sections~\ref{sec:perl-mac}
% and~\ref{sec:perl-env} enable an author to inject subroutines into the
% Perl sandbox.  The final \PerlTeX\ macro, |\perldo|, instructs the
% Perl sandbox to execute a block of code outside of all subroutines.
% |\perldo|'s implementation is much simpler than that of the other
% author macros because |\perldo| does not have to process subroutine
% arguments.  Figure~\ref{fig:tofile-run} illustrates the data that gets
% written to |plmac@tofile| (indirectly) by |\perldo|.
%
% \begin{figure}[htbp]
%   \centering
%   \DeleteShortVerb\|
%   \begin{tabular}{|l|}
%     \hline
%     \verb|RUN|             \\ \hline
%     \verb|\plmac@tag|      \\ \hline
%     \textit{Ignored}       \\ \hline
%     \verb|\plmac@tag|      \\ \hline
%     \verb|\plmac@perlcode| \\ \hline
%   \end{tabular}
%   \MakeShortVerb\|
%   \caption{Data written to \texttt{\string\plmac@tofile} to execute
%     Perl code}
%   \label{fig:tofile-run}
% \end{figure}
%
%
% \begin{macro}{\perldo}
% Execute a block of Perl code and pass the result to \LaTeX\ for
% further processing.  This code is nearly identical to that of
% Section~\ref{sec:perl-mac}'s |\plmac@haveargs| but ends by invoking
% |\plmac@have@run@code| instead of |\plmac@havecode|.
% \changes{v1.3}{2006/06/23}{Introduced \texttt{\string\string\string\perldo}
%   to support code execution outside of all subroutines.}
%    \begin{macrocode}
\def\perldo{%
  \begingroup
    \let\do\@makeother\dospecials
    \catcode`\^^M=\active
    \newlinechar`\^^M
    \endlinechar=`\^^M
    \catcode`\{=1
    \catcode`\}=2
    \afterassignment\plmac@have@run@code
    \global\plmac@perlcode
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\plmac@have@run@code}
% \begin{macro}{\plmac@run@code}
% Pass a block of code to Perl to execute.  |\plmac@have@run@code| is
% identical to |\plmac@havecode| but specifies the |RUN| tag instead of
% the |DEF| tag.
% \changes{v1.3}{2006/06/23}{Added to assist
%   \texttt{\string\string\string\perldo}}
%    \begin{macrocode}
\def\plmac@have@run@code{%
  \endgroup
  \edef\plmac@run@code{%
    \noexpand\plmac@write@perl{RUN\plmac@sep
      \plmac@tag\plmac@sep
      N/A\plmac@sep
      \plmac@tag\plmac@sep
      \the\plmac@perlcode
    }%
  }%
  \plmac@run@code
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%
% \subsubsection{Communication between \LaTeX{} and Perl}
%
% As shown in the previous section, when a document invokes
% |\perl|[|re|]|newcommand| to define a macro, \perlmac{} defines the
% macro in terms of a call to |\plmac@write@perl|.  In this section, we
% learn how |\plmac@write@perl| operates.
%
% At the highest level, \LaTeX-to-Perl communication is performed via
% the filesystem.  In essence, \LaTeX{} writes a file (|\plmac@tofile|)
% corresponding to the information in either
% Figure~\ref{fig:tofile-define} or Figure~\ref{fig:tofile-use}; Perl
% reads the file, executes the code within it, and writes a |.tex| file
% (|\plmac@fromfile|); and, finally, \LaTeX{} reads and executes the new
% |.tex| file.  However, the actual communication protocol is a bit more
% involved than that.  The problem is that Perl needs to know when
% \LaTeX{} has finished writing Perl code and \LaTeX{} needs to know
% when Perl has finished writing \LaTeX{} code.  The solution involves
% introducing three extra files---|\plmac@toflag|, |\plmac@fromflag|,
% and |\plmac@doneflag|---which are used exclusively for \LaTeX-to-Perl
% synchronization.
%
% There's a catch: Although Perl can create and delete files, \LaTeX{}
% can only create them.  Even worse, \LaTeX{} (more specifically,
% te\TeX, which is the \TeX{} distribution under which I developed
% \PerlTeX) cannot reliably poll for a file's \emph{non}existence; if a
% file is deleted in the middle of an |\immediate\openin|, |latex|
% aborts with an error message.  These restrictions led to the
% regrettably convoluted protocol illustrated in
% Figure~\ref{fig:comm-protocol}.  In the figure, ``Touch'' means
% ``create a zero-length file''; ``Await'' means ``wait until the file
% exists''; and, ``Read'', ``Write'', and ``Delete'' are defined as
% expected.  Assuming the filesystem performs these operations in a
% sequentially consistent order (not necessarily guaranteed on all
% filesystems, unfortunately), \PerlTeX{} should behave as expected.
%
% \begin{figure}[htbp]
%   \centering
%   \makeatletter\setlength{\unitlength}{\baselineskip}\makeatother
%   \DeleteShortVerb\|
%   \def\topl{\texttt{\string\plmac@tofile}}
%   \def\frpl{\texttt{\string\plmac@fromfile}}
%   \def\tfpl{\texttt{\string\plmac@toflag}}
%   \def\ffpl{\texttt{\string\plmac@fromflag}}
%   \def\dfpl{\texttt{\string\plmac@doneflag}}
%   \begin{tabular}{@{}c@{\hspace*{1cm}}|l@{~}l|c|l@{~}l|@{}}
%     \multicolumn{1}{@{}c@{\hspace*{1cm}}}{Time} &
%     \multicolumn{2}{c}{\LaTeX} &
%     \multicolumn{1}{c}{} &
%     \multicolumn{2}{c@{}}{Perl} \\
%
%     \cline{2-3}\cline{5-6}
%     \smash{\vector(0,-1){11}}
%     & Write & \topl &               &        &       \\
%     & Touch & \tfpl & $\rightarrow$ & Await  & \tfpl \\
%     &       &       &               & Read   & \topl \\
%     &       &       &               & Write  & \frpl \\
%     &       &       &               & Delete & \tfpl \\
%     &       &       &               & Delete & \topl \\
%     &       &       &               & Delete & \dfpl \\
%     & Await & \ffpl & $\leftarrow$  & Touch  & \ffpl \\
%     & Touch & \topl & $\rightarrow$ & Await  & \topl \\
%     &       &       &               & Delete & \ffpl \\
%     & Await & \dfpl & $\leftarrow$  & Touch  & \dfpl \\
%     & Read  & \frpl &               &        &       \\
%     \cline{2-3}\cline{5-6}
%   \end{tabular}
%   \MakeShortVerb\|
%   \caption{\LaTeX-to-Perl communication protocol}
%   \label{fig:comm-protocol}
% \end{figure}
%
% Although Figure~\ref{fig:comm-protocol} shows the read of
% |\plmac@fromfile| as the final step of the protocol, the file's
% contents are in fact valid as soon as \LaTeX{} detects that
% |\plmac@fromflag| exists.  Deferring the read to the end, however,
% enables \PerlTeX{} to support recursive macro invocations.
%
% \begin{macro}{\plmac@infile}
% \begin{macro}{\plmac@IfFileExists}
% \changes{v2.3}{2024/12/03}{Introduce this macro, which implements a
%   non-caching version of \string\cs{IfFileExists}}
% The Await operations in Figure~\ref{fig:comm-protocol} require testing
% if a file exists.  On the \LaTeX\ side, this normally would be
% achieved using \LaTeX's \cs{IfFileExists} macro, and this is indeed
% what \PerlTeX\ did until version~2.2.  However, the \mbox{1-Jun-2023}
% release of \LaTeX3 introduced a performance optimization that lets
% \cs{IfFileExists} cache prior results.  (See
% \url{https://www.latex-project.org/news/latex2e-news/ltnews37.pdf}.)
% In other words, once \cs{IfFileExists} determines that a file exists,
% it will follow the \textsc{true} branch on all subsequent calls
% without ever re-checking if the file still exists.  This semantics
% breaks the protocol described in Figure~\ref{fig:comm-protocol} by
% enabling Await to return before the file being waited for actually
% exists.
%
% To work around \LaTeX3's new behavior, we define our own version of
% \cs{IfFileExists} called \cs{plmac@IfFileExists}, which is derived
% from \cs{IfFileExists}'s simpler, more straightforward
% \LaTeXe\ implementation.  In particular, file existence is checked
% explicitly on each invocation.
%    \begin{macrocode}
\newread\plmac@infile
%    \end{macrocode}
%    \begin{macrocode}
\newcommand{\plmac@IfFileExists}[3]{%
  \openin\plmac@infile=#1 %
  \ifeof\plmac@infile
    \def\plmac@next{#3}%
  \else
    \closein\plmac@infile
    \def\plmac@next{#2}%
  \fi
  \plmac@next
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\plmac@await@existence}
% \changes{v1.9}{2009/09/13}{Put the
%   \texttt{\string\string\string\input\string\string\string\plmac@pipe}
%   within an \texttt{lrbox} environment to prevent a partial read from
%   introducing spurious text into the document}
% \begin{macro}{\ifplmac@file@exists}
% \begin{macro}{\plmac@file@existstrue}
% \begin{macro}{\plmac@file@existsfalse}
% The purpose of the \cs{plmac@await@existence} macro is repeatedly to
% check the existence of a given file until the file actually exists.
% We use \cs{plmac@IfFileExists} (defined above) to check if the file
% exists and accordingly either continue or exit the loop.
%
% As a performance optimization we |\input| a named pipe.  This causes
% the |latex| process to relinquish the CPU until the |perltex| process
% writes data (always just a comment plus ``|\endinput|'') into the
% named pipe.  On systems that don't support persistent named pipes
% (e.g.,~Microsoft Windows), |\plmac@pipe| is an ordinary file
% containing only a comment plus ``|\endinput|''.  While reading that
% file is not guaranteed to relinquish the CPU, it should not hurt the
% performance or correctness of the communication protocol between
% \LaTeX\ and Perl.
% \changes{v1.5}{2007/10/13}{Modified to read from a named pipe before
%   checking file existence}
%    \begin{macrocode}
\newif\ifplmac@file@exists
%    \end{macrocode}
%    \begin{macrocode}
\newcommand{\plmac@await@existence}[1]{%
  \begin{lrbox}{\@tempboxa}%
    \input\plmac@pipe
  \end{lrbox}%
  \loop
    \plmac@IfFileExists{#1}%
                       {\plmac@file@existstrue}%
                       {\plmac@file@existsfalse}%
    \ifplmac@file@exists
    \else
  \repeat
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\plmac@outfile}
% We define a file handle for |\plmac@write@perl@i| to use to create and
% write |\plmac@tofile| and |\plmac@toflag|.
%    \begin{macrocode}
\newwrite\plmac@outfile
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\plmac@write@perl}
% |\plmac@write@perl| begins the \LaTeX-to-Perl data exchange, following
% the protocol illustrated in Figure~\ref{fig:comm-protocol}.
% |\plmac@write@perl| prepares for the next piece of text in the input
% stream to be read with ``special'' characters marked as category
% code~12 (``other'').  This prevents \LaTeX{} from complaining if the
% Perl code contains invalid \LaTeX{} (which it usually will).
% |\plmac@write@perl| ends by passing control to |\plmac@write@perl@i|,
% which performs the bulk of the work.
%    \begin{macrocode}
\newcommand{\plmac@write@perl}{%
  \begingroup
    \let\do\@makeother\dospecials
    \catcode`\^^M=\active
    \newlinechar`\^^M
    \endlinechar=`\^^M
    \catcode`\{=1
    \catcode`\}=2
    \plmac@write@perl@i
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\plmac@write@perl@i}
% When |\plmac@write@perl@i| begins executing, the category codes are
% set up so that the macro's argument will be evaluated ``verbatim''
% except for the part consisting of the \LaTeX\ code passed in by the
% author, which is partially expanded.  Thus, everything is in place for
% |\plmac@write@perl@i| to send its argument to Perl and read back the
% (\LaTeX) result.
%
% Because\label{page:define-dummies} all of \perlmac's protocol
% processing is encapsulated within |\plmac@write@perl@i|, this is the
% only macro that strictly requires \perltex.  Consequently, we wrap the
% entire macro definition within a check for \perltex.
% \changes{v1.8}{2009/03/25}{Renamed
%   \texttt{\string\string\string\ifplmac@have@perltex} to
%   \texttt{\char`\\ ifperl} to help authors write
%   mixed \string\LaTeX\string\slash\space \string\PerlTeX\ documents}
%    \begin{macrocode}
\ifperl
  \newcommand{\plmac@write@perl@i}[1]{%
%    \end{macrocode}
% The first step is to write argument |#1| to |\plmac@tofile|:
% \changes{v1.1}{2004/02/19}{Made argument-handling more rational by
%   making \texttt{\string\string\string\protect},
%   \texttt{\string\string\string\begin}, and
%   \texttt{\string\string\string\end} non-expandable}
%    \begin{macrocode}
      \immediate\openout\plmac@outfile=\plmac@tofile\relax
      \let\protect=\noexpand
      \def\begin{\noexpand\begin}%
      \def\end{\noexpand\end}%
      \immediate\write\plmac@outfile{#1}%
      \immediate\closeout\plmac@outfile
%    \end{macrocode}
% \noindent
% (In the future, it might be worth redefining |\def|, |\edef|, |\gdef|,
% |\xdef|, |\let|, and maybe some other control sequences as
% ``|\noexpand|\meta{control sequence}|\noexpand|'' so that |\write|
% doesn't try to expand an undefined control sequence.)
%
% We're now finished using |#1| so we can end the group begun by
% |\plmac@write@perl|, thereby resetting each character's category code
% back to its previous value.
%    \begin{macrocode}
    \endgroup
%    \end{macrocode}
%
% Continuing the protocol illustrated in Figure~\ref{fig:comm-protocol},
% we create a zero-byte |\plmac@toflag| in order to notify \perltex{}
% that it's now safe to read |\plmac@tofile|.
%    \begin{macrocode}
    \immediate\openout\plmac@outfile=\plmac@toflag\relax
    \immediate\closeout\plmac@outfile
%    \end{macrocode}
%
% To avoid reading |\plmac@fromfile| before \perltex{} has finished
% writing it we must wait until \perltex{} creates |\plmac@fromflag|,
% which it does only after it has written |\plmac@fromfile|.
%    \begin{macrocode}
    \plmac@await@existence\plmac@fromflag
%    \end{macrocode}
%
% At this point, |\plmac@fromfile| should contain valid \LaTeX{} code.
% However, we defer inputting it until we the very end.  Doing so
% enables recursive and mutually recursive invocations of \PerlTeX{}
% macros.
% \changes{v1.2}{2004/10/07}{Moved the
%   \texttt{\string\string\string\input} of the generated Perl code to
%   the end of the routine in order to support recursive \PerlTeX{}
%   macro invocations.}
%
% Because \TeX{} can't delete files we require an additional
% \LaTeX-to-Perl synchronization step.  For convenience, we recycle
% |\plmac@tofile| as a synchronization file rather than introduce yet
% another flag file to complement |\plmac@toflag|, |\plmac@fromflag|,
% and |\plmac@doneflag|.
%    \begin{macrocode}
    \immediate\openout\plmac@outfile=\plmac@tofile\relax
    \immediate\closeout\plmac@outfile
    \plmac@await@existence\plmac@doneflag
%    \end{macrocode}
%
% The only thing left to do is to |\input| and evaluate
% |\plmac@fromfile|, which contains the \LaTeX{} output from the Perl
% subroutine.
%    \begin{macrocode}
    \input\plmac@fromfile\relax
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\plmac@write@perl@i}
% \changes{v1.1}{2004/02/24}{Added a dummy version of the macro to use
%   if \texttt{latex} was launched directly, without \perltex}
% The foregoing code represents the ``real'' definition of
% |\plmac@write@perl@i|.  For the user's convenience, we define a dummy
% version of |\plmac@write@perl@i| so that a document which utilizes
% \perlmac{} can still compile even if not built using \perltex.  All
% calls to macros defined with |\perl|[|re|]|newcommand| and all
% invocations of environments defined with |\perl|[|re|]|newenvironment|
% are replaced with ``\fbox{Perl\TeX}''.  A minor complication is that
% text can't be inserted before the |\begin{document}|.  Hence, we
% initially define |\plmac@write@perl@i| as a do-nothing macro and
% redefine it as ``|\fbox{Perl\TeX}|'' at the |\begin{document}|.
%    \begin{macrocode}
\else
  \newcommand{\plmac@write@perl@i}[1]{\endgroup}
%    \end{macrocode}
% \begin{macro}{\plmac@show@placeholder}
% There's really no point in outputting a framed ``Perl\TeX'' when a
% macro is defined \emph{and} when it's used.  |\plmac@show@placeholder|
% checks the first character of the protocol header.  If it's
% ``D''~(|DEF|), nothing is output.  Otherwise, it'll be ``U''~(|USE|)
% and ``Perl\TeX'' will be output.
%    \begin{macrocode}
  \gdef\plmac@show@placeholder#1#2\@empty{%
    \ifx#1D\relax
      \endgroup
    \else
      \endgroup
      \fbox{Perl\TeX}%
    \fi
  }%
%    \end{macrocode}
% \end{macro}
%    \begin{macrocode}
  \AtBeginDocument{%
    \renewcommand{\plmac@write@perl@i}[1]{%
      \plmac@show@placeholder#1\@empty
    }%
  }
\fi
%    \end{macrocode}
% \end{macro}
%
% \iffalse
%</package>
% \fi
%
% ^^A  Keep track of the number of lines of code in perltex.
% \makeatletter
% \immediate\write\@auxout{^^A
%   \noexpand\gdef\noexpand\perlmaclines{\the\c@CodelineNo}}
% \makeatother
%
%
% \subsection{\perltex}
% \label{sec:perltex}
%
% \perltex{} is a wrapper script for |latex| (or any other \LaTeX{}
% compiler).  It sets up client-server communication between \LaTeX{}
% and Perl, with \LaTeX{} as the client and Perl as the server.  When a
% \LaTeX{} document sends a piece of Perl code to \perltex{} (with the
% help of \perlmac, as detailed in Section~\ref{sec:perlmacros}),
% \perltex{} executes it within a secure sandbox and transmits the
% resulting \LaTeX{} code back to the document.
% \changes{v1.0a}{2003/08/21}{Made all \texttt{unlink} calls wait for the
%   file to actually disappear}
%
% \iffalse
%<*perltex>
% \fi
%
% \subsubsection{Header comments}
%
% Because \perltex{} is generated without a \textsf{DocStrip}
% preamble or postamble we have to manually include the desired
% text as Perl comments.
%
%    \begin{macrocode}
#! /usr/bin/env perl

###########################################################
# Prepare a LaTeX run for two-way communication with Perl #
# By Scott Pakin <scott+pt@pakin.org>                     #
###########################################################

#-------------------------------------------------------------------
# This is file `perltex.pl',
# generated with the docstrip utility.
#
# The original source files were:
#
# perltex.dtx  (with options: `perltex')
#
# This is a generated file.
#
# Copyright (C) 2003-2024 Scott Pakin <scott+pt@pakin.org>
#
# This file may be distributed and/or modified under the conditions
# of the LaTeX Project Public License, either version 1.3c of this
# license or (at your option) any later version.  The latest
# version of this license is in:
#
#    http://www.latex-project.org/lppl.txt
#
# and version 1.3c or later is part of all distributions of LaTeX
# version 2006/05/20 or later.
#-------------------------------------------------------------------

%    \end{macrocode}
%
% \subsubsection{Top-level code evaluation}
%
% In previous versions of \perltex, the |--nosafe| option created and
% ran code within a sandbox in which all operations are allowed (via
% |Opcode::full_opset()|).  Unfortunately, certain operations still fail
% to work within such a sandbox.  We therefore define a top-level
% ``non-sandbox'', |top_level_eval()|, in which to execute code.
% |top_level_eval()| merely calls |eval()| on its argument.  However, it
% needs to be declared top-level and before anything else because
% |eval()| runs in the lexical scope of its caller.
% \changes{v1.3}{2006/06/24}{Modified \perltex\ to eschew the sandbox
%   altogether when \texttt{--nosafe} is specified}
%
%    \begin{macrocode}
sub top_level_eval ($)
{
    return eval $_[0];
}
%    \end{macrocode}
%
% \subsubsection{Perl modules and pragmas}
%
% We use |Safe| and |Opcode| to implement the secure sandbox,
% |Getopt::Long| and |Pod::Usage| to parse the command line, and
% various other modules and pragmas for miscellaneous things.
%    \begin{macrocode}
use Safe;
use Opcode;
use Getopt::Long;
use Pod::Usage;
use File::Basename;
use Fcntl;
use POSIX;
use File::Spec;
use IO::Handle;
use warnings;
use strict;
%    \end{macrocode}
%
% \subsubsection{Variable declarations}
%
% With |use strict| in effect, we need to declare all of our variables.
% For clarity, we separate our global-variable declarations into
% variables corresponding to command-line options and other global
% variables.
%
% \paragraph{Variables corresponding to command-line arguments}
% \begin{perlvar}{$latexprog}
% \begin{perlvar}{$runsafely}
% \begin{perlvar}{@permittedops}
% \begin{perlvar}{$usepipe}
% |$latexprog| is the name of the \LaTeX{} executable
% (e.g.,~``|latex|'').  If |$runsafely| is~|1| (the default), then the
% user's Perl code runs in a secure sandbox; if it's~|0|, then arbitrary
% Perl code is allowed to run.  |@permittedops| is a list of features
% made available to the user's Perl code.  Valid values are described in
% Perl's |Opcode| manual page.  \perltex's default is a list containing
% only |:browse|.  |$usepipe| is~|1| if \perltex\ should attempt to use
% a named pipe for communicating with |latex| or~|0| if an ordinary file
% should be used instead.
%    \begin{macrocode}
my $latexprog;
my $runsafely = 1;
my @permittedops;
my $usepipe = 1;
%    \end{macrocode}
% \end{perlvar}
% \end{perlvar}
% \end{perlvar}
% \end{perlvar}
%
% \paragraph{Filename variables}
% \begin{perlvar}{$progname}
% \begin{perlvar}{$jobname}
% \begin{perlvar}{$toperl}
% \begin{perlvar}{$fromperl}
% \begin{perlvar}{$toflag}
% \begin{perlvar}{$fromflag}
% \begin{perlvar}{$doneflag}
% \begin{perlvar}{$logfile}
% \begin{perlvar}{$pipe}
% |$progname| is the run-time name of the \perltex{} program.
% |$jobname| is the base name of the user's |.tex| file, which defaults
% to the \TeX{} default of |texput|.  |$toperl| defines the filename
% used for \LaTeX-to-Perl communication.  |$fromperl| defines the
% filename used for Perl-to-\LaTeX{} communication.  |$toflag| is the
% name of a file that will exist only after \LaTeX{} creates |$tofile|.
% |$fromflag| is the name of a file that will exist only after Perl
% creates |$fromfile|.  |$doneflag| is the name of a file that will
% exist only after Perl deletes |$fromflag|.  |$logfile| is the name of
% a log file to which \perltex{} writes verbose execution information.
% |$pipe| is the name of a Unix named pipe (or ordinary file on
% operating systems that lack support for persistent named pipes or in
% the case that |$usepipe| is set to~|0|) used to convince the |latex|
% process to yield control of the CPU\@.
%    \begin{macrocode}
my $progname = basename $0;
my $jobname = "texput";
my $toperl;
my $fromperl;
my $toflag;
my $fromflag;
my $doneflag;
my $logfile;
my $pipe;
%    \end{macrocode}
% \end{perlvar}
% \end{perlvar}
% \end{perlvar}
% \end{perlvar}
% \end{perlvar}
% \end{perlvar}
% \end{perlvar}
% \end{perlvar}
% \end{perlvar}
%
% \paragraph{Other global variables}
% \begin{perlvar}{@latexcmdline}
% \begin{perlvar}{$styfile}
% \begin{perlvar}{@macroexpansions}
% \begin{perlvar}{$sandbox}
% \begin{perlvar}{$sandbox_eval}
% \begin{perlvar}{$latexpid}
% |@latexcmdline| is the command line to pass to the \LaTeX{}
% executable.  |$styfile| is the string \noperlmac{} if \perltex{} is run
% with \texttt{--makesty}, otherwise undefined.  |@macroexpansions| is a
% list of \PerlTeX{} macro expansions in the order they were encountered.
% It is used for creating a \noperlmac{} file when \texttt{--makesty} is
% specified.  |$sandbox| is a secure sandbox in which to run code that
% appeared in the \LaTeX{} document.  |$sandbox_eval| is a subroutine
% that evalutes a string within |$sandbox| (normally) or outside of all
% sandboxes (if |--nosafe| is specified).  |$latexpid| is the process~ID
% of the |latex| process.
%    \begin{macrocode}
my @latexcmdline;
my $styfile;
my @macroexpansions;
my $sandbox = new Safe;
my $sandbox_eval;
my $latexpid;
%    \end{macrocode}
% \end{perlvar}
% \end{perlvar}
% \end{perlvar}
% \end{perlvar}
% \end{perlvar}
% \end{perlvar}
%
% \begin{perlvar}{$pipestring}
% |$pipestring| is a constant string to write to the |$pipe| named pipe
% (or file) at each \LaTeX{} synchronization point.  Its particular
% definition is really a bug workaround for \XeTeX\@.  The current
% version of \XeTeX{} reads the first few bytes of a file to determine
% the character encoding (\mbox{UTF-8} or \mbox{UTF-16}, big-endian or
% little-endian) then attempts to rewind the file pointer.  Because
% pipes can't be rewound, the effect is that the first two bytes of
% |$pipe| are discarded and the rest are input.  Hence, the
% ``|\endinput|'' used in prior versions of \PerlTeX{} inserted a
% spurious ``|ndinput|'' into the author's document.  We therefore
% define |$pipestring| such that it will not interfere with the document
% even if the first few bytes are discarded.
% \changes{v1.7}{2007/12/09}{Introduced this variable as a workaround for
%   \protect\XeTeX's attempt to rewind \texttt{\$pipe}}
%    \begin{macrocode}
my $pipestring = "\%\%\%\%\% Generated by $progname\n\\endinput\n";
%    \end{macrocode}
% \end{perlvar}
%
% \subsubsection{Command-line conversion}
%
% In this section, \perltex{} parses its own command line and prepares a
% command line to pass to |latex|.
%
% \paragraph{Parsing \perltex's command line}
% We first set |$latexprog| to be the contents of the environment
% variable |PERLTEX| or the value ``|latex|'' if |PERLTEX| is not
% specified.  We then use |Getopt::Long| to parse the command line,
% leaving any parameters we don't recognize in the argument vector
% (|@ARGV|) because these are presumably |latex| options.
% \changes{v1.6}{2007/12/07}{Added an (undocumented) \texttt{--nopipe}
%   option to \protect\perltex\ to help it work with \protect\XeTeX}
% \changes{v1.7}{2007/12/09}{Added an (undocumented) \texttt{--synctext}
%   option to alter the text written to \texttt{\$pipe}}
%    \begin{macrocode}
$latexprog = $ENV{"PERLTEX"} || "latex";
Getopt::Long::Configure("require_order", "pass_through");
GetOptions("help"       => sub {pod2usage(-verbose => 1)},
           "latex=s"    => \$latexprog,
           "safe!"      => \$runsafely,
%    \end{macrocode}
% The following two options are undocumented because the defaults should
% always suffice.  We're not yet removing these options, however, in
% case they turn out to be useful for diagnostic purposes.
%    \begin{macrocode}
           "pipe!"      => \$usepipe,
           "synctext=s" => \$pipestring,
%    \end{macrocode}
%    \begin{macrocode}
           "makesty"    => sub {$styfile = "noperltex.sty"},
           "permit=s"   => \@permittedops) || pod2usage(2);
%    \end{macrocode}
%
% \paragraph{Preparing a \LaTeX{} command line}
% \begin{perlvar}{$firstcmd}
% \begin{perlvar}{$option}
% We start by searching |@ARGV| for the first string that does not start
% with ``|-|'' or ``|\|''.  This string, which represents a filename, is
% used to set |$jobname|.
%    \begin{macrocode}
@latexcmdline = @ARGV;
my $firstcmd = 0;
for ($firstcmd=0; $firstcmd<=$#latexcmdline; $firstcmd++) {
    my $option = $latexcmdline[$firstcmd];
    next if substr($option, 0, 1) eq "-";
    if (substr ($option, 0, 1) ne "\\") {
        $jobname = basename $option, ".tex" ;
        $latexcmdline[$firstcmd] = "\\input $option";
    }
    last;
}
push @latexcmdline, "" if $#latexcmdline==-1;
%    \end{macrocode}
% \end{perlvar}
% \end{perlvar}
%
% \begin{perlvar}{$separator}
% To avoid conflicts with the code and parameters passed to Perl from
% \LaTeX{} (see Figure~\vref{fig:tofile-define} and
% Figure~\vref{fig:tofile-use}) we define a separator string,
% |$separator|, containing 20 random uppercase letters.
%    \begin{macrocode}
my $separator = "";
foreach (1 .. 20) {
    $separator .= chr(ord("A") + rand(26));
}
%    \end{macrocode}
% \end{perlvar}
%
% Now that we have the name of the \LaTeX{} job (|$jobname|) we can
% assign |$toperl|, |$fromperl|, |$toflag|, |$fromflag|, |$doneflag|,
% |$logfile|, and |$pipe| in terms of |$jobname| plus a suitable
% extension.
%    \begin{macrocode}
$toperl = $jobname . ".topl";
$fromperl = $jobname . ".frpl";
$toflag = $jobname . ".tfpl";
$fromflag = $jobname . ".ffpl";
$doneflag = $jobname . ".dfpl";
$logfile = $jobname . ".lgpl";
$pipe = $jobname . ".pipe";
%    \end{macrocode}
%
% We now replace the filename of the |.tex| file passed to \perltex{}
% with a |\def|inition of the separator character, |\def|initions of the
% various files, and the original file with |\input| prepended if
% necessary.
%    \begin{macrocode}
$latexcmdline[$firstcmd] =
    sprintf '\makeatletter' . '\def%s{%s}' x 7 . '\makeatother%s',
    '\plmac@tag', $separator,
    '\plmac@tofile', $toperl,
    '\plmac@fromfile', $fromperl,
    '\plmac@toflag', $toflag,
    '\plmac@fromflag', $fromflag,
    '\plmac@doneflag', $doneflag,
    '\plmac@pipe', $pipe,
    $latexcmdline[$firstcmd];
%    \end{macrocode}
%
% \subsubsection{Increasing \PerlTeX's robustness}
%
% \changes{v2.0}{2009/11/24}{Refer to each communication file using
%   its absolute path.  This makes \perltex\ robust to user code
%   that changes the current directory}
% \changes{v2.1}{2010/07/10}{Replaced \texttt{abs\_path()} with
%   \texttt{File::Spec-\char"3Erel2abs()} because the latter seems
%   to be more robust to nonexistent files}
%    \begin{macrocode}
$toperl = File::Spec->rel2abs($toperl);
$fromperl = File::Spec->rel2abs($fromperl);
$toflag = File::Spec->rel2abs($toflag);
$fromflag = File::Spec->rel2abs($fromflag);
$doneflag = File::Spec->rel2abs($doneflag);
$logfile = File::Spec->rel2abs($logfile);
$pipe = File::Spec->rel2abs($pipe);
%    \end{macrocode}
%
% \changes{v1.9}{2009/09/13}{Introduced handlers for \textsc{sigalrm}
%   and \textsc{sigpipe} to make \perltex\ more robust to \texttt{latex}
%   exiting at an inopportune time}
%
% \perltex\ may hang if |latex| exits right before the final pipe
% communication.  We therefore define a simple \signal{ALRM} handler
% that lets \perltex\ exit after a given length of time has
% elapsed.\label{code:sigalrm}
%    \begin{macrocode}
$SIG{"ALRM"} = sub {
    undef $latexpid;
    exit 0;
};
%    \end{macrocode}
%
% To prevent Perl from aborting with a ``\texttt{Broken pipe}'' error
% message if |latex| exits during the final pipe communication we tell
% Perl to ignore \signal{PIPE} errors.  |latex|'s exiting will be
% caught via other means (the preceding \signal{ALRM} handler or the
% following call to |waitpid|).
%    \begin{macrocode}
$SIG{"PIPE"} = "IGNORE";
%    \end{macrocode}
%
% \begin{perlsub}{delete_files}
% On some operating systems and some filesystems, deleting a file may
% not cause the file to disappear immediately.  Because
% \PerlTeX\ synchronizes Perl and \LaTeX\ via the filesystem it is
% critical that file deletions be performed when requested.  We
% therefore define a |delete_files| subroutine that waits until each
% file named in the argument list is truly deleted.
% \changes{v1.9}{2009/09/13}{Replaced all
%   \texttt{unlink}\dots\texttt{while~-e} statements with calls to a new
%   \texttt{delete\_files} subroutine}
%    \begin{macrocode}
sub delete_files (@)
{
    foreach my $filename (@_) {
        unlink $filename;
        while (-e $filename) {
            unlink $filename;
            sleep 0;
        }
    }
}
%    \end{macrocode}
% \end{perlsub}
%
% \begin{perlsub}{awaitexists}
% We define an |awaitexists| subroutine that waits for a given file to
% exist.  If |latex| exits while |awaitexists| is waiting, then
% \perltex{} cleans up and exits, too.
% \changes{v1.0a}{2003/08/06}{Bug fix: Added ``\texttt{undef
%   \$latexpid}'' to make the \texttt{END} block correctly return a
%   status code of~0 on success}
% \changes{v1.9}{2009/09/13}{Hoisted \texttt{\$awaitexists} from the
%   main loop and made it a top-level subroutine}
%    \begin{macrocode}
sub awaitexists ($)
{
    while (!-e $_[0]) {
        sleep 0;
        if (waitpid($latexpid, &WNOHANG)==-1) {
            delete_files($toperl, $fromperl, $toflag,
                         $fromflag, $doneflag, $pipe);
            undef $latexpid;
            exit 0;
        }
    }
}
%    \end{macrocode}
% \end{perlsub}
%
% \subsubsection{Launching \LaTeX}
%
% We start by deleting the |$toperl|, |$fromperl|, |$toflag|,
% |$fromflag|, |$doneflag|, and |$pipe| files, in case any of these were
% left over from a previous (aborted) run.  We also create a log file
% (|$logfile|), a named pipe (|$pipe|)---or a file containing only
% |\endinput| if we can't create a named pipe---and, if |$styfile| is
% defined, a \LaTeXe\ style file.  As |@latexcmdline| contains the
% complete command line to pass to |latex| we need only |fork| a new
% process and have the child process overlay itself with |latex|.
% \perltex{} continues running as the parent.
%    \begin{macrocode}
delete_files($toperl, $fromperl, $toflag, $fromflag, $doneflag, $pipe);
open (LOGFILE, ">$logfile") || die "open(\"$logfile\"): $!\n";
autoflush LOGFILE 1;
if (defined $styfile) {
    open (STYFILE, ">$styfile") || die "open(\"$styfile\"): $!\n";
}
%    \end{macrocode}
%    \begin{macrocode}
if (!$usepipe || !eval {mkfifo($pipe, 0600)}) {
    sysopen PIPE, $pipe, O_WRONLY|O_CREAT, 0755;
    autoflush PIPE 1;
    print PIPE $pipestring;
    close PIPE;
    $usepipe = 0;
}
%    \end{macrocode}
%    \begin{macrocode}
defined ($latexpid = fork) || die "fork: $!\n";
unshift @latexcmdline, $latexprog;
if (!$latexpid) {
    exec {$latexcmdline[0]} @latexcmdline;
    die "exec('@latexcmdline'): $!\n";
}
%    \end{macrocode}
%
% \subsubsection{Preparing a sandbox}
%
% \perltex{} uses Perl's |Safe| and |Opcode| modules to declare a secure
% sandbox (|$sandbox|) in which to run Perl code passed to it from
% \LaTeX{}\@.  When the sandbox compiles and executes Perl code, it
% permits only operations that are deemed safe.  For example, the Perl
% code is allowed by default to assign variables, call functions, and
% execute loops.  However, it is not normally allowed to delete files,
% kill processes, or invoke other programs.  If \perltex\ is run with
% the |--nosafe| option we bypass the sandbox entirely and execute Perl
% code using an ordinary |eval()| statement.
%    \begin{macrocode}
if ($runsafely) {
    @permittedops=(":browse") if $#permittedops==-1;
    $sandbox->permit_only (@permittedops);
    $sandbox_eval = sub {$sandbox->reval($_[0])};
}
else {
    $sandbox_eval = \&top_level_eval;
}
%    \end{macrocode}
%
% \subsubsection{Communicating with \LaTeX{}}
%
% The following code constitutes \perltex's main loop.  Until |latex|
% exits, the loop repeatedly reads Perl code from \LaTeX{}, evaluates
% it, and returns the result as per the protocol described in
% Figure~\vref{fig:comm-protocol}.
% \changes{v1.0a}{2003/08/21}{Undefined \texttt{\string\string\string$/}
%   only locally}
%
%    \begin{macrocode}
while (1) {
%    \end{macrocode}
%
% \begin{perlvar}{$entirefile}
% Wait for |$toflag| to exist.  When it does, this implies that
% |$toperl| must exist as well.  We read the entire contents of
% |$toperl| into the |$entirefile| variable and process it.
% Figures~\ref{fig:tofile-define} and~\ref{fig:tofile-use} illustrate
% the contents of |$toperl|.
%    \begin{macrocode}
    awaitexists($toflag);
    my $entirefile;
    {
        local $/ = undef;
        open (TOPERL, "<$toperl") || die "open($toperl): $!\n";
        $entirefile = <TOPERL>;
        close TOPERL;
    }
%    \end{macrocode}
% \end{perlvar}
%
% \begin{perlvar}{$optag}
% \begin{perlvar}{$macroname}
% \begin{perlvar}{@otherstuff}
% We split the contents of |$entirefile| into an operation tag (either
% |DEF|, |USE|, or |RUN|), the macro name, and everything else
% (|@otherstuff|).  If |$optag| is |DEF| then |@otherstuff| will contain
% the Perl code to define.  If |$optag| is |USE| then |@otherstuff| will
% be a list of subroutine arguments.  If |$optag| is |RUN| then
% |@otherstuff| will be a block of Perl code to run.
% \changes{v2.1}{2010/07/10}{Normalized line endings across
%   Unix\slash Windows\slash Macintosh}
%    \begin{macrocode}
    $entirefile =~ s/\r//g;
    my ($optag, $macroname, @otherstuff) =
        map {chomp; $_} split "$separator\n", $entirefile;
%    \end{macrocode}
% \end{perlvar}
% \end{perlvar}
% \end{perlvar}
%
% We clean up the macro name by deleting all leading non-letters,
% replacing all subsequent non-alphanumerics with ``|_|'', and
% prepending ``|latex_|'' to the macro name.
%    \begin{macrocode}
    $macroname =~ s/^[^A-Za-z]+//;
    $macroname =~ s/\W/_/g;
    $macroname = "latex_" . $macroname;
%    \end{macrocode}
%
% If we're calling a subroutine, then we make the arguments more
% palatable to Perl by single-quoting them and replacing every
% occurrence of ``|\|'' with ``|\\|'' and every occurrence of ``|'|''
% with ``|\'|''.
%    \begin{macrocode}
    if ($optag eq "USE") {
      foreach (@otherstuff) {
          s/\\/\\\\/g;
          s/\'/\\\'/g;
          $_ = "'$_'";
      }
    }
%    \end{macrocode}
%
% \begin{perlvar}{$perlcode}
% There are three possible values that can be assigned to |$perlcode|.
% If |$optag| is |DEF|, then |$perlcode| is made to contain a definition
% of the user's subroutine, named |$macroname|.  If |$optag| is |USE|,
% then |$perlcode| becomes an invocation of |$macroname| which gets
% passed all of the macro arguments.  Finally, if |$optag| is |RUN|,
% then |$perlcode| is the unmodified Perl code passed to us from
% \perlmac.  Figure~\ref{fig:latex-perl-define} presents an example
% of how the following code converts a \PerlTeX{} macro definition into
% a Perl subroutine definition and Figure~\ref{fig:latex-perl-use}
% presents an example of how the following code converts a \PerlTeX{}
% macro invocation into a Perl subroutine invocation.
%
% \begin{figure}[tbp]
%   \centering
%   \DeleteShortVerb\|
%   \begin{tabular}{l|l|}
%     \cline{2-2}
%     \LaTeX: & \verb|\perlnewcommand{\mymacro}[2]{%| \\
%             & \verb|  sprintf "Isn't $_[0] %s $_[1]?\n",| \\
%             & \verb|    $_[0]>=$_[1] ? ">=" : "<"| \\
%             & \verb|}| \\
%     \cline{2-2}
%     \multicolumn{2}{c}{} \\
%     \multicolumn{1}{c}{} & \multicolumn{1}{c}{\Huge$\Downarrow$} \\
%     \multicolumn{2}{c}{} \\
%     \cline{2-2}
%     Perl:   & \verb|sub latex_mymacro {| \\
%             & \verb|  sprintf "Isn't $_[0] %s $_[1]?\n",| \\
%             & \verb|    $_[0]>=$_[1] ? ">=" : "<"| \\
%             & \verb|}| \\
%     \cline{2-2}
%   \end{tabular}
%   \MakeShortVerb\|
%   \caption{Conversion from \LaTeX{} to Perl (subroutine definition)}
%   \label{fig:latex-perl-define}
% \end{figure}
%
% \begin{figure}[tbp]
%   \centering
%   \DeleteShortVerb\|
%   \begin{tabular}{l|l|}
%     \cline{2-2}
%     \LaTeX: & \verb|\mymacro{12}{34}| \\
%     \cline{2-2}
%     \multicolumn{2}{c}{} \\
%     \multicolumn{1}{c}{} & \multicolumn{1}{c}{\Huge$\Downarrow$} \\
%     \multicolumn{2}{c}{} \\
%     \cline{2-2}
%     Perl:   & \verb|latex_mymacro ('12', '34');| \\
%     \cline{2-2}
%   \end{tabular}
%   \MakeShortVerb\|
%   \caption{Conversion from \LaTeX{} to Perl (subroutine invocation)}
%   \label{fig:latex-perl-use}
% \end{figure}
%
%    \begin{macrocode}
    my $perlcode;
    if ($optag eq "DEF") {
        $perlcode =
            sprintf "sub %s {%s}\n",
            $macroname, $otherstuff[0];
    }
    elsif ($optag eq "USE") {
        $perlcode = sprintf "%s (%s);\n", $macroname, join(", ", @otherstuff);
    }
    elsif ($optag eq "RUN") {
        $perlcode = $otherstuff[0];
    }
    else {
        die "${progname}: Internal error -- unexpected operation tag \"$optag\"\n";
    }
%    \end{macrocode}
% \end{perlvar}
%
% Log what we're about to evaluate.
%    \begin{macrocode}
    print LOGFILE "#" x 31, " PERL CODE ", "#" x 32, "\n";
    print LOGFILE $perlcode, "\n";
%    \end{macrocode}
%
% \begin{perlvar}{$result}
% \begin{perlvar}{$msg}
% We're now ready to execute the user's code using the |$sandbox_eval|
% function.  If a warning occurs we write it as a Perl comment to the
% log file.  If an error occurs (i.e.,~|$@| is defined) we replace the
% result (|$result|) with a call to \LaTeXe's |\PackageError| macro to
% return a suitable error message.  We produce one error message for
% sandbox policy violations (detected by the error message, |$@|,
% containing the string ``\texttt{trapped by}'') and a different error
% message for all other errors caused by executing the user's code.  For
% clarity of reading both warning and error messages, we elide the
% string ``\texttt{at (eval} \meta{number}\texttt{) line}
% \meta{number}''.  Once |$result| is defined---as either the resulting
% \LaTeX\ code or as a |\PackageError|---we store it in
% |@macroexpansions| in preparation for writing it to \noperlmac\
% (when \perltex\ is run with \texttt{--makesty}).
% \changes{v2.0}{2009/11/21}{Substituted
%   \texttt{\string\string\string\MessageBreak} for newline when
%   reporting error messages produced by user code}
%    \begin{macrocode}
    undef $_;
    my $result;
    {
        my $warningmsg;
        local $SIG{__WARN__} =
            sub {chomp ($warningmsg=$_[0]); return 0};
        $result = $sandbox_eval->($perlcode);
        if (defined $warningmsg) {
            $warningmsg =~ s/at \(eval \d+\) line \d+\W+//;
            print LOGFILE "# ===> $warningmsg\n\n";
        }
    }
    $result = "" if !$result || $optag eq "RUN";
    if ($@) {
        my $msg = $@;
        $msg =~ s/at \(eval \d+\) line \d+\W+//;
        $msg =~ s/\n/\\MessageBreak\n/g;
        $msg =~ s/\s+/ /;
        $result = "\\PackageError{perltex}{$msg}";
        my @helpstring;
        if ($msg =~ /\btrapped by\b/) {
            @helpstring =
                ("The preceding error message comes from Perl.  Apparently,",
                 "the Perl code you tried to execute attempted to perform an",
                 "`unsafe' operation.  If you trust the Perl code (e.g., if",
                 "you wrote it) then you can invoke perltex with the --nosafe",
                 "option to allow arbitrary Perl code to execute.",
                 "Alternatively, you can selectively enable Perl features",
                 "using perltex's --permit option.  Don't do this if you don't",
                 "trust the Perl code, however; malicious Perl code can do a",
                 "world of harm to your computer system.");
        }
        else {
            @helpstring =
              ("The preceding error message comes from Perl.  Apparently,",
               "there's a bug in your Perl code.  You'll need to sort that",
               "out in your document and re-run perltex.");
        }
        my $helpstring = join ("\\MessageBreak\n", @helpstring);
        $helpstring =~ s/\.  /.\\space\\space /g;
        $result .= "{$helpstring}";
    }
    push @macroexpansions, $result if defined $styfile && $optag eq "USE";
%    \end{macrocode}
% \end{perlvar}
% \end{perlvar}
%
% Log the resulting \LaTeX{} code.
%    \begin{macrocode}
    print LOGFILE "%" x 30, " LATEX RESULT ", "%" x 30, "\n";
    print LOGFILE $result, "\n\n";
%    \end{macrocode}
%
% We add |\endinput| to the generated \LaTeX{} code to suppress an
% extraneous end-of-line character that \TeX{} would otherwise insert.
%    \begin{macrocode}
    $result .= '\endinput';
%    \end{macrocode}
%
% Continuing the protocol described in Figure~\vref{fig:comm-protocol}
% we now write |$result| (which contains either the result of executing
% the user's or a |\PackageError|) to the |$fromperl| file, delete
% |$toflag|, |$toperl|, and |$doneflag|, and notify \LaTeX{} by touching
% the |$fromflag| file.  As a performance optimization, we also write
% |\endinput| into |$pipe| to wake up the |latex| process.
%    \begin{macrocode}
    open (FROMPERL, ">$fromperl") || die "open($fromperl): $!\n";
    syswrite FROMPERL, $result;
    close FROMPERL;
%    \end{macrocode}
%    \begin{macrocode}
    delete_files($toflag, $toperl, $doneflag);
%    \end{macrocode}
%    \begin{macrocode}
    open (FROMFLAG, ">$fromflag") || die "open($fromflag): $!\n";
    close FROMFLAG;
%    \end{macrocode}
%    \begin{macrocode}
    if (open (PIPE, ">$pipe")) {
        autoflush PIPE 1;
        print PIPE $pipestring;
        close PIPE;
    }
%    \end{macrocode}
%
% We have to perform one final \LaTeX-to-Perl synchronization step.
% Otherwise, a subsequent |\perl|[|re|]|newcommand| would see that
% |$fromflag| already exists and race ahead, finding that |$fromperl|
% does not contain what it's supposed to.
%    \begin{macrocode}
    awaitexists($toperl);
    delete_files($fromflag);
    open (DONEFLAG, ">$doneflag") || die "open($doneflag): $!\n";
    close DONEFLAG;
%    \end{macrocode}
% Again, we awaken the |latex| process, which is blocked on |$pipe|.  If
% writing to the pipe takes more than one second we assume that |latex|
% has exited and trigger the \signal{ALRM} handler
% (page~\pageref{code:sigalrm}).
%    \begin{macrocode}
    alarm 1;
    if (open (PIPE, ">$pipe")) {
        autoflush PIPE 1;
        print PIPE $pipestring;
        close PIPE;
    }
    alarm 0;
}
%    \end{macrocode}
%
% \subsubsection{Final cleanup}
%
% If we exit abnormally we should do our best to kill the child |latex|
% process so that it doesn't continue running forever, holding onto
% system resources.
%    \begin{macrocode}
END {
    close LOGFILE;
    if (defined $latexpid) {
        kill (9, $latexpid);
        exit 1;
    }

    if (defined $styfile) {
%    \end{macrocode}
% \changes{v1.4}{2007/09/29}{Added support for a \texttt{--makesty}
%   option that generates a \PerlTeX-free style file called
%   \texttt{noperltex.sty}}
% This is the big moment for the \texttt{--makesty} option.  We've
% accumulated the output from each \PerlTeX\ macro invocation into
% |@macroexpansions|, and now we need to produce a
% \noperlmac\ file.  We start by generating a boilerplate
% header in which we set up the package and load both \pkgname{perltex}
% and \pkgname{filecontents}.
%    \begin{macrocode}
        print STYFILE <<"STYFILEHEADER1";
\\NeedsTeXFormat{LaTeX2e}[1999/12/01]
\\ProvidesPackage{noperltex}
    [2007/09/29 v1.4 Perl-free version of PerlTeX specific to $jobname.tex]
STYFILEHEADER1
        ;
        print STYFILE <<'STYFILEHEADER2';
\RequirePackage{filecontents}

% Suppress the "Document must be compiled using perltex" error from perltex.
\let\noperltex@PackageError=\PackageError
\renewcommand{\PackageError}[3]{}
\RequirePackage{perltex}
\let\PackageError=\noperltex@PackageError

%    \end{macrocode}
% \begin{macro}{\plmac@macro@invocation@num}
% \begin{macro}{\plmac@show@placeholder}
% \noperlmac\ works by redefining the |\plmac@show@placeholder| macro,
% which normally outputs a framed ``\PerlTeX'' when \perltex\ isn't
% running, changing it to input |noperltex-|\meta{number}|.tex| instead
% (where \meta{number} is the contents of the
% |\plmac@macro@invocation@num| counter).  Each
% |noperltex-|\meta{number}|.tex| file contains the output from a single
% invocation of a \PerlTeX-defined macro.
%    \begin{macrocode}
% Modify \plmac@show@placeholder to input the next noperltex-*.tex file
% each time a PerlTeX-defined macro is invoked.
\newcount\plmac@macro@invocation@num
\gdef\plmac@show@placeholder#1#2\@empty{%
  \ifx#1U\relax
    \endgroup
    \advance\plmac@macro@invocation@num by 1\relax
    \global\plmac@macro@invocation@num=\plmac@macro@invocation@num
    \input{noperltex-\the\plmac@macro@invocation@num.tex}%
  \else
    \endgroup
  \fi
}
STYFILEHEADER2
        ;
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% Finally, we need to have \noperlmac\ generate each of the
% |noperltex-|\meta{number}|.tex| files.  For each element of
% |@macroexpansions| we use one |filecontents| environment to write the
% macro expansion verbatim to a file.
%    \begin{macrocode}
        foreach my $e (0 .. $#macroexpansions) {
            print STYFILE "\n";
            printf STYFILE "%% Invocation #%d\n", 1+$e;
                printf STYFILE "\\begin{filecontents}{noperltex-%d.tex}\n", 1+$e;
            print STYFILE $macroexpansions[$e], "\\endinput\n";
            print STYFILE "\\end{filecontents}\n";
        }
        print STYFILE "\\endinput\n";
        close STYFILE;
    }

    exit 0;
}

__END__
%    \end{macrocode}
%
% \subsubsection{\perltex{} POD documentation}
%
% \perltex{} includes documentation in Perl's POD (Plain Old
% Documentation) format.  This is used both to produce manual pages and
% to provide usage information when \perltex{} is invoked with the
% |--help| option.  The POD documentation is not listed here as part of
% the documented \perltex{} source code because it contains essentially
% the same information as that shown in Section~\ref{sec:perltex-man}.
% If you're curious what the POD source looks like then see the
% generated \perltex{} file.
%
% \iffalse
%    \begin{macrocode}

=head1 NAME

perltex - enable LaTeX macros to be defined in terms of Perl code


=head1 SYNOPSIS

perltex
[B<--help>]
[B<--latex>=I<program>]
[B<-->[B<no>]B<safe>]
[B<--permit>=I<feature>]
[B<--makesty>]
[I<latex options>]


=head1 DESCRIPTION

LaTeX -- through the underlying TeX typesetting system -- produces
beautifully typeset documents but has a macro language that is
difficult to program.  In particular, support for complex string
manipulation is largely lacking.  Perl is a popular general-purpose
programming language whose forte is string manipulation.  However, it
has no typesetting capabilities whatsoever.

Clearly, Perl's programmability could complement LaTeX's typesetting
strengths.  B<perltex> is the tool that enables a symbiosis between
the two systems.  All a user needs to do is compile a LaTeX document
using B<perltex> instead of B<latex>.  (B<perltex> is actually a
wrapper for B<latex>, so no B<latex> functionality is lost.)  If the
document includes a C<\usepackage{perltex}> in its preamble, then
C<\perlnewcommand> and C<\perlrenewcommand> macros will be made
available.  These behave just like LaTeX's C<\newcommand> and
C<\renewcommand> except that the macro body contains Perl code instead
of LaTeX code.


=head1 OPTIONS

B<perltex> accepts the following command-line options:

=over 4

=item B<--help>

Display basic usage information.

=item B<--latex>=I<program>

Specify a program to use instead of B<latex>.  For example,
C<--latex=pdflatex> would typeset the given document using
B<pdflatex> instead of ordinary B<latex>.

=item B<-->[B<no>]B<safe>

Enable or disable sandboxing.  With the default of B<--safe>,
B<perltex> executes the code from a C<\perlnewcommand> or
C<\perlrenewcommand> macro within a protected environment that
prohibits ``unsafe'' operations such as accessing files or executing
external programs.  Specifying B<--nosafe> gives the LaTeX document
I<carte blanche> to execute any arbitrary Perl code, including that
which can harm the user's files.  See L<Safe> for more information.

=item B<--permit>=I<feature>

Permit particular Perl operations to be performed.  The B<--permit>
option, which can be specified more than once on the command line,
enables finer-grained control over the B<perltex> sandbox.  See
L<Opcode> for more information.

=item B<--makesty>

Generate a LaTeX style file called F<noperltex.sty>.  Replacing the
document's C<\usepackage{perltex}> line with C<\usepackage{noperltex}>
produces the same output but does not require PerlTeX, making the
document suitable for distribution to people who do not have PerlTeX
installed.  The disadvantage is that F<noperltex.sty> is specific to
the document that produced it.  Any changes to the document's PerlTeX
macro definitions or macro invocations necessitates rerunning
B<perltex> with the B<--makesty> option.

=back

These options are then followed by whatever options are normally
passed to B<latex> (or whatever program was specified with
C<--latex>), including, for instance, the name of the F<.tex> file to
compile.


=head1 EXAMPLES

In its simplest form, B<perltex> is run just like B<latex>:

    perltex myfile.tex

To use B<pdflatex> instead of regular B<latex>, use the B<--latex>
option:

    perltex --latex=pdflatex myfile.tex

If LaTeX gives a ``C<trapped by operation mask>'' error and you trust
the F<.tex> file you're trying to compile not to execute malicious
Perl code (e.g., because you wrote it yourself), you can disable
B<perltex>'s safety mechansisms with B<--nosafe>:

    perltex --nosafe myfile.tex

The following command gives documents only B<perltex>'s default
permissions (C<:browse>) plus the ability to open files and invoke the
C<time> command:

    perltex --permit=:browse --permit=:filesys_open
      --permit=time myfile.tex


=head1 ENVIRONMENT

B<perltex> honors the following environment variables:

=over 4

=item PERLTEX

Specify the filename of the LaTeX compiler.  The LaTeX compiler
defaults to ``C<latex>''.  The C<PERLTEX> environment variable
overrides this default, and the B<--latex> command-line option (see
L</OPTIONS>) overrides that.

=back


=head1 FILES

While compiling F<jobname.tex>, B<perltex> makes use of the following
files:

=over 4

=item F<jobname.lgpl>

log file written by Perl; helpful for debugging Perl macros

=item F<jobname.topl>

information sent from LaTeX to Perl

=item F<jobname.frpl>

information sent from Perl to LaTeX

=item F<jobname.tfpl>

``flag'' file whose existence indicates that F<jobname.topl> contains
valid data

=item F<jobname.ffpl>

``flag'' file whose existence indicates that F<jobname.frpl> contains
valid data

=item F<jobname.dfpl>

``flag'' file whose existence indicates that F<jobname.ffpl> has been
deleted

=item F<noperltex-#.tex>

file generated by F<noperltex.sty> for each PerlTeX macro invocation

=back


=head1 NOTES

B<perltex>'s sandbox defaults to what L<Opcode> calls ``C<:browse>''.


=head1 SEE ALSO

latex(1), pdflatex(1), perl(1), Safe(3pm), Opcode(3pm)


=head1 AUTHOR

Scott Pakin, I<scott+pt@pakin.org>
%    \end{macrocode}
% \fi
%
% \iffalse
%</perltex>
% \fi
%
% ^^A  Keep track of the number of lines of code in perltex.
% \makeatletter
% \immediate\write\@auxout{^^A
%   \noexpand\gdef\noexpand\perltexlines{\the\c@CodelineNo}}
% \makeatother
%
%
% \subsection{Porting to other languages}
% \label{sec:porting}
%
% Perl is a natural choice for a \LaTeX{} macro language because of its
% excellent support for text manipulation including extended regular
% expressions, string interpolation, and ``here'' strings, to name a few
% nice features.  However, Perl's syntax is unusual and its semantics
% are rife with annoying special cases.  Some users will therefore long
% for a \meta{some-language-other-than-Perl}\TeX\@.  Fortunately,
% porting \PerlTeX{} to use a different language should be fairly
% straightforward.  \perltex{} will need to be rewritten in the target
% language, of course, but \perlmac{} modifications will likely be
% fairly minimal.  In all probability, only the following changes will
% need to be made:
%
% \begin{itemize}
%   \item Rename \perlmac{} and \perltex{} (and choose a package name
%   other than ``\PerlTeX'') as per the \PerlTeX{} license agreement
%   (Section~\ref{sec:license}).
%
%   \item In your replacement for \perlmac, replace all occurrences of
%   ``|plmac|'' with a different string.
%
%   \item In your replacement for \perltex, choose different file
%   extensions for the various helper files.
% \end{itemize}
%
% The importance of these changes is that they help ensure version
% consistency and that they make it possible to run
% \meta{some-language-other-than-Perl}\TeX{} alongside \PerlTeX,
% enabling multiple programming languages to be utilized in the same
% \LaTeX{} document.
%
% \Finale
\endinput