
쉼표로 구분된 입력 목록에서 방정식 참조 목록을 생성하는 함수를 만들고 싶습니다. 예를 들어
\erefs{eq:first, eq:second, eq:third}
\erefs{eq:first}
다음과 같은 결과가 나옵니다.
(\ref{eq:first}), (\ref{eq:second}), and (\ref{eq:third})
(\ref{eq:first})
1개의 항목 목록을 올바르게 처리할 수 있지만 마지막 요소에 대해 'and'를 생성하는 데 문제가 있습니다. 이 코드에 'and'를 추가하는 방법에 대한 아이디어가 있습니까?
\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}
hyperref와 amsmath 패키지를 동시에 사용해야 합니다.
덧셈:
나는 기술적인 부록을 자주 사용 \package{xr}
하고 \externaldocument{...}
참조하며, TA.
그 참조 앞에 두는 것을 좋아합니다. 접두사에 선택적 매개변수를 전달할 수 있다면 좋을 것 같습니다.
쉼표로 구분된 입력 목록에서 방정식 참조 목록을 생성하는 함수를 만들고 싶습니다. 예를 들어
\erefs{eq:first, eq:second, eq:third}
\erefs{eq:first}
\erefs[TA]{eq:first, eq:second, eq:third}
\erefs[TA]{eq:first}
다음과 같은 결과가 나옵니다.
(\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})
답변1
을 사용하지 않는 방법은 다음과 같습니다 cleveref
. 그러나 다음의 최신 버전이 필요합니다 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}
* 버전은 을 사용하고 \ref
, 일반 버전은 \eqref
(방정식에 더 좋습니다)을 사용합니다.
"입력" 순서는 레이블로 설정되고, 레이블 주위에 주기 \ref
가 추가됩니다. \eqref
그러면 \seq_use:Nnnn
모든 경우에 옳은 일을 합니다.
접두사를 허용하기 위한 수정 사항은 다음과 같습니다. 나는 \eqref
특수 형식이 적용되는 순서대로 유사한 명령을 정의하여 에 연결합니다 .
\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}
답변2
추가 패키지가 실제로 필요하지 않으며 LaTeX에 이미 있는 루프를 사용할 수 있습니다.
\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}
답변3
다음은 일반적인 사용 방법입니다.etoolbox
:
\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}
각 항목은 다음에 의해 표시되므로 \lastelement
항목이 레이블을 나타내는 경우 다음을 사용할 수 있습니다.
% define the handler macro:
\newcommand*{\dodisplayelement}[1]{%
\elementsep
\lastelement
\renewcommand{\lastelement}{%
\renewcommand{\elementsep}{, }%
\renewcommand{\prelastelement}{ and }%
\ref{#1}%
}}%
답변4
와 함께\xintFor
. 선택적 매개변수는 무엇이든 될 수 있지만 꼭 그럴 필요는 없습니다 TA
.
확장 가능한 방법이 요청된 경우 다음의 다른 유틸리티를 사용하여 이 작업을 수행할 수 있습니다.xinttools.
\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}