\def - primitive
\def の引数における空白の処理
のように定義して, 以下の場合を考えてみる.\def\somecs#1\+#2\plus#3+#4\+{1: [#1] \quad 2: [#2] \quad 3: [#3] \quad 4: [#4]}
第一例では, 当然ながら \somecs と解釈されない. 第二例では, \plusc と解釈されて \somecs の定義に沿わないため, \somecs が imcomplete となる. 第三例では, control sequence \somecs と \plus の後の空白は無視されるが, control symbol \+ と通常の文字である + の後の空白はそのまま引数に含まれる. 最後の第四例では, 当然ながらどの場合も引数の最後の空白はそのまま引数に含められる.\somecsa\+b\plusc+d\+
! Undefined control sequence.
\somecs a\+b\plusc+d\+
! Paragraph ended before \somecs was complete.
\somecs a\+b\plus c+d\+
1: [a] 2: [b] 3: [c] 4: [d]
\somecs a\+ b\plus c+ d\+
1: [a] 2: [ b] 3: [c] 4: [ d]
\somecs a \+b \plus c +d \+
1: [a ] 2: [b ] 3: [c ] 4: [d ]
\zap@space
\ignorespaces
\tracingmacros
正の値にすると,
log に macro の展開結果が記録される.
\@ifdefinable
\long\def\@ifdefinable #1#2{%
\edef\reserved@a{\expandafter\@gobble\string #1}%
\@ifundefined\reserved@a
{\edef\reserved@b{\expandafter\@carcube \reserved@a xxx\@nil}%
\ifx \reserved@b\@qend \@notdefinable\else
\ifx \reserved@a\@qrelax \@notdefinable\else
#2%
\fi
\fi}%
\@notdefinable}
\let\@@ifdefinable\@ifdefinable
\long\def\@rc@ifdefinable#1#2{%
\let\@ifdefinable\@@ifdefinable
#2}
用法
\@ifdefinable{\somecs}{macro}
↓\edef\reserved@a{\expandafter\@gobble\string \somecs}%
\@ifundefined\reserved@a
{\edef\reserved@b{\expandafter\@carcube \reserved@a xxx\@nil}%
\ifx \reserved@b\@qend \@notdefinable\else
\ifx \reserved@a\@qrelax \@notdefinable\else
macro%
\fi
\fi}%
\@notdefinable}
↓\edef\reserved@a{\@gobble\somecs}%
\@ifundefined\reserved@a
{\edef\reserved@b{\expandafter\@carcube \reserved@a xxx\@nil}%
\ifx \reserved@b\@qend \@notdefinable\else
\ifx \reserved@a\@qrelax \@notdefinable\else
macro%
\fi
\fi}%
\@notdefinable}
↓\edef\reserved@a{somecs}%
\@ifundefined\reserved@a
{\edef\reserved@b{\expandafter\@carcube \reserved@a xxx\@nil}%
\ifx \reserved@b\@qend \@notdefinable\else
\ifx \reserved@a\@qrelax \@notdefinable\else
macro%
\fi
\fi}%
\@notdefinable}
↓
\gdef\@notdefinable{%
\@latex@error{%
Command \@backslashchar\reserved@a\space
already defined.\MessageBreak
Or name \@backslashchar\@qend... illegal,
see p.192 of the manual}\@eha}
\edef\@qend{\expandafter\@cdr\string\end\@nil}
\edef\@qrelax{\expandafter\@cdr\string\relax\@nil}
\newcommand
\def\newcommand{\@star@or@long\new@command}
\def\new@command#1{%
\@testopt{\@newcommand#1}0}
\@testopt により option をとるかどうかを判定する.
Option が与えられていない場合は, \@newcommand#1[0] を実行.
\def\@newcommand#1[#2]{%
\@ifnextchar [{\@xargdef#1[#2]}%
{\@argdef#1[#2]}}
\long\def\@argdef#1[#2]#3{%
\@ifdefinable #1{\@yargdef#1\@ne{#2}{#3}}}
\long\def\@xargdef#1[#2][#3]#4{%
\@ifdefinable#1{%
\expandafter\def\expandafter#1\expandafter{%
\expandafter
\@protected@testopt
\expandafter
#1%
\csname\string#1\endcsname
{#3}}%
\expandafter\@yargdef
\csname\string#1\endcsname
\tw@
{#2}%
{#4}}}
\def\@protected@testopt#1{%%
\ifx\protect\@typeset@protect
\expandafter\@testopt
\else
\@x@protect#1%
\fi}
\long\def\@yargdef#1#2#3{%
\@tempcnta#3\relax
\advance \@tempcnta \@ne
\let\@hash@\relax
\edef\reserved@a{\ifx#2\tw@ [\@hash@1]\fi}%
\@tempcntb #2%
\@whilenum\@tempcntb <\@tempcnta
\do{%
\edef\reserved@a{\reserved@a\@hash@\the\@tempcntb}%
\advance\@tempcntb \@ne}%
\let\@hash@##%
\l@ngrel@x\expandafter\def\expandafter#1\reserved@a}
\long\def\@reargdef#1[#2]{%
\@yargdef#1\@ne{#2}}
\renewcommand
\def\renewcommand{\@star@or@long\renew@command}
\def\renew@command#1{%
\begingroup \escapechar\m@ne\xdef\@gtempa{{\string#1}}\endgroup
\expandafter\@ifundefined\@gtempa
{\@latex@error{\noexpand#1undefined}\@ehc}%
\relax
\let\@ifdefinable\@rc@ifdefinable
\new@command#1}
\DeclareRobustCommand
\def\DeclareRobustCommand{\@star@or@long\declare@robustcommand}
\DeclareRobustCommand* とすると, \l@ngrel@x が \long になる.
\def\declare@robustcommand#1{%
\ifx#1\@undefined\else\ifx#1\relax\else
\@latex@info{Redefining \string#1}%
\fi\fi
\edef\reserved@a{\string#1}%
\def\reserved@b{#1}%
\edef\reserved@b{\expandafter\strip@prefix\meaning\reserved@b}%
\edef#1{%
\ifx\reserved@a\reserved@b
\noexpand\x@protect
\noexpand#1%
\fi
\noexpand\protect
\expandafter\noexpand\csname
\expandafter\@gobble\string#1 \endcsname
}%
\let\@ifdefinable\@rc@ifdefinable
\expandafter\new@command\csname
\expandafter\@gobble\string#1 \endcsname
}