% \iffalse meta-comment
%
% Copyright (C) 2010 by Scott Pakin <scott+bf@pakin.org>
% ------------------------------------------------------
%
% This file may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3a
% of this license or (at your option) any later version.
% The latest version of this license is in:
%
%    http://www.latex-project.org/lppl.txt
%
% and version 1.3c or later is part of all distributions of LaTeX
% version 2006/05/20 or later.
%
% \fi
%
% \iffalse
%<*driver>
\ProvidesFile{bytefield.dtx}
%</driver>
%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
%<package>\ProvidesPackage{bytefield}
%<*package>
    [2010/10/31 v1.3 Network protocol diagrams]
%</package>
%
%<*driver>
\documentclass{ltxdoc}
\usepackage{textcomp}
\usepackage{bytefield}
\usepackage{color}
\usepackage{rotating}
\usepackage{calc}
\usepackage{array}
\IfFileExists{hyperref.sty}{%
  \usepackage{hyperref}
  \definecolor{darkred}{rgb}{0.5,0,0}
  \definecolor{darkgreen}{rgb}{0,0.3,0}
  \definecolor{darkblue}{rgb}{0,0,0.5}
  \definecolor{darkbrown}{rgb}{0.28,0.07,0.07}
  \hypersetup{%
    pdftitle={The bytefield package},
    pdfauthor={Scott Pakin <scott+bf@pakin.org>},
    pdfsubject={Protocol diagrams for LaTeX},
    pdfkeywords={bits, bytes, bit fields, communication, network protocol
      diagrams, LaTeX2e, memory maps},
    bookmarksopen=true,
    colorlinks=true,
    citecolor=darkblue,
    urlcolor=darkgreen,
    linkcolor=darkred,
    menucolor=darkbrown}
}
\EnableCrossrefs
\CodelineIndex
\RecordChanges
\setcounter{IndexColumns}{2}
\begin{document}
  \DocInput{bytefield.dtx}
  \PrintChanges
  \PrintIndex
