\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 ...;
。