Domanda

Come si crea un comando con argomenti opzionali in LaTeX? Qualcosa del tipo:

\newcommand{\sec}[2][]{
    \section*{#1
        \ifsecondargument
            and #2
        \fi}
    }
}

Quindi, posso chiamarlo come

\sec{Hello}
%Output: Hello
\sec{Hello}{Hi}
%Output: Hello and Hi
È stato utile?

Soluzione

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.

Altri suggerimenti

L'idea generale dietro la 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) usando la programmazione TeX generica. Il \ @ifnextchar di LaTeX è abbastanza utile per queste cose.

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

Nel tuo esempio hai una macro \ sec che accetta uno o due argomenti rinforzati. Questo sarebbe implementato usando xparse con il seguente:

\documentclass{article}
\usepackage{xparse}
\begin{document}
\DeclareDocumentCommand\sec{ m g }{%
    {#1%
        \IfNoValueF {#2} { and #2}%
    }%
}
(\sec{Hello})
(\sec{Hello}{Hi})
\end{document}

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

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

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

\usepackage{ifthen}  % provides conditonals...

Avvia il comando, con il " opzionale " comando impostato vuoto per impostazione predefinita:

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

Ho quindi impostato la macro una variabile temporanea, \ temp {}, in modo diverso a seconda che l'argomento opzionale sia vuoto. 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, cerco solo il singolo, " opzionale " argomento fornito da \ newcommand {}. Se dovessi configurarlo per, diciamo, 3 "facoltativo" Args, dovresti comunque inviare i 3 args 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 , forse ci proverò ...

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 avuto un problema simile, quando volevo creare un comando, \ dx , per abbreviare \; \ mathrm {d} x (ovvero mettere uno spazio extra prima del differenziale dell'integrale e avere anche la "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}}
}

Quindi

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

fornisce \ dx con argomento facoltativo

Ecco il mio tentativo, ma 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"
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top