Jak utworzyć polecenie z opcjonalnymi argumentami w LaTeX? Coś jak:
\newcommand{\sec}[2][]{
\section*{#1
\ifsecondargument
and #2
\fi}
}
}
Wtedy mogę to nazwać tak
\sec{Hello}
%Output: Hello
\sec{Hello}{Hi}
%Output: Hello and Hi
latex
optional-arguments
Verhogen
źródło
źródło
Odpowiedzi:
Przykład z przewodnika :
\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.
źródło
Ogólną ideą tworzenia „argumentów opcjonalnych” jest najpierw zdefiniowanie polecenia pośredniego, które skanuje naprzód, aby wykryć, jakie znaki pojawią się jako następne w strumieniu tokenów, a następnie wstawia odpowiednie makra, aby odpowiednio przetworzyć nadchodzące argumenty. Może to być dość żmudne (choć nie trudne) przy użyciu ogólnego programowania TeX. LaTeX
\@ifnextchar
jest całkiem przydatny do takich rzeczy.Najlepszą odpowiedzią na Twoje pytanie jest skorzystanie z nowego
xparse
pakietu. Jest częścią pakietu programowania LaTeX3 i zawiera rozbudowane funkcje definiowania poleceń z dość dowolnymi opcjonalnymi argumentami.W twoim przykładzie masz
\sec
makro, które przyjmuje jeden lub dwa argumenty stężone. Zostałoby to zaimplementowane przy użyciuxparse
:Argument
{ m g }
definiuje argumenty\sec
;m
oznacza „argument obowiązkowy” ig
jest „opcjonalnym argumentem napiętym”.\IfNoValue(T)(F)
można następnie użyć do sprawdzenia, czy drugi argument był rzeczywiście obecny, czy nie. Zobacz dokumentację dla innych typów opcjonalnych argumentów, które są dozwolone.źródło
(Hello and ) (Hello and Hi)
Wszystko to pokazuje, że ciężko jest stworzyć ładną, elastyczną (lub zabronić przeciążonej) funkcji w LaTeX !!! (ten kod TeX wygląda dla mnie jak grecki)
cóż, żeby dodać mój niedawny (aczkolwiek nie tak elastyczny) rozwój, oto czego ostatnio użyłem w mojej pracy doktorskiej, z
\usepackage{ifthen} % provides conditonals...
Uruchom polecenie, domyślnie ustawiane jako puste polecenie „opcjonalne”:
\newcommand {\figHoriz} [4] [] {
Następnie każę makro ustawić zmienną tymczasową \ temp {}, w różny sposób 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 przy użyciu zmiennej \ temp {} w dwóch przypadkach. (Tutaj po prostu ustawia krótki podpis tak, aby był równy długiemu podpisowi, 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, który dostarcza \ newcommand {}. Gdybyś miał ustawić to dla, powiedzmy, 3 "opcjonalnych" argumentów, nadal musiałbyś wysłać 3 puste argumenty ... np.
\MyCommand {first arg} {} {} {}
co jest dość głupie, wiem, ale to mniej więcej na tyle, na ile mam zamiar posunąć się do LaTeX-a - po prostu nie jest to aż tak sensowne, kiedy zacznę patrzeć na kod TeX-a ... Podoba mi się jednak metoda xparse pana Robertsona, być może ja spróbuję ...
źródło
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
źródło
x^2+1
lubx^{2+1}
Mam pytanie, czy twoje polecenie sprawdza obecność szelek? Czy jest możliwe utworzenie polecenia LaTeX, które będzie\sec
dawało: „A, b, c i d” dla polecenia\sec{A}[b,c,d]
, „A i b” dla\sec{A}[b] and "A" for
\ sec {A} `?\sec{A}[b,c,d]
lub\sec{A}[b]
lub\sec{A}
.Miałem podobny problem, gdy chciałem utworzyć polecenie,
\dx
aby skrócić\;\mathrm{d}x
(tj. Wstawić dodatkową spację przed różniczką całki i ustawić „d” w pozycji pionowej). Ale chciałem też uczynić go na tyle elastycznym, aby zawierał zmienną integracji jako opcjonalny argument. W preambule umieściłem następujący kod.\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
źródło
Oto moja próba, ale nie jest dokładnie zgodna z twoimi specyfikacjami. Nie w pełni przetestowany, więc bądź ostrożny.
\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"
źródło