diff options
Diffstat (limited to 'Master/texmf-dist')
-rw-r--r-- | Master/texmf-dist/source/latex/bytefield/bytefield.dtx | 1559 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/bytefield/bytefield.ins | 51 |
2 files changed, 1610 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/bytefield/bytefield.dtx b/Master/texmf-dist/source/latex/bytefield/bytefield.dtx new file mode 100644 index 00000000000..c5184b28d07 --- /dev/null +++ b/Master/texmf-dist/source/latex/bytefield/bytefield.dtx @@ -0,0 +1,1559 @@ +% \iffalse meta-comment +% +% Copyright (C) 2005 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.3a or later is part of all distributions of LaTeX +% version 2004/10/11 or later. +% +% \fi +% +% \iffalse +%<*driver> +\ProvidesFile{bytefield.dtx} +%</driver> +%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01] +%<package>\ProvidesPackage{bytefield} +%<*package> + [2005/07/31 v1.2a Network protocol diagrams] +%</package> +% +%<*driver> +\documentclass{ltxdoc} +\usepackage{textcomp} +\usepackage{bytefield} +\IfFileExists{hyperref.sty}{% + \usepackage{color} + \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, bitfields, protocol diagrams, LaTeX, 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{599} +% +% \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{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.) +% +% \subsection{Not-so-common tricks} +% +% 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 DLLs, 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 {\small 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 DLLs, 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 {\small 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} +% \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 diff --git a/Master/texmf-dist/source/latex/bytefield/bytefield.ins b/Master/texmf-dist/source/latex/bytefield/bytefield.ins new file mode 100644 index 00000000000..4f762755f2c --- /dev/null +++ b/Master/texmf-dist/source/latex/bytefield/bytefield.ins @@ -0,0 +1,51 @@ +%% +%% Copyright (C) 2005 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.3a or later is part of all distributions of LaTeX version +%% 2004/10/11 or later. +%% + +\input docstrip.tex +\keepsilent + +\usedir{tex/latex/bytefield} + +\preamble + +This is a generated file. + +Copyright (C) 2005 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.3a or later is part of all distributions of LaTeX version +2004/10/11 or later. + +\endpreamble + +\generate{\file{bytefield.sty}{\from{bytefield.dtx}{package}}} + +\Msg{***************************************************************} +\Msg{*} +\Msg{* To finish the installation, move bytefield.sty into a} +\Msg{* directory searched by TeX.} +\Msg{*} +\Msg{* To produce the documentation, run the file bytefield.dtx} +\Msg{* through LaTeX.} +\Msg{*} +\Msg{* Happy TeXing!} +\Msg{***************************************************************} + +\endbatchfile |