2010-05-25 24 views
17

estoy experimentando con mis propios comandos y entornos y ahora estoy frente a esos problemas: newcommand/ newenvironment - parámetros opcionales

  1. Cómo crear comandos \foo{parameter}[optional] o entorno llamada \begin{bar}{parameter}[optional]?
  2. Cómo crear comandos \foo[optional_1]...[optional_n]{parameter}

He intentado

\newcommand{\foo}[3][][]{#1#2#3} - failed 
\newcommand{\foo}[3][2][][]{#1#2#3} - failed 

¿Alguien sabe alguna pista? Muchas gracias.

Respuesta

12

Usando el paquete xparse (parte de los esfuerzos de desarrollo LaTeX3):

\usepackage{xparse} 
\NewDocumentCommand\foo{O{}O{}m}{% 
    % Code with optional #1 and #2 with empty defaults 
} 
\NewDocumentCommand\foo{mO{}}{% 
    % Code with optional #2 with empty default 
} 
\NewDocumentEnvironment{foo}{O{}}{% 
% Start code with optional #1 
}{% 
% End code with optional #1 
} 

argumentos opcionales son un poco diferentes en xparse a con \ newcommand. Puede detectar si uno se da o no:

\NewDocumentCommand\foo{mo}{% 
    \IfNoValueTF{#2} 
    {Code without #2} 
    {Code with #2}% 
} 

verá que esto funciona mediante el uso de una minúscula 'o', mientras que la mayúscula 'O' requiere entonces un valor por defecto (que he hecho vacío al incluir un grupo vacío).

+1

Lamento la respuesta tardía, no tuve tiempo de probarlo. Muchas gracias por resolver mi problema con múltiples parámetros – Crowley

+0

Nunca antes había visto este paquete, ¡eso es genial! –

15
  1. No se puede crear un comando \foo{parameter}[optional] simplemente; puede, sin embargo, crear un comando \foo[optional]{parameter} con

    \newcommand{\foo}[2][def]{Mandatory: #2; optional: #1} 
    

    Si llama como \foo{given}, producirá Mandatory: given, optional: def; si lo llama como \foo[optional]{given}, producirá Mandatory: given, optional: optional. Esta es probablemente la forma en que debe hacerlo — que se verá mejor con el resto de su código LaTeX. Creación de un nuevo entorno con parámetros opcionales se realiza de manera similar con

    \newenvironment{env}[2][def]{(#1,#2)\begingroup}{\endgroup} 
    

    donde # es de nuevo el argumento opcional; esto se escribe nuevamente como \begin{env}[opt]{req}...\end{env}. Si realmente quiere un comando en la otra forma, vea el final de mi respuesta.

  2. Las preguntas frecuentes de TeX tienen una respuesta sobre cómo escribir comandos con more than one optional argument. Hay dos opciones de cómo hacerlo. La idea subyacente es definir un comando que toma un argumento opcional, y luego ejecuta otro comando que toma un argumento opcional, etc .; el paquete twoopt encapsula esto.


Si realmente desea un comando como \reversed{mandatory}[optional], puede hacerlo como tal. Primero, define un comando que toma un argumento requerido, lo almacena en una macro y lo reenvía a otro comando. Este segundo comando toma un argumento opcional y usa el comando definido y el argumento opcional. Poniendo todo esto junto, obtenemos

\makeatletter 
\newcommand{\reversed}[1]{\def\[email protected]{#1}\[email protected]} 
\newcommand{\[email protected]}[1][def]{Required: \[email protected]; optional: #1} 
\makeatother 

A continuación, puede utilizar \reversed{mandatory}[optional] o simplemente \reversed{mandatory}, y todo debería funcionar.

+2

+1 buen resumen. Un problema particular es si la macro se usa incorrectamente, con la opción opcional arg omitida: "\ reversed [optarg]". Los mensajes de error tendrán poca legibilidad con su código: vale la pena probar para \ reverseed @ opt siendo igual a "[" y marcar esto como un error fatal si lo es. –

+1

Gracias. No estoy seguro de lo que pienso al verificar '' '-tienes razón de que se comportará inesperadamente, pero en realidad tiene un comportamiento perfectamente bien definido (imprimiendo 'Requerido: [; opcional: def', y luego tipográficamente] 'optarg]'). El * consejo * real que le daría es "no use esta técnica", si bien es técnicamente posible, probablemente sea una mala idea. –

+0

Muchas gracias por su tiempo dedicado a este tema. – Crowley

4

Considere también el paquete xargs. El siguiente es un ejemplo de su documentación.

configurarlo en la forma habitual,

\usepackage{xargs} 

y luego si se define

\newcommandx*\coord[3][1=1, 3=n]{(#2_{#1},\ldots,#2_{#3})} 

(lo que significa utilizar "1" para el primer argumento, si no se especifica, y usar "n" para el tercero). Entonces

$\coord{x}$ 

rendimientos (sans subíndices)

(x1,..., Xn)

y

$\coord[0]{y}$ 

rendimientos (de nuevo, sans subíndices)

(x0, ..., xn)

Cuestiones relacionadas