2010-01-27 7 views
35

Ich versuche, einen einfachen Beispielbefehl zu schreiben, der nichts ohne ein Argument ausgibt, aber mit einem Argument umgibt es etwas.LaTeX newcommand Standardargument: ist leer?

Ich habe gelesen, dass der Standardwert \@empty und die einfache \ifx\@empty#1 Bedingung sollte die Arbeit machen sollte:

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

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

Die letzten drei Befehle alle empty Wort aus irgendeinem Grund zu drucken, und ich möchte, dass die erste zwei, um nichts zu drucken und das letzte zu drucken (((test))).

Ich benutze TeXLive/Ubuntu. Eine Idee?

Antwort

40

Versuchen Sie, den folgenden 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} 

Die xifthen package bietet das \ifthenelse Konstrukt und die \isempty Test.

Eine weitere Option ist die Verwendung des ifmtarg Pakets (für die Dokumentation siehe ifmtarg.sty file).

+0

Funktioniert wie ein Charme, danke! :) – kolypto

8

In der zugrunde liegenden TeX-Engine, mit der LaTeX geschrieben wird, ist die Anzahl der Argumente, die ein Befehl ausführen kann, festgelegt. Was Sie mit dem Standard [\@empty] getan haben, ist LaTeX bitten, das nächste Token zu untersuchen, um zu sehen, ob es eine offene eckige Klammer [ ist. Wenn dies der Fall ist, nimmt LaTeX den Inhalt von eckigen Klammern als Argument an, wenn nicht, wird das nächste Token in den Eingabestrom zurückgelegt, und stattdessen wird das Standardargument \@empty verwendet. So Ihre Idee zu arbeiten, müssen Sie Platz Klammern verwenden, um das optionale Argument abgrenzen, wenn vorhanden:

\optarg 
\optarg[] 
\optarg[test] 

Sie sollten mit dieser Schreibweise mehr Glück haben.

Es ist ärgerlich, dass Sie nicht die gleichen Klammern für ein optionales Argument verwenden können, wie Sie für ein benötigtes Argument verwenden, aber so ist es.

+0

Wow, danke! Nie dachte Klammern sind so wichtig. Das Problem bleibt jedoch bestehen: '\ optarg' gibt mir noch' (((leer))) 'und' \ optarg [] = ((())) '(afaik sollte das sowieso nicht funktionieren). Nur '\ optarg [test]' ist jetzt '(((test)))' wie erwartet. – kolypto

+1

Probieren Sie '\ ifx! #! \ Else (((# (1)))) aus und geben Sie das Standardarg'! 'Ein. Wenn das funktioniert, können Sie das '!' In etwas ändern, das jemand aus Versehen weniger wahrscheinlich benutzt. –

11

Mit dem LaTeX3 xparse Paket:

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

Danke, das funktioniert auch, aber ist entworfen, um in Paketen AFAIK verwendet werden. – kolypto

+1

Ziel von xparse ist es, eine vollständige Alternative zu \ newcommand bereitzustellen. Es gibt keinen Grund, warum man es nicht für einen einmaligen Befehl in der Präambel eines Dokuments verwenden kann: Ich mache es zwar (aber dann habe ich den größten Teil der aktuellen Implementierung von xparse geschrieben, obwohl ich betonen möchte, dass die Ideen dies nicht sind wirklich mein). Das Beispiel in der Dokumentation bezieht sich hauptsächlich auf Pakete im Moment, aber ich habe einen TUGBoat-Artikel für die nächste Ausgabe geschrieben, die einige "Dokumente" verwendet. –

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}