162

LaTeXでオプションの引数を持つコマンドをどのように作成しますか? 何かのようなもの:

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

次に、次のように呼び出すことができます

\sec{Hello}
%Output: Hello
\sec{Hello}{Hi}
%Output: Hello and Hi
4

6 に答える 6

223

ガイドの例:

\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.
于 2009-11-28T10:50:19.093 に答える
30

「オプションの引数」を作成する背後にある一般的な考え方は、トークン ストリームで次に来る文字を検出するために前方にスキャンする中間コマンドを最初に定義し、次に、適切な引数を処理するために関連するマクロを挿入することです。これは、一般的な TeX プログラミングを使用すると、非常に面倒な場合があります (難しくはありませんが)。LaTeX\@ifnextcharは、そのような場合に非常に便利です。

あなたの質問に対する最良の答えは、新しいxparseパッケージを使用することです。これは LaTeX3 プログラミング スイートの一部であり、非常に任意のオプション引数を使用してコマンドを定義するための広範な機能が含まれています。

あなたの例では、\sec1 つまたは 2 つの中括弧付き引数を取るマクロがあります。xparseこれは、以下を使用して実装されます。

\documentclass{記事}
\usepackage{xparse}
\begin{ドキュメント}
\DeclareDocumentCommand\sec{ mg }{%
    {#1%
        \IfNoValueF {#2} { and #2}%
    }%
}
(\sec{こんにちは})
(\sec{こんにちは}{こんにちは})
\end{ドキュメント}

引数は、の{ m g }引数を定義します\secmは「必須の引数」を意味し、g「オプションの中括弧付き引数」です。\IfNoValue(T)(F)次に、2 番目の引数が実際に存在するかどうかを確認するために使用できます。許可されているその他のタイプのオプション引数については、ドキュメントを参照してください。

于 2009-11-28T11:32:00.073 に答える
29

上記のすべては、LaTeX で素敵で柔軟な (またはオーバーロードを禁止する) 関数を作成するのが難しいことを示しています!!! (その TeX コードは私にはギリシャ語のように見えます)

さて、私の最近の(柔軟性はありませんが)開発を追加するために、これが私が最近論文ドキュメントで使用したものです。

\usepackage{ifthen}  % provides conditonals...

「オプション」コマンドをデフォルトで空白に設定して、コマンドを開始します。

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

次に、マクロに一時変数 \temp{} を設定させます。これは、オプションの引数が空白かどうかによって異なります。これは、渡された任意の引数に拡張できます。

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

次に、2 つのケースで \temp{} 変数を使用してマクロを実行します。(ここでは、ユーザーによって指定されていない場合、短いキャプションが長いキャプションと等しくなるように設定します)。

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

この場合、\newcommand{} が提供する単一の「オプション」引数のみをチェックします。たとえば、3 つの「オプションの」引数を設定する場合でも、3 つの空白の引数を送信する必要があります。

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

これはかなりばかげていることはわかっていますが、それは私がLaTeXで行こうとしている限りです-TeXコードを見始めると、それほど意味がありません...私はRobertson氏のxparseメソッドが好きですが、おそらく私はやってみます...

于 2011-09-06T04:30:39.350 に答える
11

必要なものは次のとおりです。

\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
于 2009-11-28T12:57:36.533 に答える
-1

これが私の試みですが、あなたの仕様に正確に従っていません。完全にテストされていないため、注意してください。

\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"
于 2009-12-02T03:50:05.267 に答える