通过 tikzmark 宏进行对齐

通过 tikzmark 宏进行对齐

这是我上一个问题的后续tikzmark 宏的问题和潜力:动态框自适应。我认为最好还是问两个问题,尽管它们与同一个论点有关,因为问题不同。

在最近的一个回答中使用 Tikz 在方程内进行水平对齐,我导出了一个略有不同的宏版本来对齐文本。

我的解决方案有点脆弱,因为它严重依赖于\textdim用于设置text width选项的参数。

以下是示例。使用以下代码:

\documentclass[11pt]{article}
\usepackage{xparse}
\usepackage{tikz}
\usepackage{amsmath,amssymb}

\newlength\textdim
\setlength{\textdim}{2cm}

%% code by Andrew Stacey 
% https://tex.stackexchange.com/questions/51582/background-coloring-with-overlay-specification-in-algorithm2e-beamer-package#51582

\makeatletter
\tikzset{%
     remember picture with id/.style={%
       remember picture,
       overlay,
       save picture id=#1,
     },
     save picture id/.code={%
       \edef\pgf@temp{#1}%
       \immediate\write\pgfutil@auxout{%
         \noexpand\savepointas{\pgf@temp}{\pgfpictureid}}%
     },
     if picture id/.code args={#1#2#3}{%
       \@ifundefined{save@pt@#1}{%
         \pgfkeysalso{#3}%
       }{
         \pgfkeysalso{#2}%
       }
     }
   }

   \def\savepointas#1#2{%
  \expandafter\gdef\csname save@pt@#1\endcsname{#2}%
}

\def\tmk@labeldef#1,#2\@nil{%
  \def\tmk@label{#1}%
  \def\tmk@def{#2}%
}

\tikzdeclarecoordinatesystem{pic}{%
  \pgfutil@in@,{#1}%
  \ifpgfutil@in@%
    \tmk@labeldef#1\@nil
  \else
    \tmk@labeldef#1,\pgfpointorigin\@nil
  \fi
  \@ifundefined{save@pt@\tmk@label}{%
    \tikz@scan@one@point\pgfutil@firstofone\tmk@def
  }{%
  \pgfsys@getposition{\csname save@pt@\tmk@label\endcsname}\save@orig@pic%
  \pgfsys@getposition{\pgfpictureid}\save@this@pic%
  \pgf@process{\pgfpointorigin\save@this@pic}%
  \pgf@xa=\pgf@x
  \pgf@ya=\pgf@y
  \pgf@process{\pgfpointorigin\save@orig@pic}%
  \advance\pgf@x by -\pgf@xa
  \advance\pgf@y by -\pgf@ya
  }%
}
\makeatother

\NewDocumentCommand{\tikzmarkin}{m O{white} m}{%
      \tikz[remember picture,overlay,baseline]
      \draw[line width=1pt,rectangle,rounded corners,fill=#2,draw=none,outer sep=1pt,inner sep=1pt]
      (pic cs:#1) ++(0.065,-0.32) rectangle (-0.05,0.6);
      \tikz[baseline=(current bounding box.-7)] \node [align=center,text width=\textdim]at(pic cs:#1){\ensuremath{#3}}
      ;}

\newcommand\tikzmarkend[2][]{%
\tikz[remember picture with id=#2] #1;}


\begin{document}
\begin{alignat*}{3}
A &= \tikzmarkin{a}[red!20]{\dfrac{\partial u}{\partial x} + \lambda}\tikzmarkend{a}&&+ \dfrac{\partial f}{\partial y}\dfrac{\partial f}{\partial z}\\
B &= \tikzmarkin{b}[blue!20]{\dfrac{\partial u}{\partial z} + \dfrac{\partial^2 u}{\partial x}} \tikzmarkend{b}&&+ \gamma  \\
CD &=\tikzmarkin{c}[green!20]{\dfrac{\partial f}{\partial x}}\tikzmarkend{c}&& + \dfrac{\partial f}{\partial z} \\
E &= \tikzmarkin{d}[orange!20]{\Gamma(x)}\tikzmarkend{d} &&+ \Xi(y)
\end{alignat*}


\end{document}

有可能得到:

在此处输入图片描述

现在我们做一个简单的修改:

\setlength{\textdim}{4cm}

经过两次编译后,您将获得:

在此处输入图片描述

这确实出乎意料。可以通过设置以下方法纠正此行为:

\tikz[baseline=(current bounding box.-3)]...

实现:

在此处输入图片描述

水平变化影响垂直定位有什么特殊原因吗?

答案1

发生偏移的原因在于,您正在使用由指定的边界框边界上的点来设置 tikzpicture 的基线角度。这是关键中的baseline=(current bounding box.-7)。这指的是角度 -7 度给出的边界上的点。随着图片的纵横比变化,这个的高度也会变化。以下是一个例子:

带有角点标记的节点

特别注意20随着纵横比的变化,角度的边界点如何从顶部移动到侧面。

假设您将文本放在 tikzpicture 内的节点中,那么用于获取正确基线的最佳坐标可能是此节点的基锚点。因此:

\tikz[baseline=(h.base)] \node (h) [align=center,text width=\textdim]at(pic cs:#1){\ensuremath{#3}};

(也许选择一个更好的节点名称,尽管它并不那么重要)。结果如下:

背景节点

我想这就是你想要的。

以下是完整代码:

\documentclass[11pt]{article}
%\url{http://tex.stackexchange.com/q/57538/86}
\thispagestyle{empty}
\usepackage{xparse}
\usepackage{tikz}
\usetikzlibrary{calc}
\usepackage{amsmath,amssymb}

\newlength\textdim
\setlength{\textdim}{2cm}
\setlength{\textdim}{4cm}

%% code by Andrew Stacey 
% http://tex.stackexchange.com/questions/51582/background-coloring-with-overlay-specification-in-algorithm2e-beamer-package#51582

\makeatletter
\tikzset{%
     remember picture with id/.style={%
       remember picture,
       overlay,
       save picture id=#1,
     },
     save picture id/.code={%
       \edef\pgf@temp{#1}%
       \immediate\write\pgfutil@auxout{%
         \noexpand\savepointas{\pgf@temp}{\pgfpictureid}}%
     },
     if picture id/.code args={#1#2#3}{%
       \@ifundefined{save@pt@#1}{%
         \pgfkeysalso{#3}%
       }{
         \pgfkeysalso{#2}%
       }
     }
   }

   \def\savepointas#1#2{%
  \expandafter\gdef\csname save@pt@#1\endcsname{#2}%
}

\def\tmk@labeldef#1,#2\@nil{%
  \def\tmk@label{#1}%
  \def\tmk@def{#2}%
}

\tikzdeclarecoordinatesystem{pic}{%
  \pgfutil@in@,{#1}%
  \ifpgfutil@in@%
    \tmk@labeldef#1\@nil
  \else
    \tmk@labeldef#1,(0pt,0pt)\@nil
  \fi
  \@ifundefined{save@pt@\tmk@label}{%
    \tikz@scan@one@point\pgfutil@firstofone\tmk@def
  }{%
  \pgfsys@getposition{\csname save@pt@\tmk@label\endcsname}\save@orig@pic%
  \pgfsys@getposition{\pgfpictureid}\save@this@pic%
  \pgf@process{\pgfpointorigin\save@this@pic}%
  \pgf@xa=\pgf@x
  \pgf@ya=\pgf@y
  \pgf@process{\pgfpointorigin\save@orig@pic}%
  \advance\pgf@x by -\pgf@xa
  \advance\pgf@y by -\pgf@ya
  }%
}
\makeatother

\NewDocumentCommand{\tikzmarkin}{m O{white} m}{%
      \tikz[remember picture,overlay,baseline]
      \draw[line width=1pt,rectangle,rounded corners,fill=#2,draw=none,outer sep=1pt,inner sep=1pt]
      (pic cs:#1) ++(0.065,-0.32) rectangle (-0.05,0.6);
      \tikz[baseline=(h.base)] \node (h) [align=center,text width=\textdim]at(pic cs:#1){\ensuremath{#3}}
      ;}

\newcommand\tikzmarkend[2][]{%
\tikz[remember picture with id=#2] #1;}


\begin{document}
\begin{alignat*}{3}
A &= \tikzmarkin{a}[red!20]{\dfrac{\partial u}{\partial x} + \lambda}\tikzmarkend{a}&&+ \dfrac{\partial f}{\partial y}\dfrac{\partial f}{\partial z}\\
B &= \tikzmarkin{b}[blue!20]{\dfrac{\partial u}{\partial z} + \dfrac{\partial^2 u}{\partial x}} \tikzmarkend{b}&&+ \gamma  \\
CD &=\tikzmarkin{c}[green!20]{\dfrac{\partial f}{\partial x}}\tikzmarkend{c}&& + \dfrac{\partial f}{\partial z} \\
E &= \tikzmarkin{d}[orange!20]{\Gamma(x)}\tikzmarkend{d} &&+ \Xi(y)
\end{alignat*}
\end{document}

(另请注意根据我对该问题的评论对坐标系的修正。)

相关内容