0

This is intended more as a LaTeX language question than a "how do I accomplish XYZ" question.

In the code below, a usage of VerbatimOut is successful.
Place that usage inside a \newcommand* definition, and using the new command fails.

From the language perspective, why are these not equivalent?
What happens when tokenizing, processing, etc that causes these to have different behaviors?

\documentclass[11pt]{article}
\usepackage{fancyvrb}

\newcommand*{\writeToFile}{ \begin{VerbatimOut}{myFileFromCommand.txt} fromCommand \end{VerbatimOut} \input{myFileFromCommand.txt} }

\begin{document}

% works \begin{VerbatimOut}{myFileFromPlain.txt} fromPlain \end{VerbatimOut} \input{myFileFromPlain.txt}

% fails with error "FancyVerb Error: Extraneous input ` fromCommand \end {VerbatimOut} \input{myFileFromCommand.txt} ' between \begin{VerbatimOut}[<key=value>] and line end. \writeToFile

\end{document}

Note: (likely better on meta discussion, but I don't have enough rep to post there) I've seen that many questions of "why do I get error E when trying to X with code C?" get answered with:

  • (A) You can't use C - here's D that works
  • (B) Read the TeX book and the documentation for C

Upsides of these answers:

  • (A) is great for one-time LaTeX programmers who don't care about learning and just want something that does X
  • (B) is great for LaTeX experts who already know how TeX works - they just need to look at C

Downsides of these answers:

  • (A) is only useful for people who have the exact same goal X, and usually X is fairly specific
  • (B) is daunting for novices who want just enough information to understand the error and search for a solution

Perhaps some kind of debugging mode that shows the operations LaTeX ran (showing before and after expanding each user-defined command, and showing which token is currently being processed) would help, both for individual debugging and posting the "why" something went wrong/right.

  • Meta-answer: my opinion, ● that's already way better than only include the (A) part, ● it gets boring to copy stuff from the TeXbook over and over again, ● TeX is really that complicated, you'd better read the book anyway. ■ tools - How to best debug LaTeX? - TeX - LaTeX Stack Exchange -- a debugger is not impossible, but would be a huge amount of work. – user202729 Dec 04 '22 at 16:35
  • ... that having said I thought the requirement for posting on meta is 5 reputation? You have 45 so more than enough – user202729 Dec 04 '22 at 16:36
  • and usually Ulrich Diez's answers (one particular author, there's more) are of the "re-explain everything every time" kind. https://tex.stackexchange.com/a/629173/250119 ■ https://tex.stackexchange.com/a/605751/250119 should contain what you want. – user202729 Dec 04 '22 at 16:38
  • @user202729 my bad - I remember seeing I didn't have enough initially and misremembered it as 50. I'll post the meta discussion there. – David Fink Dec 04 '22 at 20:28

1 Answers1

1

It is a general rule that verb-like commands that make catcode changes may not be used in the argument of another command.

To see why you get a runaway argument VerbatimOut changes the interpretation of \ so that it is a normal character and \foo instead of making the single token with name foo it makes 4 character tokens \ f o o

So \end{VerbatimOut} would not be interpreted as \end with argument VerbatimOut in order to stop processing the environment checks for the string and ends the environment by hand.

But your definition is saved with normal catcodes in force

\newcommand*{\writeToFile}{
\begin{VerbatimOut}{myFileFromCommand.txt}
fromCommand
\end{VerbatimOut}
\input{myFileFromCommand.txt}
}

has an \end token a open group { token and character tokens VerbatimOut so the expected verbatim character tokens \end{VerbatimOut} are never found.

David Carlisle
  • 757,742
  • So \begin{VerbatimOut} is waiting to finish, looking for the sequence of 17 tokens: \ e n d { V e r b a t i m O u t } but it actually sees 14 tokens: \end { V e r b a t i m O u t }?

    (And in addition to the first token not matching, the { wouldn't match { because they have different catcodes?)

    – David Fink Dec 04 '22 at 20:48
  • Is there a "safety" setting that users can enable to catch mistakes like this with a meaningful error message, when a verb command is used somewhere it can't be?

    A similar question applies to invalid usage of "fragile" commands in general.

    – David Fink Dec 04 '22 at 20:56
  • 1
    @DavidFink yes to your first comment, no to your second – David Carlisle Dec 04 '22 at 20:57
  • @DavidFink Yes, to a limited extent. xparse's v-type argument kind of implement that, at the cost of (probably much, I didn't benchmark) slower parsing. – user202729 Dec 05 '22 at 07:42