Tikz:允许在空单元格中执行 |[style]| 语法

Tikz:允许在空单元格中执行 |[style]| 语法

\foo我有一些可以扩展为的宏|[some style]| the content,我希望能够执行:(execute at empty cell={\foo}我已经可以\foo在矩阵内部执行了)。但似乎execute at empty cell不允许这种语法。有什么想法可以让它工作吗?

重要的:我希望这两种语法都能起作用(因为我也可能使用正常语法),换句话说,我想找到一个\createNode既能execute at empty cell={\createNode{\node[red]{A};}}起作用又能execute at empty cell={\createNode{|[red]|A}}起作用的命令。

\documentclass[options]{article}
\usepackage{tikz}
\usetikzlibrary{matrix}

\begin{document}

For now I do:

\begin{tikzpicture}
  \matrix [matrix of math nodes,
    execute at empty cell={\node[red]{A};
  }]
  {
    8 &   & |[green]| B \\
    & 5 &   \\
    4 &   & 2 \\
  };
\end{tikzpicture}

And I would like this to work (the reason being that I internally call existing macros that expand to this):

\begin{tikzpicture}
  \matrix [matrix of math nodes,
    %% This ----------------v
    execute at empty cell={|[red]| A}
  ]
  {
    8 &   & |[green]| B \\
    & 5 &   \\
    4 &   & 2 \\
  };
\end{tikzpicture}


\end{document}

编辑

感谢您的回答,遗憾的是它对两者都不起作用,现在它已损坏\node

replace empty cell with={\node[red]{A};}

相反,我收到一条错误,提示节点未定义。

我也尝试用以下代码直接替换此代码:

    execute at empty cell={
      \tikz@lib@matrix@start@cell
      |[red]| A%
      \tikz@lib@matrix@end@cell
    }

但它不起作用(错误ERROR: Argument of \tikz@next has an extra }.)。知道原因吗?

然后,我在实际示例中尝试了此方法,但不起作用,因为至少所有正常节点都被删除了。我使用了类似这样的方法,但没有成功,这是否让我想起了什么?

     /tikz/replace empty cell with/.code={%
      \def\tikz@at@emptycell{%
        \tikz@lib@matrix@start@cell
        #1%
        \tikz@lib@matrix@end@cell
      }%
    },
  /tikz/replace empty cell with={%
    % /tikz/execute at empty cell={%
      % We want to check if there is a
      \ifcsname zxExecuteAtCell-\tikzcdmatrixname-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn\endcsname%
        \csname zxExecuteAtCell-\tikzcdmatrixname-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn\endcsname%
      \else%
        \ifdefined\zxCustomExecuteAtEmptyCell\zxCustomExecuteAtEmptyCell%
        \else%
          \coordinate[
          % yshift=axis_height, % We already do that elsewhere
          name=\tikzmatrixname
          -\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn];
        \fi%
      \fi%
    },

答案1

矩阵库允许单元格具有以下形式

  • <node content>
  • |<extra>| <node content>(其中 是和 之间<extra>允许的任何节点规范)以及node{
  • \path以、\draw\node等开头的任何正常路径

\path、、\draw等的检测\node是一种特殊的黑客技术,在更复杂的单元格中经常会失败(无法以\tikzset或具有可选参数的宏开始)。

matrix但是,我们可以通过在\tikz@lib@matrix@start@cell参数前面放置 (\node[red]{A};或)来使用库所做的相同 hack 检查|[red]| A。但是,由于这种情况通常在单元格的开头遇到,其中&(= \pgfmatrixnextcell) 已经完成了其工作,因此我们必须通过将参数扩展两次来模拟这种情况。

代码

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{matrix}
\makeatletter
\tikzset{
  matrix of nodes/.append style={
    execute at empty cell/.code=%
      \expandafter\def\expandafter\tikz@at@emptycell\expandafter
        {\tikz@at@emptycell\expandafter\expandafter\expandafter
          \tikz@lib@matrix@start@cell##1\tikz@lib@matrix@end@cell}}}
\makeatother
\begin{document}

For now I do:

\tikz
  \matrix [matrix of math nodes, execute at empty cell={\node[red]{A};}]{
    8 &   & |[green]| B \\
      & 5 & \\
    4 &   & 2 \\
  };


And I would like this to work (the reason being that I internally
  call existing macros that expand to this):

\tikz
  \matrix [matrix of math nodes, execute at empty cell={|[red]| A}]{
    8 &   & |[green]| B \\
    & 5 &   \\
    4 &   & 2 \\
  };

Multiple:

\tikz
  \matrix [matrix of math nodes,
    execute at empty cell={|[red]| A},
    execute at empty cell={\draw (0,.5ex) circle[radius=1em];},
    execute at empty cell={|[blue, draw, xshift=1em]|  C},
  ]{
    8 &   & |[green]| B \\
    & 5 &   \\
    4 &   & 2 \\
  };
\end{document}

答案2

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{matrix}

\makeatletter
\tikzset{
  replace empty cell with/.code={%
    \edef\tikz@at@emptycell{%
      \noexpand\tikz@lib@matrix@start@cell
      \unexpanded\expandafter\expandafter\expandafter{#1}%
      \noexpand\tikz@lib@matrix@end@cell
    }%
  }
}
\makeatother

% for better aligment and spacing
\tikzset{
  every picture/.append style={
    baseline=0pt,
    column sep={.5cm, between origins},
    row sep={.5cm, between origins},
    inner xsep=.5pt
  },
}

\begin{document}

\verb|replace empty cell with=|

\begin{tikzpicture}
  \matrix [
    matrix of math nodes,
    replace empty cell with={|[red]| A},
  ]
  {
    8 &   & |[green]| B \\
    & 5 &   \\
    4 &   & 2 \\
  };
\end{tikzpicture}
\verb+{|[red]| A}+

\begin{tikzpicture}
  \matrix [
    matrix of math nodes,
    replace empty cell with={\node[red] {A};},
  ]
  {
    8 &   & |[green]| B \\
    & 5 &   \\
    4 &   & 2 \\
  };
\end{tikzpicture}
\verb+{\node[red] {A};}+

\begin{tikzpicture}
  \matrix [
    matrix of math nodes,
    column sep={.5cm,between origins},
    replace empty cell with={\draw (0em,.3em) circle[radius=.4em];},
  ]
  {
    8 &   & |[green]| B \\
    & 5 &   \\
    4 &   & 2 \\
  };
\end{tikzpicture}
\verb+{\draw (0em,.3em) circle[radius=.4em];}+
\end{document}

现在支持所有三种形式

解释

  • \tikz@lib@matrix@start@cell<cell content>\tikz@lib@matrix@end@cell可以解析<cell content> ::= "|[red]| A"\node[red] {A};。这些宏最初由选项使用matrix of nodes,请参阅相关源代码行tikzlibrarymatrix.code.tex
  • \tikz@at@emptycell保存传递给的累积代码execute at empty cell,请参阅对应源代码行在 中tikz.code.tex。由于matrix of nodes(由 调用matrix of math nodes)包含execute at empty cell=\tikz@lib@matrix@empty@cell\def\tikz@at@emptycell{...}因此用于覆盖现有值。
  • 感谢@Qrrbrbirlbel(见这个答案),现在replace empty cell with=<cell content>接受所有三种形式的单元格内容:|<styles>| <node text>\node ...;\draw ...;

相关内容