答案1
具有自定义解析器的原始 TikZ 解决方案\foreach
,允许使用逗号分隔的选项列表,而无需保护它们免受\foreach
解析器的攻击。
其中定义了以下快捷方式:
h
(表示一半)在框中添加双波浪号,并将节点的宽度减半。w
(宽度)手动设置框的宽度(作为的因子bytefield/bit width
)bits = <start> to <end>
根据位数设置标签和框的宽度。bit = <number>
类似于bits
,但只设置一个标签,且宽度设置为1
。
要能够将 a 用作 a pic
,需要有label
密钥。(在内部, a使用与 a 相同的代码,只是将标志也设置为 true。)pic
pic
node
代码
\documentclass[tikz]{standalone}
\usepackage{xparse, libertine}
\usetikzlibrary{chains, positioning}
\makeatletter
\pgfkeys{
/tikz/pic/.code=\tikz@node@is@pictrue,
/pgf/foreach/xparser Om/.style={xparser={O{}}{{##1}/{##2}}},
/pgf/foreach/xparser/.code 2 args=%
\DeclareDocumentCommand\pgffor@scan@custom
{#1u,}{\def\pgffor@value{#2}\pgffor@scanned}%
\def\pgffor@scan{\pgfutil@ifnextchar\pgffor@stop
\pgffor@scanone\pgffor@scan@custom}}
\newcommand{\tikzBytefield}[3][]{%
\begin{tikzpicture}[
start chain=bytefield going left,
node distance=+-.5\pgflinewidth,
bytefield/bit width/.initial=8pt,
every label/.append style={node font=\small, inner ysep=.1em},
inner xsep=.1em,
every bytefield/.append style={
draw, text height=+.7\baselineskip, text depth=+0pt,
h/.style={
label={[pic, rotate=90]north:dbltld},
label={[pic, rotate=90]south:dbltld},
bytefield/bit width/.expanded=(\pgfkeysvalueof{/tikz/bytefield/bit width})/2},
w/.style={
minimum width={max(
(####1)*\pgfkeysvalueof{/tikz/bytefield/bit width},
width("M")+2*(\pgfkeysvalueof{/pgf/inner xsep}))}},
bits/.style args={####1 to ####2}{
w={1+(####2)-(####1)},
label={[anchor=south west]north west:####2},
label={[anchor=south east]north east:####1}},
bit/.style={w=1, label={[anchor=south]north:####1}}},
dbltld/.pic={
\fill[white][yshift=+1pt]
(-2pt, 0pt) to[out=70, in=180] (-1pt, 1pt) cos ( 0pt, 0pt)
sin ( 1pt, -1pt) to[out=0, in=-120] ( 2pt, 0pt)
[yshift=+-2pt] -- (2pt, 0pt) to[out=-120, in=0] ( 1pt, -1pt)
cos ( 0pt, 0pt) sin ( -1pt, 1pt) to[out=180, in=70] ( -2pt, 0pt) -- cycle;
\draw[yshift=+1pt]
(-2pt, 0pt) to[out=70, in=180] (-1pt, 1pt) cos ( 0pt, 0pt)
sin ( 1pt, -1pt) to[out=0, in=-120] ( 2pt, 0pt)
[yshift=+-2pt] (2pt, 0pt) to[out=-120, in=0] ( 1pt, -1pt)
cos ( 0pt, 0pt) sin ( -1pt, 1pt) to[out=180, in=70] ( -2pt, 0pt);},#1]
\sffamily
\foreach[xparser Om] \Options/\Text in {#2}
\node[on chain=bytefield,every bytefield,style/.expand once=\Options]{\Text};
#3
\end{tikzpicture}}
\begin{document}
\tikzBytefield{%
[bits = 0 to 7, h] Aff0,
[bits = 8 to 15, h] Aff1,
[bits = 16 to 23, h] Aff2,
[bit = 24],
[bits = 25 to 29, h] RES0,
[bit = 30] U,
[bit = 31],
[bits = 32 to 39, h] Aff3,
[bits = 40 to 63, h] RES0%
}{
\path[node distance=1em, to path={-|(\tikztotarget)}, shorten >=1pt]
node[below right=of bytefield-begin] {MT} edge (bytefield-4)
node[below left=of bytefield-end] {RES1} edge (bytefield-7);
}
\end{document}