LaTeXのオプションの引数


132

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

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

次に、私はそれを次のように呼ぶことができます

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

回答:


176

ガイドからの例:

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

21
問題は、デフォルトを提供するのではなく、オプションの引数が指定されているかどうかを判断する方法に関するものだったと思います。
Konrad Rudolph、

43
それは事実ですが、デフォルトの引数を提供する方法を探しているときにこの質問を見つけたので、この回答は私にとって最も有用なものでした。
Tanner Swett、2013年

26

「オプションの引数」の作成の背後にある一般的な考え方は、トークンストリームで次に登場する文字を検出するために先にスキャンする中間コマンドを最初に定義し、関連するマクロを挿入して、必要に応じて出現する引数を処理することです。これは、一般的なTeXプログラミングを使用する場合、(難しくはないものの)かなり退屈な作業になる可能性があります。LaTeX \@ifnextcharはそのようなものに非常に役立ちます。

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

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

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

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


4
意志!それは動作しません。出力:(Hello and ) (Hello and Hi)
Alexey Malistov 2009年

フィードバックをありがとう、アレクセイ。古いバージョンのxparseを使用していると思います。最近、多くの作業が行われています。TeX Live 2009がリリースされました:)
ウィルロバートソン、

24

上記のすべてが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メソッドが好きなのかもしれませんが、やってみます...


私はこのアプローチが好きです。より「プログラミングのような」ため、読みやすくなります。よくやった!
loved.by.Jesus

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

TeXはパラメーターとして、コマンド後の最初の「ボックス」の適切な数として理解できると思いました。この「ボックス」は中括弧で書かれているか、1つの記号です。つまり。x^2+1またはx^{2+1} 私は質問があります、あなたのコマンドは中括弧の存在をテストしますか?LaTeXコマンドを\sec生成して作成することは可能ですか?コマンドの「A、b、c、d \sec{A}[b,c,d]」、\sec{A}[b] and "A" for \ sec {A} `の「A、b」?
クローリー

2つの質問があります。1)はい、私のコマンドはブレースの存在をテストします。2)はい、\sec{A}[b,c,d]または\sec{A}[b]またはのマクロを作成できます\sec{A}
Alexey Malistov 2009年

6

同様の問題があり、\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を与える


-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"
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.