Professional Documents
Culture Documents
Scott Pakin
scott+bf@pakin.org
June 3, 2014
Abstract
The bytefield package helps the user create illustrations for network protocol specifications and anything else that utilizes fields of data. These
illustrations show how the bits and bytes are laid out in a packet or in
memory.
Introduction
Network protocols are usually specified in terms of a sequence of bits and bytes
arranged in a field. This is portrayed graphically as a grid of boxes. Each row
in the grid represents one word (frequently, 8, 16, or 32 bits), and each column
represents a bit within a word. The bytefield package makes it easy to typeset
these sorts of figures. bytefield facilitates drawing protocol diagrams that contain
words of any arbitrary number of bits,
column headers showing bit positions,
multiword fieldseven non-word-aligned and even if the total number of bits
is not a multiple of the word length,
word labels on either the left or right of the figure, and
skipped words within fields.
This
Because bytefield draws its figures using only the LATEX picture environment,
these figures are not specific to any particular backend, do not require PostScript
support, and do not need support from external programs. Furthermore, unlike an
imported graphic, bytefield pictures can include arbitrary LATEX constructs, such
as mathematical equations, \refs and \cites to the surrounding document, and
macro calls.
2
2.1
Usage
A first example
The Internet Engineering Task Forces Request for Comments (RFC) number 3016
includes the following ASCII-graphics illustration of the RTP packetization of an
MPEG-4 Visual bitstream:
0
1
2
3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P|X| CC
|M|
PT
|
sequence number
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
timestamp
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
synchronization source (SSRC) identifier
|
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|
contributing source (CSRC) identifiers
|
|
....
|
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|
|
|
MPEG-4 Visual stream (byte aligned)
|
|
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
:...OPTIONAL RTP padding
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
RTP
Header
RTP
Payload
The following LATEX code shows how straightforward it is to typeset that illustration using the bytefield package:
\begin{bytefield}[bitwidth=1.1em]{32}
\bitheader{0-31} \\
\begin{rightwordgroup}{RTP \\ Header}
\bitbox{2}{V=2} & \bitbox{1}{P} & \bitbox{1}{X}
& \bitbox{4}{CC} & \bitbox{1}{M} & \bitbox{7}{PT}
& \bitbox{16}{sequence number} \\
\bitbox{32}{timestamp}
\end{rightwordgroup} \\
\bitbox{32}{synchronization source (SSRC) identifier} \\
\wordbox[tlr]{1}{contributing source (CSRC) identifiers} \\
\wordbox[blr]{1}{$\cdots$} \\
\begin{rightwordgroup}{RTP \\ Payload}
\wordbox[tlr]{3}{MPEG-4 Visual stream (byte aligned)} \\
\bitbox[blr]{16}{}
& \bitbox{16}{\dots\emph{optional} RTP padding}
\end{rightwordgroup}
\end{bytefield}
Figure 1 presents the typeset output of the preceding code. Sections 2.2 and 2.3
explain each of the environments, macros, and arguments that were utilized plus
many additional features of the bytefield package.
0
V=2 P X
CC
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
sequence number
PT
timestamp
RTP
Header
RTP
Payload
2.2
Basic commands
This section explains how to use the bytefield package. It lists all the exported
macros and environments in approximately decreasing order of usefulness.
\begin{bytefield} [hparametersi] {hbit-widthi}
hfieldsi
\end{bytefield}
The bytefield packages top-level environment is called, not surprisingly,
bytefield. It takes one mandatory argument, which is the number of bits
in each word, and one optional argument, which is a set of parameters, described
in Section 2.3, for formatting the bit-fields layout. One can think of a bytefield
as being analogous to a tabular: words are separated by \\, and fields within
a word are separated by &. As in a tabular, \\ accepts a hlengthi as an
optional argument, and this specifies the amount of additional vertical whitespace
to include after the current word is typeset.
8 more bits
D RMF S L T D
With \bitboxes this can be abbreviated to
\begin{bytefield}{8}
\bitboxes{1}{DRMFSLTD}
\end{bytefield}
Spaces are ignored within \bitboxess htexti argument, and curly braces can
be used to group multiple characters into a single token:
\begin{bytefield}{24}
\bitboxes{3}{{DO} {RE} {MI} {FA} {SOL} {LA} {TI} {DO}}
\end{bytefield}
DO
RE
MI
FA
SOL LA
TI
DO
The starred form of \bitboxes is identical except that it suppresses all internal
vertical lines. It can therefore be quite convenient for typesetting binary constants:
\begin{bytefield}{16}
\bitboxes*{1}{01000010} & \bitbox{4}{src\strut} &
\bitbox{4}{dest\strut} & \bitbox{4}{const\strut}
\end{bytefield}
01000010
src
dest
const
optional argument is a set of parameters from the set described in Section 2.3. In
practice, the only parameters that are meaningful in the context of \bitheader
are bitformatting, endianness, and lsb. See Section 2.3 for descriptions and
examples of those parameters.
\bitheaders mandatory argument, hbit-positionsi, is a comma-separated list
of bit positions to label. For example, 0,2,4,6,8,10,12,14 means to label
those bit positions. The numbers must be listed in increasing order. (Use the
endianness parameter to display the header in reverse order.) Hyphen-separated
ranges are also valid. For example, 0-15 means to label all bits from 0 to 15, inclusive. Ranges and single numbers can even be intermixed, as in 0-3,8,12-15.
The following example shows how \bitheader may be used:
\begin{bytefield}{32}
\bitheader{0-31} \\
\bitbox{4}{Four} & \bitbox{8}{Eight} &
\bitbox{16}{Sixteen} & \bitbox{4}{Four}
\end{bytefield}
Four
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
Eight
Sixteen
Four
\begin{rightwordgroup} {htexti}
hrows of bit boxes and word boxesi
\end{rightwordgroup}
\begin{leftwordgroup} {htexti}
hrows of bit boxes and word boxesi
\end{leftwordgroup}
When a set of words functions as a single, logical unit, it helps to group these
words together visually. All words defined between \begin{rightwordgroup}
and \end{rightwordgroup} will be labeled on the right with htexti. Similarly,
all words defined between \begin{leftwordgroup} and \end{leftwordgroup}
will be labeled on the left with htexti. \begin{hsideiwordgroup} must lie at the
beginning of a row (i.e., right after a \\), and \end{hsideiwordgroup} must lie
right before the end of the row (i.e., right before a \\).
Unlike other LATEX environments, rightwordgroup and leftwordgroup
do not have to nest properly with each other.
However, they cannot overlap themselves.
In other words, \begin{rightwordgroup}. . .
\begin{leftwordgroup}. . .\end{rightwordgroup}. . .\end{leftwordgroup} is a
valid sequence, but \begin{rightwordgroup}. . .\begin{rightwordgroup}. . .
\end{rightwordgroup}. . .\end{rightwordgroup} is not.
Tag
15
Mask
Source
Header
Destination
Data
As a more complex example, the following nests left and right labels:
\begin{bytefield}{16}
\bitheader{0,7,8,15} \\
\begin{rightwordgroup}{Header}
\bitbox{4}{Tag} & \bitbox{12}{Mask} \\
\begin{leftwordgroup}{Node IDs}
\bitbox{8}{Source} & \bitbox{8}{Destination}
\end{leftwordgroup}
\end{rightwordgroup} \\
\wordbox{3}{Data}
\end{bytefield}
Tag
Node IDs
Source
15
Mask
Destination
Data
)
Header
Some data
Lots of data
hhhh
h
h hh
h
hhh
hhhh
hh
hhhh
h
hhhhh
hh
More data
2.3
Formatting options
Res
BE
CF
Name Len 1
Len Len
\begin{bytefield}[endianness=big,bitwidth=0.11111\linewidth]{8}
\bitheader{0-7} \\
\bitbox{2}{Len\_Len} & \bitbox{3}{$\mbox{Name\_Len}-1$}
& \bitbox{1}{CF} & \bitbox{1}{BE} & \bitbox{1}{Res} \\
\end{bytefield}
Len Len
Name Len 1
CF
BE
Res
T1 Fwd
Data value
10
18
17
16
F/E
T0
T1
Fwd
15
14
13
12
11
10
Data value
leftcurly = hdelimiter i
rightcurly = hdelimiter i
Word groups are normally indicated by a curly brace spanning all of its rows.
However, the curly brace can be replaced by any other extensible math delimiter
(i.e., a symbol that can meaningfully follow \left or \right in math mode) via a
suitable redefinition of leftcurly or rightcurly. As in math mode, . means
no symbol, as in the following example (courtesy of Steven R. King):
\begin{bytefield}[rightcurly=., rightcurlyspace=0pt]{32}
\bitheader[endianness=big]{0,7,8,15,16,23,24,31} \\
\begin{rightwordgroup}{0Ch}
\bitbox{8}{Byte 15 \\ \tiny (highest address)}
& \bitbox{8}{Byte 14}
& \bitbox{8}{Byte 13}
& \bitbox{8}{Byte 12}
11
\end{rightwordgroup} \\
\begin{rightwordgroup}{08h}
\bitbox{32}{Long 0}
\end{rightwordgroup} \\
\begin{rightwordgroup}{04h}
\bitbox{16}{Word 1} & \bitbox{16}{Word 0}
\end{rightwordgroup} \\
\begin{rightwordgroup}{00h}
\bitbox{8}{Byte 3}
& \bitbox{8}{Byte 2}
& \bitbox{8}{Byte 1}
& \bitbox{8}{Byte 0 \\ \tiny (lowest address)}
\end{rightwordgroup}
\end{bytefield}
31
24 23
Byte 15
(highest address)
16 15
Byte 14
Byte 13
Byte 12
08h
Long 0
Word 1
Byte 3
04h
Word 0
Byte 2
0Ch
Byte 1
Byte 0
(lowest address)
00h
leftcurlyspace = hlengthi
rightcurlyspace = hlengthi
curlyspace = hlengthi
leftcurlyspace and rightcurlyspace specify the space to insert between the
bit field and the curly brace in a left or right word group (default: 1ex). Setting
curlyspace is a shortcut for setting both leftcurlyspace and rightcurlyspace
to the same value.
leftlabelspace = hlengthi
rightlabelspace = hlengthi
labelspace = hlengthi
leftlabelspace and rightlabelspace specify the space to insert between the
curly brace and the text label in a left or right word group (default: 0.5ex). Setting
labelspace is a shortcut for setting both leftlabelbrace and rightlabelspace
to the same value.
Figure 2 illustrates the juxtaposition of rightcurlyspace and
rightlabelspace to a word group and its label.
The leftcurlyspace
and leftlabelspace parameters are symmetric.
12
hbit-field rowsi
hlabel i
|
{z
} |
rightcurlyspace
{z
rightlabelspace
12
20
ar$hln
28
ar$pro
ar$hrd
ar$pln
ar$op
13
\begin{bytefield}{32}
\bitheader[lsb=4]{4,12,20,28} \\
\bitbox{16}{ar\$hrd} & \bitbox{16}{ar\$pro} \\
\bitbox{8}{ar\$hln} & \bitbox{8}{ar\$pln} & \bitbox{16}{ar\$op} \\
\end{bytefield}
12
20
ar$pln
ar$hln
2.4
28
ar$pro
ar$hrd
ar$op
Common tricks
This section shows some clever ways to use bytefields commands to produce some
useful effects.
Odd-sized fields To produce a field that is, say, 1 words long, use a \bitbox
for the fractional part and specify appropriate values for the various hsidesi parameters. For instance:
\begin{bytefield}{16}
\bitheader{0,7,8,15} \\
\bitbox{8}{8-bit field} & \bitbox[lrt]{8}{} \\
\wordbox[lrb]{1}{24-bit field}
\end{bytefield}
15
8-bit field
24-bit field
Ellipses To skip words that appear the middle of enumerated data, put some
\vdots in a \wordbox with empty hsidesi:
\begin{bytefield}{16}
\bitbox{8}{Type} & \bitbox{8}{\# of nodes} \\
\wordbox{1}{Node~1} \\
\wordbox{1}{Node~2} \\
\wordbox[]{1}{$\vdots$} \\[1ex]
\wordbox{1}{Node~$N$}
\end{bytefield}
14
Type
# of nodes
Node 1
Node 2
..
.
Node N
The extra 1ex of vertical space helps vertically center the \vdots a bit better.
Narrow fields There are a number of options for labeling a narrow field
(e.g., one occupying a single bit):
Default:
OK
\bytefieldsetup{%
bitwidth=\widthof{OK~}}:
OK
Data
OK
Data
\tiny O \\ K:
O
K
Data
\rotatebox{90}{\small OK}:
OK
\tiny OK:
Data
Data
OK
Data
\let\bw=\width
\resizebox{\bw}{!}{~OK~}:
Multi-line bit fields Presentations of wide registers are often easier to read
when split across multiple lines. (This capability was originally requested by Chris
LEsperance and is currently implemented in bytefield based on code provided by
Renaud Pacalet.) The trick behind the typesetting of multi-line bit fields is to
pass the lsb option to \bitheader to change the starting bit number used in each
bit header:
\begin{bytefield}[endianness=big,bitwidth=2em]{16}
\bitheader[lsb=16]{16-31} \\
\bitbox{1}{\tiny Enable} & \bitbox{7}{Reserved}
& \bitbox{8}{Bus} \\[3ex]
\bitheader{0-15} \\
\bitbox{5}{Device} & \bitbox{3}{Function} & \bitbox{6}{Register}
& \bitbox{2}{00}
\end{bytefield}
15
31
30
29
28
27
26
25
24
23
22
21
20
15
14
13
12
Device
11
19
18
17
16
Bus
Reserved
Enable
10
Function
Register
00
1002
1001
1000
999998997996995
One solution is to use the bitformatting option and the graphicx packages
\rotatebox command to rotate each bit label by 90. Unfortunately, the naive
use of bitformatting and \rotatebox does not typeset nicely:
995
996
997
998
999
1000
1001
1002
\begin{bytefield}[endianness=big]{8}
\bitheader[lsb=995,
bitformatting={\tiny\rotatebox[origin=B]{90}}]{995-1002} \\
\bitbox{4}{A} & \bitbox{4}{B}
\end{bytefield}
The two problems are that (1) the numbers are left-justified, and (2) the numbers touch the top margin of the word box. To address these problems we use
\makebox to construct a right-justified region that is sufficiently wide to hold our
largest number plus some additional space to shift the rotated numbers upwards:
\newlength{\bitlabelwidth}
\newcommand{\rotbitheader}[1]{%
\tiny
\settowidth{\bitlabelwidth}{\quad 9999}%
\rotatebox[origin=B]{90}{\makebox[\bitlabelwidth][r]{#1}}%
16
995
997
996
998
999
1000
1001
1002
\begin{bytefield}[endianness=big]{8}
\bitheader[lsb=995,bitformatting=\rotbitheader]{995-1002} \\
\bitbox{4}{A} & \bitbox{4}{B}
\end{bytefield}
Unused bits Because \width and \height are defined within bit boxes (also
word boxes), we can represent unused bits by filling a \bitbox with a rule of size
\width \height:
\begin{bytefield}{32}
\bitheader{0,4,8,12,16,20,24,28} \\
\bitbox{8}{Tag} & \bitbox{8}{Value} &
\bitbox{4}{\rule{\width}{\height}} &
\bitbox{12}{Mask} \\
\wordbox{1}{Key}
\end{bytefield}
Tag
12
16
20
Value
24
28
Mask
Key
The effect is much better when the color package is used to draw the unused bits
in color. (Light gray looks nice.)
\definecolor{lightgray}{gray}{0.8}
\begin{bytefield}{32}
\bitheader{0,4,8,12,16,20,24,28} \\
\bitbox{8}{Tag} & \bitbox{8}{Value} &
\bitbox{4}{\color{lightgray}\rule{\width}{\height}} &
\bitbox{12}{Mask} \\
\wordbox{1}{Key}
\end{bytefield}
Tag
12
16
Value
20
24
Mask
Key
17
28
M y
A solution is to use the boxformatting option to trick \makebox into thinking
that all text has the same height and depth. Here we use \raisebox to indicate
that all text is as tall as a W and does not descend at all below the baseline:
\newlength{\maxheight}
\setlength{\maxheight}{\heightof{W}}
\newcommand{\baselinealign}[1]{%
\centering
\raisebox{0pt}[\maxheight][0pt]{#1}%
}
\begin{bytefield}[boxformatting=\baselinealign,
bitwidth=1.5em]{2}
\bitbox{1}{M} & \bitbox{1}{y}
\end{bytefield}
M y
Register contents Sometimes, rather than listing the meaning of each bit field
within each \bitbox or \wordbox, it may be desirable to list the contents, with the
meaning described in an additional label above each bit number in the bit header.
Although the register package is more suited to this form of layout, bytefield can
serve in a pinch with the help of the \turnbox macro from the rotating package:
\newcommand{\bitlabel}[2]{%
\bitbox[]{#1}{%
\raisebox{0pt}[4ex][0pt]{%
\turnbox{45}{\fontsize{7}{7}\selectfont#2}%
}%
}%
18
C
a
R rry
e
P ser
ar ve
R ity d
e
A ser
d ve
R jus d
es t
Ze er
r ve
Si o d
gn
T
ra
In p
t
D err
ir up
O ect t
ve io en
r n ab
I/ flow
le
O
p
N riv
e
i
R ste leg
es d
e
er ta le
ve sk ve
l
d
(
12
3)
\begin{bytefield}[bitwidth=1em]{16}
\bitlabel{1}{Carry} & \bitlabel{1}{Reserved} &
\bitlabel{1}{Parity} & \bitlabel{1}{Reserved} &
\bitlabel{1}{Adjust} & \bitlabel{1}{Reserved} &
\bitlabel{1}{Zero} & \bitlabel{1}{Sign} &
\bitlabel{1}{Trap} & \bitlabel{1}{Interrupt enable} &
\bitlabel{1}{Direction} & \bitlabel{1}{Overflow} &
\bitlabel{2}{I/O privilege level (12--13)} &
\bitlabel{1}{Nested task} & \bitlabel{1}{Reserved} \\
\bitheader{0-15} \\
\bitbox{1}{0} & \bitbox{1}{1} & \bitbox{1}{0} & \bitbox{1}{0} &
\bitbox{1}{0} & \bitbox{1}{0} & \bitbox{1}{0} & \bitbox{1}{1} &
\bitbox{1}{0} & \bitbox{1}{1} & \bitbox{1}{0} & \bitbox{1}{0} &
\bitbox{1}{0} & \bitbox{1}{0} & \bitbox{1}{0} & \bitbox{1}{0}
\end{bytefield}
9 10 11 12 13 14 15
0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 0
2.5
Not-so-common tricks
Colored fields A similar approach to that utilized to indicate unused bits can
be applied to coloring an individual bit field. The trick is to use the TEX \rlap
primitive to draw a colored box that overlaps whatever follows it to the right:
\newcommand{\colorbitbox}[3]{%
\rlap{\bitbox{#2}{\color{#1}\rule{\width}{\height}}}%
\bitbox{#2}{#3}}
\definecolor{lightcyan}{rgb}{0.84,1,1}
\definecolor{lightgreen}{rgb}{0.64,1,0.71}
\definecolor{lightred}{rgb}{1,0.7,0.71}
\begin{bytefield}[bitheight=\widthof{~Sign~},
boxformatting={\centering\small}]{32}
\bitheader[endianness=big]{31,23,0} \\
\colorbitbox{lightcyan}{1}{\rotatebox{90}{Sign}} &
\colorbitbox{lightgreen}{8}{Exponent} &
\colorbitbox{lightred}{23}{Mantissa}
\end{bytefield}
19
23
Sign
31
Exponent
Mantissa
62
F/E
T0
61
60
T1 Fwd
59
58
Data value
20
Memory-map diagrams While certainly not the intended purpose of the bytefield package, one can utilize word boxes with empty hsidesi and word labels to
produce memory-map diagrams:
\newcommand{\descbox}[2]{\parbox[c][3.8\baselineskip]{0.95\width}{%
\raggedright #1\vfill #2}}
\begin{bytefield}[bitheight=4\baselineskip]{32}
\begin{rightwordgroup}{Partition 4}
\bitbox[]{8}{\texttt{0xFFFFFFFF} \\[2\baselineskip]
\texttt{0xC0000000}} &
\bitbox{24}{\descbox{1\,GB area for VxDs, memory manager,
file system code; shared by all processes.}{Read/writable.}}
\end{rightwordgroup} \\
\begin{rightwordgroup}{Partition 3}
\bitbox[]{8}{\texttt{0xBFFFFFFF} \\[2\baselineskip]
\texttt{0x80000000}} &
\bitbox{24}{\descbox{1\,GB area for memory-mapped files,
shared system \textsc{dll}s, file system code; shared by all
processes.}{Read/writable.}}
\end{rightwordgroup} \\
\begin{rightwordgroup}{Partition 2}
\bitbox[]{8}{\texttt{0x7FFFFFFF} \\[2\baselineskip]
\texttt{0x00400000}} &
\bitbox{24}{\descbox{$\sim$2\,GB area private to process,
process code, and data.}{Read/writable.}}
\end{rightwordgroup} \\
\begin{rightwordgroup}{Partition 1}
\bitbox[]{8}{\texttt{0x003FFFFF} \\[2\baselineskip]
\texttt{0x00001000}} &
\bitbox{24}{\descbox{4\,MB area for MS-DOS and Windows~3.1
compatibility.}{Read/writable.}} \\
\bitbox[]{8}{\texttt{0x00000FFF} \\[2\baselineskip]
\texttt{0x00000000}} &
\bitbox{24}{\descbox{4096~byte area for MS-DOS and Windows~3.1
compatibility.}{Protected---catches \textsc{null}
pointers.}}
\end{rightwordgroup}
\end{bytefield}
21
Read/writable.
1 GB area for memory-mapped files, shared
system dlls, file system code; shared by all
processes.
Read/writable.
2 GB area private to process, process code,
and data.
0x00400000
0x003FFFFF
Read/writable.
4 MB area for MS-DOS and Windows 3.1
compatibility.
0x00001000
0x00000FFF
Read/writable.
4096 byte area for MS-DOS and Windows 3.1
compatibility.
0x00000000
0xFFFFFFFF
0xC0000000
0xBFFFFFFF
0x80000000
0x7FFFFFFF
Partition 4
Partition 3
Partition 2
Partition 1
22
Registers}\\
\memsection{002f bfff}{0007 0000}{3}{-- reserved --}\\
\memsection{0006 ffff}{0000 0000}{8}{Internal Flash}
\end{rightwordgroup}\\
\end{bytefield}
ffff ffff
free
0040 0000
003f ffff
Special Function Registers
002f c000
002f bfff
reserved
0007 0000
0006 ffff
Internal Flash
0000 0000
2.6
internal memory
23
2.7
bytefields user interface changed substantially with the introduction of version 2.0.
Because documents written for bytefield v1.x will not build properly under later
versions of the package, this section explains how to convert documents to the new
interface.
24
Data
offset
15 16
Reserved
23 24
U A P R S F
R C S S Y I
G K H T N N
31
Window
Urgent pointer
Checksum
These words
were taken
verbatim
from the
TCP header
definition
(RFC 793).
Data octets
hhh
h
hhhhhhhhh
hhhh
h
hhhhhhhhh
hhhh
h
hhhhhhhhh
hhhh
h
hhhhhhh
hhhh
h
Note that we
can display,
for example,
a misaligned
64-bit value
with clever
use of the
optional
argument to
\wordbox
and \bitbox.
Source
Destination
Timestamp
Length
Key
Value
Length
Unused
Why two
Length
fields? No
particular
reason.
Total number of 16-bit data words that follow this header word,
excluding the subsequent checksum-type value
Data 1
Data 2
Data 3
Data 4
..
.
..
.
Data N 1
A5A5H
N
X
Data N
!
Datai
mod 220
000010000110
i=1
\wordgroupr
\endwordgroupr
These have been replaced with the rightwordgroup environment to make
their invocation more LATEX-like. Use \begin{rightwordgroup} instead of
\wordgroupr and \end{rightwordgroup} instead of \endwordgroupr.
\wordgroupl
\endwordgroupl
These have been replaced with the leftwordgroup environment to make their
invocation more LATEX-like. Use \begin{leftwordgroup} instead of \wordgroupl
and \end{leftwordgroup} instead of \endwordgroupl.
\bitwidth
Instead of changing bit widths with \setlength{\bitwidth}{hwidthi}, use
\bytefieldsetup{bitwidth=hwidthi}.
\byteheight
Instead of changing bit heights with \setlength{\byteheight}{hheighti},
use \bytefieldsetup{bitheight=hheighti} (and note the change from byte
to bit for consistency with bitwidth).
\curlyspace
\labelspace
Instead
of
using
\setlength{\curlyspace}{hdisti}
and
\setlength{\labelspace}{hdisti} to alter the horizontal space that appears
before and after a curly brace, use \bytefieldsetup{curlyspace=hdisti} and
\bytefieldsetup{labelspace=hdisti}. Note that, as described in Section 2.2,
left and right spacing can be set independently if desired.
\curlyshrinkage
Instead of using \setlength{\curlyshrinkage}{hdisti} to reduce the vertical
space occupied by a curly brace, use \bytefieldsetup{curlyshrinkage=hdisti}.
Note that, as described in Section 2.2, left and right curly-brace height can be
reduced independently if desired.
26
Implementation
This section contains the complete source code for bytefield. Most users will not
get much out of it, but it should be of use to those who need more precise documentation and those who want to extend (or debug ,) the bytefield package.
In this section, macros marked in the margin with a ? are intended to be
called by the user (and were described in Section 2). All other macros are used
only internally by bytefield.
3.1
Required packages
Although \widthof and \heightof were introduced in June 1998, teTEX 2.0
still in widespread use at the time of this writing (2005)ships with an earlier
calc.sty in the source directory. Because a misconfigured system may find the
source version of calc.sty we explicitly specify a later date when loading the
calc package.
1
2
\RequirePackage{calc}[1998/07/07]
\RequirePackage{keyval}
3.2
Utility macros
The following macros in this section are used by the box-drawing macros and the
skipped words-drawing macros.
\bf@newdimen
\allocationnumber
\def\bf@newdimen#1{\advance\count11 by 1
27
\ch@ck1\insc@unt\dimen
\allocationnumber=\count11
\dimendef#1=\allocationnumber
\wlog{\string#1=\string\dimen\the\allocationnumber\space (locally)}%
4
5
6
7
8
\bf@newdimen
If were using -TEX then we have access to many more hdimenis than in original
TEX. The etex package makes these extra hdimenis available via the \locdimen
macro. At the start of the document we check if \locdimen is defined and, if so,
replace the preceding definition of \bf@newdimen with etexs \locdimen.
\AtBeginDocument{%
\begingroup\expandafter\expandafter\expandafter\endgroup
11
\expandafter\ifx\csname locdimen\endcsname\relax
12
\else
13
\let\bf@newdimen\locdimen
14
\fi
15 }
9
10
\bytefield@height
\ifcounting@words
When \ifcounting@words is true, add the height of the next picture environment to \bytefield@height. We set \counting@wordstrue at the beginning of each word, and \counting@wordsfalse after each \bitbox, \wordbox, or
\skippedwords picture.
16
17
\inc@bytefield@height
\newlength{\bytefield@height}
\newif\ifcounting@words
3.3
\entire@bytefield@picture
Declare a box for containing the entire bytefield. By storing everything in a box
and then typesetting it later (at the \end{bytefield}), we can center the bit
field, put a box around it, and do other operations on the entire figure.
22
bytefield
\bits@wide
\old@nl
\amp
Top-level environment
\newsavebox{\entire@bytefield@picture}
28
\newenvironment{bytefield}[2][]{%
\bf@bytefieldsetup{#1}%
25
\def\bits@wide{#2}%
26
\let\old@nl=\\%
27
\let\amp=&%
28
\catcode\&=10
29
\openup -1pt
30
\setlength{\bytefield@height}{0pt}%
31
\setlength{\unitlength}{1pt}%
32
\global\counting@wordstrue
33
\begin{lrbox}{\entire@bytefield@picture}%
23
24
\\
34
35
36
37
38
\vbox\bgroup\ialign\bgroup##\amp##\amp##\cr\amp
}{%
41
\amp\show@wordlabelr\cr\egroup\egroup
42
\end{lrbox}%
43
\usebox{\entire@bytefield@picture}}
39
40
3.4
3.4.1
\bf@bitformatting
\newcommand*{\bf@boxformatting}{\centering}
Define the width of a single bit. Note that this is wide enough to display a twodigit number without it running into adjacent numbers. For larger words, be sure
to \setlength this larger.
46
47
\bf@bitheight
\newcommand*{\bf@bitformatting}{\tiny}
Format the text within a bit box or word box. \bf@boxformatting takes either
a single argument (`
a la \textbf) or no argument (`a la \small). The text that
follows \bf@boxformatting is guaranteed to be a group that ends in \par, so
if \bf@boxformatting accepts an argument, the macro should be defined with
\long (e.g., with \newcommand but not with \newcommand*).
45
\bf@bitwidth
Drawing (proper)
\bf@boxformatting
Box-drawing macros
\newlength{\bf@bitwidth}
\settowidth{\bf@bitwidth}{\bf@bitformatting{99i}}
\newlength{\bf@bitheight}
\setlength{\bf@bitheight}{4ex}
29
\units@wide
\units@tall
These are scratch variables for storing the width and height (in points) of the box
were about to draw.
50
51
\bitbox
\newlength{\units@wide}
\newlength{\units@tall}
Put some text (#3) in a box thats a given number of bits (#2) wide and one byte
tall. An optional argument (#1) specifies which lines to draw[l]eft, [r]ight,
[t]op, and/or [b]ottom (default: lrtb). Uppercase letters suppress drawing the
[L]eft, [R]ight, [T]op, and/or [B]ottom sides.
\DeclareRobustCommand{\bitbox}[3][lrtb]{%
\setlength{\units@wide}{\bf@bitwidth * #2}%
54
\bf@parse@bitbox@arg{#1}%
55
\draw@bit@picture{\strip@pt\units@wide}{\strip@pt\bf@bitheight}{#3}}
52
53
\wordbox
Put some text (#3) in a box thats a given number of bytes (#2) tall and one
word (\bits@wide bits) wide. An optional argument (#1) specifies which lines
to draw[l]eft, [r]ight, [t]op, and/or [b]ottom (default: lrtb). Uppercase
letters suppress drawing the [L]eft, [R]ight, [T]op, and/or [B]ottom sides.
\DeclareRobustCommand{\wordbox}[3][lrtb]{%
\setlength{\units@wide}{\bf@bitwidth * \bits@wide}%
58
\setlength{\units@tall}{\bf@bitheight * #2}%
59
\bf@parse@bitbox@arg{#1}%
60
\draw@bit@picture{\strip@pt\units@wide}{\strip@pt\units@tall}{#3}}
56
57
\draw@bit@picture
Put some text (#3) in a box thats a given number of units (#1) wide and a
given number of units (#2) tall. We format the text with a \parbox to enable
word-wrapping and explicit line breaks. In addition, we define \height, \depth,
\totalheight, and \width (`a la \makebox and friends), so the user can utilize
those for special effects (e.g., a \rule that fills the entire box). As an added bonus,
we define \widthunits and \heightunits, which are the width and height of the
box in multiples of \unitlength (i.e., #1 and #2, respectively).
61
62
?
?
?
?
?
?
\height
\depth
\totalheight
\width
\widthunits
\heightunits
\DeclareRobustCommand{\draw@bit@picture}[3]{%
\begin{picture}(#1,#2)%
First, we plot the users text, with all sorts of useful lengths predefined.
63
64
65
66
67
68
69
70
71
72
73
74
\put(0,0){\makebox(#1,#2){\parbox{#1\unitlength}{%
\bf@newdimen\height
\bf@newdimen\depth
\bf@newdimen\totalheight
\bf@newdimen\width
\height=#2\unitlength
\depth=0pt%
\totalheight=#2\unitlength
\width=#1\unitlength
\def\widthunits{#1}%
\def\heightunits{#2}%
\bf@boxformatting{#3\par}}}}%
30
Next, we draw each line individually. I suppose we could make a special case for
all lines and use a \framebox above, but the following works just fine.
75
76
77
78
79
80
81
82
83
84
85
86
87
\ifbitbox@top
\put(0,#2){\line(1,0){#1}}%
\fi
\ifbitbox@bottom
\put(0,0){\line(1,0){#1}}%
\fi
\ifbitbox@left
\put(0,0){\line(0,1){#2}}%
\fi
\ifbitbox@right
\put(#1,0){\line(0,1){#2}}%
\fi
\end{picture}%
Finally, we indicate that were no longer at the beginning of a word. The following
code structure (albeit with different arguments to \inc@bytefield@height) is
repeated in various places throughout this package. We document it only here,
however.
88
89
90
91
92
?
?
\bitboxes
\bitboxes*
\ifcounting@words
\inc@bytefield@height{\unitlength * \real{#2}}%
\global\counting@wordsfalse
\fi
\ignorespaces}
Put each token in #3 into a box thats a given number of bits (#2) wide and
one byte tall. An optional argument (#1) specifies which lines to draw[l]eft,
[r]ight, [t]op, and/or [b]ottom (default: lrtb). Uppercase letters suppress
drawing the [L]eft, [R]ight, [T]op, and/or [B]ottom sides. The *-form of the
command omits interior left and right lines.
\DeclareRobustCommand{\bitboxes}{%
\@ifstar\bf@bitboxes@star\bf@bitboxes@no@star
95 }
93
94
\bf@relax
Define a macro that expands to \relax for use with \ifx tests against
\bf@bitboxes@arg, which can contain either tokens to typeset or \relax.
96
\bf@bitboxes@no@star
\bf@bitboxes@no@star@i
\newcommand{\bf@bitboxes@no@star}[3][lrtb]{%
\bf@bitboxes@arg
\next
\def\bf@relax{\relax}
\def\bf@bitboxes@no@star@i##1{%
Store the current argument token in \bf@bitboxes@arg for use with \ifx.
99
\def\bf@bitboxes@arg{##1}%
31
\ifx\bf@bitboxes@arg\bf@relax
\let\next=\relax
\else
\bitbox[#1]{#2}{##1}%
\let\next=\bf@bitboxes@no@star@i
\fi
\next
100
101
102
103
104
105
106
}%
\bf@bitboxes@no@star@i#3\relax
\ignorespaces
107
108
109
110
\bf@bitboxes@star
\bf@bitboxes@star@i
\newcommand{\bf@bitboxes@star}[3][lrtb]{%
If the argument to \bitboxes* contains a single (or no) token, simply pass control
to \bitbox and stop. Otherwise, suppress the boxs right border by appending
R to \bitboxes*s argument #1 and proceeding with the remaining tokens in #3.
112
\bf@bitboxes@arg
\next
\def\bf@bitboxes@star@i##1##2{%
Store the current argument token in \bf@bitboxes@arg for use with \ifx.
\def\bf@bitboxes@arg{##2}%
\ifx\bf@bitboxes@arg\bf@relax
\bitbox[#1]{#2}{##1}%
\let\next=\relax
\else
\bitbox[#1R]{#2}{##1}%
\def\next{\bf@bitboxes@star@ii{##2}}%
\fi
\next
113
114
115
116
117
118
119
120
121
122
\bf@bitboxes@star@ii
Process all tokens in \bitboxes*s argument #3 following the first argument. For
each token, produce a box with the left side suppressed using L.
123
\bf@bitboxes@arg@i
\bf@bitboxes@arg@ii
\bf@bitboxes@sides
\next
}%
\def\bf@bitboxes@star@ii##1##2{%
\def\bf@bitboxes@arg@i{##1}%
\def\bf@bitboxes@arg@ii{##2}%
\ifx\bf@bitboxes@arg@ii\bf@relax
\def\bf@bitboxes@sides{#1L}%
\else
\def\bf@bitboxes@sides{#1LR}%
\fi
\ifx\bf@bitboxes@arg@i\bf@relax
\let\next=\relax
32
\else
\expandafter\bitbox\expandafter[\bf@bitboxes@sides]{#2}{##1}%
\def\next{\bf@bitboxes@star@ii{##2}}%
\fi
\next
133
134
135
136
137
138
}%
139
\bf@bitboxes@star@i#3\relax\relax
\ignorespaces
140
141
3.4.2
Parsing arguments
The macros in this section are used to parse the optional argument to \bitbox or
\wordbox, which is some subset of {l, r, t, b, L, R, T, B}. Lowercase letters display
the left, right, top, or bottom side of a box; uppercase letters inhibit the display.
The default is not to display any sides, but an uppercase letter can negate the
effect of a prior lowercase letter.
\ifbitbox@top
\ifbitbox@bottom
\ifbitbox@left
\ifbitbox@right
These macros are set to true if were to draw the corresponding edge on the
subsequent \bitbox or \wordbox.
\bf@parse@bitbox@arg
This main parsing macro merely resets the above conditionals and calls a helper
function, \bf@parse@bitbox@sides.
\newif\ifbitbox@top
\newif\ifbitbox@bottom
144 \newif\ifbitbox@left
145 \newif\ifbitbox@right
142
143
\def\bf@parse@bitbox@arg#1{%
\bitbox@topfalse
148
\bitbox@bottomfalse
149
\bitbox@leftfalse
150
\bitbox@rightfalse
151
\bf@parse@bitbox@sides#1X}
146
147
\bf@parse@bitbox@sides
The helper function for \bf@parse@bitbox@arg parses a single letter, sets the
appropriate conditional to true, and calls itself tail-recursively until it sees an X.
\def\bf@parse@bitbox@sides#1{%
\ifx#1X%
154
\else
155
\ifx#1t%
156
\bitbox@toptrue
157
\else
158
\ifx#1b%
159
\bitbox@bottomtrue
160
\else
161
\ifx#1l%
162
\bitbox@lefttrue
163
\else
152
153
33
\ifx#1r%
\bitbox@righttrue
\else
\ifx#1T%
\bitbox@topfalse
\else
\ifx#1B%
\bitbox@bottomfalse
\else
\ifx#1L%
\bitbox@leftfalse
\else
\ifx#1R%
\bitbox@rightfalse
\else
\PackageWarning{bytefield}{Unrecognized box side #1}%
\fi
\fi
\fi
\fi
\fi
\fi
\fi
\fi
\expandafter\bf@parse@bitbox@sides
\fi}
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
3.5
\units@high
This is the height of each diagonal line in the \skippedwords graphic. Note that
\units@high = \units@tall optional argument to \skippedwords.
190
\skippedwords
Skipped words
\newlength{\units@high}
Output a fancy graphic representing skipped words. The optional argument is the
vertical space between the two diagonal lines (default: 2ex).
\DeclareRobustCommand{\skippedwords}[1][2ex]{%
\setlength{\units@wide}{\bf@bitwidth * \bits@wide}%
193
\setlength{\units@high}{1pt * \ratio{\units@wide}{6.0pt}}%
194
\setlength{\units@tall}{#1 + \units@high}%
195
\edef\num@wide{\strip@pt\units@wide}%
196
\edef\num@tall{\strip@pt\units@tall}%
197
\edef\num@high{\strip@pt\units@high}%
198
\begin{picture}(\num@wide,\num@tall)
199
\put(0,\num@tall){\line(6,-1){\num@wide}}
200
\put(\num@wide,0){\line(-6,1){\num@wide}}
201
\put(0,0){\line(0,1){\num@high}}
202
\put(\num@wide,\num@tall){\line(0,-1){\num@high}}
203
\end{picture}%
204
\ifcounting@words
191
192
34
\inc@bytefield@height{\unitlength * \real{\num@tall}}%
\global\counting@wordsfalse
\fi}
205
206
207
3.6
\bf@bit@endianness
bytefield can label bit headers in either little-endian (0, 1, 2, . . . , N 1) or bigendian (N 1, N 2, N 3, . . . , 0) fashion. The \bf@bit@endianness macro
specifies which to use, either l for little-endian (the default) or b for bigendian.
208
\bf@first@bit
\bitheader
\newcommand*{\bf@bit@endianness}{l}
Normally, bits are numbered starting from zero. However, \bf@first@bit can be
altered (usually locally) to begin numbering from a different value.
209
Bit-position labels
\newcommand*{\bf@first@bit}{0}
\bf@parse@range@list
226
35
\header@xpos
header@val
max@header@val
\bf@parse@range
\bf@process@bitheader@opts
\KV@bytefield@l
\KV@bytefield@b
\KV@bytefield@l@default
\KV@bytefield@b@default
\KV@bitheader@l
\KV@bitheader@b
\newcommand*{\bf@process@bitheader@opts}{%
\let\KV@bytefield@l=\KV@bitheader@l
252
\let\KV@bytefield@b=\KV@bitheader@b
253
\let\KV@bytefield@l@default=\KV@bitheader@l@default
254
\let\KV@bytefield@b@default=\KV@bitheader@b@default
255
\setkeys{bytefield}%
256 }
250
251
\define@key{bitheader}{l}[true]{%
\expandafter\ifx\csname curlyshrinkage\endcsname\relax
259
\PackageWarning{bytefield}{%
260
The "l" argument to \protect\bitheader\space is deprecated.\MessageBreak
261
Instead, please use "endianness=little", which can\MessageBreak
262
even be declared globally for the entire document.\MessageBreak
257
258
36
263
264
265
}
\define@key{bitheader}{b}[true]{%
268
\expandafter\ifx\csname curlyshrinkage\endcsname\relax
269
\PackageWarning{bytefield}{%
270
The "b" argument to \protect\bitheader\space is deprecated.\MessageBreak
271
Instead, please use "endianness=big", which can\MessageBreak
272
even be declared globally for the entire document.\MessageBreak
273
This warning occurred}%
274
\fi
275
\def\bf@bit@endianness{b}%
276 }
266
267
3.7
3.7.1
\bf@leftcurlyshrinkage
\bf@rightcurlyshrinkage
Word labels
Curly-brace manipulation
\def\bf@leftcurlyshrinkage{5pt}
\def\bf@rightcurlyshrinkage{5pt}
\bf@leftcurlyspace
\bf@rightcurlyspace
\bf@leftlabelspace
\bf@rightlabelspace
Define the amount of space to insert before a curly brace and before a word label
(i.e., after a curly brace).
\bf@leftcurly
\bf@rightcurly
Define the symbols to use as left and right curly braces. These symbols must be
extensible math symbols (i.e., they will immediately follow \left or \right in
math mode).
\def\bf@leftcurlyspace{1ex}
\def\bf@rightcurlyspace{1ex}
281 \def\bf@leftlabelspace{0.5ex}
282 \def\bf@rightlabelspace{0.5ex}
279
280
283
284
\curly@box
\store@rcurly
\curly@height
\half@curly@height
\curly@shift
\old@axis
\let\bf@leftcurly=\{
\let\bf@rightcurly=\}
\newbox{\curly@box}
Store a } thats #2 tall in box #1. The only unintuitive thing here is that we
have to redefine \fontdimen22axis heightto 0 pt. before typesetting the curly
brace. Otherwise, the brace would be vertically off-center by a few points. When
were finished, we reset it back to its old value.
37
\def\store@rcurly#1#2{%
\begingroup
288
\bf@newdimen\curly@height
289
\setlength{\curly@height}{#2 - \bf@rightcurlyshrinkage}%
290
\bf@newdimen\half@curly@height
291
\setlength{\half@curly@height}{0.5\curly@height}%
292
\bf@newdimen\curly@shift
293
\setlength{\curly@shift}{\bf@rightcurlyshrinkage}%
294
\setlength{\curly@shift}{\half@curly@height + 0.5\curly@shift}%
295
\global\sbox{#1}{\raisebox{\curly@shift}{%
296
$\xdef\old@axis{\the\fontdimen22\textfont2}$%
297
$\fontdimen22\textfont2=0pt%
298
\left.
299
\vrule height\half@curly@height
300
width 0pt
301
depth\half@curly@height\right\bf@rightcurly$%
302
$\fontdimen22\textfont2=\old@axis$}}%
303
\endgroup
304 }
286
287
\store@lcurly
\curly@height
\half@curly@height
\curly@shift
3.7.2
\show@wordlabelr
This macro is output in the third column of every row of the \ialigned bytefield
table. Its normally a no-op, but \end{rightwordgroup} defines it to output the
word label and then reset itself to a no-op.
324
\wordlabelr@start
\wordlabelr@end
Right-side labels
\def\show@wordlabelr{}
Declare the starting and ending height (in points) of the set of rows to be labeled
38
on the right.
325
326
rightwordgroup
\newlength{\wordlabelr@start}
\newlength{\wordlabelr@end}
Label
the
words
defined
between
\begin{rightwordgroup}
and
\end{rightwordgroup} on the right side of the bit field. The argument is
the text of the label. The label is typeset to the right of a large curly brace,
which groups the words together.
327
\newenvironment{rightwordgroup}[1]{%
\wordlabelr@start
\wordlabelr@text
\endgroup
\begin{rightwordgroup}
merely
stores
\wordlabelr@start and the user-supplied
\end{rightwordgroup} does most of the work.
the
text
starting
height
in
in \wordlabelr@text.
\global\wordlabelr@start=\bytefield@height
\gdef\wordlabelr@text{#1}%
331
\ignorespaces
332 }{%
329
330
\wordlabelr@end
\show@wordlabelr
\begingroup
\global\wordlabelr@end=\bytefield@height
\gdef\show@wordlabelr{%
\sbox{\word@label@box}{%
\begin{tabular}[b]{@{}l@{}}\wordlabelr@text\end{tabular}}%
\settowidth{\label@box@width}{\usebox{\word@label@box}}%
\setlength{\label@box@height}{\wordlabelr@end-\wordlabelr@start}%
\store@rcurly{\curly@box}{\label@box@height}%
\bf@newdimen\total@box@width
\setlength{\total@box@width}{%
\bf@rightcurlyspace +
\widthof{\usebox{\curly@box}} +
\bf@rightlabelspace +
\label@box@width}%
\begin{picture}(\strip@pt\total@box@width,0)
\put(0,0){%
\hspace*{\bf@rightcurlyspace}%
39
\usebox{\curly@box}%
\hspace*{\bf@rightlabelspace}%
\makebox(\strip@pt\label@box@width,\strip@pt\label@box@height){%
\usebox{\word@label@box}}}
\end{picture}%
350
351
352
353
354
355
\@currenvir
Because of our meddling with \begingroup and \endgroup, the current environment is all messed up. We therefore force the \end{rightwordgroup} to succeed,
even if it doesnt match the preceding \begin.
\def\@currenvir{rightwordgroup}%
\ignorespaces
356
357
358
3.7.3
\wordlabell@start
\wordlabell@end
Declare the starting and ending height (in points) of the set of rows to be labeled
on the left.
359
360
\total@box@width
leftwordgroup
\newlength{\total@lbox@width}
This macro is output in the first column of every row of the \ialigned bytefield
table. Its normally a no-op, but \begin{leftwordgroup} defines it to output
enough space for the next word label and then reset itself to a no-op.
362
\newlength{\wordlabell@start}
\newlength{\wordlabell@end}
Declare the total width of the next label to typeset on the left of the bit field, that
is, the aggregate width of the text box, curly brace, and spaces on either side of
the curly brace.
361
\make@lspace
Left-side labels
\gdef\make@lspace{}
40
\newenvironment{leftwordgroup}[1]{%
\wordlabell@start
\wordlabell@text
\endgroup
We store the starting height and label text, which are needed by the
\end{leftwordgroup}.
365
366
\global\wordlabell@start=\bytefield@height
\gdef\wordlabell@text{#1}%
\make@lspace
\sbox{\word@label@box}{%
\begin{tabular}[b]{@{}l@{}}\wordlabell@text\end{tabular}}%
\settowidth{\label@box@width}{\usebox{\word@label@box}}%
\store@lcurly{\curly@box}{5cm}%
\setlength{\total@lbox@width}{%
\bf@leftcurlyspace +
\widthof{\usebox{\curly@box}} +
\bf@leftlabelspace +
\label@box@width}%
\global\total@lbox@width=\total@lbox@width
Now we know how wide the box is going to be (unless, of course, the user is using
some weird math font that scales the width of a curly brace proportionally to its
height). So we redefine \make@lspace to output \total@lbox@widths worth of
space and then redefine itself back to a no-op.
\gdef\make@lspace{%
\hspace*{\total@lbox@width}%
379
\gdef\make@lspace{}}%
380
\ignorespaces
381 }{%
377
378
Because we already ended the group that \begin{leftwordgroup} created we have to start the \end{leftwordgroup} by beginning a group for
\end{leftwordgroup} to end.
382
\begingroup
41
The \end{leftwordgroup} code is comparatively straightforward. We calculate the final height of the word group, and then output the label text, followed by \bf@leftlabelspace space, followed by a curly brace (now that we
know how tall its supposed to be), followed by \bf@leftcurlyspace space. The
trick, as described earlier, is that we typeset the entire label in the second column, but in a 0 0 picture environment and with a negative horizontal offset
(\starting@point), thereby making it overlap the first column.
\global\wordlabell@end=\bytefield@height
\bf@newdimen\starting@point
\setlength{\starting@point}{%
-\total@lbox@width - \bf@bitwidth*\bits@wide}%
\sbox{\word@label@box}{%
\begin{tabular}[b]{@{}l@{}}\wordlabell@text\end{tabular}}%
\settowidth{\label@box@width}{\usebox{\word@label@box}}%
\setlength{\label@box@height}{\wordlabell@end-\wordlabell@start}%
\store@lcurly{\curly@box}{\label@box@height}%
\begin{picture}(0,0)
\put(\strip@pt\starting@point,0){%
\makebox(\strip@pt\label@box@width,\strip@pt\label@box@height){%
\usebox{\word@label@box}}%
\hspace*{\bf@leftlabelspace}%
\usebox{\curly@box}%
\hspace*{\bf@leftcurlyspace}}
\end{picture}%
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
\@currenvir
Because of our meddling with \begingroup and \endgroup, the current environment is all messed up. We therefore force the \end{leftwordgroup} to succeed,
even if it doesnt match the preceding \begin.
\def\@currenvir{leftwordgroup}%
\ignorespaces}
400
401
3.7.4
\label@box@width
\label@box@height
\word@label@box
Scratch space
Declare some scratch storage for the width, height, and contents of the word label
were about to output.
\newlength{\label@box@width}
\newlength{\label@box@height}
404 \newsavebox{\word@label@box}
402
403
3.8
\bf@enter@compatibility@mode@i
Compatibility mode
bytefields interface changed substantially with the move to version 2.0. To give
version 1.x users a quick way to build their old documents, we provide a version 1.x
compatibility mode. We dont enable this by default because it exposes a number
of extra length registers (a precious resource) and because we want to encourage
users to migrate to the new interface.
405
\newcommand{\bf@enter@compatibility@mode@i}{%
42
\bitwidth
\byteheight
\curlyspace
\labelspace
\curlyshrinkage
Define a handful of lengths that the user was allowed to \setlength explicitly in
bytefield 1.x.
406
407
408
409
410
411
412
413
414
415
416
\newbytefield
\endnewbytefield
bytefield
418
419
420
421
422
423
424
425
426
427
428
\let\newbytefield=\bytefield
\let\endnewbytefield=\endbytefield
\renewenvironment{bytefield}[1]{%
\begin{newbytefield}[%
bitwidth=\bitwidth,
bitheight=\byteheight,
curlyspace=\curlyspace,
labelspace=\labelspace,
curlyshrinkage=\curlyshrinkage]{##1}%
}{%
\end{newbytefield}%
}
\bytefieldsetup
\settowidth{\bitwidth}{\tiny 99i}%
\setlength{\byteheight}{4ex}%
\setlength{\curlyspace}{1ex}%
\setlength{\labelspace}{0.5ex}%
\setlength{\curlyshrinkage}{5pt}%
\wordgroupr
\endwordgroupr
\wordgroupl
\endwordgroupl
\def\wordgroupr{\begin{rightwordgroup}}
\def\endwordgroupr{\end{rightwordgroup}}
\def\wordgroupl{\begin{leftwordgroup}}
\def\endwordgroupl{\end{leftwordgroup}}
Disable \bytefieldsetup in compatibility mode because it doesnt work as expected. (Every use of the compatibility-mode bytefield environment overwrites
all of the figure-formatting values.)
433
434
435
436
437
438
439
440
\renewcommand{\bytefieldsetup}[1]{%
\PackageError{bytefield}{%
The \protect\bytefieldsetup\space macro is not available in\MessageBreak
version 1 compatibility mode%
}{%
Remove [compat1] from the \protect\usepackage{bytefield} line to
make \protect\bytefieldsetup\MessageBreak
available to this document.\space\space (The document may also need
43
to be modified to use\MessageBreak
the new bytefield interface.)
441
442
}%
443
}%
444
445
\wordgroupr
\endwordgroupr
\wordgroupl
\endwordgroupl
Issue a helpful error message for the commands that were removed in bytefield v2.0.
While this wont help users whose first invalid action is to modify a no-longerextant length register such as \bitwidth or \byteheight, it may benefit at least
a few users who didnt realize that the bytefield interface has changed substantially
with version 2.0.
\newcommand{\wordgroupr}{%
\PackageError{bytefield}{%
448
Macros \protect\wordgroupr, \protect\wordgroupl, \protect\endwordgroupr,
449
\MessageBreak
450
and \protect\endwordgroupl\space no longer exist%
451
}{%
452
Starting with version 2.0, bytefield uses \protect\begin{wordgroupr}...
453
\MessageBreak
454
\protect\end{wordgroupr} and \protect\begin{wordgroupl}...%
455
\protect\end{wordgroupl}\MessageBreak
456
to specify word groups and a new \protect\bytefieldsetup\space macro to
457
\MessageBreak
458
change bytefields various formatting parameters.%
459
}%
460 }
461 \let\endwordgroupr=\wordgroupr
462 \let\wordgroupl=\wordgroupr
463 \let\endwordgroupl=\wordgroupr
446
447
3.9
Option processing
We use the keyval package to handle option processing. Because all of bytefields
options have local impact, options can be specified either as package arguments
or through the use of the \bytefieldsetup macro.
\KV@bytefield@bitwidth
\bf@bw@arg
\bf@auto
Specify the width of a bit number in the bit header. If the special value auto is
given, set the width to the width of a formatted 99i.
\define@key{bytefield}{bitwidth}{%
\def\bf@bw@arg{#1}%
466
\def\bf@auto{auto}%
467
\ifx\bf@bw@arg\bf@auto
468
\settowidth{\bf@bitwidth}{\bf@bitformatting{99i}}%
469
\else
470
\setlength{\bf@bitwidth}{#1}%
471
\fi
472 }
464
465
\KV@bytefield@bf@bitheight
44
473
\KV@bytefield@bitformatting
Specify the style of a bit number in the bit header. This should be passed
an expression that takes either one argument (e.g., \textit) or no arguments
(e.g., {\small\bfseries}).
474
\KV@bytefield@boxformatting
\define@key{bytefield}{boxformatting}{\def\bf@boxformatting{#1}}
Specify the symbol to use for bracketing a left or right word group. This must be
an extensible math delimiter (i.e., something that can immediately follow \left
or \right in math mode).
476
477
\KV@bytefield@leftcurlyspace
\KV@bytefield@rightcurlyspace
\KV@bytefield@curlyspace
\define@key{bytefield}{bitformatting}{\def\bf@bitformatting{#1}}
Specify a style to be applied to the contents of every bit box and word box. This
should be passed an expression that takes either one argument (e.g., \textit) or
no arguments (e.g., {\small\bfseries}).
475
\KV@bytefield@leftcurly
\KV@bytefield@rightcurly
\define@key{bytefield}{bitheight}{\setlength{\bf@bitheight}{#1}}
\define@key{bytefield}{leftcurly}{\def\bf@leftcurly{#1}}
\define@key{bytefield}{rightcurly}{\def\bf@rightcurly{#1}}
Specify the amount of space between the bit fields in a word group and the adjacent
left or right curly brace. The curlyspace option is a shortcut that puts the same
space before both left and right curly braces.
\define@key{bytefield}{leftcurlyspace}{\def\bf@leftcurlyspace{#1}}
\define@key{bytefield}{rightcurlyspace}{\def\bf@rightcurlyspace{#1}}
480 \define@key{bytefield}{curlyspace}{%
481
\def\bf@leftcurlyspace{#1}%
482
\def\bf@rightcurlyspace{#1}%
483 }
478
479
\KV@bytefield@leftlabelspace
\KV@bytefield@rightlabelspace
\KV@bytefield@labelspace
Specify the amount of space between a left or right word groups curly brace and
the associated label text. The labelspace option is a shortcut that puts the same
space after both left and right curly braces.
\define@key{bytefield}{leftlabelspace}{\def\bf@leftlabelspace{#1}}
\define@key{bytefield}{rightlabelspace}{\def\bf@rightlabelspace{#1}}
486 \define@key{bytefield}{labelspace}{%
487
\def\bf@leftlabelspace{#1}%
488
\def\bf@rightlabelspace{#1}%
489 }
484
485
KV@bytefield@leftcurlyshrinkage
V@bytefield@rightcurlyshrinkage
\KV@bytefield@curlyshrinkage
Specify the number of points by which to reduce the height of a curly brace (left,
right, or both) so its ends dont overlap whatevers above or below it.
\define@key{bytefield}{leftcurlyshrinkage}{\def\bf@leftcurlyshrinkage{#1}}
\define@key{bytefield}{rightcurlyshrinkage}{\def\bf@rightcurlyshrinkage{#1}}
492 \define@key{bytefield}{curlyshrinkage}{%
493
\def\bf@leftcurlyshrinkage{#1}%
494
\def\bf@rightcurlyshrinkage{#1}%
495 }
490
491
\KV@bytefield@endianness
\bf@parse@endianness
\define@key{bytefield}{endianness}{\bf@parse@endianness{#1}}
45
\newcommand{\bf@parse@endianness}[1]{%
\def\bf@little{little}%
499
\def\bf@big{big}%
500
\def\bf@arg{#1}%
501
\ifx\bf@arg\bf@little
502
\def\bf@bit@endianness{l}%
503
\else
504
\ifx\bf@arg\bf@big
505
\def\bf@bit@endianness{b}%
506
\else
507
\PackageError{bytefield}{%
508
Invalid argument "#1" to the endianness option%
509
}{%
510
The endianness option must be set to either "little" or
511
"big".\MessageBreak
512
Please specify either endianness=little or endianness=big.
513
}%
514
\fi
515
\fi
516 }
497
498
\KV@bytefield@lsb
\bytefieldsetup
\bf@bytefieldsetup
\define@key{bytefield}{lsb}{\def\bf@first@bit{#1}}
\newcommand{\bf@bytefieldsetup}{\setkeys{bytefield}}
\let\bytefieldsetup=\bf@bytefieldsetup
We define only a single option that can be used only as a package option, not as
an argument to \bytefieldsetup: compat1 instructs bytefield to enter version 1
compatibility modeat the cost of a number of additional length registers and the
inability to specify parameters in the argument to the bytefield environment.
520
\bf@package@options
\next
\DeclareOption{compat1}{\bf@enter@compatibility@mode@i}
We want to use \bf@bytefieldsetup to process bytefield package options. Unfortunately, \DeclareOption doesnt handle hkeyi=hvaluei arguments. Hence,
we use \DeclareOption* to catch all options, each of which it appends to
\bf@package@options. \bf@package@options is passed to \bf@bytefieldsetup
only at the beginning of the document so that the options it specifies (a) can refer to ex-heights and (b) override the default values, which are also set at the
beginning of the document.
\def\bf@package@options{}
\DeclareOption*{%
523
\edef\next{%
524
\noexpand\g@addto@macro\noexpand\bf@package@options{,\CurrentOption}%
521
522
46
525
526
}%
\next
}
\ProcessOptions\relax
529 \expandafter\bf@bytefieldsetup\expandafter{\bf@package@options}
527
528
Future work
bytefield is my first LATEX package, and, as such, there are a number of macros
that could probably have been implemented a lot better. For example, bytefield
is somewhat wasteful of hdimeni registers (although it did get a lot better with
version 1.1 and again with version 1.3). The package should really get a major
overhaul now that Ive gotten better at TEX/LATEX programming. One minor
improvement Id like to make in the package is to move left, small curly braces
closer to the bit field. In the following figure, notice how distant the small curly
appears from the bit-field body:
Too distant
Looks okay
Something
Something else
The problem is that the curly braces are left-aligned relative to each other, while
they should be right-aligned.
Change History
v1.0
General: Initial version . . . . . . . .
v1.1
General: Restructured the .dtx file
\allocationnumber:
Bug
fix:
Added \bf@newdimen to greatly
reduce the likelihood of No
room for a new \dimen errors (reported by Vitaly A. Repin) . . . . . . . . . . . . . . . . . . .
\bf@parse@range@list: Bug fix:
Swapped order of arguments to
\ifx test (suggested by HansJoachim Widmaier) . . . . . . . .
v1.2
1
v1.2a
General: Specified an explicit package date when loading the calc
package to avoid loading an outdated version. Thanks to Kevin
Quick for discovering that outdated versions of calc are still
being included in TEX distributions. . . . . . . . . . . . . . . . . . . 27
27
35
47
v1.3
\bf@newdimen: Added support for
-TEXs larger local hdimeni
pool (code provided by Heiko
Oberdiek) . . . . . . . . . . . . . . . 28
v1.4
General: Made assignments to
\counting@words global to prevent vertical-spacing problems
with back-to-back word groups
(bug fix due to Steven R. King) 1
Split \curlyspace, \labelspace,
and \curlyshrinkage into left
and right versions . . . . . . . . . 1
\bf@bitformatting:
Introduced
this macro at Steven R. Kings
request to enable users to alter
the bit headers font size . . . . 29
v2.0
General: Made a number of
non-backwards-compatible
changes,
including
replacing
\wordgroupr
and
\endwordgroupr
with
a
rightwordgroup
environment and \wordgroupl and
\endwordgroupl
with
a
leftwordgroup
environment
and also replacing a slew of
user-visible lengths and macros
Index
Numbers written in italic refer to the page where the corresponding entry is described; numbers underlined refer to the code line of the definition; numbers in
roman refer to the code lines where the entry is used.
\& . . . . . . .
\@currenvir
\@ifstar . .
\\ . . . . . . .
\{ . . . . . . .
\} . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
Symbols
........
........
........
........
........
........
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . . . 28
356, 400
. . . . 94
. . 26, 34
. . . . 283
. . . . 284
A
\allocationnumber
............. 3
48
504
464
504
505
113
\bf@bitboxes@arg@i . . . . . . . . . . . . 124
\bf@bitboxes@arg@ii . . . . . . . . . . . 124
\bf@bitboxes@no@star . . . . . . . . 94, 97
\bf@bitboxes@no@star@i . . . . . . . . 98
\bf@bitboxes@sides . . . . . . . . . . . . 124
\bf@bitboxes@star . . . . . . . . . 94, 111
\bf@bitboxes@star@i . . . . . . . . . . . 112
\bf@bitboxes@star@ii . . . . . . 119, 123
\bf@bitformatting . . . . . . . . . . . .
. . . . . . 44, 47, 213, 247, 468, 474
\bf@bitheight . . . . . . . 48, 55, 58, 473
\bf@bitwidth . . . . . 46, 53, 57, 192,
212, 241, 243, 246, 386, 468, 470
\bf@boxformatting . . . . . . 45, 74, 475
\bf@bw@arg . . . . . . . . . . . . . . . . . . 464
\bf@bytefieldsetup . . . . . 24, 518, 529
\bf@enter@compatibility@mode@i .
. . . . . . . . . . . . . . . . . . . 405, 520
\bf@first@bit . . . . . 209, 241, 243, 517
\bf@leftcurly . . . . . . . . 283, 317, 476
\bf@leftcurlyshrinkage . . . . . . . .
. . . . . . . . 277, 308, 312, 490, 493
\bf@leftcurlyspace . . . . . . . . . . . .
. . . . . . . . 279, 372, 398, 478, 481
\bf@leftlabelspace . . . . . . . . . . . .
. . . . . . . . 279, 374, 396, 484, 487
\bf@little . . . . . . . . . . . . . . 498, 501
\bf@newdimen 3, 9, 64, 65, 66, 67, 288,
290, 292, 307, 309, 311, 341, 384
\bf@package@options . . . . . . . . . . . 521
\bf@parse@bitbox@arg . 54, 59, 146, 211
\bf@parse@bitbox@sides . . . . 151, 152
\bf@parse@endianness . . . . . . . . . . 496
\bf@parse@range . . . . . . . . . . 228, 234
\bf@parse@range@list . . . . . . 218, 225
\bf@process@bitheader@opts . 215, 250
\bf@relax . . . . . 96, 100, 114, 126, 131
\bf@rightcurly . . . . . . . 283, 301, 477
\bf@rightcurlyshrinkage . . . . . . .
. . . . . . . . 277, 289, 293, 491, 494
\bf@rightcurlyspace . . . . . . . . . . .
. . . . . . . . 279, 343, 349, 479, 482
\bf@rightlabelspace . . . . . . . . . . .
. . . . . . . . 279, 345, 351, 485, 488
\bitbox . . . . . 4, 52, 103, 115, 118, 134
\bitbox@bottomfalse . . . . . . . 148, 171
\bitbox@bottomtrue . . . . . . . . . . . . 159
\bitbox@leftfalse . . . . . . . . 149, 174
\bitbox@lefttrue . . . . . . . . . . . . . 162
\bitbox@rightfalse . . . . . . . . 150, 177
\bitbox@righttrue . . . . . . . . . . . . 165
\bitbox@topfalse . . . . . . . . . 147, 168
\bitbox@toptrue . . . . . . . . . . . . . . 156
\bitboxes . . . . . . . . . . . . . . . . . 4, 93
\bitboxes* . . . . . . . . . . . . . . . . . . 93
bitformatting (option) . . . . . . . 9, 10, 16
\bitheader . . . . . . . . . 5, 210, 260, 270
bitheight (option) . . . . . . . . . . . . . . . 9
\bits@wide . . 23, 57, 192, 212, 241, 386
\bitwidth . . . . . . . . . . 26, 27, 406, 421
bitwidth (option) . . . . . . . . 9, 10, 20, 26
boxformatting (option) . . . . . . . 9, 11, 18
\bytefield . . . . . . . . . . . . . . . . . . 417
bytefield (package) . . . . . . . . . . . . 1
4, 8, 14, 15, 18, 20, 21, 23
25, 27, 28, 35, 36, 4244, 4648
bytefield (environment) . . . 3, 23, 417
\bytefield@height . . . . . . . . . . . .
. . . . 16, 21, 30, 329, 334, 365, 383
\bytefield@height@increment . . . .
. . . . . . . . . . . . . . . . . . 18, 20, 21
\bytefieldsetup . . . . . 8, 433, 456, 518
\byteheight . . . . . . . . . . . 26, 406, 422
C
calc (package) . . . . . . . . . . . . . . . 28, 47
\centering . . . . . . . . . . . . . . . . . . 45
color (package) . . . . . . . . . . . . . . . . 17
compat1 (option) . . . . . . . . . . . . . . 36
\counting@wordsfalse . . . 90, 206, 222
\counting@wordstrue . . . . . . . . . 32, 38
\curly@box . . . . . . . . . . . . . . 285,
340, 344, 350, 370, 373, 391, 397
\curly@height . . . . . . . . . . . . 286, 305
\curly@shift . . . . . . . . . . . . . 286, 305
\curlyshrinkage . . . . . . . 26, 406, 425
curlyshrinkage (option) . . . . . . . . . . . 13
\curlyspace . . . . . . . . . . . 26, 406, 423
curlyspace (option) . . . . . . . . . . . 12, 45
\CurrentOption . . . . . . . . . . . . . . . 524
D
\DeclareOption . . . . . . . . . . . 520, 522
\define@key . . . . . . . . . . . . . . . . . .
. 257, 267, 464, 473, 474, 475,
476, 477, 478, 479, 480, 484,
485, 486, 490, 491, 492, 496, 517
\depth . . . . . . . . . . . . . . . . . . . . . . 63
\draw@bit@picture . . . . . . . 55, 60, 61
49
E
\endbytefield . . . . . . . . . .
endianness (option) . . . . . . .
\endnewbytefield . . . . . . .
\endwordgroupl . . . . . . . .
\endwordgroupr . . . . . . . .
\entire@bytefield@picture
environments:
bytefield . . . . . . . . . . .
leftwordgroup . . . . . . .
rightwordgroup . . . . . .
\fontdimen
. . . . . . 418
. . . . . 6, 9
. . . . . . 417
26, 429, 446
26, 429, 446
. 22, 33, 43
. 3, 23, 417
. . . . 6, 363
. . . . 6, 327
F
296, 297, 302, 315, 316, 321
G
\g@addto@macro . . . . . . . . . . . . . . . 524
graphicx (package) . . . . . . . . . . . . . . 16
H
\half@curly@height .
\header@val . . . . . . .
\header@xpos . . . . . .
\height . . . . . . . . . .
\heightof . . . . . . . .
\heightunits . . . . . .
. . . . . . . 286,
...........
231, 240, 243,
...........
...........
...........
I
\ialign . . . . . . . . . . . .
\ifbitbox@bottom . . . .
\ifbitbox@left . . . . . .
\ifbitbox@right . . . . .
\ifbitbox@top . . . . . . .
\ifcounting@words . . .
\inc@bytefield@height
305
231
245
63
213
63
.........
. . . . . . 78,
. . . . . . 81,
. . . . . . 84,
. . . . . . 75,
16, 88, 204,
18, 89, 205,
39
142
142
142
142
220
221
K
\KV@bitheader@b . . . . . . . . . . 252,
\KV@bitheader@b@default . . . . . . .
\KV@bitheader@l . . . . . . . . . . 251,
\KV@bitheader@l@default . . . . . . .
\KV@bytefield@b . . . . . . . . . . . . . .
\KV@bytefield@b@default . . . . . . .
\KV@bytefield@bf@bitheight . . . . .
\KV@bytefield@bitformatting . . . .
\KV@bytefield@bitwidth . . . . . . . .
\KV@bytefield@boxformatting . . . .
\KV@bytefield@curlyshrinkage . . .
\KV@bytefield@curlyspace . . . . . . .
\KV@bytefield@endianness . . . . . . .
257
254
257
253
250
250
473
474
464
475
490
478
496
\KV@bytefield@l . . . . . . . . . . . . . . 250
\KV@bytefield@l@default . . . . . . . 250
\KV@bytefield@labelspace . . . . . . . 484
\KV@bytefield@leftcurly . . . . . . . 476
\KV@bytefield@leftcurlyshrinkage 490
\KV@bytefield@leftcurlyspace . . . 478
\KV@bytefield@leftlabelspace . . . 484
\KV@bytefield@lsb . . . . . . . . . . . . 517
\KV@bytefield@rightcurly . . . . . . . 476
\KV@bytefield@rightcurlyshrinkage
. . . . . . . . . . . . . . . . . . . . . . 490
\KV@bytefield@rightcurlyspace . . 478
\KV@bytefield@rightlabelspace . . 484
L
\label@box@height . . . . . . . . . . . .
. 339, 340, 352, 390, 391, 394, 402
\label@box@width . . . . . . . . . 338,
346, 352, 369, 375, 389, 394, 402
\labelspace . . . . . . . . . . . 26, 406, 424
leftcurly (option) . . . . . . . . . . . 9, 11, 13
leftcurlyshrinkage (option) . . . . . . . . 13
leftcurlyspace (option) . . . . . . . . . . . 12
leftwordgroup (environment) . . . 6, 363
\line . 76, 79, 82, 85, 199, 200, 201, 202
\locdimen . . . . . . . . . . . . . . . . . . . 13
lsb (option) . . . . . . . . . . . . . . 13, 15, 35
M
\make@lspace . . . . . . . . . . 38, 362, 377
\makebox . . . . . . . . . . 63, 246, 352, 394
\max@header@val . . . . . . . . . . . . . . 231
\newbytefield
\next . . . . . . .
\num@high . . .
\num@tall . . .
\num@wide . . .
N
................
. . . . . . 99, 113, 124,
. . . . . . . . 197, 201,
. 196, 198, 199, 202,
. 195, 198, 199, 200,
\old@axis . . . .
\old@nl . . . . . .
\openup . . . . . .
options:
bitformatting
bitheight . . .
bitwidth . . . .
boxformatting
compat1 . . .
50
417
521
202
205
202
O
. . . . . . . 286, 315, 321
. . . . . . . . . . . . . . . 23
. . . . . . . . . . . . . . . 29
....
....
....
...
....
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . . 9, 10,
........
9, 10, 20,
. . . 9, 11,
.......
16
9
26
18
36
curlyshrinkage . .
curlyspace . . . . .
endianness . . . . .
leftcurly . . . . . . .
leftcurlyshrinkage
leftcurlyspace . . .
lsb . . . . . . . . . .
rightcurly . . . . . .
rightcurlyshrinkage
rightcurlyspace . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
..
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . . . 13
. . 12, 45
. . . 6, 9
9, 11, 13
. . . . 13
. . . . 12
13, 15, 35
. 9, 11, 13
. . . . . 13
. . . . . 12
P
\PackageError . . . . . . . . 434, 447, 507
\PackageInfo . . . . . . . . . . . . . . . . . 406
packages:
bytefield . . . . . . . . . . . . . . . . 1
4, 8, 14, 15, 18, 20, 21, 23
25, 27, 28, 35, 36, 4244, 4648
calc . . . . . . . . . . . . . . . . . . . . 28, 47
color . . . . . . . . . . . . . . . . . . . . . 17
graphicx . . . . . . . . . . . . . . . . . . 16
register . . . . . . . . . . . . . . . . . . . 18
rotating . . . . . . . . . . . . . . . . . . . 18
\PackageWarning . . . . . . 179, 259, 269
\parbox . . . . . . . . . . . . . . . . . . . . . 63
\ProcessOptions . . . . . . . . . . . . . . 528
\put . . . . . . . . . . . . . 63, 76, 79, 82,
85, 199, 200, 201, 202, 245, 348, 393
R
register (package) . . . . . . . . . .
\RequirePackage . . . . . . . . . .
rightcurly (option) . . . . . . . . . .
rightcurlyshrinkage (option) . . .
rightcurlyspace (option) . . . . . .
rightwordgroup (environment)
rotating (package) . . . . . . . . . .
\setkeys . . . . . .
\show@wordlabelr
\skippedwords . .
\starting@point
S
...
..
...
...
.
.
.
.
.
.
.
.
386
63
U
\unitlength . . . . . . . . . . . . . . . . . .
. . 31, 63, 68, 70, 71, 89, 205, 221
\units@high 190, 193, 194, 197, 214, 217
\units@tall . . . . . . . . . . . . . 50, 58,
60, 194, 196, 213, 214, 216, 221, 246
\units@wide . . . . . . . . . . . . . 50, 53,
55, 57, 60, 192, 193, 195, 212, 216
V
\vrule . . . . . . . . . . . . . . . . . . 299, 318
W
\width . . . . . . . . . . . . . . . . . . . . . . 63
\widthof . . . . . . . . . . . . . . . . 344, 373
\widthunits . . . . . . . . . . . . . . . . . . 63
\word@label@box . . . . . . . 336, 338,
353, 367, 369, 387, 389, 395, 402
\wordbox . . . . . . . . . . . . . . . . . . 4, 56
\wordgroupl . . . . . . . . . . . 26, 429, 446
\wordgroupr . . . . . . . . . . . 26, 429, 446
\wordlabell@end . . . . . . 359, 383, 390
\wordlabell@start . . . . 359, 365, 390
\wordlabell@text . . . . . 365, 368, 388
\wordlabelr@end . . . . . . 325, 333, 339
\wordlabelr@start . . . . 325, 329, 339
\wordlabelr@text . . . . . . . . . 329, 337
. . . . 18
. . . 1, 2
9, 11, 13
. . . . 13
. . . . 12
. . 6, 327
. . . . 18
. . . . . 255,
37, 41, 324,
. . . . . . . 8,
. 384, 385,
321
247
412
361
518
335
191
393
51