我正在尝试bitheader
从bytefield
包中概括它。
\begin{bytefield}[endianness=little,bitwidth=0.0625\textwidth]{16}
\bitheader{0-15}\\
\bitbox{1}{\footnotesize START} &
\bitbox{2}{\footnotesize SUBSYSTEM} &
\bitbox{2}{\footnotesize COMMAND} &
\bitbox{8}{\footnotesize DATA} &
\bitbox{2}{\footnotesize CRC} &
\bitbox{1}{\footnotesize STOP} &
\end{bytefield}
当我阅读软件包的文档时,我似乎无法找到解决方案bytefield
。我想知道是否有人可以帮助我。提前致谢。
答案1
该包似乎不支持自定义标题,因此您可以自己实现。
下面的代码采用了从包源中打印标题的原始代码,在本例中,\bf@parse@range
当您使用设置范围时调用的宏\bitheader{some range}
。
原始代码只是打印\bf@bitformatting{\theheader@val}
,即根据密钥格式化的位计数器的值bitformatting
(\tiny
默认情况下)。在下面的 MWE 中,我在此部分添加了一个有点复杂的 if-else 树,它根据计数器的值执行不同的操作。该值与两个参数\bitdots
(用于点的开始)和\bitN
(用于 N 标签的位置)进行比较。这两个参数设置在文档中实际字节字段代码上方。
\ifnum
\else
\fi
其余的基本上是(嵌套) 、\value
和\numexpr
的组合\the
。这些命令的一些细节:
\ifnum
执行两个数字之间的比较- 当你想将计数器值与需要使用的东西进行比较时
\value{countername}
- 当数字由表达式组成时,例如
\bitN-2
,那么你需要\numexpr
执行整数运算 - 表达式
\numexpr
应该以结束,以\relax
确保 LaTeX 不会尝试将后续代码合并到计算中 - 如果你想要打印一个计数器或
\numexpr
(而不是与进行比较\ifnum
),那么你可以在计数器名称或表达式前面加上\the
,就像\theheader@val
和\the\numexpr\value{header@val}-\bitN\relax
- 当您从包含字符的包源复制代码时
@
,您需要将\makeatletter
复制的代码放在\makeatother
其上方和下方
梅威瑟:
\documentclass{article}
\usepackage[left=1in,right=1in]{geometry}
\usepackage{bytefield}
\makeatletter
% code below copied and modified from bytefield.sty
\def\bf@parse@range#1-#2-#3\relax{%
\setcounter{header@val}{#1}
\setcounter{max@header@val}{#2 + 1}
\loop
\ifnum\value{header@val}<\value{max@header@val}%
\if\bf@bit@endianness b%
\setlength{\header@xpos}{%
\bf@bitwidth * (\bits@wide - \value{header@val} + \bf@first@bit - 1)}%
\else
\setlength{\header@xpos}{\bf@bitwidth * (\value{header@val} - \bf@first@bit)}%
\fi
\put(\strip@pt\header@xpos,0){%
\makebox(\strip@pt\bf@bitwidth,\strip@pt\units@tall){%
% bit counter smaller than bitdots parameter, print normal number
\ifnum\value{header@val}<\bitdots%
\bf@bitformatting{\theheader@val}%
\else%
% bit counter at bitN-1 or bigger
\ifnum\value{header@val}>\numexpr\bitN-2\relax%
% bit counter equal to bitN-1, print N-1
\ifnum\value{header@val}=\numexpr\bitN-1\relax%
\bf@bitformatting{N-1}%
\else
% bit counter equal to bitN, print N
\ifnum\value{header@val}=\bitN%
\bf@bitformatting{N}%
% bit counter larger than bitN, print N+(bit counter-bitN)
\else%
\bf@bitformatting{N+\the\numexpr\value{header@val}-\bitN\relax}%
\fi%
\fi%
% bit counter larger than bitdots but smaller than bitN-1, print dots
\else%
$\dots$%
\fi%
\fi%
}}
\addtocounter{header@val}{1}
\repeat}
\makeatletter
\begin{document}
\def\bitdots{7}
\def\bitN{12}
\begin{bytefield}[endianness=little,bitwidth=0.0625\textwidth]{16}
\bitheader{0-15}\\
\bitbox{1}{\footnotesize START} &
\bitbox{2}{\footnotesize SUBSYSTEM} &
\bitbox{2}{\footnotesize COMMAND} &
\bitbox{8}{\footnotesize DATA} &
\bitbox{2}{\footnotesize CRC} &
\bitbox{1}{\footnotesize STOP} &
\end{bytefield}
\end{document}
结果:
请注意,新代码还会影响文档中您可能希望使用常规数字的其他字节字段。在这种情况下,您只需将\bitdots
和设置\bitN
为一个较大的数字,这样\ifnum
该特定字节字段就不会触发子句。
答案2
bytefield
文档的第 22 页提出了一个\fakesixtyfourbits
执行类似操作的命令。该命令可以在bitformating
选项中使用。我已将此示例改编为\fakesexteenbits
可用于此情况。它不像 Marijn 代码那样通用,但很容易理解。
\documentclass{article}
\usepackage[left=1in,right=1in]{geometry}
\usepackage{bytefield}
\newcommand{\fakesixteenbits}[1]{%
\tiny
\ifnum#1=1234567890
#1
\else
\ifnum#1<7
#1%
\else
\ifnum#1<11
$\cdots$%
\else
\ifnum#1=11
$N-1$
\else
\ifnum#1=12
$N$
\else
\ifnum#1=13
$N+1$
\else
\ifnum#1=14
$N+2$
\else
$N+3$
\fi
\fi
\fi
\fi
\fi
\fi
\fi
}
\begin{document}
\begin{bytefield}[endianness=little,
bitwidth=0.0625\textwidth,
bitformatting=\fakesixteenbits]{16}
\bitheader{0-15}\\
\bitbox{1}{\footnotesize START} &
\bitbox{2}{\footnotesize SUBSYSTEM} &
\bitbox{2}{\footnotesize COMMAND} &
\bitbox{8}{\footnotesize DATA} &
\bitbox{2}{\footnotesize CRC} &
\bitbox{1}{\footnotesize STOP} &
\end{bytefield}
\end{document}