\ nameref โดยใช้ข้อความ 'unexpanded'?

Nov 03 2020

สมมติว่าฉันกำหนดคำสั่งแบบกำหนดเอง\exerciseดังนี้

\newcounter{exercise}
\newcommand\exercise{%
    \refstepcounter{exercise}%
    \section*{Exercise \theexercise}%
}

ตอนนี้ในตัวอย่างต่อไปนี้ฉันต้องการใช้\namerefจากhyperrefแพ็คเกจ

\exercise\label{ex:first}
foo

\exercise\label{ex:second}
see \nameref{ex:first}

\exercise\label{ex:third}
bar

ซึ่งจะทำให้เกิด "ดูแบบฝึกหัด 2" แทนที่จะเป็น "ดูแบบฝึกหัด 1" ดูเหมือนว่าจะมีการใช้ข้อความ 'unexpanded' ซึ่งขยายเป็นค่าตัวนับปัจจุบัน ฉันจะแน่ใจได้อย่างไรว่ามี\nameref{ex:first}"แบบฝึกหัดที่ 1"

(แน่นอนฉันสามารถใช้ได้Exercise~\ref{ex:first}แต่นี่เป็นข้อผิดพลาดได้ง่ายกว่าและในอนาคตฉันอาจต้องการแทนที่ "การออกกำลังกาย" ด้วย "ปัญหา" โดยไม่ต้องค้นหาและแทนที่สิ่งที่เกิดขึ้นทั้งหมดในเอกสารของฉัน)


ตัวอย่างเต็ม:

\documentclass{article}

\usepackage{hyperref}

\newcounter{exercise}
\newcommand\exercise{%
    \refstepcounter{exercise}%
    \section*{Exercise \theexercise}%
}

\begin{document}

\exercise\label{ex:first}
foo

\exercise\label{ex:second}
see \nameref{ex:first}

\exercise\label{ex:third}
bar

\end{document}

คำตอบ

1 egreg Nov 03 2020 at 16:08

แน่นอนคุณต้องผ่านการขยายตัว\theexerciseเนื่องจากhyperrefไม่ได้ทำกับชื่อเรื่อง

\documentclass{article}
\usepackage{hyperref}

\newcounter{exercise}
\newcommand\exercise{%
  \par % just in case
  \refstepcounter{exercise}%
  \begingroup\edef\x{\endgroup
    \noexpand\section*{\unexpanded{Exercise} \theexercise}%
  }\x
}

\begin{document}

\exercise\label{ex:first}
foo

\exercise\label{ex:second}
see \nameref{ex:first}

\exercise\label{ex:third}
bar

\end{document}

นี่คือเนื้อหา (ย่อ) ของ.auxไฟล์:

\newlabel{ex:first}{{1}{1}{Exercise 1}{section*.1}{}}
\newlabel{ex:second}{{2}{1}{Exercise 2}{section*.2}{}}
\newlabel{ex:third}{{3}{1}{Exercise 3}{section*.3}{}}

มันเป็น

\newlabel{ex:first}{{1}{1}{Exercise \theexercise }{section*.1}{}}
\newlabel{ex:second}{{2}{1}{Exercise \theexercise }{section*.2}{}}
\newlabel{ex:third}{{3}{1}{Exercise \theexercise }{section*.3}{}}

ด้วยรหัสของคุณ

บันทึก. ทำไม\unexpanded{Exercise}? โดยเฉพาะอย่างยิ่งเห็นได้ชัดว่าไม่จำเป็น แต่สำหรับ "Übung" ของเยอรมัน


คุณอาจใช้cleverefแทน

\documentclass{article}
\usepackage{hyperref}
\usepackage[nameinlink]{cleveref}

\newcounter{exercise}
\newcommand\exercise{%
  \par % just in case
  \refstepcounter{exercise}%
  \section*{Exercise \theexercise}
}
\crefname{exercise}{Exercise}{Exercises}

\begin{document}

\exercise\label{ex:first}
foo

\exercise\label{ex:second}
see \cref{ex:first}

\exercise\label{ex:third}
bar

\end{document}

ผลลัพธ์จะเหมือนกันในทั้งสองกรณี

เราสามารถหลีกเลี่ยง\edef\x{\endgroupกลลวงได้หรือไม่? ใช่แน่นอน

\documentclass{article}
%\usepackage{xparse} % not needed for LaTeX 2020-10-01 or later
\usepackage{hyperref}
\usepackage[nameinlink]{cleveref}

\ExplSyntaxOn
\NewDocumentCommand{\exercise}{}
 {
  \gooz_exercise:ne { \exercisename } { \theexercise }
 }
\cs_new_protected:Nn \gooz_exercise:nn
 {
  \par % just in case
  \refstepcounter{exercise}
  \section*{#1~#2}
 }
\cs_generate_variant:Nn \gooz_exercise:nn { ne }
\ExplSyntaxOff

\newcommand{\exercisename}{Exercise}
\newcounter{exercise}
\crefname{exercise}{\exercisename}{\exercisename s}

\begin{document}

\exercise\label{ex:first}
foo

\exercise\label{ex:second}
see \cref{ex:first} or \nameref{ex:first}

\exercise\label{ex:third}
bar

\end{document}

โปรดทราบว่าcleverefไม่จำเป็นเพียง \namerefแต่เอาสายที่เกี่ยวข้องถ้าคุณชอบ