특수 문자가 포함된 매크로 이름

특수 문자가 포함된 매크로 이름

특수 문자가 포함된 매크로 이름을 만들 수 있나요?

다음과 같은 이름을 가진 매크로를 만들고 싶습니다.\s1.4또한 Test가 매크로 이름의 일부로 처리되지 않는 곳에서 사용할 수 있습니다 \s1.4Test(기본적으로 float 뒤의 모든 항목은 매크로 이름의 일부로 제외됩니다).

기본적으로 이것은 두 개의 추가 문자를 추가하는 작업을 피하는 것이며 \s{1.4}Text내 목적에는 \s1.4문제가 없습니다(나는 \s1.xx가 매크로의 일부가 아니기 때문에 결코 모호함이 없을 것이라고 기대하지 않을 것입니다).

그런데 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}$}

관련 정보