Tikz: o nó na margem direita de outro nó interage com o teorema tcb

Tikz: o nó na margem direita de outro nó interage com o teorema tcb

Atualmente estou tentando usar a resposta de @GonzaloMedina paracrie um ambiente emoldurado para uma nota de margem

Considere o seguinte código simplificado:

\documentclass[oneside]{book}
\usepackage[framemethod=tikz]{mdframed}
\usepackage{tikzpagenodes}
\usepackage{lipsum}


\newcounter{mycaution}
\newcommand\tikzmark[1]{%
  \tikz[remember picture,overlay]
  \node[inner xsep=0pt,outer sep=0pt] (#1) {};
}

\newcommand{\caution}{
\stepcounter{mycaution}
\tikzmark{\themycaution}%
\begin{tikzpicture}[remember picture,overlay]
\node[draw=red,anchor=west,xshift=\marginparsep,yshift=0pt]   
  (mybox\themycaution)
  at ([yshift=3pt]current page text area.east|-\themycaution) 
  {\parbox{\marginparwidth}{Some text}};
\end{tikzpicture}
}

\begin{document}


\lipsum[1]
Some random text\caution{}
\lipsum[2-5]
\end{document}

O comando \cautionfaz o que eu espero: produz uma caixa vermelha na margem direita, logo no texto antes da chamada do \caution.

Agora, suponha que eu queira fazer a mesma coisa, mas isso \cautioné chamado dentro de um tcbtheoremambiente. Por exemplo:

\documentclass[oneside]{book}
\usepackage[framemethod=tikz]{mdframed}
\usepackage{tikzpagenodes}
\usepackage[most]{tcolorbox}
\tcbuselibrary{theorems}
\usepackage{lipsum}


\newcounter{mycaution}
\newcommand\tikzmark[1]{%
  \tikz[remember picture,overlay]
  \node[inner xsep=0pt,outer sep=0pt] (#1) {};
}

\newcommand{\caution}{
\stepcounter{mycaution}
\tikzmark{\themycaution}%
\begin{tikzpicture}[remember picture,overlay]
\node[draw=red,anchor=west,xshift=\marginparsep,yshift=0pt]   
  (mybox\themycaution)
  at ([yshift=3pt]current page text area.east|-\themycaution) 
  {\parbox{\marginparwidth}{Some text}};
\end{tikzpicture}
}

\newtcbtheorem{theo}{Theorem}{theorem style=plain}{th}

\begin{document}
\begin{theo}{}{}

Some random text\caution{}
\lipsum[1]
\end{theo}

\lipsum[1]
Some random text\caution{}

\end{document}

Então a saída é a seguinte:

saída-tcb

Não estou acostumado com TikZ, mas o que entendi é que:

  • o efeito tikzmarké colocar um nó no local exato onde ele é chamado, e as coordenadas deste nó podem ser usadas posteriormente,
  • a remember picture, overlayopção de tikzpicturepermitir o uso dessas coordenadas.

No entanto, a tcolorbox(e portanto a tcbtheorem) é desenhado usando TikZ, de modo que essas coordenadas são meio perdidas (exceto que o problema vem apenas da coordenada x, a coordenada y parece ser boa).

Parece que tikzmarkdá um nome (o valor de mycaution) ao nó que ele cria, mas não usamos realmente esse nome posteriormente, assumindo que TikZ não foi usado entre a chamada \tikzmarke o desenho da caixa. No entanto, não tenho ideia de como posso usar esse nome para especificar que minha caixa deve estar na margem direita deste nó...

Alguém pode fornecer uma solução (ou melhor: uma explicação do que realmente acontece aqui)?

Responder1

O problema é que as tcolorboxalterações \textwidthusadas no tikzpagenodespacote para calcular internamente a posição dos nós da página que ele define.

Você pode ver isso usando

\documentclass[oneside]{book}
\usepackage{tikzpagenodes}
\usepackage[most]{tcolorbox}

\newtcbtheorem{theo}{Theorem}{theorem style=plain}{th}

\begin{document}

\the\textwidth
\begin{theo}{}{}
\the\textwidth
\end{theo}

\end{document}

que dá:

insira a descrição da imagem aqui

então dentro do tcolorbox o current page text area.eastnó está à esquerda de onde realmente deveria estar.

Uma forma de evitar isso é usar as âncoras corretas que recuperamos antes do theoambiente com a ajuda do etoolboxpacote e redefinir \cautionpara usar a âncora corrigida:

\documentclass[oneside]{book}
\usepackage[framemethod=tikz]{mdframed}
\usepackage{tikzpagenodes}
\usepackage[most]{tcolorbox}
\tcbuselibrary{theorems}
\usepackage{lipsum}
\usepackage{etoolbox}
\usetikzlibrary{fit}

\newcounter{mycaution}
\newcommand\tikzmark[1]{%
  \tikz[remember picture,overlay]
  \node[inner xsep=0pt,outer sep=0pt] (#1) {};
}

\newcommand{\caution}{
\stepcounter{mycaution}%
\tikzmark{\themycaution}%
\begin{tikzpicture}[remember picture,overlay]
\node[draw=red,anchor=west,xshift=\marginparsep,yshift=0pt]   
  (mybox\themycaution)
  at ([yshift=3pt]current page text area.east|-\themycaution) 
  {\parbox{\marginparwidth}{Some text}};
\end{tikzpicture}
}

\newtcbtheorem{theo}{Theorem}{theorem style=plain}{th}

\BeforeBeginEnvironment{theo}{%
\tikz[remember picture,overlay]
  \node[fit=(current page text area),line width=0,inner sep=0,name=correct current page text area]{};
\renewcommand{\caution}{
\stepcounter{mycaution}%
\tikzmark{\themycaution}%
\begin{tikzpicture}[remember picture,overlay]
\node[draw=red,anchor=west,xshift=\marginparsep,yshift=0pt]   
  (mybox\themycaution)
  at ([yshift=3pt]correct current page text area.east|-\themycaution) 
  {\parbox{\marginparwidth}{Some text}};
\end{tikzpicture}%
}%
}

\begin{document}

\begin{theo}{}{}
Some random text\caution{}
\lipsum[1]
\end{theo}

\lipsum[1]
Some random text\caution{}

\end{document}

O resultado:

insira a descrição da imagem aqui

informação relacionada