2010-05-25 20 views
17

sto sperimentando con i miei comandi e degli ambienti e ora sto affrontando questi problemi: newcommand/ newenvironment - parametri opzionali

  1. Come creare comando \foo{parameter}[optional] o ambiente chiamata \begin{bar}{parameter}[optional]?
  2. Come creare comando \foo[optional_1]...[optional_n]{parameter}

Ho provato

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

Qualcuno sa qualche suggerimento? Molte grazie.

risposta

12

Usando il pacchetto xparse (parte degli sforzi di sviluppo 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 
} 

argomenti opzionali sono un po 'diverso in xparse a con \ newcommand. È possibile rilevare se uno è dato o no:

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

vedrai che funziona utilizzando un minuscolo 'o', mentre la maiuscola 'O' richiede quindi un valore di default (che ho reso vuoto includendo un gruppo vuoto).

+1

Mi dispiace per la risposta in ritardo, non ho avuto il tempo di provarlo. Grazie mille per aver aumentato il mio problema con più parametri – Crowley

+0

Non ho mai visto questo pacchetto prima, è davvero fantastico! –

15
  1. non è possibile creare un comando \foo{parameter}[optional] semplicemente; È possibile, tuttavia, creare un comando \foo[optional]{parameter} con

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

    Se si chiama come \foo{given}, esso produrrà Mandatory: given, optional: def; se lo chiami come \foo[optional]{given}, produrrà Mandatory: given, optional: optional. Questo è probabilmente il modo in cui dovresti farlo — che apparirà migliore con il resto del tuo codice LaTeX. La creazione di un nuovo ambiente con parametri opzionali è fatto in modo simile con

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

    dove # è di nuovo l'argomento opzionale; questo è di nuovo scritto come \begin{env}[opt]{req}...\end{env}. Se si in realtà desidera un comando nell'altro modulo, vedere la fine della mia risposta.

  2. Le domande frequenti su TeX hanno una risposta sulla scrittura di comandi con more than one optional argument. Ci sono due opzioni su come farlo. L'idea alla base è quella di definire un comando che accetta un argomento facoltativo e quindi esegue un altro comando che a sua volta prende un argomento facoltativo, ecc .; il pacchetto twoopt incapsula questo.


Se davvero vuole un comando come \reversed{mandatory}[optional], si può fare in questo modo. Innanzitutto, si definisce un comando che accetta un argomento obbligatorio, lo memorizza in una macro e quindi lo inoltra su un altro comando. Questo secondo comando accetta un argomento facoltativo e utilizza il comando definito e l'argomento facoltativo. Mettendo tutto insieme, otteniamo

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

È quindi possibile utilizzare \reversed{mandatory}[optional] o semplicemente \reversed{mandatory}, e tutto dovrebbe funzionare.

+2

+1 bel riassunto. Un problema particolare è se la macro viene utilizzata in modo errato, con l'argomento opzionale omesso: "\ reverse [optarg]". I messaggi di errore avranno una scarsa leggibilità con il tuo codice: vale la pena provare che \ reversed @ opt è uguale a "[" e contrassegnarlo come un errore fatale, se lo è. –

+1

Grazie. Non sono sicuro di cosa penso di controllare per '['-hai ragione che si comporterà inaspettatamente, ma in realtà ha un comportamento perfettamente definito (stampa 'Obbligatorio: [; opzionale: def', quindi composizione 'opzione]'). Il consiglio * effettivo * che vorrei dare è "non usare questa tecnica", mentre è tecnicamente possibile, probabilmente è una cattiva idea. –

+0

Grazie mille per il tempo dedicato a questo problema. – Crowley

4

Considerare anche il pacchetto xargs. Il seguente è un esempio dalla sua documentazione.

Set in su nel solito modo,

\usepackage{xargs} 

e poi se si definisce

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

(che significa usare "1" per il primo argomento, se non è specificato, e usare "n" per il terzo). Poi

$\coord{x}$ 

rendimenti (sans pedici)

(x1,..., Xn)

e

$\coord[0]{y}$ 

rendimenti (di nuovo, sans pedici)

(x0, ..., xn)