次のコードが動作しないのはなぜですか?
\Requirepackage{amsthm}
\renewcommand\newtheorem[2]{%
\NewEnviron{\csname #1\endcsname}[1]{%
##1 : \BODY
}
}
引数なしの for マクロの使用例は見たことがありますが、複数の引数を持つまたは\csname SOMENAME\endcsname
でそれを実行する方法がわかりません。エラー が表示されます。\NewEnviron
\newcommand
! Missing \endcsname inserted
答え1
環境名にコマンド名は必要ありません。名前だけで十分です。
つまり、次のようにすることができます:
\documentclass{article}
\usepackage{amsthm,environ}
\renewcommand\newtheorem[2]{%
\NewEnviron{#1}[1]{%
##1 : \BODY
}%
}
\begin{document}
\newtheorem{acorns}{oaks}
\begin{acorns}{trees}
leaves and things
\end{acorns}
\end{document}
このコードではアムスム\newcommand\newtheorem...
他の理由でパッケージが必要でない限り、 を使用することもできます。
また、必須となるようにコマンドを作成したとしても、2 番目の引数については何も行いません。上記の例では、 については何も行われませんoaks
。
これが本当にあなたがやりたいことなのかはわかりません。上記のコードの出力は次のようになります。
としてクリスチャン・フプファーは指摘するもちろん、これは\newtheorem
標準的な意味で使用しているものをすべて破壊します。エグレは言う、このように再定義することにどのような目的があるのか全く明らかではありません\newtheorem
。遅かれ早かれ問題を引き起こすことはほぼ確実のようです...おそらくもっと早くに。
答え2
次のコードが機能しないのはなぜですか?
次のことを詳しく見てみましょう\NewEnviron
。
短いマクロ チェーンの後、ユーザー入力を適切に解析するには、最初に使用したマクロ\NewEnviron
を使用します。\env@newenvironment
\let
\newenvironment
さて、\newenvironment
内部的には(少し簡略化して)次のようなことを行っています。
\expandafter\def\csname <env-name>\endcsname{<begin-code>}
(基本的に、内部ですでにこれが処理されていることを知らずに、正しいことを行いました。)
「 」を設定すると<env-name>=\csname SOMENAME\endcsname
(カスタム マクロを次のように使用することで発生します\newtheorem{SOMENAME}{}
)、余分なペアが生成されます\csname...\endcsname
。
\expandafter\def\csname\csname SOMENAME\endcsname\endcsname...
\expandafter
(おそらくご存知のとおり)この場合、\def
次のトークンを先読みするためにそれを取得して保存し、最初にこれを展開します。ここで、\csname
次のトークンを探し\endcsname
、その間にあるすべてのものを展開して、そこから制御シーケンスを形成します。これは、\csname
末尾の によって再び正しく終了する別のものです\endcsname
。つまり、実際にはメカニズムを 'SOMENAME' に 2 回適用し、 (計画どおりに)では\csname
なく、次のようになります。\def\SOMENAME{<begin-code>}
\def\<expansion of \SOMENAME>{<begin-code>}
が定義されていれば、\SOMENAME
問題は発生しませんでした。
\documentclass{article}
\usepackage{environ}
\def\SOMENAME{somename}
\NewEnviron{\csname SOMENAME\endcsname}{somename-content: \BODY}
\begin{document}
\begin{somename}
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Integer feugiat tempus urna, cursus placerat sapien mollis ac.
Donec a accumsan orci, in tristique ligula.
\end{somename}
\end{document}
しかし、あなたはない定義してください。このユーザー インターフェイスは、何らかの誤解を招く可能性があります。環境名の入力に関しては、\NewEnviron
次のように正確に使用してください。\newenvironment
\documentclass{article}
\usepackage{environ}
\newcommand{\FlorianEnvdefWrapper}[1]{%
\NewEnviron{#1}[1]{##1: \BODY}
}
\FlorianEnvdefWrapper{somename}
\begin{document}
\begin{somename}{foo-bar}
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Integer feugiat tempus urna, cursus placerat sapien mollis ac.
Donec a accumsan orci, in tristique ligula.
\end{somename}
\end{document}
述べる
パッケージとの衝突を避けるために、サンプル マクロの名前を変更しましたamsthm
。一般的には、そのままにしておく方が良いと思います。もちろん例外もありますが、コマンドに別の名前を選択するだけで回避できる場合、機能を完全に失うことは最善の選択肢ではないかもしれません。