2010-01-27 3 views
35

Я пытаюсь написать простую команду примера, которая ничего не печатает без аргумента, но с аргументом она что-то окружает.LaTeX newcommand аргумент по умолчанию: пуст?

Я прочитал, что значение по умолчанию должно быть \@empty и простой \ifx\@empty#1 условие должно сделать работу:

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

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

Последние три команды все печатают на empty слово по какой-то причине, и я хочу, чтобы первый два - ничего не печатают, а последние печатают (((test))).

Я использую TeXLive/Ubuntu. Идеи?

ответ

40

Попробуйте следующий тест:

\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 обеспечивает \ifthenelse конструкцию и испытание \isempty.

Другим вариантом является использование пакета ifmtarg (см. Документацию ifmtarg.sty file).

+0

Работает как очарование, спасибо! :) – kolypto

8

В базовом процессоре TeX, с которым написан LaTeX, исправлено количество аргументов, которые может принять команда. То, что вы сделали со значением по умолчанию [\@empty], попросит LaTeX изучить следующий токен, чтобы увидеть, является ли он открытой квадратной скобкой [. Если это так, LaTeX берет содержимое квадратных скобок в качестве аргумента, если нет, следующий токен возвращается во входной поток, а вместо него используется аргумент \@empty по умолчанию. Таким образом, чтобы получить вашу идею работать, вы должны использовать значение квадрата скобки, чтобы разграничить дополнительный аргумент, когда присутствует:

\optarg 
\optarg[] 
\optarg[test] 

Вы должны лучше удач с этой записью.

Досадно, что вы не можете использовать те же самые скобки для необязательного аргумента, сколько вы используете для требуемого аргумента, но так оно и есть.

+0

Вау, спасибо! Никогда не считалось, что скобки важны. Однако проблема остается: '\ optarg' все еще дает мне' (((empty))) 'и' \ optarg [] = (())) '(afaik это не должно работать в любом случае). Только '\ optarg [test]' теперь '(((test)))' как ожидалось. – kolypto

+1

Попробуйте '\ ifx! #! \ Else (((# 1))) \ fi' и сделайте по умолчанию arg'! '. Если это работает, вы можете изменить '!' На то, что кто-то менее вероятно использует случайно. –

11

Использование LaTeX3 xparse пакет:

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

Спасибо, что тоже работает, но предназначен для использования в пакетах AFAIK. – kolypto

+1

Цель xparse - предоставить полную альтернативу \ newcommand. Нет причин, по которым вы не можете использовать его для одноразовой команды в преамбуле документа: я конечно делаю (но тогда я написал большую часть текущей реализации xparse, хотя я бы подчеркнул, что идеи не действительно мой). Пример в документации в основном относится к пакетам на данный момент, но я написал статью TUGBoat для следующей проблемы, использующей некоторые «документы». –

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}