2

In this answer, @UlrichDiez created a macro \InnerCreateTheorem, as follows:

\NewDocumentCommand{\InnerCreateTheorem}{mmmod<>}{%
   % #1 = star or no star
   % #2 = name of environment
   % #3 = emptiness or star to append to name of environment
   % #4 = numbered like
   % #5 = numbered within
   \IfBooleanTF{#1}{%
     \IfValueTF{#4}{\@firstoftwo}{\IfValueTF{#5}{\@firstoftwo}{\@secondoftwo}}%
   }{\IfValueTF{#4}{\IfValueTF{#5}{\@firstoftwo}{\@secondoftwo}}{\@secondoftwo}}%
   {%
    \GenericError{}%
                 {\string\CreateTheorem\space syntax error\on@line}%
                 {You cannot call the starred variant with optional arguments.\MessageBreak
                  You cannot call the unstarred variant with several optional arguments.}%
                 {%
                   Allowed usage:\MessageBreak\MessageBreak
                   \CreateTheorem*{(name of environment)}\MessageBreak
                   \CreateTheorem{(name of environment)}[(numbered like)]\MessageBreak
                   \CreateTheorem{(name of environment)}<(numbered within)>\MessageBreak
                   \CreateTheorem{(name of environment)}\MessageBreak
                   Captions come from macros \string\(name of environment)nameEN\MessageBreak
                   respective \string\(name of environment)nameFR.\MessageBreak
                   These macros must be defined separately.%
                 }%
   }{%
     %% ...
   }%
}%

However, I was confused about this. As I understood (according to this question), \@firstoftwo corresponds to {\GenericError ...} and \@secondoftwo corresponds to {%%...}. But \GenericError seems to have four cases, so under which circumstances would each one show up?

Jinwen
  • 8,518
  • Your definition contains a superfluous "condition" for the first argument, since it's mandatory. – Werner Mar 08 '21 at 04:29
  • @Werner Sorry, I didn't understand your meaning. Could you please be more specific? – Jinwen Mar 08 '21 at 05:08
  • You test for \IfBooleanTF{#1} and state in the comments that argument #1 is an optional star/not. However, that would require a parameter specification that resembles smmod<>, not mmmod<>. – Werner Mar 08 '21 at 05:27
  • @Werner Right, but this is because the s is processed in \CreateTheorem, which then calls the \InnerCreateTheorem above with {*} or {} (I didn't add the definition of \CreateTheorem here because it is irrelevant to this question). I doubt if this is the best way, but it certainly works. – Jinwen Mar 08 '21 at 05:30
  • @Werner Be aware that \InnerCreateTheorem's test on #1 is not \IfValueTF but is \IfBooleanTF. The first argument, #1, is passed in by another macro (\CreateTheorem) and holds tokens denoting the value of the boolean after evaluating that other macro's s-type-argument. So it denotes whether in the other macro (\CreateTheorem) a star was present or not. Thus that condition is not superfluous. – Ulrich Diez Mar 08 '21 at 17:25
  • 1
    @Jinwen The first argument of \CreateTheorem is s-type. This means: In case there is no star, #1 of \CreateTheorem consists of tokens that denote the boolean-value "false". In case there is a star, #1 of \CreateTheorem consists of tokens that denote the boolean-value "true". These tokens are passed on to \InnerCreateTheorem as it's 1st argument, an m-type-argument. So \InnerCreateTheorem can fork whether in \CreateTheorem a star was present by evaluating its 1st argument via \IfBooleanTF. (Not \IfValueTF which is used for testing o-type arguments, btw.) This ... – Ulrich Diez Mar 08 '21 at 17:38
  • @Jinwen ... This has nothing to do with {*}/{}. {*}/{} is passed as 3rd argument to \InnerCreateTheorem depending on whether the name of the environment to define ends with a star or not. {*}/{} is needed because you commented that you wish fooEN*, not foo*EN. In the hope that it clarifies things a bit I added some commenting about the meaning of arguments in my answer referred by you. I should have done this earlier, so I apologize. – Ulrich Diez Mar 08 '21 at 18:15

1 Answers1

2

GenericError does take four arguments, but they don't identify four different cases in which to issue an error. Instead the four argument represent (part of ltxerror.dtx; see the LaTeX2e source documentation):

  1. a continuation,
  2. an error message,
  3. where to go for further information, and
  4. the help information.

So, with \@firstoftwo, you'll see an error generated by \GenericError.

Werner
  • 603,163
  • What does "a continuation" mean? I looked at the documentation but it's not clear. – Paul Wintz Aug 11 '23 at 23:45
  • 1
    @PaulWintz: It's what is inserted as part of the line-break in the error message. So, if the error message is lengthy and has line breaks, you can insert "a continuation" - something at the start of each line that was broken. See this code for \PackageError from the LaTeX2e source - the first argument specifies (ethel) and some spaces as the "continuation" (the first argument of \PackageError is passed on as the first argument to \GenericError). – Werner Aug 22 '23 at 04:45