У меня возникли проблемы с настройкой mdframed, чтобы
- он совместим с cleverref
- все коробки mdframed имеют один и тот же счетчик
- не ломается, когда 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}
- этот код создает три счетчика:
mastercounter
,envAcount
, иenvBcount
. - строки между
\makeatletter...\makeatother
делаютenvAcount
иenvBcount
внутренне тот же счетчик, что иmastercounter
, поэтому увеличение одного увеличивает все три * . - Затем мы определяем новые среды
envA
иenvB
; обратите внимание, что в каждой среде вы\refstepcounter
либоenvAcount
илиenvBcount
в зависимости от ситуации. Это важно, так как имя счетчика записывается в.aux
файл, когда вы\label
среду. - Обратите внимание, что мы определяем
\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
восстанавливается до того, что было до входа в среды.