Skip to content

Commit

Permalink
Introduce a c-specification argument in ltcmd (#1525)
Browse files Browse the repository at this point in the history
  • Loading branch information
josephwright authored Jan 23, 2025
1 parent 9e537e1 commit 9e6f3d0
Show file tree
Hide file tree
Showing 9 changed files with 818 additions and 515 deletions.
4 changes: 4 additions & 0 deletions base/changes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ to completeness or accuracy and it contains some references to files that are
not part of the distribution.
================================================================================

2025-01-23 Joseph Wright <[email protected]>
* ltcmd.dtx, usrguide.tex
New "c"-type argument

2025-01-21 Frank Mittelbach <[email protected]>

* ltoutput.dtx (subsection{Floats}):
Expand Down
49 changes: 49 additions & 0 deletions base/doc/ltnews41.tex
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,55 @@ \subsection{Socket and plug conditionals}
%
\githubissue{1577}

\subsection{Collecting environment bodies verbatim}

The mechanisms in \pkg{ltcmd} (\enquote{\pkg{xparse}}) offer a powerful way to
specify a range of types of document command and environment syntax. This
includes the ability to collect the entire body of an environment, for cases
where treating it as a standard argument is useful. It is also possible in
\pkg{ltcmd} to define arguments which grab their content verbatim, another
specialist argument form. To date, however, it was not possible to combine
these two ideas.

In this release, a new specifier~\texttt{c} is introduced, which collects the
body of an environment in a verbatim-like way. Like the existing
\texttt{v}~specification, each separate line is marked by the special
\cs{obeyedline} marker, which as standard issues a normal paragraph. Thus, this
new specifier is usable both for typesetting and collecting file contents (the
letter~\texttt{c} indicates \enquote{collect code}). Thus, we may use
\begin{verbatim}
\NewDocumentEnvironment
{MyVerbatim}{!O{\ttfamily} c}
{\begin{center}#1 #2\end{center}} {}
\begin{MyVerbatim}[\ttfamily\itshape]
% Some code is shown here
$y = mx + c$
\end{MyVerbatim}
\end{verbatim}
to obtain
% We can't actually use ...
%\NewDocumentEnvironment{MyVerbatim}{!O{\ttfamily} c}
% {\begin{center} #1 #2\end{center}} {}
% ... as this would prevent LaTeX News 41 being processed with LaTeX before
% 2025-06-01!
% So instead ...
\begin{center}
\makeatletter
\def\@verbatim{%
\trivlist
\centering
\let \do \@makeother
\dospecials
\obeylines
\normalfont \ttfamily \itshape
\@noligs
}
\begin{verbatim}
% Some code is shown here
$y = mx + c$
\end{verbatim}
\end{center}

\section{Code improvements}

\subsection{Refinement of \cs{MakeTitlecase}}
Expand Down
53 changes: 52 additions & 1 deletion base/doc/usrguide.tex
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
\texttt{usrguide.tex} for full details.}%
}

\date{2025-01-21}
\date{2025-01-23}

\NewDocumentCommand\cs{m}{\texttt{\textbackslash\detokenize{#1}}}
\NewDocumentCommand\marg{m}{\arg{#1}}
Expand Down Expand Up @@ -860,6 +860,57 @@ \subsection{Typesetting verbatim-like material}
Similarly, the \texttt{verbatim} environment sets up the meaning of \cs{par}
suitable for breaking lines.

\subsection{Verbatim environments}
\label{sec:cmd:verbenv}

In some cases, as well as grabbing an environment body you will want the
contents to be treated verbatim. This is available using the argument
specification~\texttt{c}. Like the \texttt{b} specification, this has to be the
last one. Thus for example
\begin{verbatim}
\NewDocumentEnvironment{MyVerbatim}{!O{\ttfamily} c}
{\begin{center} #1 #2\end{center}} {}
\begin{MyVerbatim}[\ttfamily\itshape]
% Some code is shown here
$y = mx + c$
\end{MyVerbatim}
\end{verbatim}
will typeset
\NewDocumentEnvironment{MyVerbatim}{!O{\ttfamily} c}
{\begin{center} #1 #2\end{center}} {}
\begin{MyVerbatim}[\ttfamily\itshape]
% Some code is shown here
$y = mx + c$
\end{MyVerbatim}

As grabbing the entire contents verbatim means there are no \cs{par} tokens,
newlines are always permitted: there is no need for a |+| here. As for the
\texttt{v} specification, newlines are stored as \cs{obeyedline}. In a similar
fashion to the \texttt{b}~specification, by default \emph{newlines} are trimmed
at both ends of the body. Putting the prefix |!| before \texttt{c} suppresses
space-trimming.

Collection of the body takes place on a line-by-line basis: content is
collected up to the end-of-line in the source, then examined before storage.
This means that the line ending the environment (containing in the example
above |\end{MyVerbatim}|) cannot have any text \emph{after} the end of the
environment. Text \emph{before} the end of environment is treated normally,
but note that there is no trailing \cs{obeyedline} added if there is text here.
Other than optional arguments, no text is allowed on the opening line of the
environment.

Special handling is applied to a \texttt{o}, \texttt{O}, \texttt{d} or
\texttt{D}~specification argument immediately before an
\texttt{c}~specification. This means that when the optional argument is absent,
the first character of the next line will be read properly. Issues may arise if
\emph{multiple} optional arguments are used before an \texttt{c}~specification,
and are therefore strongly discouraged.

For technical reasons, we recommend that spaces are \emph{not} ignored when
searching for an optional argument before an \texttt{c} specification: this can
be achieved by adding the \texttt{!} modifier as showing in the example.
However, this is left as a choice for the user.

\subsection{Performance}

For document commands where the argument specification is entirely
Expand Down
Loading

0 comments on commit 9e6f3d0

Please sign in to comment.