Tikz: узел на краю справа от другого узла взаимодействует с tcbtheorem

Tikz: узел на краю справа от другого узла взаимодействует с tcbtheorem

В настоящее время я пытаюсь использовать ответ @GonzaloMedina, чтобысоздать рамку для заметки на полях

Рассмотрим следующий упрощенный код:

\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}

Команда \cautionделает то, что я и ожидал: она создает красное поле в правом поле, прямо перед текстом перед вызовом \caution.

Теперь предположим, что я хочу сделать то же самое, но это \cautionназывается внутри tcbtheoremокружения. Например:

\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}

Тогда вывод будет следующим:

выход-tcb

Я не привык к TikZ, но я понимаю, что:

  • эффект tikzmarkзаключается в том, чтобы поместить узел в точное место, где он вызывается, и координаты этого узла могут быть использованы позже,
  • возможность remember picture, overlayразрешить tikzpictureиспользовать эти координаты.

Однако a tcolorbox(и, следовательно, a tcbtheorem) нарисованы с использованием TikZ, так что эти координаты как бы теряются (за исключением того, что проблема возникает только с координатой x, с координатой y, похоже, все в порядке).

Кажется, что tikzmarkдает имя (значение mycaution) узлу, который он создает, но мы на самом деле не используем это имя позже, предполагая, что TikZ не использовался между вызовом \tikzmarkи рисованием блока. Однако я понятия не имею, как я могу использовать это имя, чтобы указать, что мой блок должен быть на поле справа от этого узла...

Может ли кто-нибудь дать решение (или лучше: объяснить, что на самом деле здесь происходит)?

решение1

Проблема в том, что tcolorboxизменения \textwidthиспользуются пакетом tikzpagenodesдля внутреннего расчета позиции узлов страницы, которые он определяет.

Вы можете увидеть это с помощью

\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}

который дает:

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

поэтому внутри tcolorbox узел current page text area.eastнаходится левее того места, где он должен быть на самом деле.

Один из способов предотвратить это — использовать правильные якоря, которые мы извлекаем перед окружением theoс помощью пакета etoolboxи переопределяем \cautionдля использования исправленного якоря:

\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}

Результат:

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

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