0

Design: a (La)TeX command (maybe look like this \passresult{\outercommand}{\innercommand}{param1}{param2}),

which pass the return of a dual-parameter \innercommand{param1}{param2} into another \outercommand{} as one of its arguments (which might be a label) —— the whole process is like programming in 'normal' programming language \outercommand{\innercommand{param1}{param2}}.

Below is the MWE achieving the same effect while using \outercommand{\passresult{\innercommand}{param1}{param2}} instead, but this would fail when it comes to the \cref, \pageref or \hyperref case in the commented line below.

% https://tex.stackexchange.com/questions/721655/design-a-command-that-allows-a-dual-parameter-command-passing-its-return-into
\documentclass{article}

\usepackage{amsmath,amssymb,amsfonts}%
\usepackage{amsthm}%
\usepackage{stmaryrd} % \Yup

\usepackage{hyperref}
\usepackage{cleveref}

\usepackage{expl3}
\ExplSyntaxOn
\NewExpandableDocumentCommand{\extractelement}{mm}
{\clist_item:nn {#1} {#2}}
\ExplSyntaxOff

\newcommand{\passresult}[3]{%
    \expandafter\def\expandafter\temp\expandafter{#1{#2}{#3}}%
    \temp
}

\def\customCMD#1{#1}

\begin{document}
\section{Section}

\begin{subequations} \label{eq:0-42}
    \begin{align} 
        \bar{\bar{\underline{R}}}_{\Yup} \cdot \left( 1 - \hat{k}\hat{k} \right) \cdot \left( \bar{\bar{R}}_{\Yup} \cdot \bar{\bar{\eta}}^{\;\!\omega} \cdot \bar{\bar{\underline{R}}}_{\Yup} \right) \cdot \bar{d}^{\;\!\prime\omega} &= \frac{1}{n^{2}_{\prime\omega}} \left( \bar{\bar{\underline{R}}}_{\Yup} \cdot \bar{d}^{\;\!\prime\omega} \right), \label{eq:0-42a} \\ \left( \bar{\bar{\underline{R}}}_{\Yup} \cdot \hat{k} \right) \cdot \left( \bar{\bar{\underline{R}}}_{\Yup} \cdot \bar{d}^{\;\!\prime\omega} \right) &= 0, \label{eq:0-42b} 
    \end{align}
\end{subequations}

\customCMD{eq:0-42} \\ % individually works
\extractelement{eq:0-42,thepage}{1} \\ % individually works
\customCMD{\extractelement{eq:0-42,thepage}{1}} \\ % nestedly works
\customCMD{\extractelement{eq:0-42,thepage}{2}} \\ % nestedly works
\customCMD{\passresult{\extractelement}{eq:0-42,thepage}{1}} \\ % nestedly works

\pageref{eq:0-42} \\ % works
%\pageref{\passresult{\extractelement}{eq:0-42,thepage}{1}}% not works!

\cref{eq:0-42} \\ % works
%\cref{\passresult{\extractelement}{eq:0-42,thepage}{1}} % not works!

\hyperref[eq:0-42]{link} \\ % works
%\hyperref[\passresult{\extractelement}{tlabel,thepage}{1}]{link}% not works!
    
\pagebreak
\section{Section}
\end{document}

Requirement: \outercommand{} could be 'system' commands like \pageref{<label>}, \hyperref[<label>]{...}, which accept a label as its parameter, rather than any \commands.

Background: I am trying to hack \cref{} into surporting auto-backlinks to equations, figures/tables --> all backrefs "quoted by ..." display as margins along side them with the same heights, thus need this function; Any help would be appreciated, such as direct solutions to my final goals, i.e., auto-margin-backlinks to equations or floatings :)

Now: the patch for custom backlinks has been done, see the Comment below.

6
  • Welcome! Your proposed syntax is \passresult{\outercommand}{\innercommand}{param1}{param2} but then you say you want \passresult{\extractelement}{mylabel,thepage}{1} and \passresult{\extractelement}{mylabel,1}{1} where \passresult is used in the argument of \outercommand rather than \outercommand being used as an argument to \passresult. And I'm not sure what you mean by 'direct solutions to my last 3 big problems'? And what is an 'auto-backlink'? You don't need to do anything to get cleveref to work with linked cross-references.
    – cfr
    Commented Jul 1 at 4:37
  • 3
    All you need to do to get hyperlinked cross-references with cleveref is load cleveref last i,e, after hyperref. Then you can enable whatever links you want with hyperref. You don't need to hack anything ;). And \pageref isn't a cleveref command anyway.
    – cfr
    Commented Jul 1 at 4:41
  • Emm, sorry for being not so clear: 1). Yes, as you've noticed, \hyperlinkto{\passresult{\extractelement}{mylabel,thepage}{1}} provided in MWE is indeed not \passresult{\outercommand}{\innercommand}{param1}{param2} but \outercommand{\passresult{\innercommand}{param1}{param2}} instead, which serves the same effect only when \outercommand{} are not sth like \pageref{}... I need the outlet for \pageref{} —— So I suppose a more general command would be in \passresult{\outercommand}{\innercommand}{param1}{param2} this form, as suggested in the beginning.
    – 谢尘竹
    Commented Jul 1 at 6:52
  • 2). 3 big problems = auto-backlinks to equations, figures, and tables showing where they are mentioned (e.g. Equation. (9) is mentioned in pages 1, 4, 4, 6) and displayed as marginnotes. These cannot be automatically done by \cref, \eqref, \ref, \autoref, or \pageref... | backlinks for equations: see link backlinks for floats: see link | Best Wishes!
    – 谢尘竹
    Commented Jul 1 at 7:02
  • you need to be more specific about which commands you want to use. In general macros to not have a return value so "passing the return value of the inner command" has no meaning. If you said which commands you wanted to use and what you wanted the overall result to be, an answer is no doubt possible. Commented Jul 1 at 8:31

