Ist es möglich, Makronamen mit Sonderzeichen zu erstellen?
Ich möchte einige Makros erstellen, die Namen wie\s1.4und um sie auch so verwenden zu können, \s1.4Test
dass „Test“ nicht als Teil des Makronamens behandelt wird (grundsätzlich wird alles nach dem Float als Teil des Makronamens ausgeschlossen)
Dies dient im Grunde dazu, dies zu vermeiden, \s{1.4}Text
da dadurch zwei zusätzliche Zeichen hinzugefügt werden, und \s1.4
stellt für meine Zwecke kein Problem dar (ich werde nie Dinge wie \s1.x
„x“ haben und erwarte, dass es nicht Teil des Makros ist, sodass es nie zu Mehrdeutigkeiten kommt).
Übrigens definiere ich diese mit einem foreach:
\makeatletter
\foreach \m in {1.1, 2.2}
{
\expandafter\protected@xdef\csname s\m\endcsname{$_\mathbf{\m}$}
}
\makeatother
Antwort1
einfaches TeX-Beispiel, aber es würde in Latex funktionieren, \s
ist einfacher, erfordert aber ein .
\t
ist komplizierter, akzeptiert aber eine Ganzzahl.
\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
Antwort2
Im folgenden Beispiel \s
sammelt das Makro nur Ziffern und Punkte und setzt sie wie in der Frage gezeigt als fette Indizes. LaTeX \@ifnextchar
kann nicht verwendet werden, da es Leerzeichen verschlingt, wenn es nach dem nächsten Token sucht.
\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}
Aktualisieren
Es ist einfach, die Zuordnungsebene einschließlich Fehlermeldungen hinzuzufügen, wenn \s
nicht Ziffern und Punkte folgen oder die Ziffern-/Punktfolge nicht definiert ist.
\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}
Im nächsten Beispiel \s
ist das analysierte Argument eine Zeichenfolge, die mit einer oder mehreren Ziffern, optionalen Punkten und optionalen Ziffern beginnt.
\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}
Antwort3
Wenn die zweite Zahl nach dem Punkt nur einstellig ist, können Sie Folgendes verwenden:
\def\s#1.#2{$_\mathbf{#1.#2}$}