É possível criar nomes de macros com caracteres especiais?
Eu gostaria de criar algumas macros com nomes como\s1.4e também poder usá-los como \s1.4Test
onde Test não é tratado como parte do nome da macro (basicamente qualquer coisa após o float ser excluído como parte do nome da macro)
Basicamente, isso é para evitar ter que \s{1.4}Text
adicionar dois caracteres extras e, para meus propósitos, \s1.4
não tem problemas (nunca terei coisas como \s1.x
e espero que x não faça parte da macro, então nunca haverá qualquer ambiguidade).
Aliás, estou definindo isso usando um foreach:
\makeatletter
\foreach \m in {1.1, 2.2}
{
\expandafter\protected@xdef\csname s\m\endcsname{$_\mathbf{\m}$}
}
\makeatother
Responder1
exemplo simples de TeX, mas funcionaria em látex, \s
é mais simples, mas requer um .
\t
é mais complicado, mas aceita um número inteiro.
\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
Responder2
No exemplo a seguir, a macro \s
apenas coleta dígitos e pontos e os compõe conforme mostrado na pergunta como subscritos em negrito. O LaTeX \@ifnextchar
não pode ser usado, porque ele engole espaços quando procura o próximo token.
\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}
Atualizar
É fácil adicionar a camada de mapeamento incluindo mensagens de erro, se \s
não for seguida por dígitos e pontos ou se a sequência de dígitos/pontos não estiver definida.
\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}
No próximo exemplo, o argumento analisado de \s
é uma string que começa com um ou mais dígitos, pontos opcionais e dígitos opcionais.
\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}
Responder3
Se o segundo número após o ponto tiver apenas um dígito, você poderá usar o seguinte:
\def\s#1.#2{$_\mathbf{#1.#2}$}