Question

Comment créez-vous 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
Était-ce utile?

La solution

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.

Autres conseils

L'idée générale derrière la création de " arguments optionnels " est d’abord définir une commande intermédiaire qui balaye pour détecter les caractères à venir dans le flux de jetons, puis insère les macros appropriées pour traiter le ou les arguments à 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 très arbitraires.

Dans votre exemple, vous avez une macro \ sec qui prend un ou deux arguments entre accolades. Ceci serait implémenté en utilisant xparse avec les éléments suivants:

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

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

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 à un grec pour moi)

bon, 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 l'option " optionnel " jeu de commandes 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 à n’importe quel 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 recherche que l'élément unique, "facultatif". argument que \ newcommand {} fournit. Si vous deviez le configurer pour, par exemple, 3 "facultatif" args, vous devez toujours envoyer les 3 args vierges ... par exemple.

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

ce qui est assez stupide, je 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 ... J'aime quand même la méthode xparse de M. Robertson , peut-être que je vais l'essayer ...

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

J'ai eu un problème similaire, lorsque je voulais créer une commande, \ dx , pour abréger \; \ mathrm {d} x (c.-à-d. mettre un espace supplémentaire avant le différentiel de l'intégrale et avoir le "d" vertical aussi). 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}}
}

Alors

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

donne \ dx avec l'argument facultatif

Voici ma tentative, elle ne suit pas exactement vos spécifications. Pas complètement testé, alors soyez prudent.

\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"
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top