Пропуск нечисловой части контрметки в локальных перекрестных ссылках

Пропуск нечисловой части контрметки в локальных перекрестных ссылках

При цитировании лингвистических примеров авторов внутри цитаты я предпочитаю использовать специальную метку, указывающую имя автора. (Я заключаю ее в квадратные скобки, но здесь она не будет отображаться, поскольку не имеет значения.)

При ссылке на несколько примеров и подпримеровтого же автораЯ хочу иметь возможность пропустить эту специальную нецифровую метку и оставить только номер.

\StrCut from xstringотлично подходит для удаления неразрывного пробела, который находится между именем автора и номером.

Однако при отсутствии разделителя обычное решение с cleveref\crefstripprefix не работает так, как задумано, см. MWE.

Кроме того, разделение до разделителя уровня 2/уровня 3 с помощью \StrCut для полученияАвтор 1a.i--iiihyperrefработает, но при загрузке выдает критическую ошибку .

Позвольте мне отметить, что мне не нужны конкретно диапазоны, которые уже работают с использованием альтернативного подхода «настройки», как показано в mwe.

Я просто хочу иметь возможность пропускать имя автора при ссылке на пример, это обеспечило бы необходимую гибкость для нескольких ссылок, которые не являются диапазонами, например «Автор 1a.ii, 2b.i».

Все кредиты на кодирование можно найти здесь: Перекрестные ссылки: больше подуровней и предустановок


\documentclass{article}
\usepackage{philex} % Linguex wrapper. Awesome despite the "non-academic" coding.
\usepackage{xstring} % Provides the \StrCut command.
\usepackage{refcount} % Provides the \getrefbykeydefault command.
\usepackage{cleveref} % For ranges.


\setlength{\parskip}{1em}

\crefname{bpa}{}{} % Main Counter
\crefname{SubExNo}{}{} % Sublevel.
\crefname{SubSubExNo}{}{}

\newcommand{\dotstrip}[2]{\StrCut{#1}{.}{\onea}{\oneb}%
    \StrCut{#2}{.}{\twoa}{\twob}%
    \IfStrEq{\onea}{\twoa}{\twob}{#2}}

\newcommand{\spacestrip}[2]{\StrCut{#1}{~}{\onea}{\oneb}%
\StrCut{#2}{~}{\twoa}{\twob}%
\IfStrEq{\onea}{\twoa}{\twob}{#2}}

\crefrangelabelformat{bpa}{(#3#1#4--#5\spacestrip{#1}{#2}#6)} %   Stripping to the non-brakable space, so that Author is not repeated.
\crefrangelabelformat{SubExNo}{(#3#1#4--#5\crefstripprefix{#1}{#2}#6)} % Usually outputs 1a--b but does not work here.
\crefrangelabelformat{SubSubExNo}{(#3#1#4--#5\dotstrip{#1}{#2}#6)} % Used with roman numbering, which confuses crefstripprefix. But you need a separator (a dot in this variant).




\begin{document}

    % Philex Formatting
    
    \phildashes{}{.}        % Adds a dot between levels 2 and 3 in references.
    \subformat{a}{}{.}      % Level 2 is of the form “a.”
    \subsubformat{i}{(}{)}  % Level 3 is of the form “(i)”



\bpaformat{1}{Author~}{}

\lbpa{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.}}}

\lbpa{main2}{Example Two.}


When quoting different examples, I do not want \textit{Author} to be repeated.

Works very nicely with xstring's StrCut for the 1st level...

\crefrange{main1}{main2}

... but the 3rd does not work if hypperref is loaded :

\textbackslash crefrange\{subsub111\}\{subsub113\} yields a critical error.

\vspace{6pt}
... and more importantly, level 2 does not work at all because \textbackslash crefstripprefix fails:

\textbackslash crefrange\{sub11\}\{sub12\}  should output “Author 1a--b” but instead I get the following error :

“Improper alphabetic constant.”

\vspace{12pt}

Of course an alternative approach is to refer to “parts” so we can “cheat” and build the refs manually:
Philex already has \textbackslash rfx/rnx command to skip the main level.

Then we may define a new command to skip the first sublevel :



\makeatletter

    \@ifdefinable\gobbletodot{\long\def\gobbletodot#1.{}}% refcount package
    \newcommand\delbefdot[1]{%
      \ifcat$\detokenize\expandafter{\gobbletodot#1.}$%
      \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
      {#1}{\expandafter\delbefdot\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\delbefdot
                                \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\delbefdot
                                \expandafter\expandafter\expandafter{\getrefbykeydefault{#1}{}{??}}%
                              }%
                            }%
      }%
    }%

\makeatother



\newcommand{\rfstrip}[2]{(\rn{#1}--\rnx{#2})}
\newcommand{\rfdoublestrip}[2]{(\rn{#1}--\rnxx{#2})}

\rfstrip{sub11}{sub12}
\rfdoublestrip{subsub111}{subsub113}

\vspace{6pt}

But we lose systematicity and besides, “Author 1a.i, 2b.”  is also something I would like.


\end{document}


введите описание изображения здесь

решение1

Спасибо за пример @Ulrike Fischerздесьо том, как использовать этот замечательный пакет zref, я привел краткую иллюстрацию того, как решить проблему, поднятую мной в исходном посте.

После этого все станет гораздо проще, как вы увидите.

(Разумеется, \zlabel придется заменить \label везде в любом лингвистическом пакете, который включает последний, чтобы нам не пришлось добавлять его вручную, но это тривиально.)

\documentclass{report}
\usepackage{zref-user}
\usepackage{philex}

\setlength{\parskip}{1em}

\makeatletter
\zref@newprop{exno}{\arabic{ExNo}}
\zref@newprop{subexno}{\alph{SubExNo}}
\zref@newprop{subsubexno}{\roman{SubSubExNo}}

\zref@newprop{authorstrip}{\bota{bpa}\alph{SubExNo}{\ifnum\theExDepth=3\roman{SubSubExNo}\fi}} % Here is the key line.

\zref@newprop{refstrip}{\ifnum\theExDepth=3\roman{SubSubExNo}\else\alph{SubExNo}\fi}

\zref@addprops{main}{exno,subexno,subsubexno,authorstrip,refstrip}
\makeatother

\newcommand{\authorstrip}[2]{(\zref{#1},\,\zref[authorstrip]{#2})}

\newcommand{\rfxx}[1]{(\zref[subsubexno]{#1})}

\newcommand{\rfstrip}[2]{(\zref{#1}--\zref[refstrip]{#2})}

\begin{document}

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

\bpaformat{1}{Author~}{}

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

\lbpa{main2}{Example Two.
        \lba{sub21}{Subexample Two-One.}
        \lbz{sub22}{Subexample Two-Two.}} \zlabel{sub22}
        
\vspace{6pt}

Results :

\rfxx{subsub113}

\rfstrip{subsub111}{subsub113}

\rfstrip{sub11}{sub12}

\authorstrip{subsub111}{sub22}
\end{document}


введите описание изображения здесь

Редактировать:

Чтобы извлечь только переменную «Имя автора», которая соответствует аргументу 3 команды \bpaformat, просто добавьте в определение последней следующую команду:

\gdef\theauthor{#3}

Команда\gdef — очень эффективный способ извлечь любой аргумент из любой команды. Просто убедитесь, что используете его внутри определения, чтобы переменная была доступна с помощью кода ссылки на аргумент #н(гден— ранг аргумента, отсчет слева направо).

Связанный контент