I'm trying to figure out a way to have an input .tex file that contains a reference, but for the target of this reference to be partially based on where the .tex file is included. What I'm going for is to have the internal PDF hyperlinks be functional, so it's not enough simply to have the correct reference numbers printed out, the actual reference itself needs to be correct for the hyperlink.
Here's a stripped-down example:
\documentclass{article}
\usepackage{hyperref}
\begin{document}
\section{Section One}
\label{sec:one}
\subsection{Subsection One One}
\label{subsec:one:one}
% First instance of input.tex
\input{input.tex}
\subsection{Subsection One Two}
\label{subsec:one:two}
\section{Section Two}
\label{sec:two}
\subsection{Subsection Two One}
\label{subsec:two:one}
% Second instance of input.tex
\input{input.tex}
\subsection{Subsection Two Two}
\label{subsec:two:two}
\end{document}
Is it possible to have a reference in the input.tex file that will point to Subsection X Two, where X is the section the input.tex file is inserted into? Something like:
% contents of input.tex
Lorem ipsum blah blah blah, as described in \ref{sub{\thesection}:two}.
Although this doesn't actually work, of course, hence my issue. But the intent is to have something that resolves to \ref{subsec:one:two}
in the first instance it is included in the main document, but that resolves to \ref{subsec:two:two}
in the second instance.
And just in case I am completely wrong in my approach, and there is some way easier way to do what I'm trying to do: big-picture, I am trying to build out a library of building blocks. I am building some documentation where there are snippets that I can isolate out which are identical for multiple pieces of equipment. I'd like to put together the documentation for each piece of equipment using these snippets for the parts they have in common, both for consistency and for ease of updating. But I'd like the snippets to be able to refer to each other within the scope of each equipment's section. The entire document will cover multiple pieces of equipment, with these repeated snippets used throughout.
Edit 2022-07-03:
\ref{sub\thesection:two}
is tantalizingly close to what I'm going for, except \thesection
resolves to a number, resulting in a (non-functional) reference to sub1:two
or sub2:two
, rather than the intended subsec:one:two
or subsec:two:two
. Is there a command I could use in place of \thesection
that would give me the actual text of the current section's label instead of the numerical representation? E.g. sec:one
instead of 1
.
Edit 2022-07-04:
I have inched even closer to a solution, and refactored a bit so that input.tex
is now inline using filecontents:
\documentclass{article}
\usepackage{hyperref}
\usepackage{xstring}
\begin{filecontents*}[overwrite]{input.tex}
This should be a reference to \ref{sub\parentlabel:two}, but it doesn't work.
\end{filecontents*}
% Saves a copy of the desired label in \currentlabel, then makes a \label with it
% as normal I would have preferred to do this by changing the behavior of \label
% itself, but I ran into even more roadblocks there which are not really in the
% scope of this question.
\newcommand{\clabel}[1]{%
\def\currentlabel{#1}%
\label{#1}
}
% The substring of \currentlabel between the first 'sub' and the last ':'. In
% the absence of some better way to retrieve the current section/subsection/etc
%label, I can live with having to follow a strict naming scheme for this to work.
\newcommand{\parentlabel}{%
\StrCount{\currentlabel}{:}[\lastcolon]%
\StrBetween[1,\lastcolon]{\currentlabel}{sub}{:}
}
\begin{document}
\section{Section One}
\clabel{sec:one}
\subsection{Subsection One One}
\clabel{subsec:one:one}
% Saved copy of the current label, from using \clabel in place of \label
The current label is: \currentlabel
% Substring with the label of the parent (assuming my naming convention is used)
The parent of the current label is: \parentlabel
% Prepend 'sub' and append ':two' to create the desired reference
The desired reference is: sub\parentlabel:two
% But \ref will not accept this argument. Uncomment the following line, and
% errors will occur.
%This should be a reference to \ref{sub\parentlabel:two}, but it doesn't work.
% Likewise if it is brought in from an external file, which it ultimately will
% be. But I don't think that's pertinent to why it isn't working.
% First instance of input.tex
%\input{input.tex}
\subsection{Subsection One Two}
\clabel{subsec:one:two}
The current label is: \currentlabel
The parent of the current label is: \parentlabel
The desired reference is: sub\parentlabel:two
\section{Section Two}
\clabel{sec:two}
\subsection{Subsection Two One}
\clabel{subsec:two:one}
The current label is: \currentlabel
The parent of the current label is: \parentlabel
The desired reference is: sub\parentlabel:two
% Second instance of input.tex
%\input{input.tex}
\subsection{Subsection Two Two}
\clabel{subsec:two:two}
The current label is: \currentlabel
The parent of the current label is: \parentlabel
The desired reference is: sub\parentlabel:two
\end{document}
I feel like probably an \expandafter
is needed somewhere, but everywhere I tried to put it just resulted in a different batch of errors. Also, this feels like a pretty inelegant way of doing this, messing around with substrings and such, but hopefully it at least illustrates what I'm trying to do.
Edit 2022-07-07: Success! A.Ellett's suggestion got me pointed in the right direction with pgfkeys, so I'm going to mark that as the solution (and I really appreciate the assistance). I did some reading on pgfkeys and built up something that I can understand (I'm still quite new to LaTeX), and hopefully can explain to others who might work on these documents.
I made a new set of \sect
commands corresponding to the different sub-levels of \section
commands, and they take two arguments. One is passed along as the name to the normal \section
command, and the other is used as a "token" to build the label up according to my naming convention. This way I can be more verbose and descriptive in the actual name, but have something shorter and with no spaces for the label. The command then sets the pgfkey corresponding to the hierarchy level, to match the label it just set, and then clears out any pgfkeys that are lower in the hierarchy. There is also a set of \currentsec
commands for the different sub-levels, as a convenience to read the pgfkeys.
There is probably a more elegant way to do this using an actual hierarchy of pgfkeys rather than just overwriting the same three keys like I am doing here. But for my purposes, it's enough to be able to reference the current (sub)(sub)section. Any reference that can't be done with those, would probably be more appropriate to have as a one-off in the main document, rather than in my reusable snippets.
My working sample document is below. It displays what the values of the pgfkeys are at each level of the hierarchy, demonstrates a reference in the input.tex that is "context aware" in the way I wanted. It also has another reference thrown in there just to play around with the other hierarchy levels. And there are a few convenience commands to cut down on the overall size with all the repetition, hopefully it's still clear enough what's going on.
I did reword the section names a bit so that there is more distinction between the different levels of the hierarchy. In hindsight, I probably confused the issue by having one
s and two
s at every level of the hierarchy.
\begin{filecontents*}[overwrite]{input.tex}
Reference to subsection Two of current section: \ref{sub\currentsec:two}
\end{filecontents*}
\documentclass{article}
\usepackage{hyperref}
\usepackage{pgfkeys}
% Use in place of \section. Arg 1 is name that you would use for
% \section. Arg 2 is short name for building up the label.
\newcommand{\sect}[2]{%
\section{#1}%
\label{sec:#2}%
\pgfkeyssetvalue{/currentsec}{sec:#2}
\pgfkeyssetvalue{/currentsubsec}{}
\pgfkeyssetvalue{/currentsubsubsec}{}
}
% Ditto, but for \subsection.
\newcommand{\subsect}[2]{%
\subsection{#1}%
\label{sub\currentsec:#2}%
\pgfkeyssetvalue{/currentsubsec}{sub\pgfkeysvalueof{/currentsec}:#2}
\pgfkeyssetvalue{/currentsubsubsec}{}
}
% Ditto, but for \subsubsection.
\newcommand{\subsubsect}[2]{%
\subsubsection{#1}%
\label{sub\currentsubsec:#2}%
\pgfkeyssetvalue{/currentsubsubsec}{sub\pgfkeysvalueof{/currentsubsec}:#2}
}
% Convenience command for brevity and legibility.
\newcommand{\currentsec}{%
\pgfkeysvalueof{/currentsec}%
}
% Ditto.
\newcommand{\currentsubsec}{%
\pgfkeysvalueof{/currentsubsec}%
}
%Ditto.
\newcommand{\currentsubsubsec}{%
\pgfkeysvalueof{/currentsubsubsec}%
}
% Convenience command to cut down document size from repetition.
\newcommand{\showvalues}{%
Current section: \currentsec
Current subsection: \currentsubsec
Current subsubsection: \currentsubsubsec
}
\begin{document}
\sect{Blue}{blue}
\showvalues
\input{input.tex}
\subsect{Blue One}{one}
\showvalues
\input{input.tex}
Reference to subsubsection Alpha of current subsection: \ref{sub\currentsubsec:alpha}
\subsubsect{Blue One Alpha}{alpha}
\showvalues
\input{input.tex}
\subsect{Blue Two}{two}
\showvalues
\input{input.tex}
\sect{Red}{red}
\showvalues
\input{input.tex}
\subsect{Red One}{one}
\showvalues
\input{input.tex}
\subsubsect{Red One Bravo}{bravo}
\showvalues
\input{input.tex}
\subsect{Red Two}{two}
\showvalues
\input{input.tex}
\end{document}
currfile
to access the directory path information.subsec:one:two
when input.tex is included withinsec:one
, but will point tosubsec:two:two
when input.tex is included insec:two
. I'd like it to point to the:two
subsection of whichever section input.tex is placed in.