mdthereom общие счетчики, cleverref и вложенные теоремы

mdthereom общие счетчики, cleverref и вложенные теоремы

У меня возникли проблемы с настройкой mdframed, чтобы

  1. он совместим с cleverref
  2. все коробки mdframed имеют один и тот же счетчик
  3. не ломается, когда mdframed окружения вложены

Демо-файл. В идеале мы должны увидеть

  • Лемма 1.1: основная лемма

  • Примечание 1.2: расчеты

  • Лемма 1.3: расчет 1

  • Лемма 1.4: расчет 2

  • Примечание 1.5: рмк 1

Вот мой исходный файл преамбулы, который выполняет 1) и 3). Но у нас есть Лемма 1.1, Примечание 1.1, Лемма 1.2, Лемма 1.3. Замечание 1.1 Поскольку счетчики являются отдельными для каждого\mdtheorem

\documentclass{book}
\usepackage{amsthm,xcolor,mdframed,hyperref,cleveref}

%Headers and Sections

% Colors

\definecolor{tab-blue}{rgb}{0.341,0.471,0.643}
\definecolor{tab-orange}{rgb}{0.894,0.580,0.267}

%%%
%Counters
\newcounter{thechapter}
%%%
% Define fChapter
%for putting chapter numbers after the title


% Chapters
\newcommand{\fchapter}[1]%
{%
    \phantomsection\chapter*{Chapter #1}%
    \stepcounter{thechapter}
    \newpage% Chapter Number
} 

% Copy the same style but modify the colour only
\mdfdefinestyle{theoremstyle}{%
    backgroundcolor=tab-blue!10
}

\mdfdefinestyle{remarkstyle}{%
    backgroundcolor=tab-blue!5,
}

\mdfdefinestyle{notestyle}{%
    backgroundcolor=tab-orange!5,
}

\mdtheorem[style=theoremstyle]{lemma}{Lemma}[thechapter]
\mdtheorem[style=remarkstyle]{remark}{Remark}[thechapter]
\mdtheorem[style=notestyle]{note}{Note}[thechapter]

% Here we manage Clever Headers
\crefname{lemma}{lem.}{lems.}
\Crefname{lemma}{Lemma}{Lemmas}

\crefname{note}{note}{notes}
\Crefname{note}{Note}{Notes}

\begin{document}
\fchapter{1: main result}
\begin{lemma}[main lemma]\label{lem:main}
1234556
\end{lemma}
\begin{proof}
    123
\begin{note}[calculations]
\begin{lemma}[calculation 1]\label{lem:calc 1}
calc 1 here
\end{lemma}
\begin{proof}
calc 1 proof
\end{proof}
\begin{lemma}[calculation 2]\label{lem:calc 2}
calc 2 here
\end{lemma}
\begin{proof}
calc 2 proof
\end{proof}
\begin{remark}[rmk 1]\label{rmk: rmk 1}
rmk 
\end{remark}
\end{note}

\end{proof}

Cleveref tests: 
\begin{itemize}
    \item main lemma \cref{lem:main}
    \item note calculations: \cref{note:calculations}
    \item lemma calc 1: \cref{lem:calc 1}
    \item lemma calc 2: \cref{lem:calc 2}
    \item rmk 1 1: \cref{rmk: rmk 1}
\end{itemize}
\end{document}


Черпая вдохновение изздесь, и используя новый счетчик, boxcounter, я заменил три \mdtheoremстроки в предыдущем документе. Теперь у нас есть общий счетчик, но мы сломали cleveref (который показывает ??? при попытке сослаться на окружение). Это потому, что \crefон пытается сослаться на boxcounter вместо самого окружения.

Вложенные среды также нарушены, с повторяющимися числами (Примечание 1.5 должно быть Примечанием 1.2), как показывает компиляция документа

Лемма 1.1, Примечание 1.5, Лемма 1.3, Лемма 1.4, Замечание 1.5.

\documentclass{book}
\usepackage{amsthm,xcolor,mdframed,hyperref,cleveref}
% Colors
\definecolor{tab-blue}{rgb}{0.341,0.471,0.643}
\definecolor{tab-orange}{rgb}{0.894,0.580,0.267}

%%%
%Counters
\newcounter{thechapter}

% Chapters
\newcommand{\fchapter}[1]%
{%
    \phantomsection\chapter*{Chapter #1}%
    \stepcounter{thechapter}
    \newpage% Chapter Number
} 

% Copy the same style but modify the colour only
\mdfdefinestyle{theoremstyle}{%
    backgroundcolor=tab-blue!10
}

\mdfdefinestyle{remarkstyle}{%
    backgroundcolor=tab-blue!5,
}

\mdfdefinestyle{notestyle}{%
    backgroundcolor=tab-orange!5,
}

\newcounter{boxcounter}[thechapter]
\renewcommand{\theboxcounter}{\arabic{thechapter}.\arabic{boxcounter}}

\newenvironment{lemma}[1][]{%
    \refstepcounter{boxcounter}
    \begin{mdframed}[%
        frametitle={Lemma \theboxcounter\ #1},
        style=theoremstyle
    ]%
}{%
    \end{mdframed}
}

\newenvironment{note}[1][]{%
    \refstepcounter{boxcounter}
    \begin{mdframed}[%
        frametitle={Note \theboxcounter\ #1},
        style=notestyle
    ]%
}{%
    \end{mdframed}
}

\newenvironment{remark}[1][]{%
    \refstepcounter{boxcounter}
    \begin{mdframed}[%
        frametitle={Remark \theboxcounter\ #1},
        style=remarkstyle
    ]%
}{%
    \end{mdframed}
}

% Here we manage Clever Headers
\crefname{lemma}{lem.}{lems.}
\Crefname{lemma}{Lemma}{Lemmas}

\crefname{note}{note}{notes}
\Crefname{note}{Note}{Notes}

\begin{document}
\fchapter{1: main result}
\begin{lemma}[main lemma]\label{lem:main}
1234556
\end{lemma}
\begin{proof}
    123
\begin{note}[calculations]\label{note:calculations}
\begin{lemma}[calculation 1]\label{lem:calc 1}
calc 1 here
\end{lemma}
\begin{proof}
calc 1 proof
\end{proof}
\begin{lemma}[calculation 2]\label{lem:calc 2}
calc 2 here
\end{lemma}
\begin{proof}
calc 2 proof
\end{proof}
\begin{remark}[rmk 1]\label{rmk: rmk 1}
rmk 
\end{remark}
\end{note}

\end{proof}

Cleveref tests: 
\begin{itemize}
    \item main lemma \cref{lem:main}
    \item note calculations: \cref{note:calculations}
    \item lemma calc 1: \cref{lem:calc 1}
    \item lemma calc 2: \cref{lem:calc 2}
    \item rmk 1 1: \cref{rmk: rmk 1}
\end{itemize}
\end{document}

решение1

Поскольку вы не опубликовали компилируемый MWE, ответ ниже не соответствует вашим потребностям, а служит только для иллюстрации принципа. Причина, по которой ваш третий показанный блок кода не работает, заключается в том, что вы используете один и тот же счетчик для трех сред. Cleveref использует имя счетчика, чтобы различать различные среды.

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

Например

\documentclass{article}
\usepackage{cleveref}

\newcounter{mastercounter}
\newcounter{envAcount}
\newcounter{envBcount}
\makeatletter
\let\c@envAcount\c@mastercounter
\let\c@envBcount\c@mastercounter
\makeatother

\newenvironment{envA}{\refstepcounter{envAcount}\textbf{First Environment \theenvAcount}\par}{}
\newenvironment{envB}{\refstepcounter{envBcount}\textbf{Second Enviornment \theenvBcount}\par}{}

\Crefname{envAcount}{First}{First}
\Crefname{envBcount}{Second}{Second}

\begin{document}

\begin{envA}\label{envAtest}
        Test
\end{envA}

\begin{envB}\label{envBtest}
        Another test
\end{envB}

\Cref{envAtest} and \Cref{envBtest}

\end{document}
  1. этот код создает три счетчика: mastercounter, envAcount, и envBcount.
  2. строки между \makeatletter...\makeatotherделают envAcountи envBcountвнутренне тот же счетчик, что и mastercounter, поэтому увеличение одного увеличивает все три * .
  3. Затем мы определяем новые среды envAи envB; обратите внимание, что в каждой среде вы \refstepcounterлибо envAcountили envBcountв зависимости от ситуации. Это важно, так как имя счетчика записывается в .auxфайл, когда вы \labelсреду.
  4. Обратите внимание, что мы определяем \Crefnameс помощьюназвания счетчика, а не названия среды, использующей счетчик.

Приведенный выше код дает следующий результат введите описание изображения здесь

Теперь вы можете самостоятельно включить этот прием в свой полный документ, используя mdframedдля определения своих сред.

* Альтернативой ручному выполнению этой задачи является использование пакета вродепсевдоним.


Теперь, когда вы добавили MWE, вот версия, адаптированная для вашего MWE

\documentclass{book}
\usepackage{amsthm,xcolor,mdframed,hyperref,cleveref}
% Colors
\definecolor{tab-blue}{rgb}{0.341,0.471,0.643}
\definecolor{tab-orange}{rgb}{0.894,0.580,0.267}

%%%
%Counters
\newcounter{thechapter}

% Chapters
\newcommand{\fchapter}[1]%
{%
    \phantomsection\chapter*{Chapter #1}%
    \stepcounter{thechapter}
    \newpage% Chapter Number
} 

% Copy the same style but modify the colour only
\mdfdefinestyle{theoremstyle}{%
    backgroundcolor=tab-blue!10
}

\mdfdefinestyle{remarkstyle}{%
    backgroundcolor=tab-blue!5,
}

\mdfdefinestyle{notestyle}{%
    backgroundcolor=tab-orange!5,
}

\newcounter{boxcounter}[thechapter]
\renewcommand{\theboxcounter}{\arabic{thechapter}.\arabic{boxcounter}}
\newcounter{lemma}
\newcounter{note}
\newcounter{remark}
\makeatletter
\let\c@lemma\c@boxcounter
\let\c@note\c@boxcounter
\let\c@remark\c@boxcounter
\let\thelemma\theboxcounter
\let\thenote\theboxcounter
\let\theremark\theboxcounter
\makeatother


\newenvironment{lemma}[1][]{%
    \refstepcounter{lemma}
    \edef\x{Lemma \thelemma\ #1}
    \begin{mdframed}[%
        frametitle={\x},
        style=theoremstyle
    ]%
}{%
    \end{mdframed}
}

\newenvironment{note}[1][]{%
    \refstepcounter{note}
    \edef\x{Note \thenote\ #1}
    \begin{mdframed}[%
        frametitle={\x},
        style=notestyle
    ]%
}{%
    \end{mdframed}
}

\newenvironment{remark}[1][]{%
    \refstepcounter{remark}
    \edef\x{Remark \theremark\ #1}
    \begin{mdframed}[%
        frametitle={\x},
        style=remarkstyle
    ]%
}{%
    \end{mdframed}
}

% Here we manage Clever Headers
\crefname{lemma}{lem.}{lems.}
\Crefname{lemma}{Lemma}{Lemmas}

\crefname{note}{note}{notes}
\Crefname{note}{Note}{Notes}

\begin{document}
\fchapter{1: main result}
\begin{lemma}[main lemma]\label{lem:main}
1234556
\end{lemma}
\begin{proof}
    123
\begin{note}[calculations]\label{note:calculations}
\begin{lemma}[calculation 1]\label{lem:calc 1}
calc 1 here
\end{lemma}
\begin{proof}
calc 1 proof
\end{proof}
\begin{lemma}[calculation 2]\label{lem:calc 2}
calc 2 here
\end{lemma}
\begin{proof}
calc 2 proof
\end{proof}
\begin{remark}[rmk 1]\label{rmk: rmk 1}
rmk 
\end{remark}
\end{note}

\end{proof}

Cleveref tests: 
\begin{itemize}
    \item main lemma \cref{lem:main}
    \item note calculations: \cref{note:calculations}
    \item lemma calc 1: \cref{lem:calc 1}
    \item lemma calc 2: \cref{lem:calc 2}
    \item rmk 1 1: \cref{rmk: rmk 1}
\end{itemize}
\end{document}

который показывает

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

Хитрость здесь в линии

\edef\x{Note \thenote\ #1}

чтобы обойти проблему, когда если вы поместите \thenoteв frametitle={Note \thenote\ #1}, к тому времени, mdframedкогда доберетесь до его расширения, значение \thenoteуже будет изменено внутренними средами. Этот трюк в основном гарантирует сохранение текущего значения в \thenote, \xи с помощью магии "области действия переменных", когда внутренняя среда выходит, значение \xвосстанавливается до того, что было до входа в среды.

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