Quantcast
Channel: Active questions tagged starred-version - TeX - LaTeX Stack Exchange
Viewing all articles
Browse latest Browse all 63

Redefining \ref* along the lines of \ref to allow "local labels" in sections

$
0
0

I use the "local labels" hack from this answer to automatically prefix labels in order to be able to reuse the same labels in different places of the same document.


Background: Why?

There are two documents (doc1.tex& doc2.tex) whose content is outside of my control. I need to create a third document (main.tex) that includes the contents of the two other documents. Identical labels in doc1.tex and doc2.tex lead to duplicated labels in main.tex.

Full (non-working) example (I'm loading cleveref because I use it in my actual code – not sure if it is relevant here):

% file main.tex:\documentclass{scrartcl}\usepackage{hyperref}\usepackage{cleveref}% "doc1":\begin{filecontents}{doc1.tex}\documentclass{scrartcl}\begin{document}\input{doc1_body}\end{document}\end{filecontents}\begin{filecontents}{doc1_body.tex}\section{About Foo} \label{sec:foo}\ref{sec:foo}\end{filecontents}% "doc2" (structurally identical to "doc1"):\begin{filecontents}{doc2.tex}\documentclass{scrartcl}\begin{document}\input{doc2_body}\end{document}\end{filecontents}\begin{filecontents}{doc2_body.tex}\section{About Foo} \label{sec:foo} % same label as in doc2_body.tex\ref{sec:foo}\end{filecontents}\begin{document}% cannot modify doc1_body or doc1_body!\input{doc1_body}\input{doc2_body} % Label `sec:foo' multiply defined.\end{document}

The "local labels" hack automatically prefixes labels in order to be able to reuse the same labels in different places of the same document.

MWE, using the files generated by the filecontents environments in the first example:

\documentclass{scrartcl}\usepackage{hyperref}\usepackage{cleveref}%%% Automatically prefix labels %%%% https://tex.stackexchange.com/a/82115/37118\makeatletter\AtBeginDocument{%\let\origref\ref\let\origlabel\label\newcommand\locallabels[1]{%  \renewcommand\label[1]{\origlabel{#1##1}}%  \renewcommand\ref[1]{\origref{#1##1}}%}}\makeatother\begin{document}\locallabels{part1:}\input{doc1_body} % contains \ref{sec:foo}\locallabels{part2:}\input{doc2_body}  % contains \ref{sec:foo}\end{document}

This works great for \ref: \ref{sec:foo} in doc1_body.tex prints "1" whereas it prints "2" in doc2_body.tex.

Problem: How to achieve the same for the starred version \ref* as well, such that \ref* can be used in section commands, e.g.: \section{More on \ref*{sec:foo}}?

The patched version of \ref* should work as expected when using hyperref: Print the same output as \ref but without the hyperlink.


What I've tried:

  • Initially, I tried to naively add \renewcommand\ref*[1]{\origref*{#1##1}}, but of course patching commands with starred versions is not that simple …
  • Then, I tried to follow the advice in this answer and adapt it to my problem. (I'm aware that there are various ways to redefine commands with starred variants, but the linked answer seems to be very close to my use case).

Building on this, I came up with the following solution:

\makeatletter\AtBeginDocument{%\let\origref\ref\let\origlabel\label\newcommand*{\newrefstar}[1]{}\newcommand*{\newref}[1]{}\newcommand\locallabels[1]{%  \renewcommand\label[1]{\origlabel{#1##1}}%  \renewcommand*{\ref}{\@ifstar\newrefstar\newref}%  \renewcommand*{\newrefstar}[1]{\origref*{#1##1}}%  \renewcommand*{\newref}[1]{\hyperref[#1##1]{\newrefstar{##1}}}%}}\makeatother

Replacing the code in my initial MWE's preamble with this code (almost) works: I can use \ref*{sec:foo} just like \ref{sec:foo}. A full MWE is provided here (for the sake of keeping this question short). However, the document crashes as soon as I use \ref* within \section.


Question: How can I fix the code above such that \section{\ref*{sec:foo}} works? Full non-working example.

In a comment, Ulrike Fischer pointed out that this may lead to issues in the table of contents and bookmarks. Is this unavoidable or can \ref* be substituted by its intended output before it is written to the TOC file?

Please note that I cannot change doc1.tex or doc2.tex (or their contents) from the initial example. So just avoiding duplicate labels, or altering the ref and label commands within these documents, is not feasible. This is why I use the "local labels" trick and try to adapt it.


Viewing all articles
Browse latest Browse all 63

Trending Articles