2 Answers 2

3

the return of a dual-parameter \innercommand{param1}{param2} into another \outercommand{} as one of its arguments (which might be a label)

TeX has several stages of processing.

Using Knuth's analogy of TeX being a beast with eyes and digestive tract, TeX creates tokens (control sequence tokens, character tokens) in its mouth according to the sequence of characters TeX's eyes see in the .tex-input-file. Tokens created in TeX's mouth are sent down TeX's gullet in the order in which they are created by TeX's mouth. So the order in which tokens occur in the token-stream at the begin of TeX's gullet corresponds to the order in time in which they were created by the mouth. There might be a wish to have the order changed in which tokens occur in the token stream. There might be a wish to have some tokens removed or added or replaced by other tokens. There might be a wish to change the constellation of tokens in the token stream and/or to change the order in which tokens occur in the token stream. Such changing of the constellation/order in which tokens occur in the token stream is done in the stage of expansion, i.e., while tokens go down TeX's gullet, by means of macro tokens and/or by means of expandable primitives. Knuth describes this as a process of 'regurgitation' which means that in case an expandable token yields other expandable tokens, these will be expanded in the gullet, too. (There are situations when expansion in the gullet is suppressed. E.g., when TeX in the stomach gathers tokens forming the ⟨definition text⟩ of a \def-assignment or when TeX in the stomach gathers tokens forming the ⟨general text⟩ of a ⟨token variable⟩-assignment.) So with the "return" of routines which are based on expansion only, the focus is on obtaining specific constellations of tokens while things go through TeX's gullet. When things have passed TeX's gullet, changing the constellation of tokens that form the token stream and the order in which tokens occur in the token stream and thus are processed by subsequent "stations" of TeX's digestive tract is not possible any more.

