Come reindirizzare ambienti mobili come elenchi o figure a dove vengono menzionati?

Aug 17 2020

Voglio mettere alcune voci del codice sorgente e alcune figure / immagini nella mia appendice per maggiori dettagli vedi questa domanda ), e quindi troverei molto utile avere un backlink lì (proprio come puoi avere nella bibliografia o acronimo TOC con acroo giù di lì), perché la parte in cui si fa riferimento è molto lontana da dove è stampata (cioè in appendice).

In breve, questa domanda presuppone fondamentalmente l '"opposto" della domanda "Tenere tabelle / figure vicine a dove sono menzionate" , cioè le mie immagini / elenchi sono lontani da dove sono menzionati e quindi vorrei un backref per loro , così le persone possono trovare la spiegazione di uno snippet di codice o di un'immagine che cito quando guardano semplicemente l'appendice.

Ho usato hyperref's comandi per fare riferimento alla figura o annuncio creato tramite coniate, così per esempio \autoref, \namerefo \fullref.

Quindi, è possibile in qualche modo aggiungere un backreference (backref / backlink) alla didascalia o tenere a mente l'altra mia idea di utilizzare i titoli invece dei sottotitoli in qualche altra parte del testo?

Ad esempio, voglio una didascalia come questa:

Snippet di codice sorgente che mostra come A crea B. (menzionato alle pagine 5, 7-8).

Lo stile esatto, cioè se è compatto e salta le pagine o quale intro usa ("menzionato nelle pagine" potrebbe anche essere semplicemente sostituito da "pp." O un'altra abbreviazione che è probabilmente già definita in qualche biblatex o acro macro) quindi, non importa, ma ad esempio mi piace lo stile acroutilizzato.)

Modifica: poiché ancora non sembra essere chiaro, voglio qualcosa di simile a acro:

Voglio questi link "S. 10, 14, 27" ecc. Alla pagina. La risposta di @John Kormylo fornisce un bell'esempio, ma non è completa. Ma non li voglio come acronimo o lista di referenze (biblatex può farlo anche questo, lo so), ma per alcune figure / elenchi / didascalie in appendice .

A proposito, è sufficiente che rimandi alla pagina , non deve essere la posizione esatta.

Non c'è MWE che posso dare, perché qui non funziona.

Nota: per ovvi motivi, backref dovrebbe escludere un collegamento in un sommario come \listoflistingso \listoffigures.

Risposte

3 moewe Aug 27 2020 at 13:24

Ecco qualcosa basato vagamente sull'approccio biblatexbackref di.

Con ogni chiamata di \ref/ \autorefinviamo un marker al .auxfile a cui l'etichetta è stata referenziata in questa particolare pagina. All'inizio di ogni esecuzione di LaTeX possiamo leggere le combinazioni etichetta-pagina dal .auxfile e compilare per ogni etichetta un elenco di pagine a cui è stato fatto riferimento. Questo elenco può quindi essere utilizzato successivamente per la stampa.

Con questo semplice approccio ci colleghiamo solo alle pagine, non al punto esatto in cui si è fatto riferimento all'etichetta, inoltre non emettiamo avvisi di riesecuzione automatica di 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}


Un'alternativa basata su etichette con un contatore in esecuzione. L'output di backref restituirà solo un'etichetta di backref per pagina ed etichetta, ma potrebbe essere cambiato se lo desideri (potrebbe sembrare strano dato che otterrai qualcosa come "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}

Se si desidera stampare tutte le occasioni di backref, questo codice potrebbe essere semplificato un po ': si dovrebbe solo ricordare un elenco di conteggi di istanze di backref per ciascuna etichetta e non un elenco di pagine per ciascuna etichetta.

\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

Questa soluzione utilizza \backcaptione \backrefinvece di \caption\labele \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

Ok, grazie alla risposta di @John Kormylo ho ottenuto una soluzione parziale, cioè se usiamo un solito \labelpossiamo ovviamente usare \pagerefper fare riferimento alla pagina.

L'unico problema è: questo funziona anche solo se abbiamo un solo rif .

Ecco un po 'di codice:

\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}

Notare che dimostra anche il problema. LaTeX (giustamente) si lamenta:

Hai utilizzato la stessa etichetta più di una volta. Controlla che ogni \ label {...} etichetta solo un elemento.

Questo accade perché ho fatto riferimento a quella cifra più volte. Alla fine, l'output utilizza solo l'ultima etichetta come riferimento.

Quindi non è del tutto finito, ma immagino che dovremmo usare contatori o giù di lì per contare le etichette per una soluzione completa? Non lo faremmo? (Se hai qualche idea, non esitare a inviarla e a utilizzarla come base.)