5

I'm trying to construct a command with one optional and one mandatory argument and I'd like the default if the optional argument is not provided to be #2.

Why does this not work? (error: Illegal parameter number ...)

\documentclass{article} 
\newcommand{\mycommand}[2][#2]{\label{#1}#2}
\begin{document}
\mycommand{mytext}
\end{document}

And what would be a way around it?

EDIT:
For clarification of my specific use case: I'm trying to define a command that passes a variable on as an option to an environment along those lines, where myenv can have options like optionone=X or optiontwo=Y so the default for the optional #1 should be optionone=#2 (not literally #2).

\newcommand{\mycommand}[2][optionone=#2]{\begin{myenv}[#1]\input{#2}\end{myenv}}

Maybe there's generally a better approach? (The environment definition I'm using is from here.)

2 Answers 2

6

There are several ways to do it.

Classical method

\makeatletter
\newcommand{\mycommand}{\@dblarg\my@command}
\def\my@command[#1]#2{\label{#1}#2}
\makeatother

xparse

\usepackage{xparse}
\NewDocumentCommand{\mycommand}{O{#2}m}{\label{#1}#2}

Your use case

\NewDocumentCommand{\mycommand}{O{optionone=#2}m}{%
 \begin{myenv}[#1]\input{#2}\end{myenv}%
}
5
  • Thank you, this works with the very minimal example here, but I ran into this problem in the context of trying to pass options to an environment, so eventually I don't want the default #1 to be exactly #2 --- I don't think I understand the \def\my@command[#1]#2 syntax, I tried: \def\my@command[#1]option=#2{\label{#1}#2} but that doesn't work ...
    – jan
    Apr 17, 2019 at 10:36
  • I've edited the question for clarification of the specific use case. Also, could you explain the reason why the original solution doesn't work?
    – jan
    Apr 17, 2019 at 10:39
  • 1
    @jan That's the danger of asking XY-questions.
    – egreg
    Apr 17, 2019 at 10:42
  • sorry :/ I was trying to keep it general and minimal ...
    – jan
    Apr 17, 2019 at 10:44
  • 2
    @jan OK, but that completely hides the aim. I added the code
    – egreg
    Apr 17, 2019 at 10:48
3

Here, \mycommand determines if there is 1 or 2 arguments, and passes the result off to \mycommandaux, which handles both arguments, whether repeated or not.

\documentclass{article} 
\newcommand\mycommand[2][\relax]{%
  \ifx\relax#1%
    \mycommandaux{#2}{#2}%
  \else
    \mycommandaux{#1}{#2}%
  \fi
}
\newcommand\mycommandaux[2]{Arguments 1,2: [#1]\{#2\}}
\begin{document}
\mycommand{xyz}

\mycommand[xyz]{pdq}
\end{document} 

enter image description here

Trying to conform more to the OP's edited example

\documentclass{article} 
\usepackage[T1]{fontenc}
\newcommand\mycommand[2][\relax]{%
  \ifx\relax#1%
    \mycommandaux{optionone=#2}{#2}%
  \else
    \mycommandaux{#1}{#2}%
  \fi
}
\newcommand\mycommandaux[2]{\detokenize{\begin{myenv}[#1]\input{#2}\end{myenv}}}
\begin{document}
\mycommand{ABC}

\mycommand[optiontwo=xyz]{pdq}
\end{document} 

enter image description here

1
  • This is great too, thank you! egreg was a little faster and it's somewhat simpler (provided I use xparse) so I accepted his, but I appreciate your help ...
    – jan
    Apr 17, 2019 at 11:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .