2

I am using xparse.sty to define a command that takes an optional argument in square brackets, and another one curly braces.

Problematically, it is not uncommon that the user will often want to begin the text after the command with square brackets. Since LaTex ignores spaces before the first optional argument, naively typing \myitem [not an argument] won't work, since "[not an argument]" will be considered an argument. MWE:

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand{\myitem}{ o g }{
    \IfValueTF{#1}{%
        []-argument:~#1
    }{
        \IfValueTF{#2}{
            \{\}-argument:~#2
        }{
            no~argument:~
        }
    }
}

\ExplSyntaxOff

\begin{document}
\myitem [Not intended as argument] 
% Will output: []-argument: Not intended as argument

\end{document}

What's worse, because \myitem also takes a g argument, the standard technique for avoiding this issue (inserting a pair of braces before or around the text in square brackets) won't work eiter:

\myitem {}[Not intended as argument]
% Will output {}-argument: [Not intended as argument]

\myitem {[Not intended as argument]}
% Will output {}-argument: [Not intended as argument]

The only workaround right now is to use \relax before the square brackets, which I would like to avoid.

Is it possible to make LaTeX treat the spaces as terminating the argument list in this case? I.e., \myitem [foo] should output no argument: foo, while \myitem[foo] should (still) output []-argument: foo?

  • 4
    Welcome to TeX.SX! Using g is provided, but it's not really recommended. Anyway, there is no space in \myitem [...], because of how TeX reads its input. – egreg Aug 27 '17 at 09:37
  • It is not clear why there should be an optional argument delimited with {} in this case. What's the purpose of this? –  Aug 27 '17 at 09:48
  • @egreg: That is what I feared (seeing as similar problems would come with any g argument). So I might have to simply give up on using that argument. – Sven Lauer Aug 27 '17 at 10:08
  • @ChristianHupfer Obviously, the command implementation is just a dummy for the sake of the MWE. In my package, I provide some enhancements (by means of different optional arguments) for and \item like command, and a g argument seemed like the natural choice for one them. Given this problem, I'll have to take that argument in another way (since I could live with users having to do the "standard technique" of using curly braces for avoiding that the part in square brackets is parsed as an argument). – Sven Lauer Aug 27 '17 at 10:12
  • Thank you for your comments! Forgive my asking (I am new here), but what is the TeX.SX etiquette in cases like this, where the answer is simply "can't be done"? Obviously, there is no answer to "accept" ... – Sven Lauer Aug 27 '17 at 10:24
  • @egreg Do you want to write up an answer or should someone else? – Joseph Wright Aug 27 '17 at 10:29
  • If you never want -argument with an empty argument, you can test the content of #2 and ignore if empty. Then you can write \mymacro{} [not an argument]. But using {} for optional arguments is not a good idea unless there's very strong reason to do it. – cfr Aug 27 '17 at 12:26
  • Thanks for the tip @cfr. I've decided to not use the {} optional argument, as my reasons were not strong (and I realized more problems, and thinking about it, it is obvious that this creates all kinds of strange behavior.

    I was unsure whether I should do it in the first place, though more because going against established conventions usually is a bad idea. I did not consider that it would also lead to problems on the implementation side.

    – Sven Lauer Aug 27 '17 at 12:49
  • Remark: if the command is guaranteed to only appear in top-level and not in command argument (i.e. where \verb can appear) then it's possible, see https://tex.stackexchange.com/a/472250/250119 and the linked question from below it. – user202729 Dec 30 '22 at 03:02

1 Answers1

2

By the standard reading rules of TeX, there is no space even if you type

\myitem [abc]

because the space is ignored when the line is read in. A way out would be

\myitem\relax[abc]

because \relax will stop the scanning for optional arguments.

It has always been a problem when a command accepting an optional argument is followed by [. Note that xparse does its best in order to balance the ] of the optional argument, but it's a different problem.

Of course \myitem{[not optional]} would work as well if there wasn't a g optional argument.

In general, I wouldn't recommend this argument specifier: it has been added because some user interfaces (notably beamer) provide this convention. However, it is against the standard LaTeX interface and could be confusing: please, think well before adopting this kind of syntax.

egreg
  • 1,121,712
  • Thanks for extended explanation! I suppose this question (& answer) can serve as an illustration why using the g-parameters is not a good idea. – Sven Lauer Aug 27 '17 at 14:47
  • Also Biblatex. At least, with the multi-cite commands, the first 2 {} arguments are required, but the next n arguments are optional .... – cfr Aug 27 '17 at 20:05