Performing assignments or writing cross referencing data to aux-files and the like does not take place in the gullet but takes place in areas of TeX's digestive tract that are subsequent to the gullet.
The "return" with routines where things are to be performed in stations of TeX's digestive tract that are subsequent to the gullet in most cases is not tokens but might, e.g., be creating horizontal/vertical lists as contents of a box or box-register or might be the performing of an assignment or might be the act of writing characters to an external auxiliary file or might be shipping the content of the document's current page to the output file (.pdf-file/.dvi-file).

With commands like \hyperref and \pageref and \cref it is expected that the character tokens that form the name of the cross referencing label come into being before the tokens that form those macros' arguments for denoting the cross referencing label have passed TeX's gullet and enter TeX's stomach. I.e., expansion is applied to the tokens that form those macros' arguments for denoting the cross referencing label. Attempts at doing things in stations of TeX's digestive tract subsequent to the gullet, like assignments for (re)defining scratch macros, do not work out. This is because internally those arguments are taken for components of names of control sequence tokens which expand to the desired cross referencing data and they get placed between \csname...\endcsname for obtaining these control sequence tokens. Carrying out \csname...\endcsname for obtaining a control sequence token from a set of tokens in the stage of expansion yielding explicit character tokens denoting the name of the control sequence token in question is done in TeX's gullet/is done in the stage of expansion. So attempts at carrying out \def while TeX is processing a \csname...\endcsname-expression do not work out as the \csname...\endcsname-expression is to be processed in TeX's gullet while \def-assignments are to be processed in TeX's stomach.

But the replacement text of \passresult contains tokens that form directives for performing assignments (defining the scratch macro \temp). Performing assignments is done in a stage of processing subsequent to the gullet/subsequent to the stage of expansion.

Therefore having the macro token \passresult as a component of that argument of \hyperref/\pageref/\cref that denotes the name of the cross referencing label does not work out.

\cref{1\passresult{1\extractelement}2{1e11q11:12012-12412212,12t11h11e11p11a11g11e11}2{1112}2}2

is like

\cref{1\expandafter\def\expandafter\temp\expandafter{1\extractelement{1e11q11:12012-12412212,12t11h11e11p11a11g11e11}2{1112}2}2\temp}2.

Here \expandafter is expandable but you need more than just a single \expandafter-chain to get the result of \extractelement.

But the real crucial issue is that \def is an assignment and thus is not carried out in the stage of expansion. So this is like

\cref{1\def\temp{1⟨result of toplevel-expanding \extractelement{1e11q11:12012-12412212,12t11h11e11p11a11g11e11}2{1112}2}2⟨whatever replacement text \temp was defined to deliver when processing \cref started⟩}2

, whereby the token sequence

\def\temp{1⟨result of toplevel-expanding \extractelement{1e11q11:12012-12412212,12t11h11e11p11a11g11e11}2{1112}2}2⟨whatever replacement text \temp was defined to deliver when processing \cref started⟩

is taken for the tokens that denote the name of the cross referencing label, which does not work out for several reasons.
One of those reasons is that tokens used for denoting the name of a cross referencing label and thus to be placed between \csname...\endcsname should be or by expansion yield explicit character tokens, not non-expandable primitive control sequence tokens like \def.
Another one of those reasons is that
⟨whatever replacement text \temp was defined to deliver when processing \cref started⟩
could be anything.

With the scenario given in the question you can do by just omitting the step of applying \passresult for defining a scratch macro (and thus making it impossible to have things done by expansion only!) and afterwards producing an instance of that scratch macro-token:

\documentclass{article}

\usepackage{amsmath,amssymb,amsfonts}%
\usepackage{amsthm}%
\usepackage{stmaryrd} % \Yup

\usepackage{hyperref}
\usepackage{cleveref}

% \usepackage{expl3}
\ExplSyntaxOn \cs_new_eq:NN \extractelement \clist_item:nn \ExplSyntaxOff

