วิธีการอ้างอิงสภาพแวดล้อมแบบลอยตัวเช่นรายการหรือตัวเลขไปยังที่ที่มีการกล่าวถึง?

Aug 17 2020

ฉันต้องการใส่รายการซอร์สโค้ดและตัวเลข / รูปภาพบางส่วนในภาคผนวกของฉันสำหรับรายละเอียดเพิ่มเติมโปรดดูคำถามนี้ ) ดังนั้นฉันจะพบว่ามีประโยชน์มากที่จะมีลิงก์ย้อนกลับที่นั่น (เช่นเดียวกับที่คุณมีในบรรณานุกรมหรือตัวย่อ TOC ด้วยacroหรือมากกว่านั้น) เนื่องจากส่วนที่อ้างอิงอยู่ห่างจากที่พิมพ์มาก (เช่นในภาคผนวก)

โดยทั่วไปแล้วคำถามนี้จะถือว่า "ตรงข้าม" ของคำถาม"ทำให้ตาราง / ตัวเลขใกล้เคียงกับที่กล่าวถึง" กล่าวคือรูปภาพ / รายชื่อของฉันอยู่ห่างไกลจากที่ที่มีการกล่าวถึงดังนั้นฉันจึงต้องการ backref สำหรับพวกเขา ดังนั้นผู้คนจึงสามารถค้นหาคำอธิบายของข้อมูลโค้ดหรือรูปภาพที่ฉันอ้างอิงได้เมื่อพวกเขาดูที่ภาคผนวก

ฉันได้ใช้hyperref's คำสั่งสำหรับการอ้างอิงตัวเลขหรือรายชื่อที่สร้างผ่านมิ้นต์เพื่อให้เช่น\autoref, หรือ\nameref\fullref

ดังนั้นจึงเป็นไปได้หรือไม่ที่จะเพิ่มการอ้างอิงย้อนกลับ (backref / ลิงก์ย้อนกลับ) ในคำบรรยายภาพ - หรือเก็บความคิดอื่น ๆ ของฉันไว้ที่การใช้พาดหัวข่าวแทนคำอธิบายภาพที่อื่นในข้อความ

ฉันต้องการคำอธิบายภาพเช่นนี้:

ข้อมูลโค้ดต้นฉบับแสดงให้เห็นว่า A สร้าง B ได้อย่างไร (กล่าวไว้ในหน้า 5, 7-8)

รูปแบบที่แน่นอนกล่าวคือไม่ว่าจะเป็นแบบกะทัดรัดและข้ามหน้าหรือใช้คำนำอะไร ("ที่กล่าวถึงในหน้า" อาจแทนที่ด้วย "pp." หรือตัวย่ออื่นที่น่าจะกำหนดไว้แล้วใน biblatex หรือมาโครมาโคร) ดังนั้น ไม่สำคัญ แต่ฉันชอบสไตล์ที่acroใช้)

แก้ไข:เนื่องจากยังไม่ชัดเจนฉันต้องการบางอย่างเช่น acro ทำ:

ฉันต้องการลิงก์ย้อนกลับ "S. 10, 14, 27" ฯลฯ เหล่านี้ไปที่หน้า คำตอบจาก @John Kormylo เป็นตัวอย่างที่ดี แต่ยังไม่สมบูรณ์ แต่ผมไม่ต้องการให้พวกเขาสำหรับการย่อหรือการอ้างอิงรายการ (biblatex ยังสามารถทำอย่างนั้นฉันรู้ว่า) แต่สำหรับบางตัวเลข / รายการ / คำอธิบายภาพในภาคผนวก

BTW ก็เพียงพอแล้วหากลิงก์ย้อนกลับไปยังหน้านั้นไม่จำเป็นต้องเป็นตำแหน่งที่แน่นอน

ไม่มี MWE ที่ฉันสามารถให้ได้เพราะมันไม่ได้ผลที่นี่

หมายเหตุ:สำหรับเหตุผลที่ชัดเจนว่า backref อาจควรยกเว้นการเชื่อมโยงใน TOC เหมือนหรือ\listoflistings\listoffigures

คำตอบ

3 moewe Aug 27 2020 at 13:24

นี่คือบางสิ่งเล็กน้อยตามbiblatexวิธีการ backref แบบหลวม ๆ

