I want to change knitr
's behavior when it creates a figure
environment in LaTeX
to call a different LaTeX
command than \label{}
, e.g, \alabel{}
where I define \alabel
to run \label{foo}
as well as \hypertarget{foo}{}
using the hyperref
LaTeX
package. I'm doing this so that I can construct a URL in a web browser to get to a specific place in the .pdf
document built with pdflatex
, e.g. http://.../my.pdf#nameddest=foo
.
How can I either override \label{}
or emit an additional \hypertarget{same label used by \label{}
in the figures?
This is in the context of a .Rnw
file. I'd like the anchor to appear inside the figure
environmentfor optimal positioning of the cursor when jumping into the
.pdf` document.
UPDATE
In rethinking this I think it's best not to generate hypertarget
anchors but to write an R
function that parses the LaTeX
aux
file to retrieve the page number of the reference (\newlabel
lines) to generate the needed URL to the pdf
file. In the .Rnw
or .Rmd
file I can call this function from within a sentence to insert the computed URL.
UPDATE
I've decided after all to go with @werner's excellent method, which works flawlessly. For anyone interested in the R
-based approach that doesn't require the use of hypertarget
, here is the LaTeX
code needed to set up for it - this handles the case where physical page numbers do not match logical page numbers (e.g., using logical numbers such as chapter number - page within chapter.
% Creates .pag file mapping absolute page numbers to logical page
% numbers; works with R function latexRef
\newwrite\pgfile
\immediate\openout\pgfile=\jobname .pag
\newcounter{abspage}
\setcounter{abspage}{0}
\useackage{everypage}
\AddEverypageHook{%
\addtocounter{abspage}{1}
\immediate\write\pgfile{\thepage, \theabspage}%
}
\AtEndDocument{\clearpage\immediate\closeout\pgfile}
Here's the R
function that does the lookups in the .aux, .pag
files:
## Create hyperlink to appropriate physical page in a pdf document
## created by pdflatex given the .aux and .pag file. Absolute and
## named page numbers are store in the .pag file created by hslide.sty
latexRef <- function(label, base, name, path='doc/',
blogpath='/home/harrelfe/R/blog/blogdown/static/doc/',
lang=c('markdown', 'latex')) {
lang <- match.arg(lang)
aux <- paste0(blogpath, base, '.aux')
if(! file.exists(aux))
stop(paste('no file named', aux))
path <- paste0(path, base, '.pdf')
pag <- paste0(blogpath, base, '.pag')
pagemap <- NULL
if(file.exists(pag)) {
p <- read.table(pag, sep=',')
pagemap <- trimws(p[[2]])
names(pagemap) <- trimws(p[[1]])
}
r <- readLines(aux)
w <- paste0('\\\\newlabel\\{', label, '\\}')
i <- grepl(w, r)
if(! any(i)) stop(paste('no label =', label))
r <- r[i][1]
r <- gsub('\\{', ',', r)
r <- gsub('\\}', ',', r)
x <- scan(text=r, sep=',', what=character(0), quiet=TRUE)
section <- x[5]
if(section != '') section <- paste0(' Section ', section)
page <- trimws(x[7])
if(length(pagemap)) page <- pagemap[page]
url <- paste0('http://fharrell.com/', path, '#page=', page)
switch(lang,
markdown = paste0('[', name, section, '](', url, ')'),
latex = paste0('\\href{', url, '}{', name, section, '}')
)
}
You could add the following to your LaTeX preamble a global replacement of \label
with a combination of \label
-and-\hypertarget
in the following way:
---
title: 'A title'
author: 'An author'
date: 'A date'
output:
pdf_document:
keep_tex: true
header-includes:
- \AtBeginDocument{
\let\oldlabel\label
\renewcommand{\label}[1]{\oldlabel{#1}\hypertarget{#1}{}}
}
---
See Figure \ref{fig:figure}.
\begin{figure}
\caption{A figure caption}
\label{fig:figure}
\end{figure}