0
\documentclass{report}


\usepackage{philex} % Includes linguex. Only loading it for \phildashes.
\usepackage{cleveref}

% Referring to Subexample Ranges

\crefname{ExNo}{}{}
\crefname{SubExNo}{}{}
\crefname{SubSubExNo}{}{}

\renewcommand{\theExNo}{\arabic{ExNo}}
\renewcommand{\theSubExNo}{\theExNo\arabic{SubExNo}}
\renewcommand{\theSubSubExNo}{\theSubExNo\alph{SubSubExNo}}

\creflabelformat{ExNo}{(#2#1#3)}
\creflabelformat{SubExNo}{(#2#1#3)}
\creflabelformat{SubSubExNo}{(#2#1#3)}

\crefrangelabelformat{ExNo}{(#3#1#4)--(#5#2#6)}
\crefrangelabelformat{SubExNo}{(#3#1#4--#5\crefstripprefix{#1}{#2}#6)} % Skips the common part of the label.
\crefrangelabelformat{SubSubExNo}{(#3#1#4--#5\crefstripprefix{#1}{#2}#6)}

\phildashes{.}{}        % Adds a dot between levels 1 and 2 in references (since both have arabic-style labels).
\subformat{1}{}{.}      % Level 2 is of the form “1.”
\subsubformat{a}{}{.}   % Level 3 is of the form “a.”

\begin{document}

    \ex. This is the main level.
        \a. This is the sublevel.
            \a. This is the subsublevel. \label{1a}
            \b. Third level too.  \label{1b}

I want to keep the \cref{1a} and \crefrange{1a}{1b} styles, but when working on a given main level, I want to be able to make local references to the sublevel and subsublevel, i.e. skip the 1st or 2nd levels : (1a), (1a--b) ; (a), (a)--(b).

\end{document}

enter image description here

  • So what I basically want is to define new commands, let's say \localref and \localrefrange.

  • Note that although if we use Philex's \lb command instead of Linguex's \ex., we can then use Philex's \rfx and \rnx commands which skip the first level as desired,

    • first, they are in themselves of no help for ranges,

    • and second, they only skip the first level, not the second one,

      • i.e. as a local reference to "1.1a" you can obtain "1a" but never just "a".

I do not use roman numbering because \crefstripprefix doesn't like it. (We now have a workaround involving the xstring package and the \mystriptocolon command, cf. https://tex.stackexchange.com/a/635636/262813.)

  • I would ideally also like to have a no-parentheses variant of \localref and \localrefrange (let's say \plocalref and \plocalrefrange).

1 Answers1

-1

Edit The old solution (see infra after new one) becomes useless once you master the package zref, cf. https://tex.stackexchange.com/a/644037/262813

\documentclass{article}

\usepackage{zref-user} \usepackage{philorig}

\renewcommand{\label}{\zlabel}

\newcommand{\na}{n\textbackslash a}

\makeatletter

\zref@newprop{theexno}{\arabic{ExNo}} \zref@newprop{thesubexno}{\arabic{altsub}} \zref@newprop{theexdepth}{\theExDepth}

\zref@newprop{mainstrip}{\ifnum\theExDepth=3\alph{altsub}.\roman{altsubsub}\else\alph{altsub}\fi}

\zref@newprop{maxstrip}{\ifnum\theExDepth=3\roman{altsubsub}\else{\ifnum\theExDepth=2\alph{altsub}\else\arabic{ExNo}\fi}\fi}

\zref@newprop{mainskip}{\ifnum\theExDepth=1\arabic{ExNo}\else{% \ifnum\theExDepth=2\alph{altsub}% \else\alph{altsub}.\roman{altsubsub}\fi}% \fi}

\zref@newprop{maxskip}{\ifnum\theExDepth=3\roman{altsubsub}\else{% \ifnum\theExDepth=2\alph{altsub}\else\arabic{ExNo}\fi}% \fi}%

\zref@addprops{main}{theexno,thesubexno,theexdepth,mainstrip,maxstrip,mainskip,maxskip}

% Clever Stripping

\newcommand{\pairequal}[2]{% \ifnum\arabic{SubExNo}=0(\zref{#1},,\zref{#2})% \else{% \ifnum\zref@extract{#1}{theexno}=\zref@extract{#2}{theexno}{% \ifnum\zref@extract{#1}{thesubexno}=\zref@extract{#2}{thesubexno}(\zref{#1},,\zref[maxstrip]{#2})% \else (\zref{#1},,\zref[mainstrip]{#2})\fi}% \else (\zref{#1}) and (\zref{#2})\fi}% \fi}

\newcommand{\rangeequal}[2]{% \ifnum\arabic{SubExNo}=0(\zref{#1}--\zref{#2})% \else{% \ifnum\zref@extract{#1}{theexno}=\zref@extract{#2}{theexno}{% \ifnum\zref@extract{#1}{thesubexno}=\zref@extract{#2}{thesubexno}(\zref{#1}--\zref[maxstrip]{#2})% \else (\zref{#1}--\zref[mainstrip]{#2})\fi}% \else(\zref{#1})--(\zref{#2})\fi}% \fi}

\newcommand{\cleverange}[2]{% \ifnum\zref@extract{#1}{theexdepth}=\zref@extract{#2}{theexdepth}\rangeequal{#1}{#2}% \else(\zref{#1}--\zref{#2})\fi}

\newcommand{\clevepair}[2]{% \ifnum\zref@extract{#1}{theexdepth}=\zref@extract{#2}{theexdepth}\pairequal{#1}{#2}% \else(\zref{#1},,\zref{#2})\fi}

% Skipping Variants

% A. Main Skip

\newcommand{\mainskippairequal}[2]{% \ifnum\arabic{SubExNo}=0(\zref[mainskip]{#1},,\zref[mainskip]{#2})% \else{% \ifnum\zref@extract{#1}{theexno}=\zref@extract{#2}{theexno}{% \ifnum\zref@extract{#1}{thesubexno}=\zref@extract{#2}{thesubexno}(\zref[mainskip]{#1},,\zref[maxstrip]{#2})% \else (\zref[mainskip]{#1}) and (\zref[mainstrip]{#2})\fi}% \else (\zref[mainskip]{#1},,\zref[mainskip]{#2})\fi}% \fi}

\newcommand{\mainskiprangeequal}[2]{% \ifnum\arabic{SubExNo}=0(\zref[mainskip]{#1}--\zref[mainskip]{#2})% \else{% \ifnum\zref@extract{#1}{theexno}=\zref@extract{#2}{theexno}{% \ifnum\zref@extract{#1}{thesubexno}=\zref@extract{#2}{thesubexno}(\zref[mainskip]{#1}--\zref[maxstrip]{#2})% \else (\zref[mainskip]{#1})--(\zref[mainskip]{#2})\fi}% \else (\zref[mainskip]{#1}--\zref[mainskip]{#2})\fi} \fi}

\newcommand{\mainskipcleverange}[2]{% \ifnum\zref@extract{#1}{theexdepth}=\zref@extract{#2}{theexdepth}\mainskiprangeequal{#1}{#2}% \else (\zref[mainskip]{#1}--\zref[mainskip]{#2})\fi}

\newcommand{\mainskipclevepair}[2]{% \ifnum\zref@extract{#1}{theexdepth}=\zref@extract{#2}{theexdepth}\mainskippairequal{#1}{#2}% \else (\zref[mainskip]{#1},,\zref[mainskip]{#2})\fi}

% B. Max Skip

\newcommand{\maxskippairequal}[2]{% \ifnum\arabic{SubExNo}=0(\zref[maxskip]{#1},,\zref[maxskip]{#2})% \else{% \ifnum\zref@extract{#1}{theexno}=\zref@extract{#2}{theexno}% {\ifnum\zref@extract{#1}{thesubexno}=\zref@extract{#2}{thesubexno}(\zref[maxskip]{#1}) and (\zref[maxskip]{#2})% \else(\zref[maxskip]{#1}) and (\zref[maxskip]{#2})\fi}% \else(\zref[maxskip]{#1},,\zref[maxskip]{#2})\fi}% \fi}

\newcommand{\maxskiprangeequal}[2]{% \ifnum\arabic{SubExNo}=0(\zref[maxskip]{#1}--\zref[maxskip]{#2})% \else{% \ifnum\zref@extract{#1}{theexno}=\zref@extract{#2}{theexno}{% \ifnum\zref@extract{#1}{thesubexno}=\zref@extract{#2}{thesubexno}(\zref[maxskip]{#1})--(\zref[maxskip]{#2})% \else(\zref[maxskip]{#1})--(\zref[maxskip]{#2})\fi}% \else(\zref[maxskip]{#1}--\zref[maxskip]{#2})\fi} \fi}

\newcommand{\maxskipcleverange}[2]{% \ifnum\zref@extract{#1}{theexdepth}=\zref@extract{#2}{theexdepth}\maxskiprangeequal{#1}{#2}% \else(\zref[maxskip]{#1}--\zref[maxskip]{#2})\fi}

\newcommand{\maxskipclevepair}[2]{% \ifnum\zref@extract{#1}{theexdepth}=\zref@extract{#2}{theexdepth}\maxskippairequal{#1}{#2}% \else(\zref[maxskip]{#1},,\zref[maxskip]{#2})\fi}

\makeatother

\begin{document}

\phildashes{}{.} \subformat{a}{}{.}

\lb{main1}{Example One. \lba{sub11}{Subexample One-One. \lba{subsub111}{Subsubexample One-One-One.} \lbb{subsub112}{Subsubexample One-One-Two.} \lbz{subsub113}{Subsubexample One-One-Three.}} \lbz{sub12}{Subexample One-Two. \lba{subsub121}{Subsubexample One-Two-One.} \lbz{subsub122}{Subsubexample One-Two-Two.}}}

\lb{main2}{Example Two. \lba{sub21}{Subexample Two-One.} \lbz{sub22}{Subexample Two-Two.}}

\vspace{3ex}

\textbf{Clever Ranges} (full - mainskip - maxskip)\vspace{1ex}

\begin{tabular}[c]{lll}

\cleverange{main1}{main2} & \na & \na\

\cleverange{sub11}{sub12} & \mainskipcleverange{sub11}{sub12} & \na\

\cleverange{sub11}{sub22} & \na & \na\

\cleverange{subsub111}{subsub113} & \mainskipcleverange{subsub111}{subsub113} & \maxskipcleverange{subsub111}{subsub113}\

\cleverange{subsub113}{subsub122} & \mainskipcleverange{subsub113}{subsub122} & \na

\end{tabular}

\vspace{2ex}

------------------\vspace{2ex}

\textbf{Clever Pairs} (full - mainskip - maxskip)\vspace{1ex}

\begin{tabular}[c]{lll}

\clevepair{main1}{main2} & \na & \na\

\clevepair{sub11}{sub12} & \mainskipclevepair{sub11}{sub12} & \na\

\clevepair{sub11}{sub22} & \na & \na\

\clevepair{subsub111}{subsub113} & \mainskipclevepair{subsub111}{subsub113} & \maxskipclevepair{subsub111}{subsub113}\

\clevepair{subsub113}{subsub122} & \mainskipclevepair{subsub113}{subsub122} & \na

\end{tabular}

\end{document}

enter image description here


 

Old solution.

I have a suggestion which does not involve the cleveref package.

  • As pointed out in the original post, Philex's \rfx and \rnx commands have been purposefully design so as to be able to skip the first level sublabel.

  • Ulrich Diez has found a solution to skip the second level as well if there is a dot:

  • Below I define, using Ulrich Diez's code :

    • \rfxx, which is like Philex's \rfx (= like \ref but skipping the level-1 sublabel ; reference between parentheses), but skips the level-2 sublabel as well.

    • \rnxx, which is like Philex's \rnx (= like \ref but skipping the level-1 sublabel ; reference without parentheses), but skips the level-2 sublabel as well.

      \makeatletter
      \@ifdefinable\gobbletodot{\long\def\gobbletodot#1.{}}%
      \newcommand\KeepOnlyStuffBehindLastDot[1]{%
        \ifcat$\detokenize\expandafter{\gobbletodot#1.}$%
        \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
        {#1}{\expandafter\KeepOnlyStuffBehindLastDot\expandafter{\gobbletodot#1}}%
      }%
      \@ifdefinable\rfxx{%
        \DeclareRobustCommand\rfxx[1]{%
          \IfRefUndefinedBabel{#1}{\refused{#1}\nfss@text{\reset@font\bfseries??}}%
                              {%
                                \@ifundefined{hyperref}{\@firstofone}{\hyperref[{#1}]}%
                                {%
                                  (\expandafter\expandafter\expandafter\KeepOnlyStuffBehindLastDot
                                  \expandafter\expandafter\expandafter{\getrefbykeydefault{#1}{}{??}})%
                                }%
                              }%
        }%
      }%
      

      @ifdefinable\rnxx{% \DeclareRobustCommand\rnxx[1]{% \IfRefUndefinedBabel{#1}{\refused{#1}\nfss@text{\reset@font\bfseries??}}% {% @ifundefined{hyperref}{@firstofone}{\hyperref[{#1}]}% {% \expandafter\expandafter\expandafter\KeepOnlyStuffBehindLastDot \expandafter\expandafter\expandafter{\getrefbykeydefault{#1}{}{??}}% }% }% }% }%

      \makeatother

  • Now I define ranges :

    • using Philex's commands, we may skip the 1st level sublabel :

      \newcommand{\rfxrange}[2]{\rfx{#1}--\rfx{#2}}
      \newcommand{\rnxrange}[2]{\rnx{#1}--\rnx{#2}}
      
    • using new commands from Ulrich Diez's code, we may skip the 2nd level as well :

      \newcommand{\rfxxrange}[2]{\rfxx{#1}--\rfxx{#2}}
      \newcommand{\rnxxrange}[2]{\rnxx{#1}--\rnxx{#2}}
      
  • Then I add "prefix stripping" possibility :

    • the lines below combine a left part including the level-2 sublabel with a right part skipping it.

      \newcommand{\rfxstrip}[2]{(\rnx{#1}--\rnxx{#2})}
      \newcommand{\rnxstrip}[2]{\rnx{#1}--\rnxx{#2}}
      

Now the application in the original MWE :

\documentclass{report}

\usepackage[hidelinks]{hyperref} \usepackage{refcount} \usepackage{philex} % Includes linguex. Only loading it for \phildashes. \usepackage{cleveref}

% Referring to Subexample Ranges

\crefname{ExNo}{}{} \crefname{SubExNo}{}{} \crefname{SubSubExNo}{}{}

\renewcommand{\theExNo}{\arabic{ExNo}} \renewcommand{\theSubExNo}{\theExNo\arabic{SubExNo}} \renewcommand{\theSubSubExNo}{\theSubExNo\alph{SubSubExNo}}

\creflabelformat{ExNo}{(#2#1#3)} \creflabelformat{SubExNo}{(#2#1#3)} \creflabelformat{SubSubExNo}{(#2#1#3)}

\crefrangelabelformat{ExNo}{(#3#1#4)--(#5#2#6)} \crefrangelabelformat{SubExNo}{(#3#1#4--#5\crefstripprefix{#1}{#2}#6)} % Skips the common part of the label. \crefrangelabelformat{SubSubExNo}{(#3#1#4--#5\crefstripprefix{#1}{#2}#6)}

\phildashes{.}{.} % Adds a dot between levels in references \subformat{1}{}{.} % Level 2 is of the form “1.” \subsubformat{a}{}{.} % Level 3 is of the form “a.”

% Skip the first and second levels \makeatletter @ifdefinable\gobbletodot{\long\def\gobbletodot#1.{}}% \newcommand\KeepOnlyStuffBehindLastDot[1]{% \ifcat$\detokenize\expandafter{\gobbletodot#1.}$% \expandafter@firstoftwo\else\expandafter@secondoftwo\fi {#1}{\expandafter\KeepOnlyStuffBehindLastDot\expandafter{\gobbletodot#1}}% }% @ifdefinable\rfxx{% \DeclareRobustCommand\rfxx[1]{% \IfRefUndefinedBabel{#1}{\refused{#1}\nfss@text{\reset@font\bfseries??}}% {% @ifundefined{hyperref}{@firstofone}{\hyperref[{#1}]}% {% (\expandafter\expandafter\expandafter\KeepOnlyStuffBehindLastDot \expandafter\expandafter\expandafter{\getrefbykeydefault{#1}{}{??}})% }% }% }% }%

@ifdefinable\rnxx{% \DeclareRobustCommand\rnxx[1]{% \IfRefUndefinedBabel{#1}{\refused{#1}\nfss@text{\reset@font\bfseries??}}% {% @ifundefined{hyperref}{@firstofone}{\hyperref[{#1}]}% {% \expandafter\expandafter\expandafter\KeepOnlyStuffBehindLastDot \expandafter\expandafter\expandafter{\getrefbykeydefault{#1}{}{??}}% }% }% }% }%

\makeatother

%Now I define ranges :

\newcommand{\rfxrange}[2]{\rfx{#1}--\rfx{#2}} \newcommand{\rnxrange}[2]{\rnx{#1}--\rnx{#2}}

\newcommand{\rfxxrange}[2]{\rfxx{#1}--\rfxx{#2}} \newcommand{\rnxxrange}[2]{\rnxx{#1}--\rnxx{#2}}

\newcommand{\rfxstrip}[2]{(\rnx{#1}--\rnxx{#2})} \newcommand{\rnxstrip}[2]{\rnx{#1}--\rnxx{#2}}

\begin{document}

\lb{main}{This is the main level.
    \lba{sub}{This is the sublevel.
        \lba{subsub-a}{This is the subsublevel.}
        \lbz{subsub-b}{Third level too.}}}



I want to keep the \cref{sub} and \crefrange{subsub-a}{subsub-b} styles, but when working on a given main level, I want to be able to make local references to the sublevel and subsublevel, i.e. skip the 1st or 2nd levels.

I can use \textbackslash rfxrange and \textbackslash rnxrange commands to skip 1 level as in \rfxrange{subsub-a}{subsub-b} or \rnxrange{subsub-a}{subsub-b}

and \textbackslash rfxxrange and \textbackslash rnxxrange commands to skip the second level as well, as in \rfxxrange{subsub-a}{subsub-b} or \rnxxrange{subsub-a}{subsub-b}.

I can also, while skipping the first level, use my new \textbackslash rfxstrip and \textbackslash rnxstrip commands so as to obtain a \textbackslash crefstripprefix effect :

\rfxstrip{subsub-a}{subsub-b} and \rnxstrip{subsub-a}{subsub-b}.

\end{document}

enter image description here

  • Now to harmonize command names with cleveref non-local ranges, we may define :

    \newcommand{\rfrange}[2]{(\cref{#1})--(\cref{#2})}
    \newcommand{\rnrange}[2]{\cref{#1}--\cref{#2}}
    

    \newcommand{\rfstrip}[2]{(\crefrange{#1}{#2})} \newcommand{\rnstrip}[2]{\crefrange{#1}{#2}}

enter image description here

Also see :

Crossreference in Ref Range [(1a-1e) to (1a-e)]

Any way to reference a particular component of a label?

Refer to a range of subsubexamples