\newcommand*\customCMD[1]{#1}

\begin{document}
\section{Section}

% The purpose of this is having s.th. fancy where labels for cross-referencing are created.
\begin{subequations} \label{eq:0-42}
    \begin{align} 
        \bar{\bar{\underline{R}}}_{\Yup} \cdot \left( 1 - \hat{k}\hat{k} \right) \cdot \left( \bar{\bar{R}}_{\Yup} \cdot \bar{\bar{\eta}}^{\;\!\omega} \cdot \bar{\bar{\underline{R}}}_{\Yup} \right) \cdot \bar{d}^{\;\!\prime\omega} &= \frac{1}{n^{2}_{\prime\omega}} \left( \bar{\bar{\underline{R}}}_{\Yup} \cdot \bar{d}^{\;\!\prime\omega} \right), \label{eq:0-42a} \\ \left( \bar{\bar{\underline{R}}}_{\Yup} \cdot \hat{k} \right) \cdot \left( \bar{\bar{\underline{R}}}_{\Yup} \cdot \bar{d}^{\;\!\prime\omega} \right) &= 0, \label{eq:0-42b} 
    \end{align}
\end{subequations}

\pagebreak
\section{Section}

\noindent
\customCMD{eq:0-42}\\% individually works
\extractelement{eq:0-42,thepage}{1}\\% individually works
\customCMD{\extractelement{eq:0-42,thepage}{1}}\\% nestedly works
\customCMD{\extractelement{eq:0-42,thepage}{2}}% nestedly works

\noindent
\pageref{eq:0-42}\\% works
\pageref{\extractelement{eq:0-42,thepage}{1}}% works!

\noindent
\cref{eq:0-42}\\% works
\cref{\extractelement{eq:0-42,thepage}{1}} % works!

\noindent
\hyperref[eq:0-42]{link}\\% works
\hyperref[\extractelement{eq:0-42,thepage}{1}]{link}% works!

% The following does not work as there is no cross-referencing-labek "tlabel" defined.
%\noindent
%\hyperref[\extractelement{tlabel,thepage}{1}]{link}%
    
\end{document}

enter image description here

enter image description here

4
  • Heavens! The god must have descended! No words can describe your words! For a novice in LaTeX, digesting these "token streams" truly requires a long "gullet→stomach→digestive tract" journey combined with "rumination", akin to enduring "eighty-one hardships" before they can be fully assimilated... It might even take "more than four compilations (in the mind)" to be thoroughly understood! Yet again, hail to expertise and patience!
    – 谢尘竹
    Commented Jul 6 at 17:37
  • @谢尘竹 In case you are interested: I tried to explain TeX's different stages of processing/of digesting .tex-input in my answers to the following questions: Define commands without the need for brackets / 'a^^Mb' isn't equivalent to 'a<return>b'; instead throws pdftex into an extended mode / Conversion of space characters into space tokens Commented Jul 6 at 19:00
  • I am more than delighted to heed your guidance, my esteemed teacher!
    – 谢尘竹
    Commented Jul 6 at 19:08
  • @谢尘竹 There are far better teachers here than me. Thank you for your kind comment. ;-)) Commented Jul 6 at 19:13
0

Looking back, this issue, as @Ulrich said, is actually about the differences between \cref{\extract{label,page}{1}} and \cref{\passresult{\extract}{label,page}{1}}, at least on the surface.

At that time, I was on my way to my ultimate goal when I encountered a compiler error. I thought the problem lay \cref{\extract{label,page}{1}} and sought advice from Perplexity.AI.

