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.)

5

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}%
}
  • 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 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 at 10:39
  • 1
    @jan That's the danger of asking XY-questions. – egreg Apr 17 at 10:42
  • sorry :/ I was trying to keep it general and minimal ... – jan Apr 17 at 10:44
  • 2
    @jan OK, but that completely hides the aim. I added the code – egreg Apr 17 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

  • 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 at 11:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.