Я хотел бы реализовать команду, названную \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
пропустить подходящее место для прыжка.