\end{document}
%</driver>
% \fi
%
% \CheckSum{615}
%
% \CharacterTable
%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%   Digits        \0\1\2\3\4\5\6\7\8\9
%   Exclamation   \!     Double quote  \"     Hash (number) \#
%   Dollar        \$     Percent       \%     Ampersand     \&
%   Acute accent  \'     Left paren    \(     Right paren   \)
%   Asterisk      \*     Plus          \+     Comma         \,
%   Minus         \-     Point         \.     Solidus       \/
%   Colon         \:     Semicolon     \;     Less than     \<
%   Equals        \=     Greater than  \>     Question mark \?
%   Commercial at \@     Left bracket  \[     Backslash     \\
%   Right bracket \]     Circumflex    \^     Underscore    \_
%   Grave accent  \`     Left brace    \{     Vertical bar  \|
%   Right brace   \}     Tilde         \~}
%
%
% \changes{v1.0}{2000/07/02}{Initial version}
% \changes{v1.1}{2002/09/14}{Restructured the \texttt{.dtx} file}
%
% \GetFileInfo{bytefield.dtx}
%
% \DoNotIndex{\&,\{,\}}
% \DoNotIndex{\addtocounter,\advance}
% \DoNotIndex{\begin,\begingroup,\bgroup}
% \DoNotIndex{\catcode,\ch@ck,\count,\cr}
% \DoNotIndex{\DeclareRobustCommand,\def,\dimen,\dimendef}
% \DoNotIndex{\edef,\egroup,\else,\end,\endgroup,\expandafter}
% \DoNotIndex{\fi}
% \DoNotIndex{\gdef,\global}
% \DoNotIndex{\if,\ifnum,\ifx,\ignorespaces,\insc@unt}
% \DoNotIndex{\let}
% \DoNotIndex{\newbox,\newcounter,\newenvironment,\newif,\newlength}
% \DoNotIndex{\newsavebox}
% \DoNotIndex{\raisebox,\ratio,\real,\relax,\renewcommand}
% \DoNotIndex{\sbox,\setcounter,\setlength,\settowidth,\space,\string}
% \DoNotIndex{\the}
% \DoNotIndex{\usebox}
% \DoNotIndex{\value,\vbox}
% \DoNotIndex{\wlog}
% \DoNotIndex{\xdef}
%
%
% \title{The \textsf{bytefield} package\thanks{This document
%   corresponds to \textsf{bytefield}~\fileversion, dated \filedate.}}
% \author{Scott Pakin \\ \texttt{scott+bf@pakin.org}}
%
% \sloppy
% \maketitle
%
% ^^A  Define an environment for command/environment delcarations.
% \newsavebox{\declbox}
% \newenvironment{decl}{^^A
%   \begin{lrbox}{\declbox}\begin{tabular}{l}}{^^A
%   \end{tabular}\end{lrbox}^^A
%   \vspace{3ex}\noindent\hspace*{-3em}\fbox{\usebox{\declbox}}\vspace*{2ex}}
%
% ^^A  Draw a cute smiley face to use within text (classier than ":-)").
% \newcommand{\smileyface}{\raisebox{-2pt}{^^A
% \begin{picture}(9,9)
%   \put(5,5){\circle{9}}
%   \put(3.5,7){\circle*{2}}
%   \put(6.6,7){\circle*{2}}
%   \put(0,0){\makebox(9,3)[t]{\tiny $\,\smile$}}
% \end{picture}}}
%
% ^^A  Define an ellipsis that permits a subsequent line break.
% \newcommand{\ellipsis}{$\ldots$\linebreak[0]}
%
% ^^A  Define an environment for showing sample bytefield diagrams.
% \newenvironment{bffigure}{%
%   \bigskip
%   \noindent\hspace*{3em}%
% }{%
%   \bigskip
% }
%
% ^^A  Define something like \cs to use within \StopEventually.
% \DeclareRobustCommand{\cseq}[1]{\texttt{\string#1}}
%
%
% \begin{abstract}
% The \texttt{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.
% \end{abstract}
%
% \section{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,
% 32~bits), and each column represents a bit within a word.
% The \texttt{bytefield} package makes it easy to typeset these sorts of
% figures.
%
% \texttt{bytefield} lets one draw protocol diagrams that contain:
%
% \begin{itemize}
%   \item Words of any arbitrary number of bits
%   \item Column headers showing bit positions
%   \item Multiword fields---even non-word-aligned and even if the total
%         number of bits is not a multiple of the word length
%   \item Word labels on either the left or right of the figure
%   \item ``Skipped words'' within fields
% \end{itemize}
%
% Because \texttt{bytefield} draws its figures using only
% the \LaTeX{} \texttt{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, \texttt{bytefield} pictures can include arbitrary
% \LaTeX{} constructs, such as mathematical equations, |\ref|s and
% |\cite|s to the surrounding document, and macro calls.
%
%
% \section{Usage}
%
% \subsection{Basic commands}
%
% This section explains how to use the \texttt{bytefield} package.
% It lists all the exported environments, commands, and variables in
% decreasing order of importance.
%
% \begin{decl}
%   |\begin{bytefield}| \marg{bit-width} \\
%   \meta{fields} \\
%   |\end{bytefield}|
% \end{decl}
%
% The top-level environment is called, not surprisingly,
% ``|bytefield|''.  It takes one (mandatory) argument, which is the
% number of bits in each word.  One can think of a \texttt{bytefield} as
% being analogous to a \texttt{tabular}: words are separated
% by~|\\|, and fields within a word are separated by~|&|.
%
% \begin{decl}
%   |\wordbox| \oarg{sides} \marg{height} \marg{text} \\
%   |\bitbox| \oarg{sides} \marg{width} \marg{text}
% \end{decl}
%
% The two main commands one uses within a \texttt{bytefield} environment
% are |\wordbox| and |\bitbox|.  The former typesets a field
% that is one or more words tall and an entire word wide.
% The latter typesets a field that is one or more bits wide and a single
% word tall.
%
% The optional argument, \meta{sides}, is a list of letters
% specifying which sides of the field box to draw---|[l]|eft, |[r]|ight,
% |[t]|op, and/or |[b]|ottom.  The default is ``|lrtb|'' (i.e., all sides
% are drawn).  \meta{text} is the text to include within the |\wordbox| or
% |\bitbox|.  It is typeset horizontally centered within a vertically
% centered |\parbox|.  Hence, words will wrap, and |\\| can
% be used to break lines manually.
%
% The following example shows how to produce a simple 16-bit-wide byte field:
%
% \begin{verbatim}
%       \begin{bytefield}{16}
%         \wordbox{1}{A 16-bit field} \\
%         \bitbox{8}{8 bits} & \bitbox{8}{8 more bits} \\
%         \wordbox{2}{A 32-bit field.  Note that text wraps within the box.}
%       \end{bytefield}
% \end{verbatim}
%
% The resulting figure looks like this:
%
% \begin{bffigure}
%       \begin{bytefield}{16}
%         \wordbox{1}{A 16-bit field} \\
%         \bitbox{8}{8 bits} & \bitbox{8}{8 more bits} \\
%         \wordbox{2}{A 32-bit field.  Note that text wraps within the box.}
%       \end{bytefield}
% \end{bffigure}
%
% It is the user's responsibility to ensure that the total
% number of bits in each row adds up to the number of bits in a single
% word (the mandatory argument to the |bytefield| environment).
%
% Within a |\wordbox| or |\bitbox|, the \texttt{bytefield} package
% defines |\height|, |\depth|, |\totalheight|, and |\width| to the
% corresponding dimensions of the box.  Section~\ref{sec:tricks} gives an
% example of how these lengths may be utilized.
%
% \begin{decl}
%   |\bitheader| \oarg{endianness} \marg{bit-positions}
% \end{decl}
%
% To make the figure more readable, it helps to label bit positions across
% the top.  The |\bitheader| command provides a flexible way to do that.
% The optional argument, \meta{endianness} is one of ``|b|'' or ``|l|''
% and specifies whether the bits in each word are numbered in big-endian
% style (right to left) or little-endian style (left to right).  The default
% is little-endian (|l|).
%
% |\bitheader|'s mandatory argument, \meta{bit-positions}, 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 \meta{endianness}
% 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.  While not particularly useful, ranges and single numbers can
% be intermixed, as in ``|0-3,8,12-15|''.
%
% The following example shows how |\bitheader| may be used:
%
% \begin{verbatim}
%       \begin{bytefield}{32}
%         \bitheader{0-31} \\
%         \bitbox{4}{Four} & \bitbox{8}{Eight} &
%           \bitbox{16}{Sixteen} & \bitbox{4}{Four}
%       \end{bytefield}
% \end{verbatim}
%
% The resulting figure looks like this:
%
% \begin{bffigure}
%       \begin{bytefield}{32}
%         \bitheader{0-31} \\
%         \bitbox{4}{Four} & \bitbox{8}{Eight} &
%           \bitbox{16}{Sixteen} & \bitbox{4}{Four}
%       \end{bytefield}
% \end{bffigure}
%
%
% \begin{decl}
%   |\wordgroupr| \marg{text} \\
%   |\endwordgroupr| \\
%   \\
%   |\wordgroupl| \marg{text} \\
%   |\endwordgroupl|
% \end{decl}
%
% When a set of words functions as a single, logical unit, it helps to
% group these words together visually.  All words defined between
% |\wordgroupr| and |\endwordgroupr| will be labeled on the right with
% \meta{text}.  Similarly, all words defined between
% |\wordgroupl| and |\endwordgroupl| will be labeled on the left with
% \meta{text}.  |\wordgroup|\textit{x} must lie at the beginning of a row
% (i.e., right after a |\\|), and |\endwordgroup|\textit{x} must lie right
% \emph{before} the end of the row (i.e., right before a |\\|).
%
% |\wordgroupr|\ellipsis|\endwordgroupr| and
% |\wordgroupl|\ellipsis|\endwordgroupl| can overlap each other.
% However, they cannot overlap themselves.  In other words,
% |\wordgroupr|\ellipsis|\wordgroupl|\ellipsis|\endwordgroupr|\ellipsis|\endwordgroupl|
% is a valid sequence, but
% |\wordgroupr|\ellipsis|\wordgroupr|\ellipsis|\endwordgroupr|\ellipsis|\endwordgroupr|
% is not.
%
% The following example shows how to use |\wordgroupr| and |\endwordgroupr|:
%
% \begin{verbatim}
%       \begin{bytefield}{16}
%         \bitheader{0,7,8,15} \\
%         \wordgroupr{Header}
%           \bitbox{4}{Tag} & \bitbox{12}{Mask} \\
%           \bitbox{8}{Source} & \bitbox{8}{Destination}
%         \endwordgroupr \\
%         \wordbox{3}{Data}
%       \end{bytefield}
% \end{verbatim}
%
% \noindent
% Note the justaposition of |\\| to |\wordgroupr| and |\endwordgroupr|
% in the above.  The resulting figure looks like this:
%
% \begin{bffigure}
%       \begin{bytefield}{16}
%         \bitheader{0,7,8,15} \\
%         \wordgroupr{Header}
%           \bitbox{4}{Tag} & \bitbox{12}{Mask} \\
%           \bitbox{8}{Source} & \bitbox{8}{Destination}
%         \endwordgroupr \\
%         \wordbox{3}{Data}
%       \end{bytefield}
% \end{bffigure}
%
% \noindent
% As a more complex example, the following nests left and right labels:
%
% \begin{verbatim}
%       \begin{bytefield}{16}
%         \bitheader{0,7,8,15} \\
%         \wordgroupr{Header}
%           \bitbox{4}{Tag} & \bitbox{12}{Mask} \\
%           \wordgroupl{Node IDs}
%             \bitbox{8}{Source} & \bitbox{8}{Destination}
%           \endwordgroupl
%         \endwordgroupr \\
%         \wordbox{3}{Data}
%       \end{bytefield}
% \end{verbatim}
%
% \begin{bffigure}
%       \begin{bytefield}{16}
%         \bitheader{0,7,8,15} \\
%         \wordgroupr{Header}
%           \bitbox{4}{Tag} & \bitbox{12}{Mask} \\
%           \wordgroupl{Node IDs}
%             \bitbox{8}{Source} & \bitbox{8}{Destination}
%           \endwordgroupl
%         \endwordgroupr \\
%         \wordbox{3}{Data}
%       \end{bytefield}
% \end{bffigure}
%
% \noindent
% Again, note the justaposition of |\\| to the various word-grouping
% commands in the above.
%
% \begin{decl}
%   |\skippedwords|
% \end{decl}
%
% Draw a graphic representing a number of words that are not shown.
% |\skippedwords| is intended to work with the \meta{sides} argument
% to |\wordbox|.  For example:
%
% \begin{verbatim}
%       \begin{bytefield}{16}
%         \wordbox{1}{Some data} \\
%         \wordbox[lrt]{1}{Lots of data} \\
%         \skippedwords \\
%         \wordbox[lrb]{1}{} \\
%         \wordbox{2}{More data}
%       \end{bytefield}
% \end{verbatim}
%
% \begin{bffigure}
%       \begin{bytefield}{16}
%         \wordbox{1}{Some data} \\
%         \wordbox[lrt]{1}{Lots of data} \\
%         \skippedwords \\
%         \wordbox[lrb]{1}{} \\
%         \wordbox{2}{More data}
%       \end{bytefield}
% \end{bffigure}
%
% \begin{decl}
%   |\bitwidth| \\
%   |\byteheight|
% \end{decl}
%
% The above variables represent the width of each bit and height of each
% byte in the figure.  Change them with |\setlength| to adjust the size
% of the figure.  The default value of |\byteheight| is~|2ex|, and the
% default value of |\bitwidth| is the width of ``|{\tiny 99i}|'',
% i.e.,~the width of a two-digit number plus a small amount of extra space.
% This enables |\bitheader| to show two-digit numbers without overlap.
%
% \begin{decl}
%   |\curlyspace| \\
%   |\labelspace|
% \end{decl}
%
% |\curlyspace| is the space to insert between the figure and the curly
% brace preceding a word group (default: |1ex|).  |\labelspace| is the
% space to insert between the curly brace and the label (default: |0.5ex|).
% Change these with |\setlength| to adjust the spacing.
%
% \begin{decl}
%   |\curlyshrinkage|
% \end{decl}
%
% In \TeX/\LaTeX, the height of a curly brace does not include the tips.
% Hence, in a word group label, the tips of the curly brace will extend
% beyond the height of the word group.  |\curlyshrinkage| is an amount by
% which to reduce the height of curly braces in labels.  It is set to |5pt|,
% and it is extremely unlikely that one would ever need to change it.
% Nevertheless, it is documented here in case the document is typeset with
% a math font containing radically different curly braces from the ones
% that come with \TeX/\LaTeX.
%
% \subsection{Common tricks}
% \label{sec:tricks}
%
% This section shows some clever ways to use \texttt{bytefield}'s commands
% to produce some useful effects.
%
% \paragraph{Odd-sized fields}
% To produce a field that is, say, 1\textonehalf{} words long, use a
% |\bitbox| for the fractional part and specify appropriate values
% for the various \meta{sides} parameters.  For instance:
%
% \begin{verbatim}
%       \begin{bytefield}{16}
%         \bitheader{0,7,8,15} \\
%         \bitbox{8}{8-bit field} & \bitbox[lrt]{8}{} \\
%         \wordbox[lrb]{1}{24-bit field}
%       \end{bytefield}
% \end{verbatim}
%
% \begin{bffigure}
%       \begin{bytefield}{16}
%         \bitheader{0,7,8,15} \\
%         \bitbox{8}{8-bit field} & \bitbox[lrt]{8}{} \\
%         \wordbox[lrb]{1}{24-bit field}
%       \end{bytefield}
% \end{bffigure}
%
% \paragraph{Ellipses}
% To skip words from the middle of enumerated data, put some |\vdots|
% in a |\wordbox| with empty \meta{sides}:
%
% \begin{verbatim}
%       \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}
% \end{verbatim}
%
% \begin{bffigure}
%       \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}
% \end{bffigure}
%
% \noindent
% The extra |1ex| of vertical space helps center the |\vdots| a bit better.
%
% \paragraph{Narrow fields}
% There are a number of options for labeling a narrow field (e.g.,~one
% occupying a single bit):
%
% \newsavebox{\defaultOK}
% \begin{lrbox}{\defaultOK}
%   \begin{bytefield}{8}
%     \bitbox{1}{OK} & \bitbox{7}{Data} \\
%   \end{bytefield}
% \end{lrbox}
%
% \newsavebox{\bitwidthOK}
% \begin{lrbox}{\bitwidthOK}
%   \settowidth{\bitwidth}{OK~}\relax
%   \begin{bytefield}{8}
%     \bitbox{1}{OK} & \bitbox{7}{Data} \\
%   \end{bytefield}
% \end{lrbox}
%
% \newsavebox{\tinyOK}
% \begin{lrbox}{\tinyOK}
%   \begin{bytefield}{8}
%     \bitbox{1}{\tiny OK} & \bitbox{7}{Data} \\
%   \end{bytefield}
% \end{lrbox}
%
% \newsavebox{\verticalOK}
% \begin{lrbox}{\verticalOK}
%   \begin{bytefield}{8}
%     \bitbox{1}{\tiny O \\ K} & \bitbox{7}{Data} \\
%   \end{bytefield}
% \end{lrbox}
%
% \newsavebox{\rotateOK}
% \begin{lrbox}{\rotateOK}
%   \begin{bytefield}{8}
%     \bitbox{1}{\rotatebox{90}{\small OK}} & \bitbox{7}{Data} \\
%   \end{bytefield}
% \end{lrbox}
%
% \bigskip
%
% \begin{tabular}{ll}
%   \emph{Default}: & \raisebox{-4ex}{\usebox{\defaultOK}} \\
%   |\settowidth{\bitwidth}{OK~}|: & \raisebox{-4ex}{\usebox{\bitwidthOK}} \\
%   |\tiny OK|: & \raisebox{-4ex}{\usebox{\tinyOK}} \\
%   |\tiny O \\ K|: & \raisebox{-4ex}{\usebox{\verticalOK}} \\
%   |\rotatebox{90}{\small OK}|: & \raisebox{-4ex}{\usebox{\rotateOK}} \\
% \end{tabular}
%
% \paragraph{Unused bits}
% Because |\width| and |\height| are defined within |\bitbox|es (also
% |\wordbox|es), we can represent unused bits by filling a |\bitbox|
% with a rule of size |\width|~$\times$ |\height|:
%
% \begin{verbatim}
%       \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}
% \end{verbatim}
%
% \begin{bffigure}
%       \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}
% \end{bffigure}
%
% \noindent
% The effect is much better when the \texttt{color} package is used to
% draw the unused bits in color.  (Gray looks nice.)
%
% \begin{verbatim}
%       \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}
% \end{verbatim}
%
% \definecolor{lightgray}{gray}{0.8}
% \begin{bffigure}
%       \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}
% \end{bffigure}
%
% \subsection{Not-so-common tricks}
%
% \paragraph{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:
%
% \begin{verbatim}
%       \begingroup
%         \small
%         \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}
%
%         \settowidth{\byteheight}{~Sign~}
%         \setlength{\bitwidth}{\baselineskip}
%         \begin{bytefield}{32}
%           \bitheader[b]{31,23,0} \\
%           \colorbitbox{lightcyan}{1}{\rotatebox{90}{Sign}} &
%           \colorbitbox{lightgreen}{8}{Exponent} &
%           \colorbitbox{lightred}{23}{Mantissa} \\
%         \end{bytefield}
%       \endgroup
% \end{verbatim}
%
% \begin{center}
% \small
% \newcommand{\colorbitbox}[3]{%
%   \rlap{\bitbox{#2}{\color{#1}\rule{\width}{\height}}}^^A
%   \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}
%
% \settowidth{\byteheight}{~Sign~}
% \setlength{\bitwidth}{\baselineskip}
% \begin{bytefield}{32}
%   \bitheader[b]{31,23,0} \\
%   \colorbitbox{lightcyan}{1}{\rotatebox{90}{Sign}} &
%   \colorbitbox{lightgreen}{8}{Exponent} &
%   \colorbitbox{lightred}{23}{Mantissa} \\
% \end{bytefield}
% \end{center}
%
% \paragraph{Memory-map diagrams}
% While certainly not the intended purpose of the \texttt{bytefield}
% package, one can utilize |\wordbox|es with empty \meta{sides} and
% word labels to produce memory-map diagrams:
%
% \begin{verbatim}
%       \setlength{\byteheight}{4\baselineskip}
%       \newcommand{\descbox}[2]{\parbox[c][3.8\baselineskip]{0.95\width}{%
%         \raggedright #1\vfill #2}}
%       \begin{bytefield}{32}
%         \wordgroupr{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.}}
%         \endwordgroupr \\
%         \wordgroupr{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.}}
%         \endwordgroupr \\
%         \wordgroupr{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.}}
%         \endwordgroupr \\
%         \wordgroupr{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.}}
%         \endwordgroupr \\
% \end{verbatim}
%
% \begin{bffigure}
%       \setlength{\byteheight}{4\baselineskip}
%       \newcommand{\descbox}[2]{\parbox[c][3.8\baselineskip]{0.95\width}{%
%         \raggedright #1\vfill #2}}
%       \begin{bytefield}{32}
%         \wordgroupr{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.}}
%         \endwordgroupr \\
%         \wordgroupr{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.}}
%         \endwordgroupr \\
%         \wordgroupr{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.}}
%         \endwordgroupr \\
%         \wordgroupr{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.}}
%         \endwordgroupr \\
%       \end{bytefield}
% \end{bffigure}
%
%
% \subsection{Putting it all together}
%
% The following code showcases most of \texttt{bytefield}'s features in a
% single figure.
%
% \begin{verbatim}
%       \setlength{\byteheight}{2.5\baselineskip}
%       \begin{bytefield}{32}
%         \bitheader{0,7,8,15,16,23,24,31} \\
%         \wordgroupr{\parbox{6em}{\raggedright These words were taken
%           verbatim from the TCP header definition (RFC~793).}}
%           \bitbox{4}{Data offset} & \bitbox{6}{Reserved} &
%             \bitbox{1}{\tiny U\\R\\G} & \bitbox{1}{\tiny A\\C\\K} &
%             \bitbox{1}{\tiny P\\S\\H} & \bitbox{1}{\tiny R\\S\\T} &
%             \bitbox{1}{\tiny S\\Y\\N} & \bitbox{1}{\tiny F\\I\\N} &
%             \bitbox{16}{Window} \\
%           \bitbox{16}{Checksum} & \bitbox{16}{Urgent pointer}
%         \endwordgroupr \\
%         \wordbox[lrt]{1}{Data octets} \\
%         \skippedwords \\
%         \wordbox[lrb]{1}{} \\
%         \wordgroupl{\parbox{6em}{\raggedright Note that we can display,
%           for example, a misaligned 64-bit value with clever use of the
%           optional argument to \texttt{\textbackslash wordbox} and
%           \texttt{\textbackslash bitbox}.}}
%           \bitbox{8}{Source} & \bitbox{8}{Destination} &
%             \bitbox[lrt]{16}{} \\
%           \wordbox[lr]{1}{Timestamp} \\
%           \wordgroupr{\parbox{6em}{\raggedright Why two Length fields?
%             No particular reason.}}
%             \bitbox[lrb]{16}{} & \bitbox{16}{Length}
%         \endwordgroupl \\
%             \bitbox{6}{Key} & \bitbox{6}{Value} & \bitbox{4}{Unused} &
%               \bitbox{16}{Length}
%           \endwordgroupr \\
%         \wordbox{1}{Total number of 16-bit data words that follow this
%           header word, excluding the subsequent checksum-type value} \\
%         \bitbox{16}{Data~1} & \bitbox{16}{Data~2} \\
%         \bitbox{16}{Data~3} & \bitbox{16}{Data~4} \\
%         \bitbox[]{16}{$\vdots$ \\[1ex]} &
%           \bitbox[]{16}{$\vdots$ \\[1ex]} \\
%         \bitbox{16}{Data~$N-1$} & \bitbox{16}{Data~$N$} \\
%         \bitbox{20}{\[ \mbox{A5A5}_{\mbox{\scriptsize H}} \oplus
%           \left(\sum_{i=1}^N \mbox{Data}_i \right) \bmod 2^{20} \]} &
%           \bitbox{12}{Command} \\
%         \wordbox{2}{64-bit random number}
%       \end{bytefield}
% \end{verbatim}
%
% \noindent
% Figure~\ref{fig:complex-diagram} shows the resulting protocol diagram.
%
% \begin{figure}[phtb]
%       \setlength{\byteheight}{2.5\baselineskip}
%       \begin{bytefield}{32}
%         \bitheader{0,7,8,15,16,23,24,31} \\
%         \wordgroupr{\parbox{6em}{\raggedright These words were taken
%           verbatim from the TCP header definition (RFC~793).}}
%           \bitbox{4}{Data offset} & \bitbox{6}{Reserved} &
%             \bitbox{1}{\tiny U\\R\\G} & \bitbox{1}{\tiny A\\C\\K} &
%             \bitbox{1}{\tiny P\\S\\H} & \bitbox{1}{\tiny R\\S\\T} &
%             \bitbox{1}{\tiny S\\Y\\N} & \bitbox{1}{\tiny F\\I\\N} &
%             \bitbox{16}{Window} \\
%           \bitbox{16}{Checksum} & \bitbox{16}{Urgent pointer}
%         \endwordgroupr \\
%         \wordbox[lrt]{1}{Data octets} \\
%         \skippedwords \\
%         \wordbox[lrb]{1}{} \\
%         \wordgroupl{\parbox{6em}{\raggedright Note that we can display,
%           for example, a misaligned 64-bit value with clever use of the
%           optional argument to \texttt{\textbackslash wordbox} and
%           \texttt{\textbackslash bitbox}.}}
%           \bitbox{8}{Source} & \bitbox{8}{Destination} & \bitbox[lrt]{16}{} \\
%           \wordbox[lr]{1}{Timestamp} \\
%           \wordgroupr{\parbox{6em}{\raggedright Why two Length fields?
%             No particular reason.}}
%             \bitbox[lrb]{16}{} & \bitbox{16}{Length}
%         \endwordgroupl \\
%             \bitbox{6}{Key} & \bitbox{6}{Value} & \bitbox{4}{Unused} &
%               \bitbox{16}{Length}
%           \endwordgroupr \\
%         \wordbox{1}{Total number of 16-bit data words that follow this
%           header word, excluding the subsequent checksum-type value} \\
%         \bitbox{16}{Data~1} & \bitbox{16}{Data~2} \\
%         \bitbox{16}{Data~3} & \bitbox{16}{Data~4} \\
%         \bitbox[]{16}{$\vdots$ \\[1ex]} & \bitbox[]{16}{$\vdots$ \\[1ex]} \\
%         \bitbox{16}{Data~$N-1$} & \bitbox{16}{Data~$N$} \\
%         \bitbox{20}{\[ \mbox{A5A5}_{\mbox{\scriptsize H}} \oplus
%           \left(\sum_{i=1}^N \mbox{Data}_i \right) \bmod 2^{20} \]} &
%           \bitbox{12}{Command} \\
%         \wordbox{2}{64-bit random number}
%       \end{bytefield}
%   \caption{Complex protocol diagram drawn with the \texttt{bytefield}
%     package}
%   \label{fig:complex-diagram}
% \end{figure}
%
%
% \StopEventually{^^A
%
%   \section{Future work}
%
%   \texttt{bytefield} is my first \LaTeX{} package, and, as such, there
%   are a number of macros that could probably have been implemented a lot
%   better.  The package should really get a major rewrite.  If I were to
%   do it all over again, I would probably not use an \cseq\ialign\ for the
%   main \texttt{bytefield} environment.  The problem---as I discovered
%   too late---is that \cseq\begin\ellipsis\cseq\end\ blocks are unable to
%   cross cells of an \cseq\ialign\ (or \texttt{tabular} environment, for
%   that matter).
%
%   That said, I'd like the next major release of \texttt{bytefield} to
%   let the user use \texttt{\cseq\begin\char'173
%   wordgroup\char'175[r]}\ellipsis \texttt{\cseq\end\char'173
%   wordgroup\char'175} instead of
%   \cseq\wordgroupr\ellipsis\cseq\endwordgroupr\ and
%   \texttt{\cseq\begin\char'173 wordgroup\char'175[l]}\ellipsis
%   \texttt{\cseq\end\char'173 wordgroup\char'175} instead of
%   \cseq\wordgroupl\ellipsis\cseq\endwordgroupl.  That would make the
%   word-grouping commands a little more \LaTeX-ish.
%
%   Finally, a minor improvement I'd like to make in the package is to
%   move left, small curly braces closer to the figure.  In the following
%   figure, notice how distant the small curly appears from the figure
%   body:
%
%   \begin{bffigure}
%         \setlength{\byteheight}{4ex}
%         \begin{bytefield}{16}
%           \wordgroupl{Too distant}
%             \wordbox{1}{Something}
%           \endwordgroupl \\
%           \wordgroupl{Looks okay}
%             \wordbox{4}{Something else}
%           \endwordgroupl
%         \end{bytefield}
%   \end{bffigure}
%
%   \noindent
%   The problem is that the curly braces are left-aligned relative to
%   each other, while they should be right-aligned.
% }
%
%
% \section{Implementation}
%
% \newcommand{\usermacro}{\marginpar{\vspace*{1ex}{\hspace{18pt}\huge$\star$}\vspace*{-1ex}}}
%
% This section contains the complete source code for \texttt{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~\smileyface) the \texttt{bytefield} package.
%
% In this section, macros marked in the margin with a ``{\Large $\star$}''
% are intended to be called by the user (and were described in the previous
% section).  All other macros are used only internally by \texttt{bytefield}.
%
%    \begin{macrocode}
%<*package>
%    \end{macrocode}
%
%
% \subsection{Required packages}
%
% Although |\widthof| and |\heightof| were introduced in June~1998,
% te\kern-1.5pt\TeX~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.
% \changes{v1.2a}{2005/07/31}{Specified an explicit package date when
%   loading the \texttt{calc} package to avoid loading an outdated
%   version.  Thanks to Kevin Quick for discovering that outdated versions
%   of \texttt{calc} are still being included in \TeX{} distributions.}
%    \begin{macrocode}
\RequirePackage{calc}[1998/07/07]
%    \end{macrocode}
%
%
% \subsection{Utility macros}
%
% The following macros in this section are used by the box-drawing macros
% and the ``skipped words''-drawing macros.
%
% \begin{macro}{\bf@newdimen}
% \changes{v1.1}{2002/09/15}{Bug fix: Added
%   \texttt{\string\string\string\bf@newdimen} to eliminate ``\texttt{No
%   room for a new \string\string\string\dimen}'' errors (reported by
%   Vitaly A. Repin)}
% |\newdimen| defines new \meta{dimen}s globally.  |\bf@newdimen|
% defines them locally.  It simply merges \LaTeXe's |\newdimen| and
% |\alloc@| macros while omitting |\alloc@|'s ``|\global|'' declaration.
%    \begin{macrocode}
\def\bf@newdimen#1{\advance\count11 by 1
  \ch@ck1\insc@unt\dimen% Check room
  \allocationnumber=\count11
  \dimendef#1=\allocationnumber
  \wlog{\string#1=\string\dimen\the\allocationnumber\space (locally)}}
%    \end{macrocode}
% If we're using $\varepsilon$-\TeX, we have access to many more
% \meta{dimen}s.  The \textsf{etex} package makes these 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 \textsf{etex}'s |\locdimen|.
% \changes{v1.3}{2010/10/31}{Added support for $\varepsilon$-\TeX's larger
%   local \meta{dimen} pool (code provided by Heiko Oberdiek)}
%    \begin{macrocode}
\AtBeginDocument{%
  \begingroup\expandafter\expandafter\expandafter\endgroup
  \expandafter\ifx\csname locdimen\endcsname\relax
  \else
    \let\bf@newdimen\locdimen
  \fi
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\bytefield@height}
% \begin{macro}{\ifcounting@words}
% When |\ifcounting@words| is \textsc{True}, add the height of the next
% \texttt{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.
%    \begin{macrocode}
\newlength{\bytefield@height}
\newif\ifcounting@words
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\inc@bytefield@height}
% We have to define a special macro to increment |\bytefield@height|
% because the \texttt{calc} package's |\addtolength| macro doesn't seem
% to see the global value.  So we |\setlength| a temporary (to get
% \texttt{calc}'s nice infix features) and |\advance| |\bytefield@height|
% by that amount.
%    \begin{macrocode}
\newlength{\bytefield@height@increment}
\DeclareRobustCommand{\inc@bytefield@height}[1]{%
  \setlength{\bytefield@height@increment}{#1}%
  \global\advance\bytefield@height by \bytefield@height@increment}
%    \end{macrocode}
% \end{macro}
%
% \subsection{Top-level environment}
%
% \begin{macro}{bits@wide}
% The number of bits in each word (i.e., the argument to the |\bytefield|
% environment).
%    \begin{macrocode}
\newcounter{bits@wide}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\entire@bytefield@picture}
% A box containing the entire bytefield.  By storing everything in a box
% and then typesetting it later (at the |\end{bytefield}|), we can center
% the bytefield, put a box around it, and do other operations on the entire
% figure.
%    \begin{macrocode}
\newsavebox{\entire@bytefield@picture}
%    \end{macrocode}
% \end{macro}
%
% \begin{environment}{bytefield}
% \usermacro
% Environment containing the layout of bits in a sequence of bytes.
% This is the main environment defined by the \texttt{bytefield} pacakge.
% The argument is the number of bits wide the bytefield should be.
% We turn |&| into a space character so the user can think of a
% \texttt{bytefield} as being analogous to a \texttt{tabular} environment,
% even though we're really setting the bulk of the picture in a single
% column.  (Row labels go in separate columns, however.)
%    \begin{macrocode}
\newenvironment{bytefield}[1]{%
  \setcounter{bits@wide}{#1}%
  \let\old@nl=\\%
  \let\amp=&%
  \catcode`\&=10
  \openup -1pt
  \setlength{\bytefield@height}{0pt}%
  \setlength{\unitlength}{1pt}%
  \counting@wordstrue
  \begin{lrbox}{\entire@bytefield@picture}%