ด้วยการเรียกร้องของแต่ละ\ref/ \autorefเราส่งเครื่องหมายไปยัง.auxแฟ้มที่ฉลากที่ถูกอ้างถึงในหน้านี้โดยเฉพาะอย่างยิ่ง ในตอนเริ่มต้นของการเรียกใช้ LaTeX แต่ละครั้งเราสามารถอ่านชุดหน้าป้ายกำกับจาก.auxไฟล์และรวบรวมสำหรับป้ายกำกับแต่ละรายการที่มีการอ้างถึง รายการนี้สามารถใช้ในการพิมพ์ได้ในภายหลัง

ด้วยวิธีการง่ายๆนี้เราจะเชื่อมโยงกลับไปที่หน้าเท่านั้นไม่ใช่ไปยังตำแหน่งที่ถูกอ้างอิงตามป้ายกำกับเราจึงไม่ออกคำเตือนการเรียกใช้ LaTeX ซ้ำโดยอัตโนมัติ

\documentclass{article}
\usepackage[utf8]{inputenc}

\usepackage{etoolbox}
\usepackage{hyperref}

\makeatletter
% stolen from biblatex
% we need a way to check if printable text is in a list
\newrobustcmd{\rugk@ifprintableinlist}[2]{%
  \begingroup
    \def\rugk@tempa{\endgroup
      \@secondoftwo}%
    \renewcommand*{\do}[1]{%
      \ifstrequal{##1}{#1}
        {\def\rugk@tempa{\endgroup
           \@firstoftwo}%
         \listbreak}
        {}}%
    \dolistloop{#2}%
  \expandafter\rugk@tempa}

\newrobustcmd{\rugk@ifprintableinlistcs}[2]{%
  \expandafter\rugk@ifprintableinlistcs@i\csname #2\endcsname{#1}}
\long\def\rugk@ifprintableinlistcs@i#1#2{\rugk@ifprintableinlist{#2}{#1}}

% add <page> to the list of pages where <label> was referenced
% {<label>}{<page>}{<page int>}
\protected\def\rugk@ref@backref#1#2#3{%
  \ifcsundef{rugk@ref@backreflist@\detokenize{#1}}
    {\global\cslet{rugk@ref@backreflist@\detokenize{#1}}\@empty}
    {}%
  \rugk@ifprintableinlistcs{#2}{rugk@ref@backreflist@\detokenize{#1}}
    {}
    {\listcsgadd{rugk@ref@backreflist@\detokenize{#1}}{#2}}}

% write label backref to aux file
% {<label>}
\def\rugk@write@ref@backref#1{%
  \if@filesw
    \protected@write\@mainaux{}{\string\rugk@ref@backref
      {#1}{\thepage}{\noexpand\the\c@page}}%
  \fi}

\newcommand{\backref}[1]{%
  \rugk@write@ref@backref{#1}%
  \ref{#1}%
}
\newcommand{\autobackref}[1]{%
  \rugk@write@ref@backref{#1}%
  \autoref{#1}%
}

\newcounter{backrefpages}
\newcounter{totalbackrefpages}

\newcommand*{\printbackrefpage}[1]{%
  \stepcounter{backrefpages}%
  \hyperlink{page.#1}{#1}%
  \ifnumless{\value{backrefpages}}{\value{totalbackrefpages}}
    {, }
    {}}

\newrobustcmd*{\printlabelbackrefs}[1]{%
  \setcounter{backrefpages}{0}%
  \setcounter{totalbackrefpages}{0}%
  \ifcsundef{rugk@ref@backreflist@\detokenize{#1}}
    {Not referenced}
    {\def\do##1{\stepcounter{backrefpages}}%
     \dolistcsloop{rugk@ref@backreflist@\detokenize{#1}}%
     \setcounter{totalbackrefpages}{\value{backrefpages}}%
     \setcounter{backrefpages}{0}%
     \ifnumgreater{\value{totalbackrefpages}}{1}
       {pp.}
       {p.}~%
     \forlistcsloop{\printbackrefpage}{rugk@ref@backreflist@\detokenize{#1}}}}
\makeatother

\newrobustcmd{\backcaption}[3][]{%
  \if\relax\detokenize{#1}\relax
    \def\rugk@tmpcapt{\caption[#2]}%
  \else
    \def\rugk@tmpcapt{\caption[#1]}%
  \fi
  \rugk@tmpcapt{#2 (see \printlabelbackrefs{#3})}%
  \label{#3}}


\begin{document}
\section{Introduction}
\listoffigures

Here is a reference to \backref{test} and  \autobackref{test}

\clearpage

And here we talk about it again: \autobackref{test}

\clearpage 

\begin{figure}[p]
\backcaption{This is a test.}{test}
\end{figure}

\end{document}


ทางเลือกตามป้ายกำกับที่มีตัวนับการทำงาน ผลลัพธ์ backref จะย้อนกลับไปที่ป้ายกำกับ backref หนึ่งป้ายต่อหนึ่งหน้าและป้ายกำกับเท่านั้น แต่อาจเปลี่ยนแปลงได้หากคุณต้องการ (อาจดูแปลก ๆ เพราะคุณจะได้รับ "pp. 1, 1")

\documentclass{article}
\usepackage[utf8]{inputenc}

\usepackage{etoolbox}
\usepackage{hyperref}

\makeatletter
\newcounter{backrefinst}

% stolen from biblatex
% we need a way to check if printable text is in a list
\newrobustcmd{\rugk@ifprintableinlist}[2]{%
  \begingroup
    \def\rugk@tempa{\endgroup
      \@secondoftwo}%
    \renewcommand*{\do}[1]{%
      \ifstrequal{##1}{#1}
        {\def\rugk@tempa{\endgroup
           \@firstoftwo}%
         \listbreak}
        {}}%
    \dolistloop{#2}%
  \expandafter\rugk@tempa}

\newrobustcmd{\rugk@ifprintableinlistcs}[2]{%
  \expandafter\rugk@ifprintableinlistcs@i\csname #2\endcsname{#1}}
\long\def\rugk@ifprintableinlistcs@i#1#2{\rugk@ifprintableinlist{#2}{#1}}

% add <page> to the list of pages where <label> was referenced
% remember the first instance counter for each label/page combination
% {<label>}{<backref instance counter>}{<page>}{<page int>}
\protected\def\rugk@ref@backref#1#2#3#4{%
  \ifcsundef{rugk@ref@backreflist@\detokenize{#1}}
    {\global\cslet{rugk@ref@backreflist@\detokenize{#1}}\@empty}
    {}%
  \rugk@ifprintableinlistcs{#3}{rugk@ref@backreflist@\detokenize{#1}}
    {}
    {\listcsgadd{rugk@ref@backreflist@\detokenize{#1}}{#3}%
     \csgdef{rugk@ref@backrefinst@\detokenize{#1}@\detokenize{#3}}{#2}}}

% write label backref to aux file
% {<label>}
\def\rugk@write@ref@backref#1{%
  \if@filesw
    \protected@write\@mainaux{}{\string\rugk@ref@backref
      {#1}{\the\value{backrefinst}}{\thepage}{\noexpand\the\c@page}}%
  \fi}

\newcommand*{\rugk@create@backref@label}[1]{%
  \begingroup
    \refstepcounter{backrefinst}%
    \label{backref.\the\value{backrefinst}}%
    \rugk@write@ref@backref{#1}%
  \endgroup
}

\newcommand{\backref}[1]{%
  \ref{#1}%
  \rugk@create@backref@label{#1}%
}
\newcommand{\autobackref}[1]{%
  \autoref{#1}%
  \rugk@create@backref@label{#1}%
}

\newcounter{backrefpages}
\newcounter{totalbackrefpages}

% {<label>}{<page>}
\newcommand*{\printbackrefpage}[2]{%
  \stepcounter{backrefpages}%
  \pageref{backref.\csuse{rugk@ref@backrefinst@\detokenize{#1}@\detokenize{#2}}}%
  \ifnumless{\value{backrefpages}}{\value{totalbackrefpages}}
    {, }
    {}}

\newrobustcmd*{\printlabelbackrefs}[1]{%
  \setcounter{backrefpages}{0}%
  \setcounter{totalbackrefpages}{0}%
  \ifcsundef{rugk@ref@backreflist@\detokenize{#1}}
    {Not referenced}
    {\def\do##1{\stepcounter{backrefpages}}%
     \dolistcsloop{rugk@ref@backreflist@\detokenize{#1}}%
     \setcounter{totalbackrefpages}{\value{backrefpages}}%
     \setcounter{backrefpages}{0}%
     \ifnumgreater{\value{totalbackrefpages}}{1}
       {pp.}
       {p.}~%
     \forlistcsloop{\printbackrefpage{#1}}{rugk@ref@backreflist@\detokenize{#1}}}}
\makeatother

\newrobustcmd{\backcaption}[3][]{%
  \if\relax\detokenize{#1}\relax
    \def\rugk@tmpcapt{\caption[#2]}%
  \else
    \def\rugk@tmpcapt{\caption[#1]}%
  \fi
  \rugk@tmpcapt{#2 (see \printlabelbackrefs{#3})}%
  \label{#3}}

\begin{document}
\section{Introduction}
\listoffigures

Here is a reference to \backref{test} and  \autobackref{test}

\clearpage

And here we talk about it again: \autobackref{test}

\clearpage 

\begin{figure}[p]
\backcaption{This is a test.}{test}
\end{figure}

\end{document}

หากคุณต้องการพิมพ์โอกาสย้อนกลับทั้งหมดรหัสนี้สามารถปรับปรุงได้เล็กน้อย: หนึ่งจะต้องจำรายการจำนวนอินสแตนซ์ backref สำหรับแต่ละป้ายกำกับไม่ใช่รายการหน้าสำหรับแต่ละป้ายกำกับ

\documentclass{article}
\usepackage[utf8]{inputenc}

\usepackage{etoolbox}
\usepackage{hyperref}

\makeatletter
\newcounter{backrefinst}

% add <page> to the list of pages where <label> was referenced
% remember the first instance counter for each label/page combination
% {<label>}{<backref instance counter>}
\protected\def\rugk@ref@backref#1#2{%
  \ifcsundef{rugk@ref@backreflist@\detokenize{#1}}
    {\global\cslet{rugk@ref@backreflist@\detokenize{#1}}\@empty}
    {}%
  \ifinlistcs{#2}{rugk@ref@backreflist@\detokenize{#1}}
    {}
    {\listcsgadd{rugk@ref@backreflist@\detokenize{#1}}{#2}}}

% write label backref to aux file
% {<label>}
\def\rugk@write@ref@backref#1{%
  \if@filesw
    \protected@write\@mainaux{}{\string\rugk@ref@backref
      {#1}{\the\value{backrefinst}}}%
  \fi}

\newcommand*{\rugk@create@backref@label}[1]{%
  \begingroup
    \refstepcounter{backrefinst}%
    \label{backref.\the\value{backrefinst}}%
    \rugk@write@ref@backref{#1}%
  \endgroup
}

\newcommand{\backref}[1]{%
  \ref{#1}%
  \rugk@create@backref@label{#1}%
}
\newcommand{\autobackref}[1]{%
  \autoref{#1}%
  \rugk@create@backref@label{#1}%
}

\newcounter{backrefpages}
\newcounter{totalbackrefpages}

% {<label>}{<page>}
\newcommand*{\printbackrefpage}[1]{%
  \stepcounter{backrefpages}%
  \pageref{backref.#1}%
  \ifnumless{\value{backrefpages}}{\value{totalbackrefpages}}
    {, }
    {}}

\newrobustcmd*{\printlabelbackrefs}[1]{%
  \setcounter{backrefpages}{0}%
  \setcounter{totalbackrefpages}{0}%
  \ifcsundef{rugk@ref@backreflist@\detokenize{#1}}
    {Not referenced}
    {\def\do##1{\stepcounter{backrefpages}}%
     \dolistcsloop{rugk@ref@backreflist@\detokenize{#1}}%
     \setcounter{totalbackrefpages}{\value{backrefpages}}%
     \setcounter{backrefpages}{0}%
     \ifnumgreater{\value{totalbackrefpages}}{1}
       {pp.}
       {p.}~%
     \forlistcsloop{\printbackrefpage}{rugk@ref@backreflist@\detokenize{#1}}}}
\makeatother

\newrobustcmd{\backcaption}[3][]{%
  \if\relax\detokenize{#1}\relax
    \def\rugk@tmpcapt{\caption[#2]}%
  \else
    \def\rugk@tmpcapt{\caption[#1]}%
  \fi
  \rugk@tmpcapt{#2 (see \printlabelbackrefs{#3})}%
  \label{#3}}

\begin{document}
\section{Introduction}
\listoffigures

Here is a reference to \backref{test} and  \autobackref{test}

\clearpage

And here we talk about it again: \autobackref{test}

\clearpage 

\begin{figure}[p]
\backcaption{This is a test.}{test}
\end{figure}

\end{document}
2 JohnKormylo Aug 24 2020 at 21:04

นี้ใช้วิธีการแก้ปัญหา\backcaptionและการ\backrefแทนและ\caption\label\ref

\documentclass{article}
\usepackage{hyperref}

\newcommand{\backref}[1]% #1 = label name
{\raisebox{\baselineskip}[\ht\strutbox]{\hypertarget{#1.back}{}}\ref{#1}}

\newcommand{\backcaption}[2]% #1 = caption, #2= label
{\caption[#1]{\hyperlink{#2.back}{#1}}\label{#2}}

\begin{document}
\listoffigures

\vspace{2in}
Here is a reference to \backref{test}.

\begin{figure}[p]
\backcaption{This is a test.}{test}
\end{figure}

\end{document}
1 rugk Aug 27 2020 at 00:36

โอเคขอบคุณสำหรับคำตอบโดย@John Kormyloฉันมีวิธีแก้ปัญหาบางส่วนกล่าวคือถ้าเราใช้ปกติ\labelเราสามารถใช้\pagerefเพื่ออ้างอิงกลับไปที่หน้าได้แน่นอน

ปัญหาเดียวคือ: สิ่งนี้จะใช้ได้ก็ต่อเมื่อเรามีref .

นี่คือรหัสบางส่วน:

\documentclass{article}
\usepackage[utf8]{inputenc}

\title{test-backref}
\date{August 2020}

\usepackage{hyperref}

% thanks https://tex.stackexchange.com/a/559834/98645
\newcommand{\backref}[1]% #1 = label name
{
    \raisebox{\baselineskip}[\ht\strutbox]{\label{#1.back}{}}%
    \ref{#1}
}
\newcommand{\autobackref}[1]% #1 = label name
{
    \raisebox{\baselineskip}[\ht\strutbox]{\label{#1.back}{}}%
    \autoref{#1}
}

\newcommand{\backcaption}[2]% #1 = caption, #2= label
{\caption[#1]{#1 (see p.~\pageref{#2.back})}\label{#2}}
\newcommand{\backcaptionoptional}[3]% #1 optional label, 2 = caption, #3= label
{\caption[#1]{#2 (see p.~\pageref{#3.back})}\label{#3}}


\begin{document}

\maketitle

\section{Introduction}
\listoffigures

\vspace{2in}
Here is a reference to \backref{test} and  \autobackref{test}….

\newpage

And here we talk about it again: \autobackref{test}

\newpage 

\begin{figure}[p]
\backcaption{This is a test.}{test}
\end{figure}

\end{document}

โปรดทราบว่ายังแสดงให้เห็นถึงปัญหา LaTeX (ถูกต้อง) บ่นว่า:

คุณใช้ป้ายกำกับเดียวกันมากกว่าหนึ่งครั้ง ตรวจสอบว่าแต่ละ \ label {... } ติดป้ายกำกับเพียงรายการเดียว

สิ่งนี้เกิดขึ้นเพราะฉันอ้างถึงตัวเลขนั้นหลายครั้ง ในท้ายที่สุดผลลัพธ์จะใช้ป้ายกำกับสุดท้ายเป็นข้อมูลอ้างอิง

ดังนั้นมันยังไม่เสร็จสมบูรณ์ แต่ฉันเดาว่าเราต้องใช้ตัวนับหรือมากกว่านั้นเพื่อนับป้ายกำกับสำหรับโซลูชันแบบเต็ม? เราจะไม่? (หากคุณมีความคิดใด ๆ โปรดอย่าลังเลที่จะส่งและใช้สิ่งนี้เป็นฐานของคุณ)