9

I'm wondering if it's possible to use the new c arg spec (or any other method) in LaTeX to define a verbatim environment as a pair of commands. I also want the starting command to take an optional argument. My attempt, following the example in ltnews41, fails:

\documentclass{article} \NewDocumentEnvironment{tubtyping}{!O{} c} {\begin{verbatim}#2 \end{verbatim} } {} \def\starttyping{\begin{tubtyping}} \def\stoptyping{\end{tubtyping}} \begin{document} \starttyping[foo] foo \stoptyping \starttyping bar \stoptyping \end{document} 

Not surprisingly, it gets the error

Runaway argument? bar\obeyedline \stoptyping\obeyedline \end{document}\obeyedline \obeyedline \ET C. ! File ended while scanning use of \@xverbatim. 

I presume the verbatim environment can't recognize the \end{verbatim} since it's already been tokenized in the definition. I get similar errors with commands defined using traditional optional arguments (\newcommand\starttyping[1][]), etc., since (it seems) looking ahead for the [ freezes the tokens.

I'm not worried about end of line behavior, having text on the \start or \stop lines, etc. It would just be helpful to have the basic idea work.

This is with current (as of 2025-09-16) pdflatex-dev, LaTeX2e <2025-06-01> patch level 1 and L3 programming layer <2025-08-13>.

I saw the previous question Defining a new environment extending a verbatim environment but it's not about L3. If anything in fancyvrb, listings, or any other verbatim package offers this functionality, I'd be happy to hear about it. I don't need to define it myself, I just couldn't find anything that provides it.

P.S. I should mention, an alternative approach would be a way to change the end-verbatim string from \end{verbatim} to \stoptyping. Then \starttyping could take the optional arg and start the verbatim env, and the env could end normally. As far as I know the end-verbatim string cannot be changed, though.

8
  • 1
    If a LuaLaTeX-based solution is of interest to you, my answer to the query How to handle verbatim material in LuaLaTeX? may be of interest to you. In particular, my answer defines a pair of commands called \Verbatim and \EndVerbatim. Commented Sep 16 at 17:42
  • It seemed unrelated with tag latex3. Commented Sep 16 at 18:35
  • 1
    The c-type, like b-type, is a LaTeX environment so \begin{XXX} ... \end{XXX} is required: the end marker is not arbitrary. Commented Sep 16 at 18:50
  • You've asked me for this before :) From: Max Chernoff // Subject: Re: \type for LaTeX // Date: Sat, 08 Jul 2023. Commented Sep 16 at 22:35
  • Karl Berry? Hi, congrats for your nice naming scheme! Commented Sep 17 at 0:05

3 Answers 3

7

why the non-latex document syntax?

But..

enter image description here

\documentclass{article} \makeatletter \NewDocumentCommand\starttyping{O{}}{% \par \begingroup \@verbatim \frenchspacing\@vobeyspaces \xstarttyping{#1}} \expanded{\def\noexpand\xstarttyping#1#2\@backslashchar stoptyping}{% % something with #1 #2% \endgroup \par} \makeatother \begin{document} \starttyping[foo] foo \abc }{ \stoptyping \starttyping bar \sss { \stoptyping \end{document} 
6
  • “why the non-latex document syntax?” Almost certainly for this: github.com/TeXUsersGroup/tugboat/blob/trunk/misc/… Commented Sep 16 at 22:36
  • David, that seems ... magical. Especially the \@backslashchar. I would never have gotten there. Thanks! Commented Sep 17 at 16:57
  • Shouldn't that second \makeatletter be \makeatother instead? Commented Sep 17 at 19:51
  • @jjramsey it is now:-) thanks Commented Sep 17 at 20:04
  • For the record, David subsequently sent me a small fix to handle the first token better: ``` \NewDocumentCommand\starttyping{}{% \par \smallskip \begingroup \@verbatim \frenchspacing\@vobeyspaces \xstarttyping } \NewDocumentCommand\gobbleopt{O{}}{} \expanded{\def\noexpand\xstarttyping#1\@backslashchar stoptyping}{% % ignore the optional arg #1 \gobbleopt#1% \endgroup \par \smallskip } ``` (also, thanks max :) Commented Sep 19 at 21:13
7

Assuming that this is for tugboat.abbr-ctx, the easiest solution is to modify \@TBverbatim so that it can also scan for \stoptyping:

\documentclass{ltugboat} %%%%%%%%%%%%%%%%%%%%%% %%% Implementation %%% %%%%%%%%%%%%%%%%%%%%%% \input{tugboat.abbr-ctx} \makeatletter \NewDocumentCommand{\TB@gobbleoptional}{!O{}}{} \newif\ifTB@starttyping \def\starttyping{\TB@starttypingtrue\par\begin{verbatim}[\small \catcode`\|=12 \hfuzz=2pt \tubextratyping]\TB@gobbleoptional} { \catcode`\|=0 \catcode`\\=12 |gdef|TB@starttyping#1\stoptyping{#1|end{verbatim}|TB@starttypingfalse} } \def\@TBverbatim{% \@verbatim\frenchspacing\@vobeyspaces% \ifTB@starttyping\TB@starttyping\else\@xverbatim\fi% } \makeatother %%%%%%%%%%%%%%%%%%%%% %%% Demonstration %%% %%%%%%%%%%%%%%%%%%%%% \def\rtitlenexttopage{} \def\tubtypesetpageno#1{} \begin{document} \starttyping[with an optional argument] This is \ConTeXt{}. \stoptyping \begin{verbatim} This is \LaTeX{}. \end{verbatim} \end{document} 

output

If you're okay processing Hans' articles using LuaTeX, this is one of the very few cases where using process_input_buffer is acceptable:

\documentclass{ltugboat} %%%%%%%%%%%%%%%%%%%%%% %%% Implementation %%% %%%%%%%%%%%%%%%%%%%%%% \input{tugboat.abbr-ctx} \directlua{ luatexbase.add_to_callback("process_input_buffer", function(line) return line:gsub("stoptyping", "end{verbatim}") end, "tugboat-ctx-verbatim") } %%%%%%%%%%%%%%%%%%%%% %%% Demonstration %%% %%%%%%%%%%%%%%%%%%%%% \def\rtitlenexttopage{} \def\tubtypesetpageno#1{} \begin{document} \starttyping This is \ConTeXt{}. \stoptyping \begin{verbatim} This is \LaTeX{}. \end{verbatim} \end{document} 

output

3
  • 2
    an inside job ... Commented Sep 17 at 0:29
  • Modifying \@TBverbatim to look for \stoptyping is a good idea, but is it possible for \starttyping to accept (and ignore) an optional argument? That's where I failed along this road. It happens when the fake \starttyping is used for \startbuffer. It looks like David's answer handles this. Commented Sep 17 at 16:56
  • @KarlBerry Sure, that's easy; see the edit. Commented Sep 17 at 22:12
4

If you really want to use \NewDocumentCommand, you can do something like the following. This is only mostly verbatim though, since an extra space will be inserted after anything that looks like a macro, so I wouldn't really recommend using this solution.

\documentclass{article} %%%%%%%%%%%%%%%%%%%%%% %%% Implementation %%% %%%%%%%%%%%%%%%%%%%%%% \makeatletter \NewDocumentCommand{\starttyping}{O{}}{% \bgroup% \obeyspaces\obeylines% \let\do\@makeother\dospecials% \catcode`\\=0% \@starttyping!% } \NewDocumentCommand{\@detokenize}{m}{% \ExpandArgs{e}\scantokens{\detokenize{#1}} } \ExpandArgs{nne}\NewDocumentCommand{\@starttyping}{r!\stoptyping}{% \begin{verbatim}% \@detokenize{#1}% \@backslashchar end\string{verbatim\string}% \egroup% } \makeatother %%%%%%%%%%%%%%%%%%%%% %%% Demonstration %%% %%%%%%%%%%%%%%%%%%%%% \pagestyle{empty} \begin{document} \starttyping[foo] foo % Comments work but spaces show up after \macros{}. \stoptyping \starttyping bar \stoptyping \end{document} 

output

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.