
Ich möchte eine Funktion erstellen, die aus einer durch Kommas getrennten Eingabeliste eine Liste mit Gleichungsreferenzen generiert. zB
\erefs{eq:first, eq:second, eq:third}
\erefs{eq:first}
ergibt Folgendes:
(\ref{eq:first}), (\ref{eq:second}), and (\ref{eq:third})
(\ref{eq:first})
Ich kann die Liste mit einem Element richtig verwalten, habe aber Probleme, das „und“ für das letzte Element zu generieren. Irgendwelche Ideen, wie man das „und“ zu diesem Code hinzufügt?
\documentclass{article}
\usepackage{tikz, amsmath, hyperref}
\def\erefs#1{%
\gdef\firstelement{1}
\foreach \e [count=\ni] in {#1}{%
\ifnum\firstelement=0 , \fi %
(\ref{\e})%
\gdef\firstelement{0}%
}
}
\begin{document}
\begin{equation}\label{eq:first}\end{equation}
\begin{equation}\label{eq:second}\end{equation}
\begin{equation}\label{eq:third}\end{equation}
\erefs{eq:first, eq:second, eq:third}
\erefs{eq:first}
\end{document}
Ich muss die Pakete hyperref und amsmath gleichzeitig verwenden
ZUSATZ:
Ich verwende häufig \package{xr}
und \externaldocument{...}
um auf einen technischen Anhang zu verweisen, und stelle TA.
diese Verweise gerne voran. Es wäre schön, wenn ein optionaler Parameter für ein Präfix übergeben werden könnte
Ich möchte eine Funktion erstellen, die aus einer durch Kommas getrennten Eingabeliste eine Liste mit Gleichungsreferenzen generiert. zB
\erefs{eq:first, eq:second, eq:third}
\erefs{eq:first}
\erefs[TA]{eq:first, eq:second, eq:third}
\erefs[TA]{eq:first}
ergibt Folgendes:
(\ref{eq:first}), (\ref{eq:second}), and (\ref{eq:third})
(\ref{eq:first})
(TA.\ref{eq:first}), (TA.\ref{eq:second}), and (TA.\ref{eq:third})
(TA.\ref{eq:first})
Antwort1
Hier ist eine Möglichkeit ohne cleveref
, die allerdings eine aktuelle Version von erfordert expl3
:
\documentclass{article}
\usepackage{xparse,amsmath}
\ExplSyntaxOn
\NewDocumentCommand{\erefs}{sm}
{
\IfBooleanTF{#1}
{ \jlperla_erefs:Nn \ref { #2 } }
{ \jlperla_erefs:Nn \eqref { #2 } }
}
\seq_new:N \l_jlperla_input_seq
\seq_new:N \l_jlperla_output_seq
\cs_new_protected:Npn \jlperla_erefs:Nn #1 #2
{
\seq_set_split:Nnn \l_jlperla_input_seq { , } { #2 }
\seq_clear:N \l_jlperla_output_seq
\seq_map_inline:Nn \l_jlperla_input_seq
{
\seq_put_right:Nn \l_jlperla_output_seq { #1 { ##1 } }
}
\seq_use:Nnnn \l_jlperla_output_seq
{ ~ and ~ } % between two
{ , ~ } % between more than two
{ , ~ and ~ } % between last two
}
\ExplSyntaxOff
\begin{document}
Some text before
\begin{align}
0+0&=0\label{eq:first}\\
0+1&=1\label{eq:second}\\
1+1&=2\label{eq:third}
\end{align}
One: \erefs{eq:first}
Two: \erefs{eq:second, eq:third}
Three: \erefs{eq:first,eq:second,eq:third}
One: \erefs*{eq:first}
Two: \erefs*{eq:second, eq:third}
Three: \erefs*{eq:first,eq:second,eq:third}
\end{document}
Die *-Version verwendet \ref
, während die normale Version verwendet \eqref
(was für Gleichungen besser ist).
Die „Input“-Sequenz wird auf die Labels gesetzt, der Zyklus fügt sie hinzu \ref
oder \eqref
um sie herum. Dann \seq_use:Nnnn
macht er in allen Fällen das Richtige.
Hier ist die Änderung, um ein Präfix zuzulassen. Ich greife darauf zu \eqref
und definiere einen ähnlichen Befehl, damit die spezielle Formatierung angewendet wird.
\documentclass{article}
\usepackage{xparse,amsmath}
\makeatletter
\newcommand{\peqref}[2]{\textup{\tagform@{#1\ref{#2}}}}
\newcommand{\pref}[2]{#1\ref{#2}}
\makeatother
\ExplSyntaxOn
\NewDocumentCommand{\erefs}{ s o m }
{
\IfBooleanTF{#1}
{
\IfNoValueTF{#2}
{ \jlperla_erefs:Nnn \pref { } { #3 } }
{ \jlperla_erefs:Nnn \pref { #2. } { #3 } }
}
{
\IfNoValueTF{#2}
{ \jlperla_erefs:Nnn \peqref { } { #3 } }
{ \jlperla_erefs:Nnn \peqref { #2. } { #3 } }
}
}
\seq_new:N \l_jlperla_input_seq
\seq_new:N \l_jlperla_output_seq
\cs_new_protected:Npn \jlperla_erefs:Nnn #1 #2 #3
{
\seq_set_split:Nnn \l_jlperla_input_seq { , } { #3 }
\seq_clear:N \l_jlperla_output_seq
\seq_map_inline:Nn \l_jlperla_input_seq
{
\seq_put_right:Nn \l_jlperla_output_seq { #1 { #2 } { ##1 } }
}
\seq_use:Nnnn \l_jlperla_output_seq
{ ~ and ~ } % between two
{ , ~ } % between more than two
{ , ~ and ~ } % between last two
}
\ExplSyntaxOff
\begin{document}
Some text before
\begin{align}
0+0&=0\label{eq:first}\\
0+1&=1\label{eq:second}\\
1+1&=2\label{eq:third}
\end{align}
No prefix
One: \erefs{eq:first}
Two: \erefs{eq:second, eq:third}
Three: \erefs{eq:first,eq:second,eq:third}
One: \erefs*{eq:first}
Two: \erefs*{eq:second, eq:third}
Three: \erefs*{eq:first,eq:second,eq:third}
\bigskip
With prefix
One: \erefs[TA]{eq:first}
Two: \erefs[TA]{eq:second, eq:third}
Three: \erefs[TA]{eq:first,eq:second,eq:third}
One: \erefs*[TA]{eq:first}
Two: \erefs*[TA]{eq:second, eq:third}
Three: \erefs*[TA]{eq:first,eq:second,eq:third}
\end{document}
Antwort2
Sie benötigen eigentlich kein zusätzliches Paket, Sie können einfach die in LaTeX bereits vorhandenen Schleifen verwenden:
\documentclass{article}
\makeatletter
\def\erefs#1{%
\count@\z@
\@for\tmp:=#1\do{\advance\count@\@ne}%
\edef\xtmp{\ifcase\count@\or\or\ and\ \else, and\ \fi}%
\@for\tmp:=#1\do{%
\advance\count@\m@ne
\edef\tmp{%
\noexpand\ref{\expandafter\zap@space\tmp\@gobble{} \@empty}}%
\tmp
\ifnum\count@>\@ne, %
\else
\ifnum\count@=\@ne\xtmp
\fi\fi}}
\makeatother
\begin{document}
\begin{equation}\label{eq:first}\end{equation}
\begin{equation}\label{eq:second}\end{equation}
\begin{equation}\label{eq:third}\end{equation}
A \erefs{eq:first, eq:second, eq:third}
B \erefs{eq:first, eq:second}
C \erefs{eq:first}
\end{document}
Antwort3
Hier ist eine allgemeine Methode, die verwendetetoolbox
:
\documentclass{article}
\usepackage{etoolbox}
% set up defaults so we don't get an error
% when we try to redefine these commands
\newcommand*{\elementsep}{}%
\newcommand*{\lastelement}{}%
\newcommand*{\prelastelement}{}%
% define the handler macro:
\newcommand*{\dodisplayelement}[1]{%
\elementsep
\lastelement
\renewcommand{\lastelement}{%
\renewcommand{\elementsep}{, }%
\renewcommand{\prelastelement}{ and }%
#1%
}}%
% define the new command to process a list of elements:
\newcommand*{\displayelements}[1]{%
% initialise:
\renewcommand*{\elementsep}{}%
\renewcommand*{\lastelement}{}%
\renewcommand*{\prelastelement}{}%
% Iterate through list
\forcsvlist{\dodisplayelement}{#1}%
% Finish off:
\prelastelement \lastelement
}
\begin{document}
\displayelements{first,second,third,fourth,fifth}
\end{document}
Jedes Element wird wie \lastelement
folgt angezeigt: Wenn das Element also eine Bezeichnung darstellen würde, könnten Sie Folgendes verwenden:
% define the handler macro:
\newcommand*{\dodisplayelement}[1]{%
\elementsep
\lastelement
\renewcommand{\lastelement}{%
\renewcommand{\elementsep}{, }%
\renewcommand{\prelastelement}{ and }%
\ref{#1}%
}}%
Antwort4
Mit\xintFor
. Der optionale Parameter kann alles sein, muss aber nicht TA
.
Wenn eine erweiterbare Möglichkeit gewünscht wäre, könnte dies mit einigen anderen Dienstprogrammen vonwerkzeug.
\documentclass{article}
\usepackage{amsmath, hyperref}
\usepackage{xinttools}
\makeatletter
% with optional parameter.
\def\erefs {\@ifnextchar[\@erefsTA\@erefs }
\def\@erefs #1{%
\xintFor ##1 in {#1}\do
{\xintifForFirst{}{, \xintifForLast{and }{}}(\ref{##1})}%
}
\def\@erefsTA [#1]#2{%
\xintFor ##1 in {#2}\do
{\xintifForFirst{}{, \xintifForLast{and }{}}(#1, \ref{##1})}%
}
\makeatother
\begin{document}\thispagestyle{empty}
\begin{equation}E=mc^2\label{eq:first}\end{equation}
\begin{equation}E=h\nu\label{eq:second}\end{equation}
\begin{equation}\zeta(s)=0\label{eq:third}\end{equation}
\erefs{eq:first, eq:second, eq:third}
\erefs{eq:first}
\erefs[TA]{eq:first, eq:second, eq:third}
\erefs[TA]{eq:first}
\end{document}