Реализовать фиксированную метку в мемуарах

Реализовать фиксированную метку в мемуарах

Я хотел бы реализовать команду, названную \newfixedlabelпо аналогии с мемуарами, \newfixedcaptionтаким образом, чтобы:

\begin{myfloat}
\caption{...}
\label{myfloat:a}
...
\end{myfloat}

Дает тот же результат с cleveref(или любым другим пакетом), что и:

\myfloatfixedcaption{...}% setup via memoirs \newfixedcaption
\label{myfloat:a}
...

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

Полный пример может выглядеть так:

\documentclass{memoir}
\usepackage{etoolbox}
\usepackage{hyperref}
\usepackage{cleveref}

\makeatletter
\newcommand*{\cftonlycaption}[2][]%
{\begingroup
   \let\@makecaption\@gobbletwo
   \ifstrempty{#1}%
     {\caption{#2}}%
     {\caption[#1]{#2}}
 \endgroup}
\makeatother

\newfloat[chapter]{myfloat}{lmf}{My Float}
\newfixedcaption[\cftonlycaption]{\myfloatfixedcaption}{myfloat}

\crefname{myfloat}{My Float}{My Floats}

\begin{document}
\chapter{A}
\begin{myfloat}
\caption{A}% or \myfloatfixedcaption{A}
\label{keya}
\end{myfloat}
\section{B}
\myfloatfixedcaption{B}
\label{keyb}
\cref{keya}
\cref{keyb}
\end{document}

По какой-то причине \label{keyb}команда указывает на раздел B вместо My Float.

Ps. Я знаю о настройке cleveref с помощью \crefname, проблема заключается в создании \newfixedlabelмакроса. Я попробовал тот же трюк, который использует memoir для имитации среды float, определив \@captype, но безрезультатно.

решение1

При использовании \captionвнутри группы некоторые обновления не сохраняются после этого. В частности, \captionобновления \cref@currentlabel, которые необходимы дляcleverefдля определения соответствующего типа ссылки.

Вы можете обновить свой тип \cftonlycaption, указав его конкретно, myfloatиспользуя следующее:

\makeatletter
\newcommand*{\cftonlycaption}[2][]%
{\begingroup
   \let\@makecaption\@gobbletwo
   \ifstrempty{#1}%
     {\caption{#2}}%
     {\caption[#1]{#2}}
 \endgroup
 \protected@edef\cref@currentlabel{%
      \expandafter\cref@override@label@type%
        \cref@currentlabel\@nil{myfloat}}}
\makeatother

Финальное \cref@currentlabelобновлениеснаружигруппа сохранит текущий тип ссылки как myfloat.

В качестве альтернативы, если это покажется вам слишком жестким, вы всегда можете переопределить ссылочный тип локально, используя

\label[myfloat]{keyb}

Ниже приведен минимальный пример использования первого подхода:

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

\documentclass{memoir}
\usepackage{etoolbox}
\usepackage{hyperref}
\usepackage{cleveref}

\makeatletter
\newcommand*{\cftonlycaption}[2][]%
{\begingroup
   \let\@makecaption\@gobbletwo
   \ifstrempty{#1}%
     {\caption{#2}}%
     {\caption[#1]{#2}}
 \endgroup
 \protected@edef\cref@currentlabel{%
      \expandafter\cref@override@label@type%
        \cref@currentlabel\@nil{myfloat}}}
\makeatother

\newfloat[chapter]{myfloat}{lmf}{My Float}
\newfixedcaption[\cftonlycaption]{\myfloatfixedcaption}{myfloat}

\crefname{myfloat}{My Float}{My Floats}

\begin{document}
\chapter{A}
\begin{myfloat}
\caption{A}% or \myfloatfixedcaption{A}
\label{keya}
\end{myfloat}
\section{B}
\myfloatfixedcaption{B}
\label{keyb}% or \label[myfloat]{keyb}
\cref{keya}
\cref{keyb}
\end{document}

Обратите внимание, что опорожнение \@makecaption(через \let\@makecaption\@gobbletwo) вызываетhyperrefпропустить подходящее место для прыжка.

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