web-dev-qa-db-fra.com

Arguments optionnels LaTeX

Comment créer une commande avec des arguments optionnels dans LaTeX? Quelque chose comme:

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

Ensuite, je peux l'appeler comme

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

Exemple tiré du guide :

\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.
155
miku

L'idée générale derrière la création "d'arguments facultatifs" est de définir tout d'abord une commande intermédiaire qui analyse en avant pour détecter les caractères à venir dans le flux de jetons, puis insère les macros appropriées pour traiter l'argument (s) à venir, le cas échéant. Cela peut être assez fastidieux (bien que pas difficile) en utilisant la programmation générique TeX. Le \@ifnextchar De LaTeX est très utile pour de telles choses.

La meilleure réponse à votre question consiste à utiliser le nouveau package xparse. Il fait partie de la suite de programmation LaTeX3 et contient de nombreuses fonctionnalités pour définir des commandes avec des arguments optionnels assez arbitraires.

Dans votre exemple, vous avez une macro \sec Qui prend un ou deux arguments. Ceci serait implémenté en utilisant xparse avec ce qui suit:

\documentclass {article} 
\usepackage {xparse} 
\begin {document} 
\DeclareDocumentCommand\sec {mg} {% 
 { # 1% 
\IfNoValueF {# 2} {et # 2}% 
}% 
} 
 (\ Sec {Bonjour}) 
 (\ sec {Bonjour} {Bonjour}) 
\end {document} 

L'argument { m g } Définit les arguments de \sec; m signifie "argument obligatoire" et g est "argument facultatif entre accolades". \IfNoValue(T)(F) peut ensuite être utilisé pour vérifier si le deuxième argument était bien présent ou non. Consultez la documentation pour connaître les autres types d'arguments facultatifs autorisés.

24
Will Robertson

Tout ce qui précède montre qu’il est difficile de créer une fonction agréable et flexible (ou d’interdire une surcharge) dans LaTeX !!! (ce code TeX ressemble à du grec pour moi)

eh bien, juste pour ajouter mon développement récent (bien que pas aussi flexible), voici ce que j’ai récemment utilisé dans mon mémoire de thèse, avec

\usepackage{ifthen}  % provides conditonals...

Lancez la commande avec la commande "facultative" définie vide par défaut:

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

La macro a ensuite défini une variable temporaire,\temp {}, différemment selon que l’argument optionnel est vide ou non. Cela pourrait être étendu à tout argument passé.

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

Ensuite, je lance la macro en utilisant la variable\temp {} pour les deux cas. (Ici, il suffit de définir la légende courte pour qu'elle corresponde à la légende longue si elle n'a pas été spécifiée par l'utilisateur).

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

Dans ce cas, je ne vérifie que le seul argument "optionnel" fourni par\newcommand {}. Si vous deviez le configurer pour, par exemple, 3 arguments "optionnels", vous auriez encore à envoyer les 3 arguments vides ... par exemple.

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

ce qui est assez stupide, je le sais, mais c'est à peu près tout ce que je vais faire avec LaTeX - ce n'est tout simplement pas si logique une fois que je commence à regarder le code TeX ... allez l'essayer ...

22
Demis

Tout ce dont vous avez besoin est le suivant:

\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
13
Alexey Malistov

J'ai eu un problème similaire, quand je voulais créer une commande, \dx, pour abréger \;\mathrm{d}x _ (c’est-à-dire placez un espace supplémentaire avant le différentiel de l’intégrale et placez également le "d" droit). Mais j’ai aussi voulu rendre suffisamment souple l’inclusion de la variable d’intégration comme argument optionnel. Je mets le code suivant dans le préambule.

\usepackage{ifthen}

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

Ensuite

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

donne \ dx avec argument optionnel

4
csar