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提供了一个名称(的值),但我们实际上并没有在以后使用这个名称,假设在调用和绘制框之间没有使用 TikZ。但是,我不知道如何使用这个名称来指定我的框应该位于此节点右侧的空白处...mycaution\tikzmark

有人能提供解决方案(或更好的是:对这里到底发生了什么的解释)吗?

答案1

问题在于,该包用于内部计算其定义的页面节点的位置的tcolorbox变化。\textwidthtikzpagenodes

你可以使用以下方式查看

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

结果:

在此处输入图片描述

相关内容