it-swarm.dev

Argumenty opcjonalne LaTeX

Jak utworzyć komendę z opcjonalnymi argumentami w LaTeX? Coś jak:

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

Potem mogę to tak nazwać

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

Przykład z przewodnik :

\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

Ogólną ideą tworzenia „opcjonalnych argumentów” jest najpierw zdefiniowanie polecenia pośredniego, które skanuje z wyprzedzeniem, aby wykryć, które znaki będą pojawiać się w strumieniu tokena, a następnie wstawi odpowiednie makra, aby przetworzyć nadchodzące argumenty odpowiednio. Może to być dość żmudne (choć nie trudne) przy użyciu ogólnego programowania TeX. \@ifnextchar LaTeXa jest bardzo przydatne do takich rzeczy.

Najlepszą odpowiedzią na twoje pytanie jest użycie nowego pakietu xparse. Jest częścią pakietu programistycznego LaTeX3 i zawiera obszerne funkcje do definiowania poleceń z dość dowolnymi opcjonalnymi argumentami.

W twoim przykładzie masz makro \sec, Które przyjmuje jeden lub dwa sparowane argumenty. Zostałoby to zaimplementowane przy użyciu xparse z następującymi elementami:

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

Argument { m g } Definiuje argumenty \sec; m oznacza „argument obowiązkowy”, a g jest „opcjonalnym argumentem wzmocnionym”. \IfNoValue(T)(F) można następnie wykorzystać do sprawdzenia, czy drugi argument rzeczywiście był obecny, czy nie. Zobacz dokumentację innych dopuszczalnych typów argumentów opcjonalnych.

24
Will Robertson

Wszystkie powyższe pokazują, że w LaTeXie może być fajna, elastyczna (lub zabraniająca przeciążania) funkcja !!! (ten kod TeX wygląda dla mnie jak grecki)

cóż, aby dodać mój niedawny (choć nie tak elastyczny) rozwój, oto, czego ostatnio użyłem w mojej pracy dyplomowej, z

\usepackage{ifthen}  % provides conditonals...

Uruchom polecenie, domyślnie puste ustawienie „opcjonalne”:

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

Następnie ustawiam makro zmienną tymczasową\temp {}, w zależności od tego, czy opcjonalny argument jest pusty. Można to rozszerzyć na dowolny przekazany argument.

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

Następnie uruchamiam makro za pomocą zmiennej\temp {} dla dwóch przypadków. (Tutaj ustawia tylko krótki podpis na równy z długim podpisem, jeśli nie został określony przez użytkownika).

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

W tym przypadku sprawdzam tylko pojedynczy „opcjonalny” argument dostarczony przez\newcommand {}. Jeśli miałbyś ustawić na przykład 3 „opcjonalne” argumenty, nadal musiałbyś wysłać 3 puste argumenty ... np.

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

co jest dość głupie, wiem, ale to tak daleko, jak mam zamiar pójść z LaTeX - to po prostu nie jest tak sensowne, kiedy zacznę patrzeć na kod TeX ... Jednak lubię metodę Xparse pana Robertsona, być może ja Spróbuję ...

22
Demis

Wszystko czego potrzebujesz to:

\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

Miałem podobny problem, kiedy chciałem utworzyć polecenie, \dx, w skrócie \;\mathrm{d}x (tj. wstaw dodatkowe spacje przed różnicą całki i ustaw „d” również pionowo). Ale potem chciałem również uczynić go wystarczająco elastycznym, aby uwzględnić zmienną integracji jako opcjonalny argument. Umieszczam następujący kod w preambule.

\usepackage{ifthen}

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

Następnie

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

daje \ dx z opcjonalnym argumentem

4
csar