특수 문자가 포함된 매크로 이름을 만들 수 있나요?
다음과 같은 이름을 가진 매크로를 만들고 싶습니다.\s1.4또한 Test가 매크로 이름의 일부로 처리되지 않는 곳에서 사용할 수 있습니다 \s1.4Test
(기본적으로 float 뒤의 모든 항목은 매크로 이름의 일부로 제외됩니다).
기본적으로 이것은 두 개의 추가 문자를 추가하는 작업을 피하는 것이며 \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 예제이지만 라텍스에서 작동하고 \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
하나 이상의 숫자, 선택적 점 및 선택적 숫자로 시작하는 문자열입니다.
\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
마침표 뒤의 두 번째 숫자가 한 자리인 경우 다음을 사용할 수 있습니다.
\def\s#1.#2{$_\mathbf{#1.#2}$}