The feedback led me to mistakenly believe that \expandafter could solve the issue, but it was actually a misdiagnosis — the compiler error was not caused by \cref{\extract{label,page}{1}} (which diverges from the thread's main topic) and complicated the problem (I even thought \cref{\extract{label,page}{1}} definitely wouldn't work, so I didn't include it in the MWE... Ironically, it was/is the correct answer :).

Regardless, I greatly appreciate @Ulrich for taking the time to meticulously explain the entire flow from first principles.


As a gesture of appreciation and to bring this thread to a close,

  1. I have slightly modified the previous MWE and included it here to better align with the "original theme" of this thread:
% https://tex.stackexchange.com/questions/721655/design-a-command-that-allows-a-dual-parameter-command-passing-its-return-into
\documentclass{article}

\usepackage{amsmath,amssymb,amsfonts}%
\usepackage{amsthm}%
\usepackage{stmaryrd} % \Yup

\usepackage{hyperref}
\usepackage{cleveref}

%\ExplSyntaxOn
%\NewExpandableDocumentCommand{\extractelement}{mm}
%{\clist_item:nn {#1} {#2}}
%\ExplSyntaxOff

\newcommand{\passresult}[3]{%
    \expandafter\def\expandafter\temp\expandafter{#1{#2}{#3}}%
    \temp
}

\ExplSyntaxOn
\cs_new_eq:NN \extractelement \clist_item:nn
\ExplSyntaxOff

%\def\customCMD#1{#1}
\newcommand*\customCMD[1]{#1}

\begin{document}
\section{Section}

\begin{subequations} \label{eq:0-42}
    \begin{align} 
        \bar{\bar{\underline{R}}}_{\Yup} \cdot \left( 1 - \hat{k}\hat{k} \right) \cdot \left( \bar{\bar{R}}_{\Yup} \cdot \bar{\bar{\eta}}^{\;\!\omega} \cdot \bar{\bar{\underline{R}}}_{\Yup} \right) \cdot \bar{d}^{\;\!\prime\omega} &= \frac{1}{n^{2}_{\prime\omega}} \left( \bar{\bar{\underline{R}}}_{\Yup} \cdot \bar{d}^{\;\!\prime\omega} \right), \label{eq:0-42a} \\ \left( \bar{\bar{\underline{R}}}_{\Yup} \cdot \hat{k} \right) \cdot \left( \bar{\bar{\underline{R}}}_{\Yup} \cdot \bar{d}^{\;\!\prime\omega} \right) &= 0, \label{eq:0-42b} 
    \end{align}
\end{subequations}

\section{Section}

\noindent
\customCMD{eq:0-42} \\ % individually works
\extractelement{eq:0-42,thepage}{1} \\ % individually works

\noindent
\customCMD{\extractelement{eq:0-42,thepage}{2}} \\ % nestedly works
\customCMD{\passresult{\extractelement}{eq:0-42,thepage}{1}} \\ % nestedly works

\noindent
\pageref{eq:0-42} \\ % works
\pageref{\extractelement{eq:0-42,thepage}{1}} \\ % nestedly works
%\pageref{\passresult{\extractelement}{eq:0-42,thepage}{1}}% not works!

\noindent
\cref{eq:0-42} \\ % works
\cref{\extractelement{eq:0-42,thepage}{1}} \\ % nestedly works
%\cref{\passresult{\extractelement}{eq:0-42,thepage}{1}} % not works!

\noindent
\hyperref[eq:0-42]{link} \\ % works
\hyperref[\extractelement{eq:0-42,thepage}{1}]{link}% nestedly works
%\hyperref[\passresult{\extractelement}{tlabel,thepage}{1}]{link}% not works!

\pagebreak
\section{Section}
\end{document}
  1. and with the help of Perplexity.AI, after about a week, I have achieved my desired final goals in the bibtex (& natbib) environment.

auto backlinks alongside figures' captions

  • auto backlinks alongside figures' captions

auto backlinks alongside tables' captions

  • auto backlinks alongside tables' captions

auto backlinks alongside bibliography' items

  • auto backlinks alongside bibliography' items | odd = left

auto backlinks alongside bibliography' items

  • auto backlinks alongside bibliography' items | even = right

auto backlinks alongside equations' tags

  • auto backlinks alongside equations' tags

I will publish the source code in a new thread in the near future. The reasons why not now are:

  1. I am writing my article using the sn-article template, thus time is limited;
  2. Uncertain if it will work with other templates (such as biblatex, or non-natbib bibtex);
  3. The code is a messy quagmire for anyone (including myself) due to my lack of expertise.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .