2010-01-27 11 views
35

Próbuję napisać proste przykładowe polecenie, które wypisuje nic bez argumentów, ale z argumentem otacza je czymś.LaTeX newcommand domyślny argument: jest pusty?

Czytałem, że wartość domyślna powinna być \@empty i prosty \ifx\@empty#1 warunek powinien wykonać zadanie:

\newcommand{\optarg}[1][\@empty]{% 
\ifx\@empty#1 {} \else {(((#1)))} \fi 
} 

\optarg % (((empty))) 
\optarg{} % (((empty))) 
\optarg{test} % (((empty))) test 

Te ostatnie trzy polecenia Wszystkie Drukuj ten empty słowo z jakiegoś powodu, i chcę pierwszy dwa, aby nic nie wydrukować, a ostatni wydrukować (((test))).

Używam TeXLive/Ubuntu. Pomysły?

Odpowiedz

40

Spróbuj następujący test:

\documentclass{article} 

\usepackage{xifthen}% provides \isempty test 

\newcommand{\optarg}[1][]{% 
    \ifthenelse{\isempty{#1}}% 
    {}% if #1 is empty 
    {(((#1)))}% if #1 is not empty 
} 

\begin{document} 

Testing \verb|\optarg|: \optarg% prints nothing 

Testing \verb|\optarg[]|: \optarg[]% prints nothing 

Testing \verb|\optarg[test]|: \optarg[test]% prints (((test))) 

\end{document} 

xifthen package zapewnia \ifthenelse konstrukcję i test \isempty.

Inną opcją jest użycie pakietu ifmtarg (dokumentację można znaleźć w dokumencie ifmtarg.sty file).

+0

Działa jak urok, dziękuję! :) – kolypto

8

W podstawowym silniku TeX, z którym jest napisany LaTeX, liczba argumentów, które może wykonać polecenie, jest stała. To, co zrobiłeś z domyślnym [\@empty], to poprosić LaTeX, aby zbadał następny token, aby sprawdzić, czy jest to otwarty kwadratowy nawias [. Jeśli tak, LaTeX bierze jako argument wartość nawiasów kwadratowych, jeśli nie, następny token jest umieszczany z powrotem w strumieniu wejściowym, a zamiast niego używany jest domyślny argument \@empty. Tak, aby uzyskać swój pomysł do pracy, trzeba użyć kwadrat wsporniki do oddzielania opcjonalnego argumentu, gdy są obecne:

\optarg 
\optarg[] 
\optarg[test] 

Powinieneś mieć więcej szczęścia z tego zapisu.

To denerwujące, że nie można używać tych samych nawiasów do opcjonalnego argumentu, jak w przypadku wymaganego argumentu, ale tak właśnie jest.

+0

Wow, dziękuję! Nigdy nie sądziłem, że nawiasy są tak ważne. Jednak problem pozostaje: '\ optarg' nadal daje mi' (((puste)) 'i' \ optarg [] = (((())) '(afaik to i tak nie powinno działać). Tylko '\ optarg [test]' jest teraz '((((test))) zgodnie z oczekiwaniami. – kolypto

+1

Wypróbuj '\ ifx! #! \ Else (((# #))) \ fi' i ustaw domyślny arg"! ". Jeśli to działa, możesz zmienić '!' Na coś, co jest mniej prawdopodobne, aby ktoś użył go przypadkowo. –

11

Używanie LaTeX3 pakiet pakiet xparse:

\usepackage{xparse} 
\NewDocumentCommand\optarg{g}{% 
    \IfNoValueF{#1}{(((#1)))}% 
} 
+0

Dziękujemy, że działa również, ale jest przeznaczony do stosowania w paczkach AFAIK. – kolypto

+1

Celem xparse jest zapewnienie kompletnej alternatywy dla \ newcommand. Nie ma powodu, dla którego nie można go użyć do jednorazowego polecenia w preambule dokumentu: Z pewnością (ale wtedy napisałem większość aktualnej implementacji xparse, chociaż podkreślam, że pomysły nie są naprawdę moje). Przykład w dokumentacji dotyczy głównie pakietów w tym momencie, ale napisałem artykuł TUGBoat dotyczący kolejnego problemu, który ma pewne zastosowania "dokumentacyjne". –

3
\documentclass{article} 

\usepackage{ifthen} % provides \ifthenelse test 
\usepackage{xifthen} % provides \isempty test 

\newcommand{\inlinenote}[2][]{% 
    {\bfseries{Note:}}% 
    \ifthenelse{\isempty{#1}} 
      {#2}    % if no title option given 
      {~\emph{#1} #2} % if title given 
} 

\begin{document} 

\inlinenote{ 
    simple note 
} 

\inlinenote[the title]{ 
    simple note with title 
} 

\end{document} 
Powiązane problemy