Argomenti opzionali LaTeX


Risposte:


176

Esempio dalla guida :

\newcommand{\example}[2][YYY]{Mandatory arg: #2;
                                 Optional arg: #1.}

This defines \example to be a command with two arguments, 
referred to as #1 and #2 in the {<definition>}--nothing new so far. 
But by adding a second optional argument to this \newcommand 
(the [YYY]) the first argument (#1) of the newly defined 
command \example is made optional with its default value being YYY.

Thus the usage of \example is either:

   \example{BBB}
which prints:
Mandatory arg: BBB; Optional arg: YYY.
or:
   \example[XXX]{AAA}
which prints:
Mandatory arg: AAA; Optional arg: XXX.

21
Penso che la domanda fosse su come determinare se fosse stato fornito un argomento facoltativo, non fornendo un valore predefinito.
Konrad Rudolph,

43
Sebbene sia vero, ho trovato questa domanda mentre cercavo un modo per fornire un argomento predefinito, quindi questa risposta è stata la più utile per me.
Tanner Swett,

26

L'idea generale alla base della creazione di "argomenti opzionali" è innanzitutto definire un comando intermedio che scansiona in avanti per rilevare quali caratteri verranno visualizzati successivamente nel flusso di token e quindi inserirà le macro pertinenti per elaborare gli argomenti che si presentano in modo appropriato. Questo può essere abbastanza noioso (anche se non difficile) utilizzando la programmazione TeX generica. LaTeX \@ifnextcharè abbastanza utile per queste cose.

La migliore risposta alla tua domanda è usare il nuovo xparsepacchetto. Fa parte della suite di programmazione LaTeX3 e contiene ampie funzionalità per la definizione di comandi con argomenti opzionali abbastanza arbitrari.

Nel tuo esempio hai una \secmacro che accetta uno o due argomenti rinforzati. Questo verrebbe implementato usando xparsequanto segue:

\ Documentclass {article}
\ Usepackage {} xparse
\ Begin {document}
\ DeclareDocumentCommand \ sec {mg} {%
    {# 1%
        \ IfNoValueF {# 2} {e # 2}%
    }%
}
(\ Sec {Ciao})
(\ Sec {Ciao} {} Hi)
\ End {document}

L'argomento { m g }definisce gli argomenti di \sec; msignifica "argomento obbligatorio" ed gè "argomento rinforzato opzionale". \IfNoValue(T)(F)può quindi essere utilizzato per verificare se il secondo argomento era effettivamente presente o meno. Consultare la documentazione per gli altri tipi di argomenti facoltativi consentiti.


4
Volere! Non funziona. Uscita:(Hello and ) (Hello and Hi)
Alexey Malistov,

Grazie per il feedback, Alexey. Sospetto che tu stia utilizzando una versione precedente di xparse; c'è stato molto lavoro fatto di recente. TeX Live 2009 è appena stato rilasciato :)
Will Robertson il

24

Tutto quanto sopra mostra che può essere difficile realizzare una funzione piacevole, flessibile (o proibire un sovraccarico) in LaTeX !!! (quel codice TeX mi sembra greco)

bene, solo per aggiungere il mio recente sviluppo (anche se non altrettanto flessibile), ecco quello che ho usato di recente nel mio documento di tesi, con

\usepackage{ifthen}  % provides conditonals...

Avviare il comando, con il comando "opzionale" impostato in bianco per impostazione predefinita:

\newcommand {\figHoriz} [4] []  {

Ho quindi impostato la macro una variabile temporanea, \ temp {}, in modo diverso a seconda che l'argomento facoltativo sia vuoto o meno. Questo potrebbe essere esteso a qualsiasi argomento passato.

\ifthenelse { \equal {#1} {} }  %if short caption not specified, use long caption (no slant)
    { \def\temp {\caption[#4]{\textsl{#4}}} }   % if #1 == blank
    { \def\temp {\caption[#1]{\textsl{#4}}} }   % else (not blank)

Quindi eseguo la macro usando la variabile \ temp {} per i due casi. (Qui imposta semplicemente la didascalia in modo che sia uguale alla didascalia lunga se non è stata specificata dall'utente).

\begin{figure}[!]
    \begin{center}
        \includegraphics[width=350 pt]{#3}
        \temp   %see above for caption etc.
        \label{#2}
    \end{center}
\end{figure}
}

In questo caso, controllo solo il singolo argomento "facoltativo" fornito da \ newcommand {}. Se dovessi configurarlo per, diciamo, 3 arg "opzionali", dovresti comunque inviare i 3 arg vuoti ... ad es.

\MyCommand {first arg} {} {} {}

il che è abbastanza sciocco, lo so, ma questo è quanto mi spingerò verso LaTeX - non è poi così sensato una volta che inizio a guardare il codice TeX ... Mi piace il metodo xparse del signor Robertson però, forse io lo proverò ...


Mi piace questo approccio. È più "simile alla programmazione" e quindi più facile da leggere. Buon lavoro!
amato da Gesù, il

11

Tutto ciò che serve è il seguente:

\makeatletter
\def\sec#1{\def\tempa{#1}\futurelet\next\sec@i}% Save first argument
\def\sec@i{\ifx\next\bgroup\expandafter\sec@ii\else\expandafter\sec@end\fi}%Check brace
\def\sec@ii#1{\section*{\tempa\ and #1}}%Two args
\def\sec@end{\section*{\tempa}}%Single args
\makeatother

\sec{Hello}
%Output: Hello
\sec{Hello}{Hi}
%Output: Hello and Hi

Ho pensato che TeX comprenda come parametro il conteggio appropriato delle prime 'caselle' dopo il comando. questa 'scatola' è scritta con parentesi graffe o è un simbolo. Vale a dire. x^2+1o x^{2+1} Quindi ho una domanda, il tuo comando verifica la presenza di parentesi graffe? È possibile creare il comando LaTeX \secproducendo: "A, b, c e d" per il comando \sec{A}[b,c,d], "A e b" per \sec{A}[b] and "A" for \ sec {A} `?
Crowley,

Hai due domande. 1) Sì, il mio comando verifica la presenza di parentesi graffe. 2) Sì, è possibile creare macro per \sec{A}[b,c,d]o \sec{A}[b]o \sec{A}.
Alexey Malistov,

6

Ho avuto un problema simile, quando volevo creare un comando, \dxper abbreviare \;\mathrm{d}x(cioè mettere uno spazio extra prima del differenziale dell'integrale e avere anche la "d" in posizione verticale). Ma poi volevo anche renderlo abbastanza flessibile da includere la variabile di integrazione come argomento facoltativo. Ho inserito il seguente codice nel preambolo.

\usepackage{ifthen}

\newcommand{\dx}[1][]{%
   \ifthenelse{ \equal{#1}{} }
      {\ensuremath{\;\mathrm{d}x}}
      {\ensuremath{\;\mathrm{d}#1}}
}

Poi

\begin{document}
   $$\int x\dx$$
   $$\int t\dx[t]$$
\end{document}

\ dx con argomento facoltativo


-1

Ecco il mio tentativo, non segue esattamente le tue specifiche. Non completamente testato, quindi sii cauto.

\newcount\seccount

\def\sec{%
    \seccount0%
    \let\go\secnext\go
}

\def\secnext#1{%
    \def\last{#1}%
    \futurelet\next\secparse
}

\def\secparse{%
    \ifx\next\bgroup
        \let\go\secparseii
    \else
        \let\go\seclast
    \fi
    \go
}

\def\secparseii#1{%
    \ifnum\seccount>0, \fi
    \advance\seccount1\relax
    \last
    \def\last{#1}%
    \futurelet\next\secparse
}

\def\seclast{\ifnum\seccount>0{} and \fi\last}%

\sec{a}{b}{c}{d}{e}
% outputs "a, b, c, d and e"

\sec{a}
% outputs "a"

\sec{a}{b}
% outputs "a and b"
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.