%    \end{macrocode}
% \begin{macro}{\\}
% We redefine |\\| within the |bytefield| environment to make it aware
% of curly braces that surround the protocol diagram.
%    \begin{macrocode}
  \renewcommand{\\}{%
    \amp\show@wordlabelr\cr%
    \ignorespaces\counting@wordstrue\make@lspace\amp}%
%    \end{macrocode}
% \end{macro}
%    \begin{macrocode}
  \vbox\bgroup\ialign\bgroup##\amp##\amp##\cr\amp%
}{%
  \amp\show@wordlabelr\cr\egroup\egroup%
  \end{lrbox}%
  \usebox{\entire@bytefield@picture}}
%    \end{macrocode}
% \end{environment}
%
% \subsection{Box-drawing macros}
%
% \subsubsection{Drawing (proper)}
%
% \begin{macro}{\bitwidth}
% \usermacro
% The width of a single bit.  Note that this is wide enough to display a
% two-digit number without it running into adjacent numbers.  For larger
% words, be sure to |\setlength| this larger.
%    \begin{macrocode}
\newlength{\bitwidth}
\AtBeginDocument{\settowidth{\bitwidth}{\tiny 99i}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\byteheight}
% \usermacro
% The height of a single byte.
%    \begin{macrocode}
\newlength{\byteheight}
\AtBeginDocument{\setlength{\byteheight}{4ex}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\units@wide}
% \begin{macro}{\units@tall}
% Scratch variables for storing the width and height (in points) of
% the box we're about to draw.
%    \begin{macrocode}
\newlength{\units@wide}
\newlength{\units@tall}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\bitbox}
% \usermacro
% Put some text (|#3|) in a box that's 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|).
%    \begin{macrocode}
\DeclareRobustCommand{\bitbox}[3][lrtb]{%
  \setlength{\units@wide}{\bitwidth * #2}%
  \parse@bitbox@arg{#1}%
  \draw@bit@picture{\strip@pt\units@wide}{\strip@pt\byteheight}{#3}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\wordbox}
% \usermacro
% Put some text (|#3|) in a box that's 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|).
%    \begin{macrocode}
\DeclareRobustCommand{\wordbox}[3][lrtb]{%
  \setlength{\units@wide}{\bitwidth * \value{bits@wide}}%
  \setlength{\units@tall}{\byteheight * #2}%
  \parse@bitbox@arg{#1}%
  \draw@bit@picture{\strip@pt\units@wide}{\strip@pt\units@tall}{#3}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\draw@bit@picture}
% Put some text (|#3|) in a box that's 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).
%    \begin{macrocode}
\DeclareRobustCommand{\draw@bit@picture}[3]{%
  \begin{picture}(#1,#2)%
%    \end{macrocode}
% \begin{macro}{\height}
% \begin{macro}{\depth}
% \begin{macro}{\totalheight}
% \begin{macro}{\width}
% \begin{macro}{\widthunits}
% \begin{macro}{\heightunits}
%   First, we plot the user's text, with all sorts of useful lengths
%   predefined.
%    \begin{macrocode}
    \put(0,0){\makebox(#1,#2){\parbox[c]{#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}%
      \centering #3}}}%
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%   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.
%    \begin{macrocode}
    \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}%
%    \end{macrocode}
%   Finally, we indicate that we're 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.
%    \begin{macrocode}
  \ifcounting@words
    \inc@bytefield@height{\unitlength * \real{#2}}%
    \counting@wordsfalse
  \fi
  \ignorespaces}
%    \end{macrocode}
% \end{macro}
%
% \subsubsection{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| \}$.
%
% \begin{macro}{\ifbitbox@top}
% \begin{macro}{\ifbitbox@bottom}
% \begin{macro}{\ifbitbox@left}
% \begin{macro}{\ifbitbox@right}
% These macros are set to \textsc{True} if we're to draw the
% corresponding edge on the subsequent |\bitbox| or |\wordbox|.
%    \begin{macrocode}
\newif\ifbitbox@top
\newif\ifbitbox@bottom
\newif\ifbitbox@left
\newif\ifbitbox@right
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\parse@bitbox@arg}
% This main parsing macro merely resets the above conditionals and
% calls a helper function, |\parse@bitbox@sides|.
%    \begin{macrocode}
\def\parse@bitbox@arg#1{%
  \bitbox@topfalse
  \bitbox@bottomfalse
  \bitbox@leftfalse
  \bitbox@rightfalse
  \parse@bitbox@sides#1X}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\parse@bitbox@sides}
% The helper function for |\parse@bitbox@arg| parses a single letter,
% sets the appropriate conditional to \textsc{True}, and calls itself
% tail-recursively until it sees an ``|X|''.
%    \begin{macrocode}
\def\parse@bitbox@sides#1{%
  \ifx#1X%
  \else
    \ifx#1t%
      \bitbox@toptrue
    \else
      \ifx#1b%
        \bitbox@bottomtrue
      \else
        \ifx#1l%
          \bitbox@lefttrue
        \else
          \ifx#1r%
            \bitbox@righttrue
          \fi
        \fi
      \fi
    \fi
    \expandafter\parse@bitbox@sides
  \fi}
%    \end{macrocode}
% \end{macro}
%
% \subsection{Skipped words}
%
% \begin{macro}{\units@high}
% The height of each diagonal line in the |\skippedwords| graphic.
% Note that |\units@high|~$=$ |\units@tall|~$-$ \textit{optional argument
% to} |\skippedwords|.
%    \begin{macrocode}
\newlength{\units@high}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\skippedwords}
% \usermacro
% Output a fancy graphic representing skipped words.  The optional argument
% is the vertical space between the two diagonal lines (default: |2ex|).
%    \begin{macrocode}
\DeclareRobustCommand{\skippedwords}[1][2ex]{%
  \setlength{\units@wide}{\bitwidth * \value{bits@wide}}%
  \setlength{\units@high}{1pt * \ratio{\units@wide}{6.0pt}}%
  \setlength{\units@tall}{#1 + \units@high}%
  \edef\num@wide{\strip@pt\units@wide}%
  \edef\num@tall{\strip@pt\units@tall}%
  \edef\num@high{\strip@pt\units@high}%
  \begin{picture}(\num@wide,\num@tall)
    \put(0,\num@tall){\line(6,-1){\num@wide}}
    \put(\num@wide,0){\line(-6,1){\num@wide}}
    \put(0,0){\line(0,1){\num@high}}
    \put(\num@wide,\num@tall){\line(0,-1){\num@high}}
  \end{picture}%
  \ifcounting@words
    \inc@bytefield@height{\unitlength * \real{\num@tall}}%
    \counting@wordsfalse
  \fi}
%    \end{macrocode}
% \end{macro}
%
% \subsection{Bit-position labels}
%
% \begin{macro}{\bitheader}
% \usermacro
% Output a header of numbered bit positions. The optional argument (|#1|)
% is ``|l|'' for little-endian (default) or ``|b|'' for big-endian.
% The required argument (|#2|) is a list of bit positions to label.
% It is composed of comma-separated ranges of numbers, for example,
% ``|0-31|'', ``|0,7-8,15-16,23-24,31|'', or even something odd like
% ``|0-7,15-23|''.  Ranges must be specified in increasing order; use the
% optional argument to |\bitheader| to reverse the labels' direction.
%    \begin{macrocode}
\DeclareRobustCommand{\bitheader}[2][l]{%
  \parse@bitbox@arg{lrtb}%
  \setlength{\units@wide}{\bitwidth * \value{bits@wide}}%
  \setlength{\units@tall}{\heightof{\tiny 9}}%
  \setlength{\units@high}{\units@tall * -1}%
  \def\bit@endianness{#1}%
  \begin{picture}(\strip@pt\units@wide,\strip@pt\units@tall)%
                 (0,\strip@pt\units@high)
    \parse@range@list#2,X,
  \end{picture}%
  \ifcounting@words
    \inc@bytefield@height{\unitlength * \real{\strip@pt\units@tall}}%
    \counting@wordsfalse
  \fi
  \ignorespaces}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\parse@range@list}
% Helper function~\#1 for |\bitheader|---parse a comma-separated list of
% ranges, calling |\parse@range| on each range.
% \changes{v1.1}{2002/06/24}{Bug fix: Swapped order of arguments to
%   \texttt{\string\bslash\space ifx} test (suggested by Hans-Joachim
%   Widmaier)}
%    \begin{macrocode}
\def\parse@range@list#1,{%
  \ifx X#1
  \else
    \parse@range#1-#1-#1\relax
    \expandafter\parse@range@list
  \fi}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\header@xpos}
% \begin{macro}{header@val}
% \begin{macro}{max@header@val}
% Miscellaneous variables used internally by |\parse@range|---$x$ position
% of header, current label to output, and maximum label to output ($+ 1$).
%    \begin{macrocode}
\newlength{\header@xpos}
\newcounter{header@val}
\newcounter{max@header@val}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\parse@range}
% Helper function~\#2 for |\bitheader|---parse a hyphen-separated pair
% of numbers (or a single number) and display the number at the correct
% bit position.
%    \begin{macrocode}
\def\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\bit@endianness b%
        \setlength{\header@xpos}{%
          \bitwidth * (\value{bits@wide}-\value{header@val}-1)}
      \else
        \setlength{\header@xpos}{\bitwidth * \value{header@val}}
      \fi
      \put(\strip@pt\header@xpos,0){%
        \makebox(\strip@pt\bitwidth,\strip@pt\units@tall){%
          \tiny \theheader@val}}
      \addtocounter{header@val}{1}
  \repeat}
%    \end{macrocode}
% \end{macro}
%
% \subsection{Word labels}
%
% \subsubsection{Curly-brace manipulation}
%
% \begin{macro}{\curlyshrinkage}
% \usermacro
% Reduce the height of a curly brace by |\curlyshrinkage| so its ends don't
% overlap whatever is above or below it.  The default value (5\,pt.) was
% determined empirically and shouldn't need to be changed.  However,
% on the off-chance the user employs a math font with very different
% curly braces from Computer Modern's, |\curlyshrinkage| can be modified.
%    \begin{macrocode}
\newlength{\curlyshrinkage}
\setlength{\curlyshrinkage}{5pt}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\curlyspace}
% \usermacro
% \begin{macro}{\labelspace}
% \usermacro
% Space to insert before a curly brace and before a word label
% (i.e., after a curly brace).  Because the default values are specified
% in terms of $x$~heights, we wait until the |\begin{document}| to set
% them, after the default font has been selected.
%    \begin{macrocode}
\newlength{\curlyspace}
\AtBeginDocument{\setlength{\curlyspace}{1ex}}
\newlength{\labelspace}
\AtBeginDocument{\setlength{\labelspace}{0.5ex}}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\curly@box}
% Define a box in which to temporarily store formatted curly braces.
% \changes{v1.2}{2004/06/14}{Bug fix: Defined
%   \texttt{\string\string\string\curly@box} globally (suggested by
%     Stefan Ulrich)}
%    \begin{macrocode}
\newbox{\curly@box}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\store@rcurly}
% \begin{macro}{\curly@height}
% \begin{macro}{\half@curly@height}
% \begin{macro}{\curly@shift}
% Store a ``\}'' that's |#2| tall in box |#1|.
% The only unintuitive thing here is that we have to redefine
% |\fontdimen22|---axis height---to~0\,pt.\ before typesetting the curly
% brace.  Otherwise, the brace would be vertically off-center by a few
% points.  When we're finished, we reset it back to its old value.
%    \begin{macrocode}
\def\store@rcurly#1#2{%
  \begingroup
    \bf@newdimen\curly@height%
    \setlength{\curly@height}{#2 - \curlyshrinkage}%
    \bf@newdimen\half@curly@height%
    \setlength{\half@curly@height}{0.5\curly@height}%
    \bf@newdimen\curly@shift%
    \setlength{\curly@shift}{\half@curly@height + 0.5\curlyshrinkage}%
    \global\sbox{#1}{\raisebox{\curly@shift}{%
      $\xdef\old@axis{\the\fontdimen22\textfont2}$%
      $\fontdimen22\textfont2=0pt%
       \left.\vrule height\half@curly@height
                    width 0pt
                    depth\half@curly@height\right\}$%
      $\fontdimen22\textfont2=\old@axis$}}%
  \endgroup
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\store@lcurly}
% \begin{macro}{\curly@height}
% \begin{macro}{\half@curly@height}
% \begin{macro}{\curly@shift}
% Same as |\store@rcurly|, but using a ``\{'' instead of a ``\}''.
%    \begin{macrocode}
\def\store@lcurly#1#2{%
  \begingroup
    \bf@newdimen\curly@height%
    \setlength{\curly@height}{#2 - \curlyshrinkage}%
    \bf@newdimen\half@curly@height%
    \setlength{\half@curly@height}{0.5\curly@height}%
    \bf@newdimen\curly@shift%
    \setlength{\curly@shift}{\half@curly@height + 0.5\curlyshrinkage}%
    \global\sbox{#1}{\raisebox{\curly@shift}{%
      $\xdef\old@axis{\the\fontdimen22\textfont2}$%
      $\fontdimen22\textfont2=0pt%
       \left\{\vrule height\half@curly@height
                     width 0pt
                     depth\half@curly@height\right.$%
      $\fontdimen22\textfont2=\old@axis$}}%
  \endgroup
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \subsubsection{Right-side labels}
%
% \begin{macro}{\show@wordlabelr}
% This macro is output in the third column of every row of the
% |\ialign|ed bytefield table.  It's normally a no-op, but
% |\endwordgroupr| defines it to output the word label and then
% reset itself to a no-op.
%    \begin{macrocode}
\def\show@wordlabelr{}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\wordlabelr@start}
% \begin{macro}{\wordlabelr@end}
% The starting and ending height (in points) of the set of rows to be
% labelled on the right.
%    \begin{macrocode}
\newlength{\wordlabelr@start}
\newlength{\wordlabelr@end}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\wordgroupr}
% \usermacro
% \begin{macro}{\endwordgroupr}
% \usermacro
% Label the words defined between |\wordgroupr| and |\endwordgroupr|
% on the right side of the figure.
% 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.
%    \begin{macrocode}
\newenvironment{wordgroupr}[1]{%
%    \end{macrocode}
% \begin{macro}{\wordlabelr@start}
% \begin{macro}{\wordlabelr@text}
% \begin{macro}{\wordlabelr@end}
% |\wordgroupr| merely stores the starting height in |\wordlabelr@start|
% and the user-supplied text in |\wordlabelr@text|.  |\endwordgroupr|
% does most of the work.
%    \begin{macrocode}
  \global\wordlabelr@start=\bytefield@height
  \gdef\wordlabelr@text{#1}%
  \ignorespaces%
}{%
  \global\wordlabelr@end=\bytefield@height
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \begin{macro}{\show@wordlabelr}
% Redefine |\show@wordlabelr| to output |\curlyspace| space, followed by
% a large curly brace (in |\curlybox|), followed by |\labelspace| space,
% followed by the user's text (previously recorded in |\wordlabelr@text|).
% We typeset |\wordlabelr@text| within a |tabular| environment, so
% \LaTeX\ will calculate its width automatically.
%    \begin{macrocode}
  \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}{%
      \curlyspace +
      \widthof{\usebox{\curly@box}} +
      \labelspace +
      \label@box@width}%
    \begin{picture}(\strip@pt\total@box@width,0)
      \put(0,0){%
        \hspace*{\curlyspace}%
        \usebox{\curly@box}%
        \hspace*{\labelspace}%
        \makebox(\strip@pt\label@box@width,\strip@pt\label@box@height){%
          \usebox{\word@label@box}}}
    \end{picture}%
%    \end{macrocode}
% The last thing |\show@wordlabelr| does is redefine itself back to a no-op.
%    \begin{macrocode}
    \gdef\show@wordlabelr{}}%
  \ignorespaces}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \subsubsection{Left-side labels}
%
% \begin{macro}{\wordlabell@start}
% \begin{macro}{\wordlabell@end}
% The starting and ending height (in points) of the set of rows to be
% labelled on the left.
%    \begin{macrocode}
\newlength{\wordlabell@start}
\newlength{\wordlabell@end}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\total@box@width}
% The total width of the next label to typeset on the left of the figure,
% that is, the aggregate width of the text box, curly brace, and spaces
% on either side of the curly brace.
%    \begin{macrocode}
\newlength{\total@lbox@width}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\make@lspace}
% This macro is output in the first column of every row of the
% |\ialign|ed bytefield table.  It's normally a no-op, but
% |\wordgroupl| defines it to output enough space for the next word
% label and then reset itself to a no-op.
%    \begin{macrocode}
\gdef\make@lspace{}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\wordgroupl}
% \usermacro
% \begin{macro}{\endwordgroupl}
% \usermacro
% Same as |\wordgroupr| and |\endwordgroupr|, but put the label on the left.
% However, the following code is not symmetric to that of |\wordgroupr|
% and |\endwordgroupr|.  The problem is that we encounter |\wordgroupl|
% after entering the second (i.e., figure) column, which doesn't give us
% a chance to reserve space in the first (i.e., left label) column.
% When we reach the |\endwordgroupl|, we know the height of the group of
% words we wish to label.  However, if we try to label the words in the
% subsequent first column, we won't know the vertical offset from the
% ``cursor'' at which to start drawing the label, because we can't know
% the height of the subsequent row until we reach the second
% column.\footnote{Question: Is there a way to push the label up to the
% \emph{top} of the subsequent row, perhaps with
% \texttt{\textbackslash vfill}?}
%
% Our solution is to allocate space for the box the next time we enter a
% first column.  As long as space is eventually allocated, the column
% will expand to fit that space.  |\endwordgroupl| outputs the label
% immediately.  Even though |\endwordgroupl| is called at the end
% of the \emph{second} column, it |\put|s the label at a sufficiently
% negative $x$ location for it to overlap the first column.  Because there
% will eventually be enough space to accomodate the label, we know that
% the label won't overlap the figure or extend beyond the figure boundaries.
%    \begin{macrocode}
\newenvironment{wordgroupl}[1]{%
%    \end{macrocode}
% \begin{macro}{\wordlabell@start}
% \begin{macro}{\wordlabell@text}
% First, we store the starting height and label text, which are needed
% by |\endwordgroupl|.
%    \begin{macrocode}
  \global\wordlabell@start=\bytefield@height
  \gdef\wordlabell@text{#1}%
%    \end{macrocode}
% \end{macro}
% \end{macro}
% Next, we typeset a draft version of the label into |\word@label@box|,
% which we measure (into |\total@lbox@width|) and then discard.
% We can't typeset the final version of the label until we reach the
% |\endwordgroupl|, because that's when we learn the height of the
% word group.  Without knowing the height of the word group, we don't
% how how big to make the curly brace.  In the scratch version, we make
% the curly brace 5\,cm.~tall.  This should be more than large enough to
% reach the maximum curly-brace width, which is all we really care about
% at this point.
%    \begin{macrocode}
  \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}{%
    \curlyspace +
    \widthof{\usebox{\curly@box}} +
    \labelspace +
    \label@box@width}%
  \global\total@lbox@width=\total@lbox@width
%    \end{macrocode}
% 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@width|'s worth of space and then redefine itself
% back to a no-op.
%    \begin{macrocode}
  \gdef\make@lspace{%
    \hspace*{\total@lbox@width}%
    \gdef\make@lspace{}}%
  \ignorespaces%
}{%
%    \end{macrocode}
% |\endwordgroupl| is comparatively straightforward.  We calculate the
% final height of the word group, and then output the label text, followed
% by |\labelspace| space, followed by a curly brace (now that we know how
% tall it's supposed to be), followed by |\curlyspace| space.  The trick,
% as described earlier, is that we typeset the entire label in the second
% column, but in a $0 \times 0$ |picture| environment and with a negative
% horizontal offset (|\starting@point|), thereby making it overlap the
% first column.
%    \begin{macrocode}
  \global\wordlabell@end=\bytefield@height
  \bf@newdimen\starting@point
  \setlength{\starting@point}{%
    -\total@lbox@width - \bitwidth*\value{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*{\labelspace}%
      \usebox{\curly@box}%
      \hspace*{\curlyspace}}
  \end{picture}%
  \ignorespaces}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \subsubsection{Scratch space}
%
% \begin{macro}{\label@box@width}
% \begin{macro}{\label@box@height}
% \begin{macro}{\word@label@box}
% Scratch storage for the width, height, and contents of the word label
% we're about to output.
%    \begin{macrocode}
\newlength{\label@box@width}
\newlength{\label@box@height}
\newsavebox{\word@label@box}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
%    \begin{macrocode}
%</package>
%    \end{macrocode}
%
% \Finale
\endinput
