特殊文字を含むマクロ名を作成することは可能ですか?
次のような名前のマクロをいくつか作成したいと思います。\s1.4\s1.4Test
また、Test がマクロ名の一部として扱われないような場合(基本的に、float の後の部分はマクロ名の一部として除外されます)でも使用できるようになります。
基本的に、これは 2 つの余分な文字を追加する を実行することを避けるためのもの\s{1.4}Text
で、私の目的には\s1.4
問題はありません ( のようなことは決してなく\s1.x
、 x はマクロの一部ではないと想定されるため、あいまいさは決して発生しません)。
ちなみに、私は foreach を使用してこれらを定義しています:
\makeatletter
\foreach \m in {1.1, 2.2}
{
\expandafter\protected@xdef\csname s\m\endcsname{$_\mathbf{\m}$}
}
\makeatother
答え1
単純な TeX の例ですが、LaTeX でも動作します。より\s
単純ですが、.
\t
より複雑ですが、整数を受け入れます。
\def\s#1.{%
\def\tmp{#1.}%
\afterassignment\xxs\count0= }
\def\xxs{\csname s\tmp\the\count0\endcsname}
%%%%%%%%%%%%%%%%%%%
\def\t{\afterassignment\xxt\count0= }
\def\xxt{\futurelet\tmp\xxxt}
\def\xxxt{%
\if.\noexpand\tmp
\expandafter\xxxxt
\else
\csname s\the\count0\expandafter\endcsname
\fi}
\def\xxxxt.{\afterassignment\xtx\count2= }
\def\xtx{\csname s\the\count0.\the\count2\endcsname}
%%%%%%%%%%%%%%%%%%%
\expandafter\def\csname s1.4\endcsname{one point four }
\expandafter\def\csname s2.6\endcsname{ten point six }
\expandafter\def\csname s5\endcsname{five }
%%%%%%%%%%%%%%%%%%%
\s1.4more text \s2.6 and more
\t1.4more text \t2.6 and more and \t5 yet more
\bye
答え2
次の例のマクロは\s
数字とドットを収集し、質問に示されているように太字の下付き文字としてタイプセットします。LaTeX は\@ifnextchar
次のトークンを探すときにスペースを取り込んでしまうため、使用できません。
\documentclass{article}
\usepackage{ltxcmds}[2011/04/14]
\makeatletter
\newcommand*{\s}{%
\begingroup
\let\tmp\ltx@empty
\s@aux
}
\newcommand*{\s@aux}{%
\ltx@ifnextchar@nospace{.}{%
\edef\tmp{\tmp.}%
\expandafter\s@aux\ltx@gobble
}{\ltx@ifnextchar@nospace{0}{%
\edef\tmp{\tmp0}%
\expandafter\s@aux\ltx@gobble
}{\ltx@ifnextchar@nospace{1}{%
\edef\tmp{\tmp1}%
\expandafter\s@aux\ltx@gobble
}{\ltx@ifnextchar@nospace{2}{%
\edef\tmp{\tmp2}%
\expandafter\s@aux\ltx@gobble
}{\ltx@ifnextchar@nospace{3}{%
\edef\tmp{\tmp3}%
\expandafter\s@aux\ltx@gobble
}{\ltx@ifnextchar@nospace{4}{%
\edef\tmp{\tmp4}%
\expandafter\s@aux\ltx@gobble
}{\ltx@ifnextchar@nospace{5}{%
\edef\tmp{\tmp5}%
\expandafter\s@aux\ltx@gobble
}{\ltx@ifnextchar@nospace{6}{%
\edef\tmp{\tmp6}%
\expandafter\s@aux\ltx@gobble
}{\ltx@ifnextchar@nospace{7}{%
\edef\tmp{\tmp7}%
\expandafter\s@aux\ltx@gobble
}{\ltx@ifnextchar@nospace{8}{%
\edef\tmp{\tmp8}%
\expandafter\s@aux\ltx@gobble
}{\ltx@ifnextchar@nospace{9}{%
\edef\tmp{\tmp9}%
\expandafter\s@aux\ltx@gobble
}{%
\expandafter\s@end\expandafter{\tmp}%
}}}}}}}}}}}%
}
\newcommand*{\s@end}[1]{%
\endgroup
\ensuremath{_\mathbf{#1}}%
}
\makeatother
\begin{document}
\s1.4Test and \s2more.
\end{document}
アップデート
\s
の後に数字とドットが続かない場合、または数字/ドットの文字列が定義されていない場合は、エラー メッセージを含むマッピング レイヤーを簡単に追加できます。
\documentclass{article}
\usepackage{pgffor}
\usepackage{ltxcmds}[2011/04/14]
\makeatletter
\foreach \m in {1.1, 1.4, 2, 2.2}{%
\expandafter\protected@xdef\csname s\m\endcsname{$_\mathbf{\m}$}%
}
\newcommand*{\s}{%
\begingroup
\let\tmp\ltx@empty
\s@aux
}
\newcommand*{\s@aux}{%
\ltx@ifnextchar@nospace{.}{%
\edef\tmp{\tmp.}%
\expandafter\s@aux\ltx@gobble
}{\ltx@ifnextchar@nospace{0}{%
\edef\tmp{\tmp0}%
\expandafter\s@aux\ltx@gobble
}{\ltx@ifnextchar@nospace{1}{%
\edef\tmp{\tmp1}%
\expandafter\s@aux\ltx@gobble
}{\ltx@ifnextchar@nospace{2}{%
\edef\tmp{\tmp2}%
\expandafter\s@aux\ltx@gobble
}{\ltx@ifnextchar@nospace{3}{%
\edef\tmp{\tmp3}%
\expandafter\s@aux\ltx@gobble
}{\ltx@ifnextchar@nospace{4}{%
\edef\tmp{\tmp4}%
\expandafter\s@aux\ltx@gobble
}{\ltx@ifnextchar@nospace{5}{%
\edef\tmp{\tmp5}%
\expandafter\s@aux\ltx@gobble
}{\ltx@ifnextchar@nospace{6}{%
\edef\tmp{\tmp6}%
\expandafter\s@aux\ltx@gobble
}{\ltx@ifnextchar@nospace{7}{%
\edef\tmp{\tmp7}%
\expandafter\s@aux\ltx@gobble
}{\ltx@ifnextchar@nospace{8}{%
\edef\tmp{\tmp8}%
\expandafter\s@aux\ltx@gobble
}{\ltx@ifnextchar@nospace{9}{%
\edef\tmp{\tmp9}%
\expandafter\s@aux\ltx@gobble
}{%
\ifx\tmp\@empty
\@latex@error{\string\s: no digits/dots found}\@ehc
\else
\@ifundefined{s\tmp}{%
\@latex@error{\string\s: Undefined `\tmp'}\@ehc
}{%
\@nameuse{s\tmp}%
}%
\fi
\endgroup
}}}}}}}}}}}%
}
\makeatother
\begin{document}
\s1.4Test and \s2more.
\end{document}
次の例では、解析された引数は、\s
1 つ以上の数字、オプションのドット、およびオプションの数字で始まる文字列です。
\documentclass{article}
\usepackage{pgffor}
\usepackage{ltxcmds}[2011/04/14]
\makeatletter
\foreach \m in {1.1, 1.4, 2, 2.2}{%
\expandafter\protected@xdef\csname s\m\endcsname{$_\mathbf{\m}$}%
}
\newcommand*{\s}{%
\begingroup
\let\s@tmp\ltx@empty
\futurelet\s@tok\s@startnum
}
\newcommand*{\s@startnum}{%
\s@digit\s@digitordot
\s@next
}
\newcommand*{\s@digit}[1]{%
\def\s@next{\s@add#1}%
\ifx0\s@tok
\else\ifx1\s@tok
\else\ifx2\s@tok
\else\ifx3\s@tok
\else\ifx4\s@tok
\else\ifx5\s@tok
\else\ifx6\s@tok
\else\ifx7\s@tok
\else\ifx8\s@tok
\else\ifx9\s@tok
\else
\let\s@next\s@end
\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
}
\newcommand*{\s@add}[2]{%
\edef\s@tmp{\s@tmp#2}%
\futurelet\s@tok
#1%
}
\newcommand*{\s@digitordot}{%
\let\s@next\s@end
\ifx.\s@tok
\def\s@next{\s@add\s@endnum}%
\else
\s@digit\s@digitordot
\fi
\s@next
}
\newcommand*{\s@endnum}{%
\s@digit\s@endnum
\s@next
}
\newcommand*{\s@end}{%
\ifx\s@tmp\@empty
\@latex@error{\string\s: no digits/dots found}\@ehc
\else
\@ifundefined{s\s@tmp}{%
\@latex@error{\string\s: Undefined `\s@tmp'}\@ehc
}{%
\@nameuse{s\s@tmp}%
}%
\fi
\endgroup
}
\makeatother
\begin{document}
\s1.4Test and \s2more.
\end{document}
答え3
ピリオドの後の 2 番目の数字が 1 桁のみの場合は、次のように使用できます。
\def\s#1.#2{$_\mathbf{#1.#2}$}