Estou tendo problemas ao tentar configurar o mdframed para que
- é compatível com smartref
- todas as caixas mdframed compartilham o mesmo contador
- não quebra quando ambientes mdframed estão aninhados
Arquivo de demonstração. Idealmente deveríamos ver
Lema 1.1: lema principal
Nota 1.2: cálculos
Lema 1.3: cálculo 1
Lema 1.4: cálculo 2
Observação 1.5: rmk 1
Aqui está meu arquivo de preâmbulo original, que cumpre 1) e 3). Mas temos Lema 1.1, Nota 1.1, Lema 1.2, Lema 1.3. Observação 1.1 Como os contadores são separados para cada\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}
Inspirando-se emaqui, e usando um novo contador boxcounter
, substituí as três \mdtheorem
linhas do documento anterior. Agora temos um contador compartilhado, mas quebramos a inteligência (que mostra ??? ao tentar referenciar os ambientes). Isso ocorre porque \cref
está tentando fazer referência ao boxcounter em vez do próprio ambiente.
Os ambientes aninhados também estão quebrados, com números repetidos (Nota 1.5 deve ser Nota 1.2), conforme a compilação do documento dá
Lema 1.1, Nota 1.5, Lema 1.3, Lema 1.4, Observação 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}
Responder1
Como você não postou MWE compilável, a resposta abaixo não foi adaptada diretamente às suas necessidades, mas serve apenas para ilustrar o princípio. A razão pela qual o terceiro bloco de código exibido não funciona é que você está usando o mesmo contador para os três ambientes. Cleveref usa o nome do contador para diferenciar os vários ambientes.
A solução para isso (que é usada internamente pelo cleveref
para lidar com ambientes de teoremas que compartilham o mesmo contador criado pelo amsthm
qual tem o mesmo problema) é criar um contador escravo duplicado.
Por exemplo
\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}
- este código cria três contadores:
mastercounter
,envAcount
eenvBcount
. - as linhas entre
\makeatletter...\makeatother
makeenvAcount
eenvBcount
internamente o mesmo contador quemastercounter
, portanto, aumentando um, aumenta todos os três * . - Depois definimos novos ambientes
envA
eenvB
; observe que em cada ambiente você\refstepcounter
ouenvAcount
conformeenvBcount
apropriado. Isso é importante porque o nome do contador é registrado no.aux
arquivo quando você\label
configura o ambiente. - Observe que definimos o
\Crefname
usando onomes do contador, não os nomes do ambiente que usa o contador.
O código acima produz a seguinte saída
Agora você mesmo pode incorporar o truque em seu documento completo usando mdframed
para definir seus ambientes.
* Uma alternativa para fazer isso manualmente é usar um pacote comoaliascnt.
Agora que você adicionou um MWE, aqui está uma versão adaptada ao seu 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}
que mostra
Um truque aqui é a linha
\edef\x{Note \thenote\ #1}
para contornar o problema de que se você colocar \thenote
em frametitle={Note \thenote\ #1}
, na hora mdframed
de expandi-lo o valor de \thenote
já foi alterado pelos ambientes internos. Esse truque basicamente garante o armazenamento do valor atual de \thenote
into \x
, e com a mágica do "escopo variável" quando o ambiente interno sai, o valor de \x
é restaurado para o que era o caso antes de entrar nos ambientes.