Вопрос

Как создать команду с необязательными аргументами в LaTeX?Что -то вроде:

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

Тогда я могу назвать это следующим образом

\sec{Hello}
%Output: Hello
\sec{Hello}{Hi}
%Output: Hello and Hi
Это было полезно?

Решение

Пример из руководства

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

Другие советы

Общая идея создания " необязательных аргументов " состоит в том, чтобы сначала определить промежуточную команду, которая сканирует вперед, чтобы определить, какие символы появляются в потоке токенов, а затем вставляет соответствующие макросы для обработки подходящего аргумента (аргументов). Это может быть довольно утомительно (хотя и не сложно) при использовании общего программирования TeX. \ @ ifnextchar от LaTeX весьма полезен для таких вещей.

Лучший ответ на ваш вопрос - использовать новый пакет xparse . Он является частью пакета программирования LaTeX3 и содержит широкие возможности для определения команд с совершенно произвольными необязательными аргументами.

В вашем примере у вас есть макрос \ sec , который принимает один или два квадратных аргумента. Это будет реализовано с использованием xparse со следующим:

\documentclass{article}
\usepackage{xparse}
\begin{document}
\DeclareDocumentCommand\sec{ m g }{%
    {#1%
        \IfNoValueF {#2} { and #2}%
    }%
}
(\sec{Hello})
(\sec{Hello}{Hi})
\end{document}

Аргумент {m g} определяет аргументы \ sec ; m означает " обязательный аргумент " и g является " необязательным аргументом в скобках " ;. Затем можно использовать \ IfNoValue (T) (F) , чтобы проверить, действительно ли присутствовал второй аргумент или нет. См. Документацию для других типов необязательных аргументов, которые разрешены.

Все вышесказанное показывает, насколько сложно создать красивую, гибкую (или запретить перегруженную) функцию в LaTeX!!!(этот текстовый код для меня выглядит как греческий)

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

\usepackage{ifthen}  % provides conditonals...

Запустите команду с "необязательной" командой, по умолчанию установленной пустой:

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

Затем я прошу макрос установить временную переменную emp{} по-разному в зависимости от того, является ли необязательный аргумент пустым.Это может быть распространено на любой переданный аргумент.

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

Затем я запускаю макрос, используя переменную emp{} для этих двух случаев.(Здесь он просто устанавливает короткий заголовок равным длинному заголовку, если он не был указан пользователем).

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

В этом случае я проверяю только один "необязательный" аргумент, который предоставляет ewcommand{}.Если бы вы настроили его, скажем, для 3 "необязательных" аргументов, вам все равно пришлось бы отправить 3 пустых аргумента...например.

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

это довольно глупо, я знаю, но это примерно все, что я собираюсь сделать с LaTeX - просто это не так уж и бессмысленно, как только я начинаю смотреть на TeX-код...Мне действительно нравится мистерХотя, возможно, я попробую метод xparse Робертсона...

Все, что вам нужно, это следующее:

\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

У меня была похожая проблема, когда я хотел создать команду \ dx для сокращения \; \ mathrm {d} x (то есть поставить дополнительный пробел перед дифференциалом от интеграла и иметь «d» также в вертикальном положении). Но затем я также хотел сделать его достаточно гибким, чтобы включить переменную интеграции в качестве необязательного аргумента. Я вставил следующий код в преамбулу.

\usepackage{ifthen}

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

Тогда

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

дает \ dx с необязательным аргументом

Вот моя попытка, она не совсем соответствует вашим спецификациям. Проверено не полностью, поэтому будьте осторожны.

\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"
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top