From a14b05861d2dd0b4c264b70a4d181f6f8533cedf Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Sat, 29 Jan 2011 23:24:14 +0000 Subject: bytefield 2.0 (30jan11) git-svn-id: svn://tug.org/texlive/trunk@21225 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/doc/latex/bytefield/README | 2 +- .../texmf-dist/doc/latex/bytefield/bf-example.pdf | Bin 0 -> 118948 bytes .../texmf-dist/doc/latex/bytefield/bf-example.tex | 496 +++++ .../texmf-dist/doc/latex/bytefield/bytefield.pdf | Bin 267485 -> 375344 bytes Master/texmf-dist/doc/latex/bytefield/example.pdf | Bin 124895 -> 0 bytes Master/texmf-dist/doc/latex/bytefield/example.tex | 500 ----- .../source/latex/bytefield/bytefield.dtx | 1901 ++++++++++++++++---- .../source/latex/bytefield/bytefield.ins | 4 +- .../texmf-dist/tex/latex/bytefield/bytefield.sty | 262 ++- 9 files changed, 2200 insertions(+), 965 deletions(-) create mode 100644 Master/texmf-dist/doc/latex/bytefield/bf-example.pdf create mode 100644 Master/texmf-dist/doc/latex/bytefield/bf-example.tex delete mode 100644 Master/texmf-dist/doc/latex/bytefield/example.pdf delete mode 100644 Master/texmf-dist/doc/latex/bytefield/example.tex (limited to 'Master') diff --git a/Master/texmf-dist/doc/latex/bytefield/README b/Master/texmf-dist/doc/latex/bytefield/README index 66ba8b7a5bd..24710fe8d9b 100644 --- a/Master/texmf-dist/doc/latex/bytefield/README +++ b/Master/texmf-dist/doc/latex/bytefield/README @@ -34,7 +34,7 @@ hyperref hyperlinks. Copyright and license --------------------- -Copyright (C) 2010 Scott Pakin, scott+bf@pakin.org +Copyright (C) 2011 Scott Pakin, scott+bf@pakin.org This package may be distributed and/or modified under the conditions of the LaTeX Project Public License, either version 1.3a of this diff --git a/Master/texmf-dist/doc/latex/bytefield/bf-example.pdf b/Master/texmf-dist/doc/latex/bytefield/bf-example.pdf new file mode 100644 index 00000000000..44f931eea43 Binary files /dev/null and b/Master/texmf-dist/doc/latex/bytefield/bf-example.pdf differ diff --git a/Master/texmf-dist/doc/latex/bytefield/bf-example.tex b/Master/texmf-dist/doc/latex/bytefield/bf-example.tex new file mode 100644 index 00000000000..1604261a2c1 --- /dev/null +++ b/Master/texmf-dist/doc/latex/bytefield/bf-example.tex @@ -0,0 +1,496 @@ +\documentclass[11pt]{article} +\usepackage[margin=1in]{geometry} +\usepackage{longtable} +\usepackage[bitheight=6ex]{bytefield} +\usepackage{color} +\usepackage[bookmarksopen=true]{hyperref} + +\title{Integrating \texttt{bytefield} and \texttt{hyperref}} +\author{\href{http://www.pakin.org/~scott}{Scott Pakin + \texttt{}}} +\date{18 January 2011} +\hypersetup{% +pdftitle={Integrating bytefield and hyperref}, +pdfauthor={Scott Pakin }, +pdfsubject={Example of bytefield package}, +pdfkeywords={bytefield, hyperref, multicast transport protocol, hyperlink, example}} + +% Set up hyperlink colors +\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{% + colorlinks=true, + citecolor=darkblue, + urlcolor=darkgreen, + linkcolor=darkred, + menucolor=darkbrown} + +\begin{document} +\sloppy +\maketitle + +\begin{abstract} +This document is a demonstration of how the \texttt{bytefield} package can +integrate seamlessly with \texttt{hyperref}. The text that follows was +copy-and-pasted from +\href{http://www.rfc-editor.org/rfc/rfc1301.txt}{RFC~1301, ``Multicast +Transport Protocol''}~\cite{Armstrong92}. + +The important thing to note is the way the fields in the protocol diagrams +(drawn with \texttt{bytefield}) are hyperlinked to their descriptions (with +\texttt{hyperref}). Few typesetting systems enable authors to specify +hyperlinks from within a figure to the surrounding text. Fewer still do +not require hyperlinks to be re-specified when the figure changes. +\texttt{bytefield}~+ \texttt{hyperref} can do both. +\end{abstract} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\setcounter{section}{1} + +\section{Protocol description} + + MTP is a transport in that it is a client of the network layer (as + defined by the OSI networking model).\footnote{The network layer is not + specified by MTP. One of the goals is to specify a transport that can be + implemented with equal functionality on many network architectures.} + MTP provides reliable delivery of client data between one or more + communicating processes, as well as a predefined principal process. The + collection of processes is called a web. + + In addition to transporting data reliably and efficiently, MTP + provides the synchronization necessary for web members to agree on + the order of receipt of all messages and can agree on the delivery of + the message even in the face of partitions. This ordering and + agreement protocol uses serialized tokens granted by the master to + producers. + + The processes may have any one of three levels of capability. One + member must be the master. The master instantiates and controls the + behavior of the web, including its membership and performance. Non + master members may be either producer/consumers or pure consumers. + The former class of member is permitted to transmit user data to the + entire membership (and expected to logically hear itself), while the + latter is prohibited from transmitting user data. + + MTP is a negative acknowledgement protocol, exploiting the highly + reliable delivery of the local area and wide area network + technologies of today. Successful delivery of data is accepted by + consuming stations silently rather than having the successful + delivery noted to the producing process, thus reducing the amount of + reverse traffic required to maintain synchronization. + +\subsection{Definition of terms} + +\begin{center} + \fbox{Skipped; see~\cite{Armstrong92}} +\end{center} + +\subsection{Packet format} + + An MTP packet consists of a transport protocol header followed by a + variable amount of data. The protocol header, shown in + Figure~\ref{fig:packet-format}, is part of every packet. The remainder + of the packet is either user data (packet type = data) or additional + transport specific information. The fields in the header are statically + defined as n-bit wide quantities. There are no undefined fields or + fields that may at any time have undefined values. Reserved fields, if + they exist, must always have a value of zero. + +\begin{figure}[htbp] + \centering + \begin{bytefield}{32} + \bitheader{0,7-8,15-16,23-24,31} \\ + + \begin{rightwordgroup}{transport \\ header} + % We have to do the \parbox explicitly in the next line because + % \hyperlink typesets its argument in horizontal mode. + \bitbox{8}{\hyperlink{protocol-version}{\parbox{\width}{\centering protocol version}}} & + \bitbox{8}{\hyperlink{packet-type-modifier}{packet type}} & + \bitbox{8}{\hyperlink{packet-type-modifier}{type modifier}} & + \bitbox{8}{\hyperlink{subchannel}{client channel}} \\ + + \wordbox{1}{\hyperlink{source-connect}{source connection identifier}} \\ + + \wordbox{1}{\hyperlink{dest-connect}{destination connection identifier}} \\ + + \wordbox{1}{\hyperlink{msg-accept}{message acceptance criteria}} \\ + + \wordbox{1}{\hyperlink{heartbeat}{heartbeat}} \\ + + \bitbox{16}{\hyperlink{window}{window}} & + \bitbox{16}{\hyperlink{retention}{retention}} + \end{rightwordgroup} \\ + + \begin{rightwordgroup}{data \\ fields} + \wordbox[lrt]{1}{% + \parbox{0.6\width}{\centering (data content and format dependent on packet type and modifier)}} \\ + \skippedwords \\ + \wordbox[lrb]{1}{} + \end{rightwordgroup} + \end{bytefield} + \caption{MTP packet format} + \label{fig:packet-format} +\end{figure} + +\hypertarget{protocol-version}{\subsubsection{Protocol version}} + + The first 8 bits of the packet are the protocol version number. This + document describes version 1 of the Multicast Transport Protocol and + thus the version field has a value of 0x01. + +\hypertarget{packet-type-modifier}{\subsubsection{Packet type and modifier}} + + The second byte of the header is the packet type and the following + byte contains the packet type modifier. Typical control message + exchanges are in a request/response pair. The modifier field + simplifies the construction of responses by permitting reuse of the + incoming message with minimal modification. The following table gives + the packet type field values along with their modifiers. The + modifiers are valid only in the context of the type. In the prose of + the definitions and later in the document, the syntax for referring + to one of the entries described in the following table will be + type[modifier]. For example, a reference to data[eow] would be a + packet of type data with an end of window modifier. + +\begin{center} +\renewcommand{\arraystretch}{1.5} +\begin{longtable}{llp{0.6\textwidth}} + type & modifier & description \\ \hline + + data(0) & data(0) & The packet is one that contains user + information. Only the process possessing a + transmit token is permitted to send data + unless specifically requested to retransmit + previously transmitted data. All packets of + type data are multicast to the entire web. \\ + + & eow(1) & A data packet with the eow (end of window) + modifier set indicates that the transmitter + intends to send no more packets in this + heartbeat either because it has sent as many + as permitted given the window parameter or + simply has no more data to send during the + current heartbeat. This is not client + information but rather a hint to be used by + transport providers to synchronize the + computation and transmission of naks. \\ + + & eom(2) & Data[eom] marks the end of the message to the + consumers, and the surrendering of the + transmit token to the master. And like a + data[eow] a data[eom] packet implies the end + of window. \\ + nak(1) & request(0) & A nak[request] packet is a consumer + requesting a retransmission of one or more + data packets. The data field contains an + ordered list of packet sequence numbers that + are being requested. Naks of any form are + always unicast. \\ + + & deny(1) & A nak[deny] message indicates that the + producer source of the nak[deny]) cannot + retransmit one or more of the packets + requested. The process receiving the + nak[deny] must report the failure to its + client. \\ + + empty(2) & dally(0) & An empty[dally] packet is multicast to + maintain synchronization when no client data + is available. \\ + + & cancel(1) & If a producer finds itself in possession of a + transmit token and has no data to send, it + may cancel the token[request] by multicasting + an empty[cancel] message. \\ + + & hibernate(2)&If the master possesses all of the web's + transmit tokens and all outstanding messages + have been accepted or rejected, the master + may transmit empty[hibernate] packets at a + rate significantly slower than indicated by + the web's value of heartbeat. \\ + + join(3) & request(0) & A join[request] packet is sent by a process + wishing to join a web to the web's unknown + TSAP (see section~\ref{sec:dest-connect}). \\ + + & confirm(1) & The join[confirm] packet is the master's + confirmation of the destination's request to + join the web. It will be unicast by the + master (and only the master) to the station + that sent the join[request]. \\ + + & deny(2) & A join[deny] packet indicates permission to + join the web was denied. It may only be + transmitted by the master and will be unicast + to the member that sent the join[request]. \\ + + quit(4) & request(0) & A quit[request] may be unicast to the master + by any member of the web at any time to + indicate the sending process wishes to + withdraw from the web. Any member may unicast + a quit to another member requesting that the + destination member quit the web due to + intolerable behavior. The master may + multicast a quit[request] requiring that the + entire web disband. The request will be + multicast at regular heartbeat intervals + until there are no responses to retention + requests. \\ + + & confirm(1) & The quit[confirm] packet is the indication + that a quit[request] has been observed and + appropriate local action has been taken. + Quit[confirm] are always unicast. \\ + + token(5) & request(0) & A token[request] is a producing member + requesting a transmit token from the master. + Such packets are unicast to the master. \\ + + & confirm(1) & The token[confirm] packet is sent by the + master to assign the transmit token to a + member that has requested it. token[confirm] + will be unicast to the member being granted + the token. \\ + + isMember(6)&request(0)& An isMember[request] is soliciting + verification that the target member is a + recognized member of the web. All forms of + the isMember packet are unicast to a specific + member. \\ + + & confirm(1) & IsMember[confirm] packets are positive + responses to isMember[requests]. \\ + + & deny(2) & If the member receiving the isMember[request] + cannot confirm the target's membership in the + web, it responds with a isMember[deny]. +\end{longtable} +\end{center} + +\hypertarget{subchannel}{\subsubsection{Subchannel}} + + The fourth byte of the transport header contains the client's + subchannel value. The default value of the subchannel field is zero. + Semantics of the subchannel value are defined by the transport client + and therefore are only applicable to packets of type data. All other + packet types must have a subchannel value of zero. + +\hypertarget{source-connect}{\subsubsection{Source connection identifier}} + + The source connection identifier field is a 32 bit field containing a + transmitting system unique value assigned at the time the transport + is created. The field is used in identifying the particular transport + instantiation and is a component of the TSAP\@. Every packet + transmitted by the transport must have this field set. + +\hypertarget{dest-connect}{\subsubsection{Destination connection identifier}} +\label{sec:dest-connect} + + The destination connection identifier is the 32 bit identifier of the + target transport. From the point of view of a process sending a + packet, there are three types of destination connection identifiers. + First, there is the unknown connection identifier (0x00000000). The + unknown value is used only as the destination connection identifier + in the join[request] packet. + + Second, there is the multicast connection identifier gleaned from the + join[confirm] message sent by the master. The multicast connection + identifier is used in conjunction with the multicast NSAP to form the + destination TSAP of all packets multicast to the entire + web.\footnote{There's only one such multicast connection identifier per + web. If there are multiple processes on the same machine participating + in a web, the transport must descriminate between those processes by + using the connnection identifier.} + + The last class of connection identifier is a unicast identifier and + is used to form the destination TSAP when unicasting packets to + individual members. Every member of the web has associated with it a + unicast connection identifier that is used to form its own unicast + TSAP. + +\hypertarget{msg-accept}{\subsubsection{Message acceptance}} + + MTP ensures that all processes agree on which messages are accepted + and in what order they are accepted. The master controls this aspect + of the protocol by controlling allocation of transmit tokens and + setting the status of messages. Once a token for a message has been + assigned (see section 3.2.1) the master sets the status of that + message according to the following rules~\cite{Armstrong91}: + + \begin{itemize} + \item If the master has seen the entire message (i.e., has seen the + data[eom] and all intervening data packets), the status is accepted. + + \item If the master has not seen the entire message but believes the + message sender is still operational and connected to the master (as + determined by the master), the status is pending. + + \item If the master has not seen the entire message and believes the + sender to have failed or partitioned away, the status is rejected. + \end{itemize} + + Message status is carried in the message acceptance record (see + Figure~\ref{fig:msg-accept}) of every packet, and processes learn the + status of earlier messages by processing this information. + + The acceptance criteria is a multiple part record that carries the rules + of agreement to determine the message acceptance. + \hypertarget{synchro}{The most significant 8 bits is a flag that, if not + zero, indicates synchronization is required.} The field may vary on a + per message basis as directed by producing transport's client. The + default is that no synchronization is required. + + \hypertarget{tri-state}{The second part of the record is a 12 element + vector that represents the status of the last 12 messages transmitted + into the web.} + +\begin{figure}[htbp] + \centering + \begin{bytefield}{32} + \bitheader{0,7-8,15-16,23-24,31} \\ + + \bitbox{8}{\hyperlink{synchro}{synchro}} & + \bitbox{24}{\hyperlink{tri-state}{tri-state bitmask{[12]}}} \\ + + \bitbox{16}{\hyperlink{msg-seq}{message sequence number}} & + \bitbox{16}{\hyperlink{packet-seq}{packet sequence number}} + \end{bytefield} + \caption{Message acceptance record} + \label{fig:msg-accept} +\end{figure} + + Each element of the array is two bits in length and may have one of + three values: accepted(0), pending(1) or rejected(2). Initially, the + bit mask is set to all zeros. When the token for message $m$ is + transmitted, the first (left-most) element of the vector represents + the the state of message $m - 1$, the second element of the vector is + the status of message $m - 2$, and so forth. Therefore the status of + the last 12 messages are visible, the status of older messages are + lost, logically by shifting the elements out of the vector. Only the + master is permitted to set the status of messages. The master is not + permitted to shift a status of pending beyond the end of the vector. + If that situation arises, the master must instead not confirm any + token[request] until the oldest message can be marked as either + rejected or accepted. + + \hypertarget{msg-seq}{Message sequence numbers are 16 bit unsigned + values.} The field is initialized to zero by the master when the + transport is initialized, and incremented by one after each token is + granted. Only the master is permitted to change the value of the message + sequence number. Once granted, that message sequence number is consumed + and the state of the message must eventually become either accepted or + rejected. No transmit tokens may be granted if the assignment of a + message sequence number that would cause a value of pending to be + shifted beyond the end of the status vector. + + \hypertarget{packet-seq}{Packet sequence numbers are unsigned 16 bit + numbers assigned by the producing process on a per message basis.} + Packet sequence numbers start at a value of zero for each new message + and are incremented by one (consumed) for each data packet making up the + message. Consumers detecting missing packet sequence numbers must send a + nak[request] to the appropriate producer to recover the missed data. + + Control packets always contain the message acceptance criteria with a + synchronization flag set to zero (0x00), the highest message sequence + number observed and a packet sequence number one greater than + previously observed. Control packets do not consume any sequence + numbers. Since control messages are not reliably delivered, the + acceptance criteria should only be checked to see if they fall within + the proper range of message numbers, relative to the current message + number of the receiving station. The range of acceptable sequence + numbers should be $m-11$ to $m-13$, inclusive, where $m$ is the current + message number. + +\hypertarget{heartbeat}{\subsubsection{Heartbeat}} + + Heartbeat is an unsigned 32 bit field that has the units of + milliseconds. The value of heartbeat is shared by all members of the + web. By definition at least one packet (either data, empty or quit + from the master) will be multicast into the web within every + heartbeat period. + +\hypertarget{window}{\subsubsection{Window}} + + The allocation window (or simply window) is a 16 bit unsigned field + that indicates the maximum number of data packets that can be + multicasted by a member in a single heartbeat. It is the sum of the + retransmitted and new data packets. + +\hypertarget{retention}{\subsubsection{Retention}} + + The retention field is a 16 bit unsigned value that is the number of + heartbeats for which a producer must retain transmitted client data + and state for the purpose of retransmission. + +\subsection{Transport addresses} + + Associated with each transport are logically three transport service + access points (TSAP), logically formed by the concatenation of a + network service access point (NSAP) and a transport connection + identifier. These TSAPs are the unknown TSAP, the web's multicast + TSAP and each individual member's TSAP. + +\subsubsection{Unknown transport address} + + Stations that are just joining must use the multicast NSAP associated + with the transport, but are not yet aware of either the web's + multicast TSAP the master process' TSAP\@. Therefore, joining stations + fabricate a temporary TSAP (referred to as a unknown TSAP) by using a + connection identifier reserved to mean unknown (0x00000000). The + join[confirm] message will be sourced from the master's TSAP and will + include the multicast transport connection identifier in the data + field. Those values must be extracted from the join[confirm] and + remembered by the joining process. + +\subsubsection{Web's multicast address} + + The multicast TSAP is formed by logically concatenating the multicast + NSAP associated with the transport creation and the transport + connection identifier returned in the data field of the join[confirm] + packet. If more than one network is involved in the web, then the + multicast transport address becomes a list, one for each network + represented. This list is supplied in the data field of + token[confirm] packets. + + The multicast TSAP is used as the target for all messages that are + destined to the entire web, such as data and empty. The master's + decision to abandon the transport (quit) is also sent to the + multicast transport address. + +\subsubsection{Member addresses} + + The member TSAP is formed by using the process' unicast NSAP + concatenated with a locally generated unique connection identifier. + That TSAP must be the source of every packet transmitted by the + process, regardless of its destination, for the lifetime of the + transport. + + Packets unicast to specific members must contain the appropriate + TSAP\@. For producers and consumers this is not difficult. The only + TSAPs of interest are the master and the station(s) currently + transmitting data. + + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\begin{thebibliography}{AFM91} +\bibitem[AFM91]{Armstrong91} +S.~Armstrong, A.~Freier, and K.~Marzullo. +\emph{MTP: An atomic multicast transport protocol}. +Xerox Webster Research Center technical report X9100359, +March 1991. + +\bibitem[AFM92]{Armstrong92} +S.~Armstrong, A.~Freier, and K.~Marzullo. +\emph{Multicast transport protocol}. +RFC 1301, Internet Engineering Task Force, February 1992. +Available from \url{http://www.rfc-editor.org/rfc/rfc1301.txt}. +\end{thebibliography} + +\end{document} diff --git a/Master/texmf-dist/doc/latex/bytefield/bytefield.pdf b/Master/texmf-dist/doc/latex/bytefield/bytefield.pdf index e2d1e3bbcf0..b00314cce3e 100644 Binary files a/Master/texmf-dist/doc/latex/bytefield/bytefield.pdf and b/Master/texmf-dist/doc/latex/bytefield/bytefield.pdf differ diff --git a/Master/texmf-dist/doc/latex/bytefield/example.pdf b/Master/texmf-dist/doc/latex/bytefield/example.pdf deleted file mode 100644 index 57d9108c361..00000000000 Binary files a/Master/texmf-dist/doc/latex/bytefield/example.pdf and /dev/null differ diff --git a/Master/texmf-dist/doc/latex/bytefield/example.tex b/Master/texmf-dist/doc/latex/bytefield/example.tex deleted file mode 100644 index 1c69023fdcd..00000000000 --- a/Master/texmf-dist/doc/latex/bytefield/example.tex +++ /dev/null @@ -1,500 +0,0 @@ -\documentclass[11pt]{article} -\usepackage{fullpage} -\usepackage{longtable} -\usepackage{bytefield} -\usepackage{color} -\usepackage[bookmarksopen=true]{hyperref} - -\title{Integrating \texttt{bytefield} and \texttt{hyperref}} -\author{\href{http://www.pakin.org/~scott}{Scott Pakin - \texttt{}}} -\date{21 June 2000} -\hypersetup{% -pdftitle={Integrating bytefield and hyperref}, -pdfauthor={Scott Pakin }, -pdfsubject={Example of bytefield package}, -pdfkeywords={bytefield, hyperref, multicast transport protocol, hyperlink, example}} - -% Set up hyperlink colors -\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{% - colorlinks=true, - citecolor=darkblue, - urlcolor=darkgreen, - linkcolor=darkred, - menucolor=darkbrown} - -\begin{document} -\sloppy -\maketitle - -\begin{abstract} -This document is a demonstration of how the \texttt{bytefield} package can -integrate seamlessly with \texttt{hyperref}. The text that follows was -copy-and-pasted from -\href{http://www.rfc-editor.org/rfc/rfc1301.txt}{RFC~1301, ``Multicast -Transport Protocol''}~\cite{Armstrong92}. - -The important thing to note is the way the fields in the protocol diagrams -(drawn with \texttt{bytefield}) are hyperlinked to their descriptions (with -\texttt{hyperref}). Few typesetting systems enable authors to specify -hyperlinks from within a figure to the surrounding text. Fewer still do -not require hyperlinks to be re-specified when the figure changes. -\texttt{bytefield}~+ \texttt{hyperref} can do both. -\end{abstract} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\setcounter{section}{1} - -\section{Protocol description} - - MTP is a transport in that it is a client of the network layer (as - defined by the OSI networking model).\footnote{The network layer is not - specified by MTP. One of the goals is to specify a transport that can be - implemented with equal functionality on many network architectures.} - MTP provides reliable delivery of client data between one or more - communicating processes, as well as a predefined principal process. The - collection of processes is called a web. - - In addition to transporting data reliably and efficiently, MTP - provides the synchronization necessary for web members to agree on - the order of receipt of all messages and can agree on the delivery of - the message even in the face of partitions. This ordering and - agreement protocol uses serialized tokens granted by the master to - producers. - - The processes may have any one of three levels of capability. One - member must be the master. The master instantiates and controls the - behavior of the web, including its membership and performance. Non - master members may be either producer/consumers or pure consumers. - The former class of member is permitted to transmit user data to the - entire membership (and expected to logically hear itself), while the - latter is prohibited from transmitting user data. - - MTP is a negative acknowledgement protocol, exploiting the highly - reliable delivery of the local area and wide area network - technologies of today. Successful delivery of data is accepted by - consuming stations silently rather than having the successful - delivery noted to the producing process, thus reducing the amount of - reverse traffic required to maintain synchronization. - -\subsection{Definition of terms} - -\begin{center} - \fbox{Skipped; see~\cite{Armstrong92}} -\end{center} - -\subsection{Packet format} - - An MTP packet consists of a transport protocol header followed by a - variable amount of data. The protocol header, shown in - Figure~\ref{fig:packet-format}, is part of every packet. The remainder - of the packet is either user data (packet type = data) or additional - transport specific information. The fields in the header are statically - defined as n-bit wide quantities. There are no undefined fields or - fields that may at any time have undefined values. Reserved fields, if - they exist, must always have a value of zero. - -\begin{figure}[htbp] - \begin{center} - \setlength{\byteheight}{6ex} - \begin{bytefield}{32} - \bitheader{0,7-8,15-16,23-24,31} \\ - - \wordgroupr{transport \\ header} - % We have to do the \parbox explicitly in the next line because - % \hyperlink typesets its argument in horizontal mode. - \bitbox{8}{\hyperlink{protocol-version}{\parbox{\width}{\centering protocol version}}} & - \bitbox{8}{\hyperlink{packet-type-modifier}{packet type}} & - \bitbox{8}{\hyperlink{packet-type-modifier}{type modifier}} & - \bitbox{8}{\hyperlink{subchannel}{client channel}} \\ - - \wordbox{1}{\hyperlink{source-connect}{source connection identifier}} \\ - - \wordbox{1}{\hyperlink{dest-connect}{destination connection identifier}} \\ - - \wordbox{1}{\hyperlink{msg-accept}{message acceptance criteria}} \\ - - \wordbox{1}{\hyperlink{heartbeat}{heartbeat}} \\ - - \bitbox{16}{\hyperlink{window}{window}} & - \bitbox{16}{\hyperlink{retention}{retention}} - \endwordgroupr \\ - - \wordgroupr{data \\ fields} - \wordbox[lrt]{1}{% - \parbox{0.6\width}{\centering (data content and format dependent on packet type and modifier)}} \\ - \skippedwords \\ - \wordbox[lrb]{1}{} - \endwordgroupr - \end{bytefield} - \end{center} - \caption{MTP packet format} - \label{fig:packet-format} -\end{figure} - -\hypertarget{protocol-version}{\subsubsection{Protocol version}} - - The first 8 bits of the packet are the protocol version number. This - document describes version 1 of the Multicast Transport Protocol and - thus the version field has a value of 0x01. - -\hypertarget{packet-type-modifier}{\subsubsection{Packet type and modifier}} - - The second byte of the header is the packet type and the following - byte contains the packet type modifier. Typical control message - exchanges are in a request/response pair. The modifier field - simplifies the construction of responses by permitting reuse of the - incoming message with minimal modification. The following table gives - the packet type field values along with their modifiers. The - modifiers are valid only in the context of the type. In the prose of - the definitions and later in the document, the syntax for referring - to one of the entries described in the following table will be - type[modifier]. For example, a reference to data[eow] would be a - packet of type data with an end of window modifier. - -\begin{center} -\renewcommand{\arraystretch}{1.5} -\begin{longtable}{llp{0.6\textwidth}} - type & modifier & description \\ \hline - - data(0) & data(0) & The packet is one that contains user - information. Only the process possessing a - transmit token is permitted to send data - unless specifically requested to retransmit - previously transmitted data. All packets of - type data are multicast to the entire web. \\ - - & eow(1) & A data packet with the eow (end of window) - modifier set indicates that the transmitter - intends to send no more packets in this - heartbeat either because it has sent as many - as permitted given the window parameter or - simply has no more data to send during the - current heartbeat. This is not client - information but rather a hint to be used by - transport providers to synchronize the - computation and transmission of naks. \\ - - & eom(2) & Data[eom] marks the end of the message to the - consumers, and the surrendering of the - transmit token to the master. And like a - data[eow] a data[eom] packet implies the end - of window. \\ - nak(1) & request(0) & A nak[request] packet is a consumer - requesting a retransmission of one or more - data packets. The data field contains an - ordered list of packet sequence numbers that - are being requested. Naks of any form are - always unicast. \\ - - & deny(1) & A nak[deny] message indicates that the - producer source of the nak[deny]) cannot - retransmit one or more of the packets - requested. The process receiving the - nak[deny] must report the failure to its - client. \\ - - empty(2) & dally(0) & An empty[dally] packet is multicast to - maintain synchronization when no client data - is available. \\ - - & cancel(1) & If a producer finds itself in possession of a - transmit token and has no data to send, it - may cancel the token[request] by multicasting - an empty[cancel] message. \\ - - & hibernate(2)&If the master possesses all of the web's - transmit tokens and all outstanding messages - have been accepted or rejected, the master - may transmit empty[hibernate] packets at a - rate significantly slower than indicated by - the web's value of heartbeat. \\ - - join(3) & request(0) & A join[request] packet is sent by a process - wishing to join a web to the web's unknown - TSAP (see section~\ref{sec:dest-connect}). \\ - - & confirm(1) & The join[confirm] packet is the master's - confirmation of the destination's request to - join the web. It will be unicast by the - master (and only the master) to the station - that sent the join[request]. \\ - - & deny(2) & A join[deny] packet indicates permission to - join the web was denied. It may only be - transmitted by the master and will be unicast - to the member that sent the join[request]. \\ - - quit(4) & request(0) & A quit[request] may be unicast to the master - by any member of the web at any time to - indicate the sending process wishes to - withdraw from the web. Any member may unicast - a quit to another member requesting that the - destination member quit the web due to - intolerable behavior. The master may - multicast a quit[request] requiring that the - entire web disband. The request will be - multicast at regular heartbeat intervals - until there are no responses to retention - requests. \\ - - & confirm(1) & The quit[confirm] packet is the indication - that a quit[request] has been observed and - appropriate local action has been taken. - Quit[confirm] are always unicast. \\ - - token(5) & request(0) & A token[request] is a producing member - requesting a transmit token from the master. - Such packets are unicast to the master. \\ - - & confirm(1) & The token[confirm] packet is sent by the - master to assign the transmit token to a - member that has requested it. token[confirm] - will be unicast to the member being granted - the token. \\ - - isMember(6)&request(0)& An isMember[request] is soliciting - verification that the target member is a - recognized member of the web. All forms of - the isMember packet are unicast to a specific - member. \\ - - & confirm(1) & IsMember[confirm] packets are positive - responses to isMember[requests]. \\ - - & deny(2) & If the member receiving the isMember[request] - cannot confirm the target's membership in the - web, it responds with a isMember[deny]. -\end{longtable} -\end{center} - -\hypertarget{subchannel}{\subsubsection{Subchannel}} - - The fourth byte of the transport header contains the client's - subchannel value. The default value of the subchannel field is zero. - Semantics of the subchannel value are defined by the transport client - and therefore are only applicable to packets of type data. All other - packet types must have a subchannel value of zero. - -\hypertarget{source-connect}{\subsubsection{Source connection identifier}} - - The source connection identifier field is a 32 bit field containing a - transmitting system unique value assigned at the time the transport - is created. The field is used in identifying the particular transport - instantiation and is a component of the TSAP\@. Every packet - transmitted by the transport must have this field set. - -\hypertarget{dest-connect}{\subsubsection{Destination connection identifier}} -\label{sec:dest-connect} - - The destination connection identifier is the 32 bit identifier of the - target transport. From the point of view of a process sending a - packet, there are three types of destination connection identifiers. - First, there is the unknown connection identifier (0x00000000). The - unknown value is used only as the destination connection identifier - in the join[request] packet. - - Second, there is the multicast connection identifier gleaned from the - join[confirm] message sent by the master. The multicast connection - identifier is used in conjunction with the multicast NSAP to form the - destination TSAP of all packets multicast to the entire - web.\footnote{There's only one such multicast connection identifier per - web. If there are multiple processes on the same machine participating - in a web, the transport must descriminate between those processes by - using the connnection identifier.} - - The last class of connection identifier is a unicast identifier and - is used to form the destination TSAP when unicasting packets to - individual members. Every member of the web has associated with it a - unicast connection identifier that is used to form its own unicast - TSAP. - -\hypertarget{msg-accept}{\subsubsection{Message acceptance}} - - MTP ensures that all processes agree on which messages are accepted - and in what order they are accepted. The master controls this aspect - of the protocol by controlling allocation of transmit tokens and - setting the status of messages. Once a token for a message has been - assigned (see section 3.2.1) the master sets the status of that - message according to the following rules~\cite{Armstrong91}: - - \begin{itemize} - \item If the master has seen the entire message (i.e., has seen the - data[eom] and all intervening data packets), the status is accepted. - - \item If the master has not seen the entire message but believes the - message sender is still operational and connected to the master (as - determined by the master), the status is pending. - - \item If the master has not seen the entire message and believes the - sender to have failed or partitioned away, the status is rejected. - \end{itemize} - - Message status is carried in the message acceptance record (see - Figure~\ref{fig:msg-accept}) of every packet, and processes learn the - status of earlier messages by processing this information. - - The acceptance criteria is a multiple part record that carries the rules - of agreement to determine the message acceptance. - \hypertarget{synchro}{The most significant 8 bits is a flag that, if not - zero, indicates synchronization is required.} The field may vary on a - per message basis as directed by producing transport's client. The - default is that no synchronization is required. - - \hypertarget{tri-state}{The second part of the record is a 12 element - vector that represents the status of the last 12 messages transmitted - into the web.} - -\begin{figure}[htbp] - \begin{center} - \setlength{\byteheight}{6ex} - \begin{bytefield}{32} - \bitheader{0,7-8,15-16,23-24,31} \\ - - \bitbox{8}{\hyperlink{synchro}{synchro}} & - \bitbox{24}{\hyperlink{tri-state}{tri-state bitmask{[12]}}} \\ - - \bitbox{16}{\hyperlink{msg-seq}{message sequence number}} & - \bitbox{16}{\hyperlink{packet-seq}{packet sequence number}} - \end{bytefield} - \end{center} - \caption{Message acceptance record} - \label{fig:msg-accept} -\end{figure} - - Each element of the array is two bits in length and may have one of - three values: accepted(0), pending(1) or rejected(2). Initially, the - bit mask is set to all zeros. When the token for message $m$ is - transmitted, the first (left-most) element of the vector represents - the the state of message $m - 1$, the second element of the vector is - the status of message $m - 2$, and so forth. Therefore the status of - the last 12 messages are visible, the status of older messages are - lost, logically by shifting the elements out of the vector. Only the - master is permitted to set the status of messages. The master is not - permitted to shift a status of pending beyond the end of the vector. - If that situation arises, the master must instead not confirm any - token[request] until the oldest message can be marked as either - rejected or accepted. - - \hypertarget{msg-seq}{Message sequence numbers are 16 bit unsigned - values.} The field is initialized to zero by the master when the - transport is initialized, and incremented by one after each token is - granted. Only the master is permitted to change the value of the message - sequence number. Once granted, that message sequence number is consumed - and the state of the message must eventually become either accepted or - rejected. No transmit tokens may be granted if the assignment of a - message sequence number that would cause a value of pending to be - shifted beyond the end of the status vector. - - \hypertarget{packet-seq}{Packet sequence numbers are unsigned 16 bit - numbers assigned by the producing process on a per message basis.} - Packet sequence numbers start at a value of zero for each new message - and are incremented by one (consumed) for each data packet making up the - message. Consumers detecting missing packet sequence numbers must send a - nak[request] to the appropriate producer to recover the missed data. - - Control packets always contain the message acceptance criteria with a - synchronization flag set to zero (0x00), the highest message sequence - number observed and a packet sequence number one greater than - previously observed. Control packets do not consume any sequence - numbers. Since control messages are not reliably delivered, the - acceptance criteria should only be checked to see if they fall within - the proper range of message numbers, relative to the current message - number of the receiving station. The range of acceptable sequence - numbers should be $m-11$ to $m-13$, inclusive, where $m$ is the current - message number. - -\hypertarget{heartbeat}{\subsubsection{Heartbeat}} - - Heartbeat is an unsigned 32 bit field that has the units of - milliseconds. The value of heartbeat is shared by all members of the - web. By definition at least one packet (either data, empty or quit - from the master) will be multicast into the web within every - heartbeat period. - -\hypertarget{window}{\subsubsection{Window}} - - The allocation window (or simply window) is a 16 bit unsigned field - that indicates the maximum number of data packets that can be - multicasted by a member in a single heartbeat. It is the sum of the - retransmitted and new data packets. - -\hypertarget{retention}{\subsubsection{Retention}} - - The retention field is a 16 bit unsigned value that is the number of - heartbeats for which a producer must retain transmitted client data - and state for the purpose of retransmission. - -\subsection{Transport addresses} - - Associated with each transport are logically three transport service - access points (TSAP), logically formed by the concatenation of a - network service access point (NSAP) and a transport connection - identifier. These TSAPs are the unknown TSAP, the web's multicast - TSAP and each individual member's TSAP. - -\subsubsection{Unknown transport address} - - Stations that are just joining must use the multicast NSAP associated - with the transport, but are not yet aware of either the web's - multicast TSAP the master process' TSAP\@. Therefore, joining stations - fabricate a temporary TSAP (referred to as a unknown TSAP) by using a - connection identifier reserved to mean unknown (0x00000000). The - join[confirm] message will be sourced from the master's TSAP and will - include the multicast transport connection identifier in the data - field. Those values must be extracted from the join[confirm] and - remembered by the joining process. - -\subsubsection{Web's multicast address} - - The multicast TSAP is formed by logically concatenating the multicast - NSAP associated with the transport creation and the transport - connection identifier returned in the data field of the join[confirm] - packet. If more than one network is involved in the web, then the - multicast transport address becomes a list, one for each network - represented. This list is supplied in the data field of - token[confirm] packets. - - The multicast TSAP is used as the target for all messages that are - destined to the entire web, such as data and empty. The master's - decision to abandon the transport (quit) is also sent to the - multicast transport address. - -\subsubsection{Member addresses} - - The member TSAP is formed by using the process' unicast NSAP - concatenated with a locally generated unique connection identifier. - That TSAP must be the source of every packet transmitted by the - process, regardless of its destination, for the lifetime of the - transport. - - Packets unicast to specific members must contain the appropriate - TSAP\@. For producers and consumers this is not difficult. The only - TSAPs of interest are the master and the station(s) currently - transmitting data. - - - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\begin{thebibliography}{AFM91} -\bibitem[AFM91]{Armstrong91} -S.~Armstrong, A.~Freier, and K.~Marzullo. -\emph{MTP: An atomic multicast transport protocol}. -Xerox Webster Research Center technical report X9100359, -March 1991. - -\bibitem[AFM92]{Armstrong92} -S.~Armstrong, A.~Freier, and K.~Marzullo. -\emph{Multicast transport protocol}. -RFC 1301, Internet Engineering Task Force, February 1992. -Available from \url{http://www.rfc-editor.org/rfc/rfc1301.txt}. -\end{thebibliography} - -\end{document} diff --git a/Master/texmf-dist/source/latex/bytefield/bytefield.dtx b/Master/texmf-dist/source/latex/bytefield/bytefield.dtx index 4f6d096cb78..7a6c8b42a81 100644 --- a/Master/texmf-dist/source/latex/bytefield/bytefield.dtx +++ b/Master/texmf-dist/source/latex/bytefield/bytefield.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 2010 by Scott Pakin +% Copyright (C) 2011 by Scott Pakin % ------------------------------------------------------ % % This file may be distributed and/or modified under the @@ -22,7 +22,7 @@ %\NeedsTeXFormat{LaTeX2e}[1999/12/01] %\ProvidesPackage{bytefield} %<*package> - [2010/10/31 v1.3 Network protocol diagrams] + [2011/01/25 v2.0 Network protocol diagrams] % % %<*driver> @@ -31,27 +31,29 @@ \usepackage{bytefield} \usepackage{color} \usepackage{rotating} +\usepackage{multirow} \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 }, - 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} -} +\usepackage{wasysym} +\IfFileExists{hypdoc.sty}{\usepackage{hypdoc}}{} +\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 }, + 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 @@ -64,7 +66,7 @@ % % \fi % -% \CheckSum{615} +% \CheckSum{851} % % \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 @@ -85,25 +87,40 @@ % % \changes{v1.0}{2000/07/02}{Initial version} % \changes{v1.1}{2002/09/14}{Restructured the \texttt{.dtx} file} +% \changes{v1.4}{2011/01/09}{Made assignments to \cs{counting@words} +% global to prevent vertical-spacing problems with back-to-back word +% groups (bug fix due to Steven R. King)} +% \changes{v1.4}{2011/01/16}{Split \cs{curlyspace}, \cs{labelspace}, and +% \cs{curlyshrinkage} into \texttt{left} and \texttt{right} versions} +% \changes{v2.0}{2011/01/18}{Made a number of non-backwards-compatible +% changes, including replacing \cs{wordgroupr} and \cs{endwordgroupr} +% with a \texttt{rightwordgroup} environment and \cs{wordgroupl} and +% \cs{endwordgroupl} with a \texttt{leftwordgroup} environment and +% also replacing a slew of user-visible lengths and macros with a +% single \cs{bytefieldsetup} macro} % % \GetFileInfo{bytefield.dtx} % % \DoNotIndex{\&,\{,\}} % \DoNotIndex{\addtocounter,\advance} % \DoNotIndex{\begin,\begingroup,\bgroup} -% \DoNotIndex{\catcode,\ch@ck,\count,\cr} +% \DoNotIndex{\catcode,\ch@ck,\count,\cr,\csname} % \DoNotIndex{\DeclareRobustCommand,\def,\dimen,\dimendef} -% \DoNotIndex{\edef,\egroup,\else,\end,\endgroup,\expandafter} +% \DoNotIndex{\edef,\egroup,\else,\end,\endcsname,\endgroup,\expandafter} % \DoNotIndex{\fi} % \DoNotIndex{\gdef,\global} +% \DoNotIndex{\hspace} % \DoNotIndex{\if,\ifnum,\ifx,\ignorespaces,\insc@unt} -% \DoNotIndex{\let} -% \DoNotIndex{\newbox,\newcounter,\newenvironment,\newif,\newlength} -% \DoNotIndex{\newsavebox} +% \DoNotIndex{\let,\loop} +% \DoNotIndex{\MessageBreak} +% \DoNotIndex{\newbox,\newcommand,\newcounter,\newenvironment,\newif} +% \DoNotIndex{\newlength,\newsavebox,\noexpand} % \DoNotIndex{\raisebox,\ratio,\real,\relax,\renewcommand} +% \DoNotIndex{\par,\protect} +% \DoNotIndex{\renewenvironment,\repeat} % \DoNotIndex{\sbox,\setcounter,\setlength,\settowidth,\space,\string} % \DoNotIndex{\the} -% \DoNotIndex{\usebox} +% \DoNotIndex{\usebox,\usepackage} % \DoNotIndex{\value,\vbox} % \DoNotIndex{\wlog} % \DoNotIndex{\xdef} @@ -123,15 +140,6 @@ % \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]} % @@ -146,24 +154,110 @@ % ^^A Define something like \cs to use within \StopEventually. % \DeclareRobustCommand{\cseq}[1]{\texttt{\string#1}} % +% ^^A Index a package. This code was adapted from \SpecialEnvIndex. +% \makeatletter +% \def\SpecialPkgIndex#1{^^A +% \@bsphack +% \index{#1\actualchar{\protect\sffamily#1} (package)\encapchar usage}^^A +% \index{packages:\levelchar#1\actualchar{\protect\sffamily#1}^^A +% \encapchar usage}^^A +% \@esphack +% } +% +% ^^A The following was adapted from hypdoc's redefinition of \SpecialEnvIndex. +% \expandafter\ifx\csname c@HD@hypercount\endcsname\relax +% \else +% \let\HDorg@SpecialPkgIndex\SpecialPkgIndex +% \renewcommand*\SpecialPkgIndex[1]{^^A +% \@bsphack +% \begingroup +% \HD@target +% \let\HDorg@encapchar\encapchar +% \edef\encapchar usage{^^A +% \HDorg@encapchar hdpindex{usage}^^A +% }^^A +% \HDorg@SpecialPkgIndex{#1}^^A +% \endgroup +% \@esphack +% } +% \fi +% \makeatother +% +% ^^A Define a logical style for package names. +% \DeclareRobustCommand{\pkgname}[1]{^^A +% \textsf{#1}^^A +% \SpecialPkgIndex{#1}^^A +% } +% +% +% ^^A Index an option. This code was adapted from \SpecialEnvIndex. +% \makeatletter +% \def\SpecialOptionIndex#1{^^A +% \@bsphack +% \index{#1\actualchar{\protect\sffamily#1} (option)\encapchar usage}^^A +% \index{options:\levelchar#1\actualchar{\protect\sffamily#1}^^A +% \encapchar usage}^^A +% \@esphack +% } +% +% ^^A The following was adapted from hypdoc's redefinition of \SpecialEnvIndex. +% \expandafter\ifx\csname c@HD@hypercount\endcsname\relax +% \else +% \let\HDorg@SpecialOptionIndex\SpecialOptionIndex +% \renewcommand*\SpecialOptionIndex[1]{^^A +% \@bsphack +% \begingroup +% \HD@target +% \let\HDorg@encapchar\encapchar +% \edef\encapchar usage{^^A +% \HDorg@encapchar hdpindex{usage}^^A +% }^^A +% \HDorg@SpecialOptionIndex{#1}^^A +% \endgroup +% \@esphack +% } +% \fi +% \makeatother +% +% ^^A Define a logical style for package-option names. +% \DeclareRobustCommand{\optname}[1]{^^A +% \texttt{#1}^^A +% \SpecialOptionIndex{#1}^^A +% } +% % % \begin{abstract} -% The \texttt{bytefield} package helps the user create illustrations for +% The \pkgname{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} % +% +% \vspace{\baselineskip} +% \begin{center} +% \fbox{% +% \begin{minipage}{0.65\linewidth} +% \textsc{Warning}: \pkgname{bytefield} version~2.\textit{x} breaks +% compatibility with older versions of the package. See +% Section~\ref{sec:upgrading} for help porting documents to the new +% interface. +% \end{minipage}% +% } +% \end{center} +% \vspace{\baselineskip} +% +% % \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 +% The \pkgname{bytefield} package makes it easy to typeset these sorts of % figures. % -% \texttt{bytefield} lets one draw protocol diagrams that contain: +% \pkgname{bytefield} lets one draw protocol diagrams that contain: % % \begin{itemize} % \item Words of any arbitrary number of bits @@ -174,55 +268,62 @@ % \item ``Skipped words'' within fields % \end{itemize} % -% Because \texttt{bytefield} draws its figures using only +% Because \pkgname{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 +% imported graphic, \pkgname{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} +% \label{sec:usage} % % \subsection{Basic commands} +% \label{sec:basic-cmds} % -% This section explains how to use the \texttt{bytefield} package. +% This section explains how to use the \pkgname{bytefield} package. % It lists all the exported environments, commands, and variables in -% decreasing order of importance. +% decreasing order of usefulness. % % \begin{decl} -% |\begin{bytefield}| \marg{bit-width} \\ +% \SpecialEnvIndex{bytefield} +% |\begin{bytefield}| \oarg{parameters} \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~|&|. +% The \pkgname{bytefield} package's top-level environment is called, not +% surprisingly, ``|bytefield|''. It takes one mandatory argument, which +% is the number of bits in each word, and one optional argument, which +% is a set of parameters, described in Section~\ref{sec:options}, for +% formatting the bit-field's layout. One can think of a |bytefield| as +% being analogous to a |tabular|: words are separated by~``|\\|'', and +% fields within a word are separated by~``|&|''. % % \begin{decl} -% |\wordbox| \oarg{sides} \marg{height} \marg{text} \\ -% |\bitbox| \oarg{sides} \marg{width} \marg{text} +% \SpecialUsageIndex{\bitbox} +% |\bitbox| \oarg{sides} \marg{width} \marg{text} \\ +% \SpecialUsageIndex{\wordbox} +% |\wordbox| \oarg{sides} \marg{height} \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 two main commands one uses within a \pkgname{bytefield} +% environment are |\bitbox| and |\wordbox|. The former typesets a field +% that is one or more bits wide and a single word tall. The latter +% typesets a field that is one or more words tall and an entire word +% wide. % -% 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 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 |\bitbox| or +% |\wordbox|. 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: +% The following example shows how to produce a simple 16-bit-wide field: % % \begin{verbatim} % \begin{bytefield}{16} @@ -232,7 +333,7 @@ % \end{bytefield} % \end{verbatim} % -% The resulting figure looks like this: +% The resulting bit field looks like this: % % \begin{bffigure} % \begin{bytefield}{16} @@ -242,20 +343,22 @@ % \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). +% 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); +% \pkgname{bytefield} does not currently check for under- or overruns. % -% Within a |\wordbox| or |\bitbox|, the \texttt{bytefield} package +% Within a |\bitbox| or |\wordbox|, the \pkgname{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} +% \SpecialUsageIndex{\bitheader} % |\bitheader| \oarg{endianness} \marg{bit-positions} % \end{decl} % -% To make the figure more readable, it helps to label bit positions across +% To make the bit field 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 @@ -281,7 +384,7 @@ % \end{bytefield} % \end{verbatim} % -% The resulting figure looks like this: +% The resulting bit field looks like this: % % \begin{bffigure} % \begin{bytefield}{32} @@ -293,54 +396,62 @@ % % % \begin{decl} -% |\wordgroupr| \marg{text} \\ -% |\endwordgroupr| \\ +% \SpecialEnvIndex{rightwordgroup} +% |\begin{rightwordgroup}| \marg{text} \\ +% \meta{rows of bit boxes and word boxes} \\ +% |\end{rightwordgroup}| \\ % \\ -% |\wordgroupl| \marg{text} \\ -% |\endwordgroupl| +% \SpecialEnvIndex{leftwordgroup} +% |\begin{leftwordgroup}| \marg{text} \\ +% \meta{rows of bit boxes and word boxes} \\ +% |\end{leftwordgroup}| % \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. +% |\begin{rightwordgroup}| and |\end{rightwordgroup}| will be labeled on +% the right with \meta{text}. Similarly, all words defined between +% |\begin{leftwordgroup}| and |\end{leftwordgroup}| will be labeled on +% the left with \meta{text}. |\begin{|\meta{side}|wordgroup}| must lie +% at the beginning of a row (i.e.,~right after a ``|\\|''), and +% |\end{|\meta{side}|wordgroup}| must lie right \emph{before} the end of +% the row (i.e.,~right before a ``|\\|''). +% +% Unlike other \LaTeX\ environments, |rightwordgroup| and +% |leftwordgroup| do not have to nest properly with each other. % However, they cannot overlap themselves. In other words, -% |\wordgroupr|\ellipsis|\wordgroupl|\ellipsis|\endwordgroupr|\ellipsis|\endwordgroupl| -% is a valid sequence, but -% |\wordgroupr|\ellipsis|\wordgroupr|\ellipsis|\endwordgroupr|\ellipsis|\endwordgroupr| -% is not. +% |\begin{rightwordgroup}|\ellipsis |\begin{leftwordgroup}|\ellipsis +% |\end{rightwordgroup}|\ellipsis |\end{leftwordgroup}| is a valid +% sequence, but |\begin{rightwordgroup}|\ellipsis +% |\begin{rightwordgroup}|\ellipsis |\end{rightwordgroup}|\ellipsis +% |\end{rightwordgroup}| is not. % -% The following example shows how to use |\wordgroupr| and |\endwordgroupr|: +% The following example presents the basic usage of +% |\begin{rightwordgroup}| and |\end{rightwordgroup}|: % % \begin{verbatim} % \begin{bytefield}{16} % \bitheader{0,7,8,15} \\ -% \wordgroupr{Header} +% \begin{rightwordgroup}{Header} % \bitbox{4}{Tag} & \bitbox{12}{Mask} \\ % \bitbox{8}{Source} & \bitbox{8}{Destination} -% \endwordgroupr \\ +% \end{rightwordgroup} \\ % \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: +% Note the juxtaposition of ``|\\|'' to the |\begin{rightwordgroup}| and +% the |\end{rightwordgroup}| in the above. The resulting bit field +% looks like this: % % \begin{bffigure} % \begin{bytefield}{16} % \bitheader{0,7,8,15} \\ -% \wordgroupr{Header} +% \begin{rightwordgroup}{Header} % \bitbox{4}{Tag} & \bitbox{12}{Mask} \\ % \bitbox{8}{Source} & \bitbox{8}{Destination} -% \endwordgroupr \\ +% \end{rightwordgroup} \\ % \wordbox{3}{Data} % \end{bytefield} % \end{bffigure} @@ -351,12 +462,12 @@ % \begin{verbatim} % \begin{bytefield}{16} % \bitheader{0,7,8,15} \\ -% \wordgroupr{Header} +% \begin{rightwordgroup}{Header} % \bitbox{4}{Tag} & \bitbox{12}{Mask} \\ -% \wordgroupl{Node IDs} +% \begin{leftwordgroup}{Node IDs} % \bitbox{8}{Source} & \bitbox{8}{Destination} -% \endwordgroupl -% \endwordgroupr \\ +% \end{leftwordgroup} +% \end{rightwordgroup} \\ % \wordbox{3}{Data} % \end{bytefield} % \end{verbatim} @@ -364,27 +475,31 @@ % \begin{bffigure} % \begin{bytefield}{16} % \bitheader{0,7,8,15} \\ -% \wordgroupr{Header} +% \begin{rightwordgroup}{Header} % \bitbox{4}{Tag} & \bitbox{12}{Mask} \\ -% \wordgroupl{Node IDs} +% \begin{leftwordgroup}{Node IDs} % \bitbox{8}{Source} & \bitbox{8}{Destination} -% \endwordgroupl -% \endwordgroupr \\ +% \end{leftwordgroup} +% \end{rightwordgroup} \\ % \wordbox{3}{Data} % \end{bytefield} % \end{bffigure} % % \noindent -% Again, note the justaposition of |\\| to the various word-grouping +% Because |rightwordgroup| and |leftwordgroup| are not required to nest +% properly, the resulting bit field would look the same if the +% |\end{leftwordgroup}| and |\end{rightwordgroup}| were swapped. Again, +% note the justaposition of ``|\\|'' to the various word-grouping % commands in the above. % % \begin{decl} +% \SpecialUsageIndex{\skippedwords} % |\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: +% to |\wordbox|, as in the following example: % % \begin{verbatim} % \begin{bytefield}{16} @@ -407,44 +522,291 @@ % \end{bffigure} % % \begin{decl} -% |\bitwidth| \\ -% |\byteheight| +% \SpecialUsageIndex{\bytefieldsetup} +% |\bytefieldsetup| \marg{key=value list} % \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. +% Alter the formatting of all subsequent bit fields. +% Section~\ref{sec:options} describes the possible values for each +% \meta{key=value} item in the (comma-separated) list that +% |\bytefieldsetup| accepts as its argument. Note that changes made +% with |\bytefieldsetup| are local to their current scope. Hence, if +% used within an environment (e.g.,~|figure|), |\bytefieldsetup| does +% not impact bit fields drawn outside that environment. +% +% +% \subsection{Formatting options} +% \label{sec:options} +% +% A document author can customize many of the \pkgname{bytefield} +% package's figure-formatting parameters, either globally or on a +% per-figure basis. The parameters described below can be specified in +% any of three locations: +% +% \begin{itemize} +% \item as package options (i.e.,~in the +% |\usepackage|\oarg{options}|{bytefield}| line), which affects all +% |bytefield| environments in the entire document, +% +% \item anywhere in the document using the |\bytefieldsetup| command, +% which affects all subsequent |bytefield| environments in the +% current scope, or +% +% \item as the optional argument to a |\begin{bytefield}|, which +% affects only that single bit-field figure. +% \end{itemize} +% +% Unfortunately, \LaTeXe\ tends to abort with a ``\texttt{TeX capacity +% exceeded}'' or ``\texttt{Missing \cs{endcsname} inserted}'' error +% when a control sequence (i.e.,~|\|\meta{name}) or |\|\meta{symbol}) is +% encountered within the optional argument to |\usepackage|. Hence, +% parameters that typically expect a control sequence in their +% argument---in particular, \optname{bitformatting}, +% \optname{boxformatting}, \optname{leftcurly}, and +% \optname{rightcurly}---should best be avoided within the +% |\usepackage|\oarg{options}|{bytefield}| line. % % \begin{decl} -% |\curlyspace| \\ -% |\labelspace| +% \optname{bitwidth} = \meta{length} \\ +% \optname{bitheight} = \meta{length} % \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. +% The above parameters represent the width and height of each bit in a +% bit field. The default value of \optname{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. The default value of \optname{bitheight} +% is~|2ex|, which should allow a normal piece of text to appear within a +% |\bitbox| or |\wordbox| without abutting the box's top or bottom edge. +% +% As a special case, if \optname{bitwidth} is set to the word +% ``|auto|'', it will be set to the width of ``|99i|'' in the current +% bit-number formatting (cf.~\optname{bitformatting} below). This +% feature provides a convenient way to adjust the bit width after a +% formatting change. % % \begin{decl} -% |\curlyshrinkage| +% \optname{bitformatting} = \meta{command} \emph{or} \marg{commands} +% \end{decl} +% +% The numbers that appear in a bit header are typeset in the +% \optname{bitformatting} style, which defaults to |\tiny|. To alter +% the style of bit numbers in the bit header, set +% \optname{bitformatting} to a macro that takes a single argument (like +% |\textbf|) or no arguments (like |\small|). Groups of commands +% (e.g.,~|{\large\itshape}|) are also acceptable. +% +% When \optname{bitformatting} is set, \optname{bitwidth} usually needs +% to be recalculated as well to ensure that a correct amount of spacing +% surrounds each number in the bit header. As described above, setting +% |bitwidth=auto| is a convenient shortcut for recalculating the +% bit-width in the common case of bit fields containing no more than 99 +% bits per line and no particularly wide labels in bit boxes that +% contain only a few bits. +% +% The following example shows how to use \optname{bitformatting} and +% \optname{bitwidth} to format a bit header with small, boldface text: +% +% \begin{verbatim} +% \begin{bytefield}[bitformatting={\small\bfseries},bitwidth=auto]{20} +% \bitheader[b]{0-19} \\ +% \bitbox{1}{\tiny F/E} & \bitbox{1}{\tiny T0} & \bitbox{1}{\tiny T1} +% & \bitbox{1}{\tiny Fwd} & \bitbox{16}{Data value} \\ +% \end{bytefield} +% \end{verbatim} +% +% \noindent +% The resulting bit field looks like this: +% +% \begin{bffigure} +% \begin{bytefield}[bitformatting={\small\bfseries},bitwidth=auto]{20} +% \bitheader[b]{0-19} \\ +% \bitbox{1}{\tiny F/E} & \bitbox{1}{\tiny T0} & \bitbox{1}{\tiny T1} +% & \bitbox{1}{\tiny Fwd} & \bitbox{16}{Data value} \\ +% \end{bytefield} +% \end{bffigure} +% +% \begin{decl} +% \optname{boxformatting} = \meta{command} \emph{or} \marg{commands} +% \end{decl} +% +% The text that appears in a |\bitbox| or |\wordbox| is formatted in the +% \optname{boxformatting} style, which defaults to |\centering|. To +% alter the style of bit numbers in the bit header, set +% \optname{boxformatting} to a macro that takes a single argument (like +% |\textbf| but not |\textbf|---see below) or no arguments (like +% |\small|). Groups of commands (e.g.,~|{\large\itshape}|) are also +% acceptable. +% +% If \optname{boxformatting} is set to a macro that takes an argument, +% the macro must be defined as a ``long'' macro, which means it can +% accept more than one paragraph as an argument. Commands defined with +% |\newcommand| are automatically made long, but commands defined with +% |\newcommand*| are not. \LaTeX's |\text|\dots\ formatting commands +% (e.g.,~|\textbf|) are not long and therefore cannot be used directly +% in \optname{boxformatting}; use the zero-argument versions +% (e.g.,~|\bfseries|) instead. +% +% The following example shows how to use \optname{boxformatting} to +% format the text within each box horizontally centered and italicized: +% +% \begin{verbatim} +% \begin{bytefield}[boxformatting={\centering\itshape}, +% bitwidth=1.5em]{20} +% \bitheader[b]{0-19} \\ +% \bitbox{1}{\tiny F/E} & \bitbox{1}{\tiny T0} & \bitbox{1}{\tiny T1} +% & \bitbox{1}{\tiny Fwd} & \bitbox{16}{Data value} \\ +% \end{bytefield} +% \end{verbatim} +% +% \noindent +% The resulting bit field looks like this: +% +% \begin{bffigure} +% \begin{bytefield}[boxformatting={\centering\itshape}, +% bitwidth=1.5em]{20} +% \bitheader[b]{0-19} \\ +% \bitbox{1}{\tiny F/E} & \bitbox{1}{\tiny T0} & \bitbox{1}{\tiny T1} +% & \bitbox{1}{\tiny Fwd} & \bitbox{16}{Data value} \\ +% \end{bytefield} +% \end{bffigure} +% +% \begin{decl} +% \optname{leftcurly} = \meta{delimiter} \\ +% \optname{rightcurly} = \meta{delimiter} +% \end{decl} +% +% Word groups are normally indicated by a curly brace spanning all of +% its rows. However, the curly brace can be replaced by any other +% extensible math delimiter (i.e.,~a symbol that can meaningfully follow +% |\left| or |\right| in math mode) via a suitable redefinition of +% \optname{leftcurly} or \optname{rightcurly}. As in math mode, ``|.|'' +% means ``no symbol'', as in the following example (courtesy of +% Steven~R. King): +% +% \begin{verbatim} +% \begin{bytefield}[rightcurly=., rightcurlyspace=0pt]{32} +% \bitheader[b]{0,7,8,15,16,23,24,31} \\ +% \begin{rightwordgroup}{0Ch} +% \bitbox{8}{Byte 15 \\ \tiny (highest address)} +% & \bitbox{8}{Byte 14} +% & \bitbox{8}{Byte 13} +% & \bitbox{8}{Byte 12} +% \end{rightwordgroup} \\ +% \begin{rightwordgroup}{08h} +% \bitbox{32}{Long 0} +% \end{rightwordgroup} \\ +% \begin{rightwordgroup}{04h} +% \bitbox{16}{Word 1} & \bitbox{16}{Word 0} +% \end{rightwordgroup} \\ +% \begin{rightwordgroup}{00h} +% \bitbox{8}{Byte 3} +% & \bitbox{8}{Byte 2} +% & \bitbox{8}{Byte 1} +% & \bitbox{8}{Byte 0 \\ \tiny (lowest address)} +% \end{rightwordgroup} \\ +% \end{bytefield} +% \end{verbatim} +% +% \begin{bffigure} +% \begin{bytefield}[rightcurly=., rightcurlyspace=0pt]{32} +% \bitheader[b]{0,7,8,15,16,23,24,31} \\ +% \begin{rightwordgroup}{0Ch} +% \bitbox{8}{Byte 15 \\ \tiny (highest address)} +% & \bitbox{8}{Byte 14} +% & \bitbox{8}{Byte 13} +% & \bitbox{8}{Byte 12} +% \end{rightwordgroup} \\ +% \begin{rightwordgroup}{08h} +% \bitbox{32}{Long 0} +% \end{rightwordgroup} \\ +% \begin{rightwordgroup}{04h} +% \bitbox{16}{Word 1} & \bitbox{16}{Word 0} +% \end{rightwordgroup} \\ +% \begin{rightwordgroup}{00h} +% \bitbox{8}{Byte 3} +% & \bitbox{8}{Byte 2} +% & \bitbox{8}{Byte 1} +% & \bitbox{8}{Byte 0 \\ \tiny (lowest address)} +% \end{rightwordgroup} \\ +% \end{bytefield} +% \end{bffigure} +% +% \begin{decl} +% \optname{leftcurlyspace} = \meta{length} \\ +% \optname{rightcurlyspace} = \meta{length} \\ +% \optname{curlyspace} = \meta{length} +% \end{decl} +% +% \optname{leftcurlyspace} and \optname{rightcurlyspace} specify the +% space to insert between the bit field and the curly brace in a left or +% right word group (default:~|1ex|). Setting \optname{curlyspace} is a +% shortcut for setting both \optname{leftcurlyspace} and +% \optname{rightcurlyspace} to the same value. +% +% \begin{decl} +% |leftlabelspace| = \meta{length} \\ +% |rightlabelspace| = \meta{length} \\ +% |labelspace| = \meta{length} +% \end{decl} +% +% |leftlabelspace| and |rightlabelspace| specify the space to insert +% between the curly brace and the text label in a left or right word +% group (default:~|0.5ex|). Setting |labelspace| is a shortcut for +% setting both |leftlabelbrace| and |rightlabelspace| to the same value. +% +% \bigskip +% +% Figure~\ref{fig:rightspace} illustrates the juxtaposition of +% \optname{rightcurlyspace} and |rightlabelspace| to a word group and +% its label. The \optname{leftcurlyspace} and |leftlabelspace| +% parameters are symmetric. +% +% \begin{figure}[htbp] +% \[ +% \begin{array}{*5{@{}c}@{}} +% \cline{1-1} +% \multicolumn{1}{c|}{\cdots\quad\meta{bit-field rows}} +% & +% & \left.\rule{0pt}{3ex}\right\} +% & +% & \meta{label} \\[2ex] \cline{1-1} +% & \underbrace{\hspace*{6em}}_{\mathtt{rightcurlyspace}} +% & +% & \underbrace{\hspace*{6em}}_{\mathtt{rightlabelspace}} \\ +% \end{array} +% \] +% \caption{Role of \texttt{rightcurlyspace} and \texttt{rightlabelspace}} +% \label{fig:rightspace} +% \end{figure} +% +% \begin{decl} +% \optname{leftcurlyshrinkage} = \meta{length} \\ +% \optname{rightcurlyshrinkage} = \meta{length} \\ +% \optname{curlyshrinkage} = \meta{length} % \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. +% beyond the height of the word group. +% \optname{leftcurlyshrinkage}\slash \optname{rightcurlyshrinkage} is an +% amount by which to reduce the height of the curly brace in a +% left\slash right word group's label. Setting \optname{curlyshrinkage} +% is a shortcut for setting both \optname{leftcurlyshrinkage} and +% \optname{rightcurlyshrinkage} to the same value. Shrinkages default +% to~|5pt|, and it is extremely unlikely that one would ever need to +% change them. Nevertheless, these parameters are included here in case +% a document is typeset with a math font containing radically different +% curly braces from the ones that come with \TeX/\LaTeX\ or that +% replaces the curly braces (using \optname{leftcurly}\slash +% \optname{rightcurly}, described above) with symbols of substantially +% different heights. +% % % \subsection{Common tricks} % \label{sec:tricks} % -% This section shows some clever ways to use \texttt{bytefield}'s commands +% This section shows some clever ways to use \pkgname{bytefield}'s commands % to produce some useful effects. % % \paragraph{Odd-sized fields} @@ -469,8 +831,8 @@ % \end{bffigure} % % \paragraph{Ellipses} -% To skip words from the middle of enumerated data, put some |\vdots| -% in a |\wordbox| with empty \meta{sides}: +% To skip words that appear the middle of enumerated data, put some +% |\vdots| in a |\wordbox| with empty \meta{sides}: % % \begin{verbatim} % \begin{bytefield}{16} @@ -508,7 +870,7 @@ % % \newsavebox{\bitwidthOK} % \begin{lrbox}{\bitwidthOK} -% \settowidth{\bitwidth}{OK~}\relax +% \bytefieldsetup{bitwidth=\widthof{OK~}}\relax % \begin{bytefield}{8} % \bitbox{1}{OK} & \bitbox{7}{Data} \\ % \end{bytefield} @@ -539,16 +901,18 @@ % % \begin{tabular}{ll} % \emph{Default}: & \raisebox{-4ex}{\usebox{\defaultOK}} \\ -% |\settowidth{\bitwidth}{OK~}|: & \raisebox{-4ex}{\usebox{\bitwidthOK}} \\ +% |\bytefieldsetup{%| +% & \multirow{2}*{\raisebox{-4ex}{\usebox{\bitwidthOK}}} \\ +% | bitwidth=\widthof{OK~}}|: & \\[2ex] % |\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|: +% Because |\width| and |\height| are defined within bit boxes (also word +% boxes), we can represent unused bits by filling a |\bitbox| with a +% rule of size |\width|~$\times$ |\height|: % % \begin{verbatim} % \begin{bytefield}{32} @@ -571,7 +935,7 @@ % \end{bffigure} % % \noindent -% The effect is much better when the \texttt{color} package is used to +% The effect is much better when the \pkgname{color} package is used to % draw the unused bits in color. (Gray looks nice.) % % \begin{verbatim} @@ -596,6 +960,120 @@ % \end{bytefield} % \end{bffigure} % +% \paragraph{Aligning text on the baseline} +% Because \pkgname{bytefield} internally uses \LaTeX's |picture| +% environment and that environment's |\makebox| command to draw bit +% boxes and word boxes, the text within a box is centered vertically +% with no attention paid to the text's baseline. As a result, some bit +% fields appear somewhat askew: +% +% \begin{verbatim} +% \begin{bytefield}[bitwidth=1.5em]{2} +% \bitbox{1}{M} & \bitbox{1}{y} \\ +% \end{bytefield} +% \end{verbatim} +% +% \begin{bffigure} +% \begin{bytefield}[bitwidth=1.5em]{2} +% \bitbox{1}{M} & \bitbox{1}{y} \\ +% \end{bytefield} +% \end{bffigure} +% +% A solution is to use the \optname{boxformatting} option to trick +% |\makebox| into thinking that all text has the same height and depth. +% Here we use |\raisebox| to indicate that all text is as tall as a +% ``|W|'' and does not descend at all below the baseline: +% +% \begin{verbatim} +% \newlength{\maxheight} +% \setlength{\maxheight}{\heightof{W}} +% +% \newcommand{\baselinealign}[1]{% +% \centering +% \raisebox{0pt}[\maxheight][0pt]{#1}% +% } +% +% \begin{bytefield}[boxformatting=\baselinealign, +% bitwidth=1.5em]{2} +% \bitbox{1}{M} & \bitbox{1}{y} \\ +% \end{bytefield} +% \end{verbatim} +% +% \begin{bffigure} +% \newlength{\maxheight} +% \setlength{\maxheight}{\heightof{W}} +% \newcommand{\baselinealign}[1]{% +% \centering +% \raisebox{0pt}[\maxheight][0pt]{#1}% +% } +% \begin{bytefield}[boxformatting=\baselinealign, +% bitwidth=1.5em]{2} +% \bitbox{1}{M} & \bitbox{1}{y} \\ +% \end{bytefield} +% \end{bffigure} +% +% \paragraph{Register contents} +% Sometimes, rather than listing the \emph{meaning} of each bit field +% within each |\bitbox| or |\wordbox|, it may be desirable to list the +% \emph{contents}, with the meaning described in an additional label +% above each bit number in the bit header. Although the +% \pkgname{register} package is more suited to this form of layout, +% \pkgname{bytefield} can serve in a pinch with the help of the +% |\turnbox| macro from the \pkgname{rotating} package: +% +% \begin{verbatim} +% \newcommand{\bitlabel}[2]{% +% \bitbox[]{#1}{% +% \raisebox{0pt}[4ex][0pt]{% +% \turnbox{45}{\fontsize{7}{7}\selectfont#2}% +% }% +% }% +% } +% +% \begin{bytefield}[bitwidth=1em]{16} +% \bitlabel{1}{Carry} & \bitlabel{1}{Reserved} & +% \bitlabel{1}{Parity} & \bitlabel{1}{Reserved} & +% \bitlabel{1}{Adjust} & \bitlabel{1}{Reserved} & +% \bitlabel{1}{Zero} & \bitlabel{1}{Sign} & +% \bitlabel{1}{Trap} & \bitlabel{1}{Interrupt enable} & +% \bitlabel{1}{Direction} & \bitlabel{1}{Overflow} & +% \bitlabel{2}{I/O privilege level (12--13)} & +% \bitlabel{1}{Nested task} & \bitlabel{1}{Reserved} \\ +% \bitheader{0-15} \\ +% \bitbox{1}{0} & \bitbox{1}{1} & \bitbox{1}{0} & \bitbox{1}{0} & +% \bitbox{1}{0} & \bitbox{1}{0} & \bitbox{1}{0} & \bitbox{1}{1} & +% \bitbox{1}{0} & \bitbox{1}{1} & \bitbox{1}{0} & \bitbox{1}{0} & +% \bitbox{1}{0} & \bitbox{1}{0} & \bitbox{1}{0} & \bitbox{1}{0} \\ +% \end{bytefield} +% \end{verbatim} +% +% \vspace{3\baselineskip} ^^A Allow extra room for the rotated headers. +% \begin{bffigure} +% \newcommand{\bitlabel}[2]{% +% \bitbox[]{#1}{% +% \raisebox{0pt}[4ex][0pt]{% +% \turnbox{45}{\fontsize{7}{7}\selectfont#2}% +% }% +% }% +% } +% \begin{bytefield}[bitwidth=1em]{16} +% \bitlabel{1}{Carry} & \bitlabel{1}{Reserved} & +% \bitlabel{1}{Parity} & \bitlabel{1}{Reserved} & +% \bitlabel{1}{Adjust} & \bitlabel{1}{Reserved} & +% \bitlabel{1}{Zero} & \bitlabel{1}{Sign} & +% \bitlabel{1}{Trap} & \bitlabel{1}{Interrupt enable} & +% \bitlabel{1}{Direction} & \bitlabel{1}{Overflow} & +% \bitlabel{2}{I/O privilege level (12--13)} & +% \bitlabel{1}{Nested task} & \bitlabel{1}{Reserved} \\ +% \bitheader{0-15} \\ +% \bitbox{1}{0} & \bitbox{1}{1} & \bitbox{1}{0} & \bitbox{1}{0} & +% \bitbox{1}{0} & \bitbox{1}{0} & \bitbox{1}{0} & \bitbox{1}{1} & +% \bitbox{1}{0} & \bitbox{1}{1} & \bitbox{1}{0} & \bitbox{1}{0} & +% \bitbox{1}{0} & \bitbox{1}{0} & \bitbox{1}{0} & \bitbox{1}{0} \\ +% \end{bytefield} +% \end{bffigure} +% +% % \subsection{Not-so-common tricks} % % \paragraph{Colored fields} @@ -614,9 +1092,7 @@ % \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} +% \begin{bytefield}[bitheight=\widthof{~Sign~}]{32} % \bitheader[b]{31,23,0} \\ % \colorbitbox{lightcyan}{1}{\rotatebox{90}{Sign}} & % \colorbitbox{lightgreen}{8}{Exponent} & @@ -625,55 +1101,212 @@ % \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} +% \begin{bffigure} +% \begingroup +% \small +% \newcommand{\colorbitbox}[3]{^^A +% \rlap{\bitbox{#2}{\color{#1}\rule{\width}{\height}}}^^A +% \bitbox{#2}{#3}}^^A +% \definecolor{lightcyan}{rgb}{0.84,1,1}^^A +% \definecolor{lightgreen}{rgb}{0.64,1,0.71}^^A +% \definecolor{lightred}{rgb}{1,0.7,0.71}^^A +% \bytefieldsetup{bitheight=\widthof{~Sign~}}^^A +% \begin{bytefield}[bitheight=\widthof{~Sign~}]{32} +% \bitheader[b]{31,23,0} \\ +% \colorbitbox{lightcyan}{1}{\rotatebox{90}{Sign}} & +% \colorbitbox{lightgreen}{8}{Exponent} & +% \colorbitbox{lightred}{23}{Mantissa} \\ +% \end{bytefield} +% \endgroup +% \end{bffigure} +% +% \paragraph{Renumbered bit headers} +% The |\bitheader| macro always numbers bits starting from~0. However, +% one may occasionally want to begin numbering from a different value. +% (This was in fact a feature request from Chris L'Esperance.) The way +% to accomplish this is to define a macro that adds a value to its +% argument and specify this macro to the \optname{bitformatting} +% parameter. This works because the argument passed to a macro named by +% \optname{bitformatting} is always numeric except when called from +% |bitwidth=auto|. (Caveat: This happens automatically at the +% |\begin{document}|.) However, \pkgname{bytefield} sometimes passes a +% \optname{bitformatting}-named macro the value~|1234567890| to measure +% the height of a formatted bit number. The examples below include a +% case in which this value needs to be checked explicitly to ensure that +% the height is correct even when the formatted number is rotated by +% 90\textdegree. +% +% \begin{verbatim} +% \begin{bytefield}{16} +% \bitheader{0-15} \\ +% \bitbox{8}{Header} & \bitbox{8}{First byte} \\ +% \end{bytefield} +% \end{verbatim} +% +% \begin{bffigure} +% \begin{bytefield}{16} +% \bitheader{0-15} \\ +% \bitbox{8}{Header} & \bitbox{8}{First byte} \\ +% \end{bytefield} +% \end{bffigure} +% +% \begin{verbatim} +% \newcommand{\formatplusXVI}[1]{% +% \tiny +% \count10=#1 +% \advance\count10 by 16 +% \the\count10 +% } +% \begin{bytefield}[bitformatting=\formatplusXVI]{16} +% \bitheader{0-15} \\ +% \bitbox{8}{Second byte} & \bitbox{8}{Third byte} \\ +% \end{bytefield} +% \end{verbatim} +% +% \begin{bffigure} +% \newcommand{\formatplusXVI}[1]{% +% \tiny +% \count10=#1 +% \advance\count10 by 16 +% \the\count10 +% } +% \begin{bytefield}[bitformatting=\formatplusXVI]{16} +% \bitheader{0-15} \\ +% \bitbox{8}{Second byte} & \bitbox{8}{Third byte} \\ +% \end{bytefield} +% \end{bffigure} +% +% \begin{verbatim} +% \newcommand{\formatplusMMMMMMMMCLXXVI}[1]{% +% \tiny +% \count10=#1 +% \ifnum\count10=1234567890 +% \rotatebox[origin=B]{90}{8191}% +% \else +% \advance\count10 by 8176 +% \rotatebox[origin=B]{90}{\the\count10}% +% \fi +% } +% +% \begin{bytefield}[bitformatting=\formatplusMMMMMMMMCLXXVI]{16} +% \bitheader{0-15} \\ +% \bitbox{8}{1022nd byte} & \bitbox{8}{Trailer} \\ +% \end{bytefield} +% \end{verbatim} +% +% \begin{bffigure} +% \newcommand{\formatplusMMMMMMMMCLXXVI}[1]{% +% \tiny +% \count10=#1 +% \ifnum\count10=1234567890 +% \rotatebox[origin=B]{90}{8191}% +% \else +% \advance\count10 by 8176 +% \rotatebox[origin=B]{90}{\the\count10}% +% \fi +% } +% \begin{bytefield}[bitformatting=\formatplusMMMMMMMMCLXXVI]{16} +% \bitheader{0-15} \\ +% \bitbox{8}{1022nd byte} & \bitbox{8}{Trailer} \\ +% \end{bytefield} +% \end{bffigure} +% +% As an even trickier example of modifying bit numbers, the following +% shows how to \emph{conditionally} modify the bit number: If the number +% is |1234567890| (for \pkgname{bytefield}'s bit-height calculation, the +% number is used as is; numbers greater than~9 are increased by 48; +% numbers less than~4 are unmodified; the number~6 is replaced by an +% ellipsis; and all other numbers are discarded. +% +% \begin{verbatim} +% \newcommand{\fakesixtyfourbits}[1]{% +% \tiny +% \ifnum#1=1234567890 +% #1 +% \else +% \ifnum#1>9 +% \count32=#1 +% \advance\count32 by 48 +% \the\count32% +% \else +% \ifnum#1<4 +% #1% +% \else +% \ifnum#1=6 +% $\cdots$% +% \fi +% \fi +% \fi +% \fi +% } +% \begin{bytefield}[% +% bitwidth=\widthof{\tiny Fwd~}, +% bitformatting=\fakesixtyfourbits]{16} +% \bitheader[b]{0-15} \\ +% \bitbox{1}{\tiny F/E} & \bitbox{1}{\tiny T0} & \bitbox{1}{\tiny T1} +% & \bitbox{1}{\tiny Fwd} & \bitbox{12}{Data value} \\ +% \end{bytefield} +% \end{verbatim} +% +% \begin{bffigure} +% \newcommand{\fakesixtyfourbits}[1]{% +% \tiny +% \ifnum#1=1234567890 +% #1 +% \else +% \ifnum#1>9 +% \count32=#1 +% \advance\count32 by 48 +% \the\count32% +% \else +% \ifnum#1<4 +% #1% +% \else +% \ifnum#1=6 +% $\cdots$% +% \fi +% \fi +% \fi +% \fi +% } +% \begin{bytefield}[% +% bitwidth=\widthof{\tiny Fwd~}, +% bitformatting=\fakesixtyfourbits]{16} +% \bitheader[b]{0-15} \\ +% \bitbox{1}{\tiny F/E} & \bitbox{1}{\tiny T0} & \bitbox{1}{\tiny T1} +% & \bitbox{1}{\tiny Fwd} & \bitbox{12}{Data value} \\ +% \end{bytefield} +% \end{bffigure} % % \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 +% While certainly not the intended purpose of the \pkgname{bytefield} +% package, one can utilize word boxes 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} +% \begin{bytefield}[bitheight=4\baselineskip]{32} +% \begin{rightwordgroup}{Partition 4} % \bitbox[]{8}{\texttt{0xFFFFFFFF} \\[2\baselineskip] % \texttt{0xC0000000}} & % \bitbox{24}{\descbox{1\,GB area for VxDs, memory manager, % file system code; shared by all processes.}{Read/writable.}} -% \endwordgroupr \\ -% \wordgroupr{Partition 3} +% \end{rightwordgroup} \\ +% \begin{rightwordgroup}{Partition 3} % \bitbox[]{8}{\texttt{0xBFFFFFFF} \\[2\baselineskip] % \texttt{0x80000000}} & % \bitbox{24}{\descbox{1\,GB area for memory-mapped files, % shared system \textsc{dll}s, file system code; shared by all % processes.}{Read/writable.}} -% \endwordgroupr \\ -% \wordgroupr{Partition 2} +% \end{rightwordgroup} \\ +% \begin{rightwordgroup}{Partition 2} % \bitbox[]{8}{\texttt{0x7FFFFFFF} \\[2\baselineskip] % \texttt{0x00400000}} & % \bitbox{24}{\descbox{$\sim$2\,GB area private to process, % process code, and data.}{Read/writable.}} -% \endwordgroupr \\ -% \wordgroupr{Partition 1} +% \end{rightwordgroup} \\ +% \begin{rightwordgroup}{Partition 1} % \bitbox[]{8}{\texttt{0x003FFFFF} \\[2\baselineskip] % \texttt{0x00001000}} & % \bitbox{24}{\descbox{4\,MB area for MS-DOS and Windows~3.1 @@ -683,34 +1316,33 @@ % \bitbox{24}{\descbox{4096~byte area for MS-DOS and Windows~3.1 % compatibility.}{Protected---catches \textsc{null} % pointers.}} -% \endwordgroupr \\ +% \end{rightwordgroup} \\ % \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} +% \begin{bytefield}[bitheight=4\baselineskip]{32} +% \begin{rightwordgroup}{Partition 4} % \bitbox[]{8}{\texttt{0xFFFFFFFF} \\[2\baselineskip] % \texttt{0xC0000000}} & % \bitbox{24}{\descbox{1\,GB area for VxDs, memory manager, % file system code; shared by all processes.}{Read/writable.}} -% \endwordgroupr \\ -% \wordgroupr{Partition 3} +% \end{rightwordgroup} \\ +% \begin{rightwordgroup}{Partition 3} % \bitbox[]{8}{\texttt{0xBFFFFFFF} \\[2\baselineskip] % \texttt{0x80000000}} & % \bitbox{24}{\descbox{1\,GB area for memory-mapped files, % shared system \textsc{dll}s, file system code; shared by all % processes.}{Read/writable.}} -% \endwordgroupr \\ -% \wordgroupr{Partition 2} +% \end{rightwordgroup} \\ +% \begin{rightwordgroup}{Partition 2} % \bitbox[]{8}{\texttt{0x7FFFFFFF} \\[2\baselineskip] % \texttt{0x00400000}} & % \bitbox{24}{\descbox{$\sim$2\,GB area private to process, process % code, and data.}{Read/writable.}} -% \endwordgroupr \\ -% \wordgroupr{Partition 1} +% \end{rightwordgroup} \\ +% \begin{rightwordgroup}{Partition 1} % \bitbox[]{8}{\texttt{0x003FFFFF} \\[2\baselineskip] % \texttt{0x00001000}} & % \bitbox{24}{\descbox{4\,MB area for MS-DOS and Windows~3.1 @@ -720,21 +1352,20 @@ % \bitbox{24}{\descbox{4096~byte area for MS-DOS and Windows~3.1 % compatibility.}{Protected---catches \textsc{null} % pointers.}} -% \endwordgroupr \\ +% \end{rightwordgroup} \\ % \end{bytefield} % \end{bffigure} % % % \subsection{Putting it all together} % -% The following code showcases most of \texttt{bytefield}'s features in a +% The following code showcases most of \pkgname{bytefield}'s features in a % single figure. % % \begin{verbatim} -% \setlength{\byteheight}{2.5\baselineskip} -% \begin{bytefield}{32} +% \begin{bytefield}[bitheight=2.5\baselineskip]{32} % \bitheader{0,7,8,15,16,23,24,31} \\ -% \wordgroupr{\parbox{6em}{\raggedright These words were taken +% \begin{rightwordgroup}{\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} & @@ -742,24 +1373,24 @@ % \bitbox{1}{\tiny S\\Y\\N} & \bitbox{1}{\tiny F\\I\\N} & % \bitbox{16}{Window} \\ % \bitbox{16}{Checksum} & \bitbox{16}{Urgent pointer} -% \endwordgroupr \\ +% \end{rightwordgroup} \\ % \wordbox[lrt]{1}{Data octets} \\ % \skippedwords \\ % \wordbox[lrb]{1}{} \\ -% \wordgroupl{\parbox{6em}{\raggedright Note that we can display, +% \begin{leftwordgroup}{\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}.}} +% optional argument to \texttt{\string\wordbox} and +% \texttt{\string\bitbox}.}} % \bitbox{8}{Source} & \bitbox{8}{Destination} & % \bitbox[lrt]{16}{} \\ % \wordbox[lr]{1}{Timestamp} \\ -% \wordgroupr{\parbox{6em}{\raggedright Why two Length fields? +% \begin{rightwordgroup}{\parbox{6em}{\raggedright Why two Length fields? % No particular reason.}} % \bitbox[lrb]{16}{} & \bitbox{16}{Length} -% \endwordgroupl \\ +% \end{leftwordgroup} \\ % \bitbox{6}{Key} & \bitbox{6}{Value} & \bitbox{4}{Unused} & % \bitbox{16}{Length} -% \endwordgroupr \\ +% \end{rightwordgroup} \\ % \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} \\ @@ -777,11 +1408,13 @@ % \noindent % Figure~\ref{fig:complex-diagram} shows the resulting protocol diagram. % +% \newsavebox{\protocoldiagram} % \begin{figure}[phtb] -% \setlength{\byteheight}{2.5\baselineskip} -% \begin{bytefield}{32} +% \centering +% \begin{lrbox}{\protocoldiagram} +% \begin{bytefield}[bitheight=2.5\baselineskip]{32} % \bitheader{0,7,8,15,16,23,24,31} \\ -% \wordgroupr{\parbox{6em}{\raggedright These words were taken +% \begin{rightwordgroup}{\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} & @@ -789,23 +1422,23 @@ % \bitbox{1}{\tiny S\\Y\\N} & \bitbox{1}{\tiny F\\I\\N} & % \bitbox{16}{Window} \\ % \bitbox{16}{Checksum} & \bitbox{16}{Urgent pointer} -% \endwordgroupr \\ +% \end{rightwordgroup} \\ % \wordbox[lrt]{1}{Data octets} \\ % \skippedwords \\ % \wordbox[lrb]{1}{} \\ -% \wordgroupl{\parbox{6em}{\raggedright Note that we can display, +% \begin{leftwordgroup}{\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}.}} +% optional argument to \texttt{\string\wordbox} and +% \texttt{\string\bitbox}.}} % \bitbox{8}{Source} & \bitbox{8}{Destination} & \bitbox[lrt]{16}{} \\ % \wordbox[lr]{1}{Timestamp} \\ -% \wordgroupr{\parbox{6em}{\raggedright Why two Length fields? +% \begin{rightwordgroup}{\parbox{6em}{\raggedright Why two Length fields? % No particular reason.}} % \bitbox[lrb]{16}{} & \bitbox{16}{Length} -% \endwordgroupl \\ +% \end{leftwordgroup} \\ % \bitbox{6}{Key} & \bitbox{6}{Value} & \bitbox{4}{Unused} & % \bitbox{16}{Length} -% \endwordgroupr \\ +% \end{rightwordgroup} \\ % \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} \\ @@ -817,49 +1450,126 @@ % \bitbox{12}{Command} \\ % \wordbox{2}{64-bit random number} % \end{bytefield} -% \caption{Complex protocol diagram drawn with the \texttt{bytefield} +% \end{lrbox} +% \makebox[0pt][c]{\usebox{\protocoldiagram}} +% \caption{Complex protocol diagram drawn with the \pkgname{bytefield} % package} % \label{fig:complex-diagram} % \end{figure} % % +% \subsection{Upgrading from older versions} +% \label{sec:upgrading} +% +% \pkgname{bytefield}'s user interface changed substantially with the +% introduction of version~2.0. Because documents written for +% \pkgname{bytefield}~v1.\textit{x} will not build properly under later +% versions of the package, this section shows how to convert documents +% to the new interface. +% +% \begin{decl} +% \SpecialUsageIndex{\wordgroupr} +% |\wordgroupr| \\ +% \SpecialUsageIndex{\endwordgroupr} +% |\endwordgroupr| +% \end{decl} +% +% These have been replaced with the |rightwordgroup| environment to make +% their invocation more \LaTeX-like. Use |\begin{rightwordgroup}| +% instead of |\wordgroupr| and |\end{rightwordgroup}| instead of +% |\endwordgroupr|. +% +% \begin{decl} +% \SpecialUsageIndex{\wordgroupl} +% |\wordgroupl| \\ +% \SpecialUsageIndex{\endwordgroupl} +% |\endwordgroupl| +% \end{decl} +% +% These have been replaced with the |leftwordgroup| environment to make +% their invocation more \LaTeX-like. Use |\begin{leftwordgroup}| +% instead of |\wordgroupl| and |\end{leftwordgroup}| instead of +% |\endwordgroupl|. +% +% \begin{decl} +% \SpecialUsageIndex{\bitwidth} +% |\bitwidth| +% \end{decl} +% +% Instead of changing bit widths with +% |\setlength{\bitwidth}{|\meta{width}|}|, use +% |\bytefieldsetup{bitwidth=|\meta{width}|}|. +% +% \begin{decl} +% \SpecialUsageIndex{\byteheight} +% |\byteheight| +% \end{decl} +% +% Instead of changing bit heights with +% |\setlength{\byteheight}{|\meta{height}|}|, use +% |\bytefieldsetup{bitheight=|\meta{height}|}| (and note the change from +% ``|byte|'' to ``|bit|'' for consistency with \optname{bitwidth}). +% +% \begin{decl} +% \SpecialUsageIndex{\curlyspace} +% |\curlyspace| \\ +% \SpecialUsageIndex{\labelspace} +% |\labelspace| +% \end{decl} +% +% Instead of using |\setlength{\curlyspace}{|\meta{dist}|}| and +% |\setlength{\labelspace}{|\meta{dist}|}| to alter the horizontal space +% that appears before and after a curly brace, use +% |\bytefieldsetup{curlyspace=|\meta{dist}|}| and +% |\bytefieldsetup{labelspace=|\meta{dist}|}|. Note that, as described +% in Section~\ref{sec:basic-cmds}, left and right spacing can be set +% independently if desired. +% +% \begin{decl} +% \SpecialUsageIndex{\curlyshrinkage} +% |\curlyshrinkage| +% \end{decl} +% +% Instead of using |\setlength{\curlyshrinkage}{|\meta{dist}|}| to +% reduce the vertical space occupied by a curly brace, use +% |\bytefieldsetup{curlyshrinkage=|\meta{dist}|}|. Note that, as +% described in Section~\ref{sec:basic-cmds}, left and right curly-brace +% height can be reduced independently if desired. +% +% \bigskip +% +% As a crutch to help build older documents with minimal modification, +% \pkgname{bytefield} provides a |compat1| package option that restores +% the old interface. This option, invoked with +% |\usepackage[compat1]{bytefield}|, may disappear in a future version +% of the package and should therefore not be relied upon as a long-term +% approach to using \pkgname{bytefield}. +% +% % \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: +% \pkgname{bytefield} is my first \LaTeX\ package, and, as such, there +% are a number of macros that could probably have been implemented a +% lot better. For example, \pkgname{bytefield} is somewhat wasteful +% of \meta{dimen} registers (although it did get a lot better with +% version~1.1 and again with version~1.3). The package should really +% get a major overhaul now that I've gotten better at \TeX\slash +% \LaTeX\ programming. One minor improvement I'd like to make in the +% package is to move left, small curly braces closer to the bit field. +% In the following figure, notice how distant the small curly appears +% from the bit-field body: % % \begin{bffigure} -% \setlength{\byteheight}{4ex} +% \bytefieldsetup{bitheight=4ex} % \begin{bytefield}{16} -% \wordgroupl{Too distant} +% \begin{leftwordgroup}{Too distant} % \wordbox{1}{Something} -% \endwordgroupl \\ -% \wordgroupl{Looks okay} +% \end{leftwordgroup} \\ +% \begin{leftwordgroup}{Looks okay} % \wordbox{4}{Something else} -% \endwordgroupl +% \end{leftwordgroup} % \end{bytefield} % \end{bffigure} % @@ -873,19 +1583,15 @@ % % \newcommand{\usermacro}{\marginpar{\vspace*{1ex}{\hspace{18pt}\huge$\star$}\vspace*{-1ex}}} % -% This section contains the complete source code for \texttt{bytefield}. +% This section contains the complete source code for \pkgname{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} +% (or debug~\smiley) the \pkgname{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 Section~\ref{sec:usage}). All other macros are used only +% internally by \pkgname{bytefield}. % % \subsection{Required packages} % @@ -896,11 +1602,12 @@ % 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 +% loading the \pkgname{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.} +% of \pkgname{calc} are still being included in \TeX{} distributions.} % \begin{macrocode} \RequirePackage{calc}[1998/07/07] +\RequirePackage{keyval} % \end{macrocode} % % @@ -910,25 +1617,31 @@ % 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)} +% \begin{macro}{\allocationnumber} +% \changes{v1.1}{2002/09/15}{Bug fix: Added \cs{bf@newdimen} to greatly +% reduce the likelihood of ``\texttt{No room for a new \cs{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 + \ch@ck1\insc@unt\dimen \allocationnumber=\count11 \dimendef#1=\allocationnumber - \wlog{\string#1=\string\dimen\the\allocationnumber\space (locally)}} + \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|. +% \end{macro} +% \end{macro} +% +% \begin{macro}{\bf@newdimen} +% If we're using $\varepsilon$-\TeX\ then we have access to many more +% \meta{dimen}s than in original \TeX\@. The \textsf{etex} package +% makes these extra \meta{dimen}s 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} @@ -958,9 +1671,9 @@ % % \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 +% because the \pkgname{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| +% \pkgname{calc}'s nice infix features) and |\advance| |\bytefield@height| % by that amount. % \begin{macrocode} \newlength{\bytefield@height@increment} @@ -983,7 +1696,7 @@ % \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 +% the bit field, put a box around it, and do other operations on the entire % figure. % \begin{macrocode} \newsavebox{\entire@bytefield@picture} @@ -992,38 +1705,44 @@ % % \begin{environment}{bytefield} % \usermacro +% \begin{macro}{\old@nl} +% \begin{macro}{\amp} % Environment containing the layout of bits in a sequence of bytes. -% This is the main environment defined by the \texttt{bytefield} pacakge. +% This is the main environment defined by the \pkgname{bytefield} package. % 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, +% \pkgname{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}% +\newenvironment{bytefield}[2][]{% + \bf@bytefieldsetup{#1}% + \setcounter{bits@wide}{#2}% \let\old@nl=\\% \let\amp=&% \catcode`\&=10 \openup -1pt \setlength{\bytefield@height}{0pt}% \setlength{\unitlength}{1pt}% - \counting@wordstrue + \global\counting@wordstrue \begin{lrbox}{\entire@bytefield@picture}% % \end{macrocode} +% \end{macro} +% \end{macro} % \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}% + \unskip + \amp\show@wordlabelr\cr + \ignorespaces\global\counting@wordstrue\make@lspace\amp}% % \end{macrocode} % \end{macro} % \begin{macrocode} - \vbox\bgroup\ialign\bgroup##\amp##\amp##\cr\amp% + \vbox\bgroup\ialign\bgroup##\amp##\amp##\cr\amp }{% - \amp\show@wordlabelr\cr\egroup\egroup% + \amp\show@wordlabelr\cr\egroup\egroup \end{lrbox}% \usebox{\entire@bytefield@picture}} % \end{macrocode} @@ -1033,23 +1752,44 @@ % % \subsubsection{Drawing (proper)} % -% \begin{macro}{\bitwidth} -% \usermacro +% \begin{macro}{\bf@bitformatting} +% Formats a bit number in the bit header. |\bf@bitformatting| may be +% redefined to take either a single argument (\`a~la |\textbf|) or no +% argument (\`a~la |\small|). +% \changes{v1.4}{2011/01/15}{Introduced this macro at Steven R. King's +% request to enable users to alter the bit header's font size} +% \begin{macrocode} +\newcommand*{\bf@bitformatting}{\tiny} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\bf@boxformatting} +% Formats the text within a bit box or word box. |\bf@boxformatting| +% takes either a single argument (\`a~la |\textbf|) or no argument +% (\`a~la |\small|). The text that follows |\bf@boxformatting| is +% guaranteed to be a group that ends in |\par|, so if +% |\bf@boxformatting| accepts an argument, the macro should be defined +% with |\long| (e.g.,~with |\newcommand| but not with |\newcommand*|). +% \begin{macrocode} +\newcommand*{\bf@boxformatting}{\centering} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\bf@bitwidth} % 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}} +\newlength{\bf@bitwidth} +\settowidth{\bf@bitwidth}{\bf@bitformatting{99i}} % \end{macrocode} % \end{macro} % -% \begin{macro}{\byteheight} -% \usermacro -% The height of a single byte. +% \begin{macro}{\bf@bitheight} +% The height of a single bit within the bit field. % \begin{macrocode} -\newlength{\byteheight} -\AtBeginDocument{\setlength{\byteheight}{4ex}} +\newlength{\bf@bitheight} +\setlength{\bf@bitheight}{4ex} % \end{macrocode} % \end{macro} % @@ -1072,9 +1812,9 @@ % |[r]|ight, |[t]|op, and/or |[b]|ottom (default: |lrtb|). % \begin{macrocode} \DeclareRobustCommand{\bitbox}[3][lrtb]{% - \setlength{\units@wide}{\bitwidth * #2}% + \setlength{\units@wide}{\bf@bitwidth * #2}% \parse@bitbox@arg{#1}% - \draw@bit@picture{\strip@pt\units@wide}{\strip@pt\byteheight}{#3}} + \draw@bit@picture{\strip@pt\units@wide}{\strip@pt\bf@bitheight}{#3}} % \end{macrocode} % \end{macro} % @@ -1086,8 +1826,8 @@ % |[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}% + \setlength{\units@wide}{\bf@bitwidth * \value{bits@wide}}% + \setlength{\units@tall}{\bf@bitheight * #2}% \parse@bitbox@arg{#1}% \draw@bit@picture{\strip@pt\units@wide}{\strip@pt\units@tall}{#3}} % \end{macrocode} @@ -1116,7 +1856,7 @@ % 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}{% + \put(0,0){\makebox(#1,#2){\parbox{#1\unitlength}{% \bf@newdimen\height \bf@newdimen\depth \bf@newdimen\totalheight @@ -1127,7 +1867,7 @@ \width=#1\unitlength \def\widthunits{#1}% \def\heightunits{#2}% - \centering #3}}}% + \bf@boxformatting{#3\par}}}}% % \end{macrocode} % \end{macro} % \end{macro} @@ -1160,7 +1900,7 @@ % \begin{macrocode} \ifcounting@words \inc@bytefield@height{\unitlength * \real{#2}}% - \counting@wordsfalse + \global\counting@wordsfalse \fi \ignorespaces} % \end{macrocode} @@ -1247,7 +1987,7 @@ % 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@wide}{\bf@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}% @@ -1261,7 +2001,7 @@ \end{picture}% \ifcounting@words \inc@bytefield@height{\unitlength * \real{\num@tall}}% - \counting@wordsfalse + \global\counting@wordsfalse \fi} % \end{macrocode} % \end{macro} @@ -1280,8 +2020,8 @@ % \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@wide}{\bf@bitwidth * \value{bits@wide}}% + \setlength{\units@tall}{\heightof{\bf@bitformatting{1234567890}}}% \setlength{\units@high}{\units@tall * -1}% \def\bit@endianness{#1}% \begin{picture}(\strip@pt\units@wide,\strip@pt\units@tall)% @@ -1290,7 +2030,7 @@ \end{picture}% \ifcounting@words \inc@bytefield@height{\unitlength * \real{\strip@pt\units@tall}}% - \counting@wordsfalse + \global\counting@wordsfalse \fi \ignorespaces} % \end{macrocode} @@ -1338,13 +2078,13 @@ \ifnum\value{header@val}<\value{max@header@val}% \if\bit@endianness b% \setlength{\header@xpos}{% - \bitwidth * (\value{bits@wide}-\value{header@val}-1)} + \bf@bitwidth * (\value{bits@wide}-\value{header@val}-1)} \else - \setlength{\header@xpos}{\bitwidth * \value{header@val}} + \setlength{\header@xpos}{\bf@bitwidth * \value{header@val}} \fi \put(\strip@pt\header@xpos,0){% - \makebox(\strip@pt\bitwidth,\strip@pt\units@tall){% - \tiny \theheader@val}} + \makebox(\strip@pt\bf@bitwidth,\strip@pt\units@tall){% + \bf@bitformatting{\theheader@val}}} \addtocounter{header@val}{1} \repeat} % \end{macrocode} @@ -1354,41 +2094,61 @@ % % \subsubsection{Curly-brace manipulation} % -% \begin{macro}{\curlyshrinkage} -% \usermacro -% Reduce the height of a curly brace by |\curlyshrinkage| so its ends don't +% \begin{macro}{\bf@leftcurlyshrinkage} +% \begin{macro}{\bf@rightcurlyshrinkage} +% Reduce the height of a left (right) curly brace by +% |\bf@leftcurlyshrinkage| (|\bf@rightcurlyshrinkage|) 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. +% 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, |\bf@leftcurlyshrinkage| and +% |\bf@rightcurlyshrinkage| can be modified. % \begin{macrocode} -\newlength{\curlyshrinkage} -\setlength{\curlyshrinkage}{5pt} +\def\bf@leftcurlyshrinkage{5pt} +\def\bf@rightcurlyshrinkage{5pt} % \end{macrocode} % \end{macro} +% \end{macro} % -% \begin{macro}{\curlyspace} -% \usermacro -% \begin{macro}{\labelspace} -% \usermacro +% \begin{macro}{\bf@leftcurlyspace} +% \begin{macro}{\bf@rightcurlyspace} +% \begin{macro}{\bf@leftlabelspace} +% \begin{macro}{\bf@rightlabelspace} % 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. +% (i.e.,~after a curly brace). +% \begin{macrocode} +\def\bf@leftcurlyspace{0pt} +\def\bf@rightcurlyspace{0pt} +\def\bf@leftlabelspace{0pt} +\def\bf@rightlabelspace{0pt} +% \end{macrocode} +% \begin{macrocode} +\gdef\bf@leftcurlyspace{1ex} +\gdef\bf@rightcurlyspace{1ex} +\gdef\bf@leftlabelspace{0.5ex} +\gdef\bf@rightlabelspace{0.5ex} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\bf@leftcurly} +% \begin{macro}{\bf@rightcurly} +% Symbols to use as left and right curly braces. These symbols must be +% extensible math symbols (i.e.,~they will immediately follow |\left| or +% |\right| in math mode). % \begin{macrocode} -\newlength{\curlyspace} -\AtBeginDocument{\setlength{\curlyspace}{1ex}} -\newlength{\labelspace} -\AtBeginDocument{\setlength{\labelspace}{0.5ex}} +\let\bf@leftcurly=\{ +\let\bf@rightcurly=\} % \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)} +% \changes{v1.2}{2004/06/14}{Bug fix: Defined \cs{curly@box} globally +% (suggested by Stefan Ulrich)} % \begin{macrocode} \newbox{\curly@box} % \end{macrocode} @@ -1398,6 +2158,7 @@ % \begin{macro}{\curly@height} % \begin{macro}{\half@curly@height} % \begin{macro}{\curly@shift} +% \begin{macro}{\old@axis} % 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 @@ -1406,18 +2167,20 @@ % \begin{macrocode} \def\store@rcurly#1#2{% \begingroup - \bf@newdimen\curly@height% - \setlength{\curly@height}{#2 - \curlyshrinkage}% - \bf@newdimen\half@curly@height% + \bf@newdimen\curly@height + \setlength{\curly@height}{#2 - \bf@rightcurlyshrinkage}% + \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}% + \bf@newdimen\curly@shift + \setlength{\curly@shift}{\bf@rightcurlyshrinkage}% + \setlength{\curly@shift}{\half@curly@height + 0.5\curly@shift}% \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\}$% + \left. + \vrule height\half@curly@height + width 0pt + depth\half@curly@height\right\bf@rightcurly$% $\fontdimen22\textfont2=\old@axis$}}% \endgroup } @@ -1426,6 +2189,7 @@ % \end{macro} % \end{macro} % \end{macro} +% \end{macro} % % \begin{macro}{\store@lcurly} % \begin{macro}{\curly@height} @@ -1435,18 +2199,20 @@ % \begin{macrocode} \def\store@lcurly#1#2{% \begingroup - \bf@newdimen\curly@height% - \setlength{\curly@height}{#2 - \curlyshrinkage}% - \bf@newdimen\half@curly@height% + \bf@newdimen\curly@height + \setlength{\curly@height}{#2 - \bf@leftcurlyshrinkage}% + \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}% + \bf@newdimen\curly@shift + \setlength{\curly@shift}{\bf@leftcurlyshrinkage}% + \setlength{\curly@shift}{\half@curly@height + 0.5\curly@shift}% \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.$% + \left\bf@leftcurly + \vrule height\half@curly@height + width 0pt + depth\half@curly@height\right.$% $\fontdimen22\textfont2=\old@axis$}}% \endgroup } @@ -1461,7 +2227,7 @@ % \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 +% |\end{rightwordgroup}| defines it to output the word label and then % reset itself to a no-op. % \begin{macrocode} \def\show@wordlabelr{} @@ -1479,39 +2245,49 @@ % \end{macro} % \end{macro} % -% \begin{macro}{\wordgroupr} -% \usermacro -% \begin{macro}{\endwordgroupr} +% \begin{environment}{rightwordgroup} % \usermacro -% Label the words defined between |\wordgroupr| and |\endwordgroupr| -% on the right side of the figure. +% Label the words defined between |\begin{rightwordgroup}| and |\end{rightwordgroup}| +% on the right side of the bit field. % The argument is the text of the label. The label is typeset to the % right of a large curly brace, which groups the words together. % \begin{macrocode} -\newenvironment{wordgroupr}[1]{% +\newenvironment{rightwordgroup}[1]{% +% \end{macrocode} +% We begin by ending the group that |\begin{rightwordgroup}| created. This +% lets the |rightwordgroup| environment span rows (because we're technically +% no longer within the environment). +% \begin{macrocode} + \endgroup % \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| +% |\begin{rightwordgroup}| merely stores the starting height in |\wordlabelr@start| +% and the user-supplied text in |\wordlabelr@text|. |\end{rightwordgroup}| % does most of the work. % \begin{macrocode} \global\wordlabelr@start=\bytefield@height \gdef\wordlabelr@text{#1}% - \ignorespaces% + \ignorespaces }{% - \global\wordlabelr@end=\bytefield@height % \end{macrocode} % \end{macro} % \end{macro} +% \begin{macro}{\wordlabelr@end} +% Because we already ended the group that |\begin{rightwordgroup}| created +% we now have to begin a group for |\end{rightwordgroup}| to end. +% \begin{macrocode} + \begingroup + \global\wordlabelr@end=\bytefield@height +% \end{macrocode} % \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. +% Redefine |\show@wordlabelr| to output |\bf@rightcurlyspace| space, +% followed by a large curly brace (in |\curlybox|), followed by +% |\bf@rightlabelspace| 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}{% @@ -1519,17 +2295,17 @@ \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% + \bf@newdimen\total@box@width \setlength{\total@box@width}{% - \curlyspace + + \bf@rightcurlyspace + \widthof{\usebox{\curly@box}} + - \labelspace + + \bf@rightlabelspace + \label@box@width}% \begin{picture}(\strip@pt\total@box@width,0) \put(0,0){% - \hspace*{\curlyspace}% + \hspace*{\bf@rightcurlyspace}% \usebox{\curly@box}% - \hspace*{\labelspace}% + \hspace*{\bf@rightlabelspace}% \makebox(\strip@pt\label@box@width,\strip@pt\label@box@height){% \usebox{\word@label@box}}} \end{picture}% @@ -1537,11 +2313,20 @@ % The last thing |\show@wordlabelr| does is redefine itself back to a no-op. % \begin{macrocode} \gdef\show@wordlabelr{}}% - \ignorespaces} % \end{macrocode} % \end{macro} +% \begin{macro}{\@currenvir} +% \begin{macrocode} +% Because of our meddling with |\begingroup| and |\endgroup|, the +% current environment is all messed up. We therefore force the +% |\end{rightwordgroup}| to succeed, even if it doesn't match the preceding +% |\begin|. + \def\@currenvir{rightwordgroup}% + \ignorespaces +} +% \end{macrocode} % \end{macro} -% \end{macro} +% \end{environment} % % \subsubsection{Left-side labels} % @@ -1557,7 +2342,7 @@ % \end{macro} % % \begin{macro}{\total@box@width} -% The total width of the next label to typeset on the left of the figure, +% The total width of the next label to typeset on the left of the bit field, % that is, the aggregate width of the text box, curly brace, and spaces % on either side of the curly brace. % \begin{macrocode} @@ -1568,46 +2353,52 @@ % \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 +% |\begin{leftwordgroup}| 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} +% \begin{environment}{leftwordgroup} % \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 +% This environment is essentially the same as the |rightwordgroup| +% environment but puts the label on the left. However, the following +% code is not symmetric to that of |rightwordgroup|. The problem is that we +% encounter |\begin{leftwordgroup}| 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 +% |\end{leftwordgroup}|, 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}?} +% \emph{top} of the subsequent row, perhaps with +% \texttt{\string\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. +% will expand to fit that space. |\end{leftwordgroup}| outputs the label +% immediately. Even though |\end{leftwordgroup}| 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 bit field or extend beyond the bit-field +% boundaries. % \begin{macrocode} -\newenvironment{wordgroupl}[1]{% +\newenvironment{leftwordgroup}[1]{% +% \end{macrocode} +% We begin by ending the group that |\begin{rightwordgroup}| created. This +% lets the |leftwordgroup| environment span rows (because we're technically +% no longer within the environment). +% \begin{macrocode} + \endgroup % \end{macrocode} % \begin{macro}{\wordlabell@start} % \begin{macro}{\wordlabell@text} -% First, we store the starting height and label text, which are needed -% by |\endwordgroupl|. +% We store the starting height and label text, which are needed by the +% |\end{leftwordgroup}|. % \begin{macrocode} \global\wordlabell@start=\bytefield@height \gdef\wordlabell@text{#1}% @@ -1617,7 +2408,7 @@ % 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 +% |\end{leftwordgroup}|, 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 @@ -1629,12 +2420,13 @@ \settowidth{\label@box@width}{\usebox{\word@label@box}}% \store@lcurly{\curly@box}{5cm}% \setlength{\total@lbox@width}{% - \curlyspace + + \bf@leftcurlyspace + \widthof{\usebox{\curly@box}} + - \labelspace + + \bf@leftlabelspace + \label@box@width}% \global\total@lbox@width=\total@lbox@width % \end{macrocode} +% \begin{macro}{\make@lspace} % 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 @@ -1644,22 +2436,29 @@ \gdef\make@lspace{% \hspace*{\total@lbox@width}% \gdef\make@lspace{}}% - \ignorespaces% + \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. +% \end{macro} +% Because we already ended the group that |\begin{leftwordgroup}| created +% we have to start the |\end{leftwordgroup}| by beginning a group for +% |\end{leftwordgroup}| to end. +% \begin{macrocode} + \begingroup +% \end{macrocode} +% The |\end{leftwordgroup}| code is comparatively straightforward. We +% calculate the final height of the word group, and then output the +% label text, followed by |\bf@leftlabelspace| space, followed by a +% curly brace (now that we know how tall it's supposed to be), followed +% by |\bf@leftcurlyspace| space. The trick, as described earlier, is +% that we typeset the entire label in the second column, but in a $0 +% \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}}% + -\total@lbox@width - \bf@bitwidth*\value{bits@wide}}% \sbox{\word@label@box}{% \begin{tabular}[b]{@{}l@{}}\wordlabell@text\end{tabular}}% \settowidth{\label@box@width}{\usebox{\word@label@box}}% @@ -1669,14 +2468,22 @@ \put(\strip@pt\starting@point,0){% \makebox(\strip@pt\label@box@width,\strip@pt\label@box@height){% \usebox{\word@label@box}}% - \hspace*{\labelspace}% + \hspace*{\bf@leftlabelspace}% \usebox{\curly@box}% - \hspace*{\curlyspace}} + \hspace*{\bf@leftcurlyspace}} \end{picture}% +% \end{macrocode} +% \begin{macro}{\@currenvir} +% \begin{macrocode} +% Because of our meddling with |\begingroup| and |\endgroup|, the +% current environment is all messed up. We therefore force the +% |\end{leftwordgroup}| to succeed, even if it doesn't match the preceding +% |\begin|. + \def\@currenvir{leftwordgroup}% \ignorespaces} % \end{macrocode} % \end{macro} -% \end{macro} +% \end{environment} % % \subsubsection{Scratch space} % @@ -1694,9 +2501,315 @@ % \end{macro} % \end{macro} % +% \subsection{Compatibility mode} +% +% \begin{macro}{\bf@enter@compatibility@mode@i} +% \pkgname{bytefield}'s interface changed substantially with the move to +% version~2.0. To give version~1.\textit{x} users a quick way to build +% their old documents, we provide a version~1.\textit{x} compatibility +% mode. We don't enable this by default because it exposes a number of +% extra length registers (a precious resource) and we therefore want to +% encourage users to migrate to the new interface. % \begin{macrocode} -% +\newcommand{\bf@enter@compatibility@mode@i}{% % \end{macrocode} +% \begin{macro}{\bitwidth} +% \begin{macro}{\byteheight} +% \begin{macro}{\curlyspace} +% \begin{macro}{\labelspace} +% \begin{macro}{\curlyshrinkage} +% Define a handful of lengths that the user was allowed to |\setlength| +% explicitly in \pkgname{bytefield}~1.\textit{x}. +% \begin{macrocode} + \PackageInfo{bytefield}{Entering version 1 compatibility mode}% + \newlength{\bitwidth}% + \newlength{\byteheight}% + \newlength{\curlyspace}% + \newlength{\labelspace}% + \newlength{\curlyshrinkage}% +% \end{macrocode} +% \begin{macrocode} + \settowidth{\bitwidth}{\tiny 99i}% + \setlength{\byteheight}{4ex}% + \setlength{\curlyspace}{1ex}% + \setlength{\labelspace}{0.5ex}% + \setlength{\curlyshrinkage}{5pt}% +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \begin{macro}{\newbytefield} +% \begin{macro}{\endnewbytefield} +% \begin{environment}{bytefield} +% Redefine the |bytefield| environment in terms of the existing +% (new-interface) |bytefield| environment. The difference is that the +% redefinition utilizes all of the preceding lengths. +% \begin{macrocode} + \let\newbytefield=\bytefield + \let\endnewbytefield=\endbytefield + \renewenvironment{bytefield}[1]{% + \begin{newbytefield}[% + bitwidth=\bitwidth, + bitheight=\byteheight, + curlyspace=\curlyspace, + labelspace=\labelspace, + curlyshrinkage=\curlyshrinkage]{##1}% + }{% + \end{newbytefield}% + } +% \end{macrocode} +% \end{environment} +% \end{macro} +% \end{macro} +% \begin{macro}{\wordgroupr} +% \begin{macro}{\endwordgroupr} +% \begin{macro}{\wordgroupl} +% \begin{macro}{\endwordgroupl} +% Define |\wordgroupr|, |\endwordgroupr|, |\wordgroupl|, and +% |\endwordgroupl| in terms of the new |rightwordgroup| and +% |leftwordgroup| environments. +% \begin{macrocode} + \def\wordgroupr{\begin{rightwordgroup}} + \def\endwordgroupr{\end{rightwordgroup}} + \def\wordgroupl{\begin{leftwordgroup}} + \def\endwordgroupl{\end{leftwordgroup}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\bytefieldsetup} +% Disable |\bytefieldsetup| in compatibility mode because it doesn't +% work as expected. (Every use of the compatibility-mode |bytefield| +% environment overwrites all of the figure-formatting values.) +% \begin{macrocode} + \renewcommand{\bytefieldsetup}[1]{% + \PackageError{bytefield}{% + The \protect\bytefieldsetup\space macro is not available in\MessageBreak + version 1 compatibility mode% + }{% + Remove [compat1] from the \protect\usepackage{bytefield} line to + make \protect\bytefieldsetup\MessageBreak + available to this document.\space\space (The document may also need + to be modified to use\MessageBreak + the new bytefield interface.) + }% + }% +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\wordgroupr} +% \begin{macro}{\endwordgroupr} +% \begin{macro}{\wordgroupl} +% \begin{macro}{\endwordgroupl} +% Issue a helpful error message for the commands that were removed in +% \pkgname{bytefield}~v2.0. While this won't help users who first +% invalid action is to modify a no-longer-extant length register such as +% |\bitwidth| or |\byteheight|, it may benefit at least a few users who +% didn't realize that the \pkgname{bytefield} interface has changed +% substantially with version~2.0. +% \begin{macrocode} +\newcommand{\wordgroupr}{% + \PackageError{bytefield}{% + Macros \protect\wordgroupr, \protect\wordgroupl, \protect\endwordgroupr, + \MessageBreak + and \protect\endwordgroupl\space no longer exist% + }{% + Starting with version 2.0, bytefield uses \protect\begin{wordgroupr}... + \MessageBreak + \protect\end{wordgroupr} and \protect\begin{wordgroupl}...% + \protect\end{wordgroupl}\MessageBreak + to specify word groups and a new \protect\bytefieldsetup\space macro to + \MessageBreak + change bytefield's various formatting parameters.% + }% +} +\let\endwordgroupr=\wordgroupr +\let\wordgroupl=\wordgroupr +\let\endwordgroupl=\wordgroupr +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \subsection{Option processing} +% +% We use the \textsf{keyval} package to handle option processing. +% Because all of \pkgname{bytefield}'s options have local impact, options +% can be specified either as package arguments or through the use of the +% |\bytefieldsetup| macro. +% +% \begin{macro}{\KV@bytefield@bitwidth} +% \begin{macro}{\bf@bw@arg} +% \begin{macro}{\bf@auto} +% Specify the width of a bit number in the bit header. If the special +% value ``|auto|'' is given, set the width to the width of a formatted +% ``|99i|''. +% \begin{macrocode} +\define@key{bytefield}{bitwidth}{% + \def\bf@bw@arg{#1}% + \def\bf@auto{auto}% + \ifx\bf@bw@arg\bf@auto + \settowidth{\bf@bitwidth}{\bf@bitformatting{99i}}% + \else + \setlength{\bf@bitwidth}{#1}% + \fi +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\KV@bytefield@bf@bitheight} +% Specify the height of a bit in a |\bitbox| or |\wordbox|. +% \begin{macrocode} +\define@key{bytefield}{bitheight}{\setlength{\bf@bitheight}{#1}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\KV@bytefield@bitformatting} +% Specify the style of a bit number in the bit header. This should be +% passed an expression that takes either one argument (e.g.,~|\textit|) +% or no arguments (e.g.,~|{\small\bfseries}|). +% \begin{macrocode} +\define@key{bytefield}{bitformatting}{\def\bf@bitformatting{#1}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\KV@bytefield@boxformatting} +% Specify a style to be applied to the contents of every bit box and +% word box. This should be passed an expression that takes either one +% argument (e.g.,~|\textit|) or no arguments +% (e.g.,~|{\small\bfseries}|). +% \begin{macrocode} +\define@key{bytefield}{boxformatting}{\def\bf@boxformatting{#1}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\KV@bytefield@leftcurly} +% \begin{macro}{\KV@bytefield@rightcurly} +% Specify the symbol to use for bracketing a left or right word group. +% This must be an extensible math delimiter (i.e.,~something that can +% immediately follow |\left| or |\right| in math mode). +% \begin{macrocode} +\define@key{bytefield}{leftcurly}{\def\bf@leftcurly{#1}} +\define@key{bytefield}{rightcurly}{\def\bf@rightcurly{#1}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\KV@bytefield@leftcurlyspace} +% \begin{macro}{\KV@bytefield@rightcurlyspace} +% \begin{macro}{\KV@bytefield@curlyspace} +% Specify the amount of space between the bit fields in a word group and +% the adjacent left or right curly brace. The \optname{curlyspace} +% option is a shortcut that puts the same space before both left and +% right curly braces. +% \begin{macrocode} +\define@key{bytefield}{leftcurlyspace}{\def\bf@leftcurlyspace{#1}} +\define@key{bytefield}{rightcurlyspace}{\def\bf@rightcurlyspace{#1}} +\define@key{bytefield}{curlyspace}{% + \def\bf@leftcurlyspace{#1}% + \def\bf@rightcurlyspace{#1}% +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\KV@bytefield@leftlabelspace} +% \begin{macro}{\KV@bytefield@rightlabelspace} +% \begin{macro}{\KV@bytefield@labelspace} +% Specify the amount of space between a left or right word group's curly +% brace and the associated label text. The |labelspace| option is a +% shortcut that puts the same space after both left and right curly +% braces. +% \begin{macrocode} +\define@key{bytefield}{leftlabelspace}{\def\bf@leftlabelspace{#1}} +\define@key{bytefield}{rightlabelspace}{\def\bf@rightlabelspace{#1}} +\define@key{bytefield}{labelspace}{% + \def\bf@leftlabelspace{#1}% + \def\bf@rightlabelspace{#1}% +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\KV@bytefield@leftcurlyshrinkage} +% \begin{macro}{\KV@bytefield@rightcurlyshrinkage} +% \begin{macro}{\KV@bytefield@curlyshrinkage} +% Specify the number of points by which to reduce the height of a curly +% brace (left, right, or both) so its ends don't overlap whatever's +% above or below it. +% \begin{macrocode} +\define@key{bytefield}{leftcurlyshrinkage}{\def\bf@leftcurlyshrinkage{#1}} +\define@key{bytefield}{rightcurlyshrinkage}{\def\bf@rightcurlyshrinkage{#1}} +\define@key{bytefield}{curlyshrinkage}{% + \def\bf@leftcurlyshrinkage{#1}% + \def\bf@rightcurlyshrinkage{#1}% +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\bytefieldsetup} +% \usermacro +% \changes{v2.0}{2011/01/18}{Introduced this macro to provide a more +% convenient way of configuring \pkgname{bytefield}'s parameters} +% \begin{macro}{\bf@bytefieldsetup} +% Reconfigure values for various \pkgname{bytefield} parameters. +% Internally to the package we use the |\bf@bytefieldsetup| macro +% instead of |\bytefieldsetup|. This enables us to redefine +% |\bytefieldsetup| when entering version~1 compatibility mode without +% impacting the rest of \pkgname{bytefield}. +% \begin{macrocode} +\newcommand{\bf@bytefieldsetup}{\setkeys{bytefield}} +\let\bytefieldsetup=\bf@bytefieldsetup +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% We define only a single option that can be used only as a package +% option, not as an argument to |\bytefieldsetup|: |compat1| instructs +% \pkgname{bytefield} to enter version~1 compatibility mode---at the +% cost of a number of additional length registers and the inability to +% specify parameters in the argument to the |bytefield| environment. +% \begin{macrocode} +\DeclareOption{compat1}{\bf@enter@compatibility@mode@i} +% \end{macrocode} +% +% \begin{macro}{\bf@package@options} +% \begin{macro}{\next} +% We want to use |\bf@bytefieldsetup| to process \pkgname{bytefield} +% package options. Unfortunately, |\DeclareOption| doesn't handle +% \meta{key}=\meta{value} arguments. Hence, we use |\DeclareOption*| to +% catch \emph{all} options, each of which it appends to +% |\bf@package@options|. |\bf@package@options| is passed to +% |\bf@bytefieldsetup| only at the beginning of the document so that the +% options it specifies (a)~can refer to ex-heights and (b)~override the +% default values, which are also set at the beginning of the document. +% \begin{macrocode} +\def\bf@package@options{} +\DeclareOption*{% + \edef\next{% + \noexpand\g@addto@macro\noexpand\bf@package@options{,\CurrentOption}% + }% + \next +} +\ProcessOptions\relax +\expandafter\bf@bytefieldsetup\expandafter{\bf@package@options} +% \end{macrocode} +% \end{macro} +% \end{macro} % % \Finale \endinput diff --git a/Master/texmf-dist/source/latex/bytefield/bytefield.ins b/Master/texmf-dist/source/latex/bytefield/bytefield.ins index adfda84046e..9eac6249190 100644 --- a/Master/texmf-dist/source/latex/bytefield/bytefield.ins +++ b/Master/texmf-dist/source/latex/bytefield/bytefield.ins @@ -1,5 +1,5 @@ %% -%% Copyright (C) 2010 by Scott Pakin +%% Copyright (C) 2011 by Scott Pakin %% %% This file may be distributed and/or modified under the conditions of %% the LaTeX Project Public License, either version 1.3a of this license @@ -21,7 +21,7 @@ This is a generated file. -Copyright (C) 2010 by Scott Pakin +Copyright (C) 2011 by Scott Pakin This file may be distributed and/or modified under the conditions of the LaTeX Project Public License, either version 1.3a of this license diff --git a/Master/texmf-dist/tex/latex/bytefield/bytefield.sty b/Master/texmf-dist/tex/latex/bytefield/bytefield.sty index 40ce86b2517..98e039072c7 100644 --- a/Master/texmf-dist/tex/latex/bytefield/bytefield.sty +++ b/Master/texmf-dist/tex/latex/bytefield/bytefield.sty @@ -8,7 +8,7 @@ %% %% This is a generated file. %% -%% Copyright (C) 2010 by Scott Pakin +%% Copyright (C) 2011 by Scott Pakin %% %% This file may be distributed and/or modified under the conditions of %% the LaTeX Project Public License, either version 1.3a of this license @@ -22,13 +22,15 @@ %% \NeedsTeXFormat{LaTeX2e}[1999/12/01] \ProvidesPackage{bytefield} - [2010/10/31 v1.3 Network protocol diagrams] + [2011/01/25 v2.0 Network protocol diagrams] \RequirePackage{calc}[1998/07/07] +\RequirePackage{keyval} \def\bf@newdimen#1{\advance\count11 by 1 - \ch@ck1\insc@unt\dimen% Check room + \ch@ck1\insc@unt\dimen \allocationnumber=\count11 \dimendef#1=\allocationnumber - \wlog{\string#1=\string\dimen\the\allocationnumber\space (locally)}} + \wlog{\string#1=\string\dimen\the\allocationnumber\space (locally)}% +} \AtBeginDocument{% \begingroup\expandafter\expandafter\expandafter\endgroup \expandafter\ifx\csname locdimen\endcsname\relax @@ -44,42 +46,46 @@ \global\advance\bytefield@height by \bytefield@height@increment} \newcounter{bits@wide} \newsavebox{\entire@bytefield@picture} -\newenvironment{bytefield}[1]{% - \setcounter{bits@wide}{#1}% +\newenvironment{bytefield}[2][]{% + \bf@bytefieldsetup{#1}% + \setcounter{bits@wide}{#2}% \let\old@nl=\\% \let\amp=&% \catcode`\&=10 \openup -1pt \setlength{\bytefield@height}{0pt}% \setlength{\unitlength}{1pt}% - \counting@wordstrue + \global\counting@wordstrue \begin{lrbox}{\entire@bytefield@picture}% \renewcommand{\\}{% - \amp\show@wordlabelr\cr% - \ignorespaces\counting@wordstrue\make@lspace\amp}% - \vbox\bgroup\ialign\bgroup##\amp##\amp##\cr\amp% + \unskip + \amp\show@wordlabelr\cr + \ignorespaces\global\counting@wordstrue\make@lspace\amp}% + \vbox\bgroup\ialign\bgroup##\amp##\amp##\cr\amp }{% - \amp\show@wordlabelr\cr\egroup\egroup% + \amp\show@wordlabelr\cr\egroup\egroup \end{lrbox}% \usebox{\entire@bytefield@picture}} -\newlength{\bitwidth} -\AtBeginDocument{\settowidth{\bitwidth}{\tiny 99i}} -\newlength{\byteheight} -\AtBeginDocument{\setlength{\byteheight}{4ex}} +\newcommand*{\bf@bitformatting}{\tiny} +\newcommand*{\bf@boxformatting}{\centering} +\newlength{\bf@bitwidth} +\settowidth{\bf@bitwidth}{\bf@bitformatting{99i}} +\newlength{\bf@bitheight} +\setlength{\bf@bitheight}{4ex} \newlength{\units@wide} \newlength{\units@tall} \DeclareRobustCommand{\bitbox}[3][lrtb]{% - \setlength{\units@wide}{\bitwidth * #2}% + \setlength{\units@wide}{\bf@bitwidth * #2}% \parse@bitbox@arg{#1}% - \draw@bit@picture{\strip@pt\units@wide}{\strip@pt\byteheight}{#3}} + \draw@bit@picture{\strip@pt\units@wide}{\strip@pt\bf@bitheight}{#3}} \DeclareRobustCommand{\wordbox}[3][lrtb]{% - \setlength{\units@wide}{\bitwidth * \value{bits@wide}}% - \setlength{\units@tall}{\byteheight * #2}% + \setlength{\units@wide}{\bf@bitwidth * \value{bits@wide}}% + \setlength{\units@tall}{\bf@bitheight * #2}% \parse@bitbox@arg{#1}% \draw@bit@picture{\strip@pt\units@wide}{\strip@pt\units@tall}{#3}} \DeclareRobustCommand{\draw@bit@picture}[3]{% \begin{picture}(#1,#2)% - \put(0,0){\makebox(#1,#2){\parbox[c]{#1\unitlength}{% + \put(0,0){\makebox(#1,#2){\parbox{#1\unitlength}{% \bf@newdimen\height \bf@newdimen\depth \bf@newdimen\totalheight @@ -90,7 +96,7 @@ \width=#1\unitlength \def\widthunits{#1}% \def\heightunits{#2}% - \centering #3}}}% + \bf@boxformatting{#3\par}}}}% \ifbitbox@top \put(0,#2){\line(1,0){#1}} \fi @@ -106,7 +112,7 @@ \end{picture}% \ifcounting@words \inc@bytefield@height{\unitlength * \real{#2}}% - \counting@wordsfalse + \global\counting@wordsfalse \fi \ignorespaces} \newif\ifbitbox@top @@ -141,7 +147,7 @@ \fi} \newlength{\units@high} \DeclareRobustCommand{\skippedwords}[1][2ex]{% - \setlength{\units@wide}{\bitwidth * \value{bits@wide}}% + \setlength{\units@wide}{\bf@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}% @@ -155,12 +161,12 @@ \end{picture}% \ifcounting@words \inc@bytefield@height{\unitlength * \real{\num@tall}}% - \counting@wordsfalse + \global\counting@wordsfalse \fi} \DeclareRobustCommand{\bitheader}[2][l]{% \parse@bitbox@arg{lrtb}% - \setlength{\units@wide}{\bitwidth * \value{bits@wide}}% - \setlength{\units@tall}{\heightof{\tiny 9}}% + \setlength{\units@wide}{\bf@bitwidth * \value{bits@wide}}% + \setlength{\units@tall}{\heightof{\bf@bitformatting{1234567890}}}% \setlength{\units@high}{\units@tall * -1}% \def\bit@endianness{#1}% \begin{picture}(\strip@pt\units@wide,\strip@pt\units@tall)% @@ -169,7 +175,7 @@ \end{picture}% \ifcounting@words \inc@bytefield@height{\unitlength * \real{\strip@pt\units@tall}}% - \counting@wordsfalse + \global\counting@wordsfalse \fi \ignorespaces} \def\parse@range@list#1,{% @@ -188,64 +194,76 @@ \ifnum\value{header@val}<\value{max@header@val}% \if\bit@endianness b% \setlength{\header@xpos}{% - \bitwidth * (\value{bits@wide}-\value{header@val}-1)} + \bf@bitwidth * (\value{bits@wide}-\value{header@val}-1)} \else - \setlength{\header@xpos}{\bitwidth * \value{header@val}} + \setlength{\header@xpos}{\bf@bitwidth * \value{header@val}} \fi \put(\strip@pt\header@xpos,0){% - \makebox(\strip@pt\bitwidth,\strip@pt\units@tall){% - \tiny \theheader@val}} + \makebox(\strip@pt\bf@bitwidth,\strip@pt\units@tall){% + \bf@bitformatting{\theheader@val}}} \addtocounter{header@val}{1} \repeat} -\newlength{\curlyshrinkage} -\setlength{\curlyshrinkage}{5pt} -\newlength{\curlyspace} -\AtBeginDocument{\setlength{\curlyspace}{1ex}} -\newlength{\labelspace} -\AtBeginDocument{\setlength{\labelspace}{0.5ex}} +\def\bf@leftcurlyshrinkage{5pt} +\def\bf@rightcurlyshrinkage{5pt} +\def\bf@leftcurlyspace{0pt} +\def\bf@rightcurlyspace{0pt} +\def\bf@leftlabelspace{0pt} +\def\bf@rightlabelspace{0pt} +\gdef\bf@leftcurlyspace{1ex} +\gdef\bf@rightcurlyspace{1ex} +\gdef\bf@leftlabelspace{0.5ex} +\gdef\bf@rightlabelspace{0.5ex} +\let\bf@leftcurly=\{ +\let\bf@rightcurly=\} \newbox{\curly@box} \def\store@rcurly#1#2{% \begingroup - \bf@newdimen\curly@height% - \setlength{\curly@height}{#2 - \curlyshrinkage}% - \bf@newdimen\half@curly@height% + \bf@newdimen\curly@height + \setlength{\curly@height}{#2 - \bf@rightcurlyshrinkage}% + \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}% + \bf@newdimen\curly@shift + \setlength{\curly@shift}{\bf@rightcurlyshrinkage}% + \setlength{\curly@shift}{\half@curly@height + 0.5\curly@shift}% \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\}$% + \left. + \vrule height\half@curly@height + width 0pt + depth\half@curly@height\right\bf@rightcurly$% $\fontdimen22\textfont2=\old@axis$}}% \endgroup } \def\store@lcurly#1#2{% \begingroup - \bf@newdimen\curly@height% - \setlength{\curly@height}{#2 - \curlyshrinkage}% - \bf@newdimen\half@curly@height% + \bf@newdimen\curly@height + \setlength{\curly@height}{#2 - \bf@leftcurlyshrinkage}% + \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}% + \bf@newdimen\curly@shift + \setlength{\curly@shift}{\bf@leftcurlyshrinkage}% + \setlength{\curly@shift}{\half@curly@height + 0.5\curly@shift}% \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.$% + \left\bf@leftcurly + \vrule height\half@curly@height + width 0pt + depth\half@curly@height\right.$% $\fontdimen22\textfont2=\old@axis$}}% \endgroup } \def\show@wordlabelr{} \newlength{\wordlabelr@start} \newlength{\wordlabelr@end} -\newenvironment{wordgroupr}[1]{% +\newenvironment{rightwordgroup}[1]{% + \endgroup \global\wordlabelr@start=\bytefield@height \gdef\wordlabelr@text{#1}% - \ignorespaces% + \ignorespaces }{% + \begingroup \global\wordlabelr@end=\bytefield@height \gdef\show@wordlabelr{% \sbox{\word@label@box}{% @@ -253,27 +271,30 @@ \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% + \bf@newdimen\total@box@width \setlength{\total@box@width}{% - \curlyspace + + \bf@rightcurlyspace + \widthof{\usebox{\curly@box}} + - \labelspace + + \bf@rightlabelspace + \label@box@width}% \begin{picture}(\strip@pt\total@box@width,0) \put(0,0){% - \hspace*{\curlyspace}% + \hspace*{\bf@rightcurlyspace}% \usebox{\curly@box}% - \hspace*{\labelspace}% + \hspace*{\bf@rightlabelspace}% \makebox(\strip@pt\label@box@width,\strip@pt\label@box@height){% \usebox{\word@label@box}}} \end{picture}% \gdef\show@wordlabelr{}}% - \ignorespaces} + \def\@currenvir{rightwordgroup}% + \ignorespaces +} \newlength{\wordlabell@start} \newlength{\wordlabell@end} \newlength{\total@lbox@width} \gdef\make@lspace{} -\newenvironment{wordgroupl}[1]{% +\newenvironment{leftwordgroup}[1]{% + \endgroup \global\wordlabell@start=\bytefield@height \gdef\wordlabell@text{#1}% \sbox{\word@label@box}{% @@ -281,20 +302,21 @@ \settowidth{\label@box@width}{\usebox{\word@label@box}}% \store@lcurly{\curly@box}{5cm}% \setlength{\total@lbox@width}{% - \curlyspace + + \bf@leftcurlyspace + \widthof{\usebox{\curly@box}} + - \labelspace + + \bf@leftlabelspace + \label@box@width}% \global\total@lbox@width=\total@lbox@width \gdef\make@lspace{% \hspace*{\total@lbox@width}% \gdef\make@lspace{}}% - \ignorespaces% + \ignorespaces }{% + \begingroup \global\wordlabell@end=\bytefield@height \bf@newdimen\starting@point \setlength{\starting@point}{% - -\total@lbox@width - \bitwidth*\value{bits@wide}}% + -\total@lbox@width - \bf@bitwidth*\value{bits@wide}}% \sbox{\word@label@box}{% \begin{tabular}[b]{@{}l@{}}\wordlabell@text\end{tabular}}% \settowidth{\label@box@width}{\usebox{\word@label@box}}% @@ -304,14 +326,118 @@ \put(\strip@pt\starting@point,0){% \makebox(\strip@pt\label@box@width,\strip@pt\label@box@height){% \usebox{\word@label@box}}% - \hspace*{\labelspace}% + \hspace*{\bf@leftlabelspace}% \usebox{\curly@box}% - \hspace*{\curlyspace}} + \hspace*{\bf@leftcurlyspace}} \end{picture}% + \def\@currenvir{leftwordgroup}% \ignorespaces} \newlength{\label@box@width} \newlength{\label@box@height} \newsavebox{\word@label@box} +\newcommand{\bf@enter@compatibility@mode@i}{% + \PackageInfo{bytefield}{Entering version 1 compatibility mode}% + \newlength{\bitwidth}% + \newlength{\byteheight}% + \newlength{\curlyspace}% + \newlength{\labelspace}% + \newlength{\curlyshrinkage}% + \settowidth{\bitwidth}{\tiny 99i}% + \setlength{\byteheight}{4ex}% + \setlength{\curlyspace}{1ex}% + \setlength{\labelspace}{0.5ex}% + \setlength{\curlyshrinkage}{5pt}% + \let\newbytefield=\bytefield + \let\endnewbytefield=\endbytefield + \renewenvironment{bytefield}[1]{% + \begin{newbytefield}[% + bitwidth=\bitwidth, + bitheight=\byteheight, + curlyspace=\curlyspace, + labelspace=\labelspace, + curlyshrinkage=\curlyshrinkage]{##1}% + }{% + \end{newbytefield}% + } + \def\wordgroupr{\begin{rightwordgroup}} + \def\endwordgroupr{\end{rightwordgroup}} + \def\wordgroupl{\begin{leftwordgroup}} + \def\endwordgroupl{\end{leftwordgroup}} + \renewcommand{\bytefieldsetup}[1]{% + \PackageError{bytefield}{% + The \protect\bytefieldsetup\space macro is not available in\MessageBreak + version 1 compatibility mode% + }{% + Remove [compat1] from the \protect\usepackage{bytefield} line to + make \protect\bytefieldsetup\MessageBreak + available to this document.\space\space (The document may also need + to be modified to use\MessageBreak + the new bytefield interface.) + }% + }% +} +\newcommand{\wordgroupr}{% + \PackageError{bytefield}{% + Macros \protect\wordgroupr, \protect\wordgroupl, \protect\endwordgroupr, + \MessageBreak + and \protect\endwordgroupl\space no longer exist% + }{% + Starting with version 2.0, bytefield uses \protect\begin{wordgroupr}... + \MessageBreak + \protect\end{wordgroupr} and \protect\begin{wordgroupl}...% + \protect\end{wordgroupl}\MessageBreak + to specify word groups and a new \protect\bytefieldsetup\space macro to + \MessageBreak + change bytefield's various formatting parameters.% + }% +} +\let\endwordgroupr=\wordgroupr +\let\wordgroupl=\wordgroupr +\let\endwordgroupl=\wordgroupr +\define@key{bytefield}{bitwidth}{% + \def\bf@bw@arg{#1}% + \def\bf@auto{auto}% + \ifx\bf@bw@arg\bf@auto + \settowidth{\bf@bitwidth}{\bf@bitformatting{99i}}% + \else + \setlength{\bf@bitwidth}{#1}% + \fi +} +\define@key{bytefield}{bitheight}{\setlength{\bf@bitheight}{#1}} +\define@key{bytefield}{bitformatting}{\def\bf@bitformatting{#1}} +\define@key{bytefield}{boxformatting}{\def\bf@boxformatting{#1}} +\define@key{bytefield}{leftcurly}{\def\bf@leftcurly{#1}} +\define@key{bytefield}{rightcurly}{\def\bf@rightcurly{#1}} +\define@key{bytefield}{leftcurlyspace}{\def\bf@leftcurlyspace{#1}} +\define@key{bytefield}{rightcurlyspace}{\def\bf@rightcurlyspace{#1}} +\define@key{bytefield}{curlyspace}{% + \def\bf@leftcurlyspace{#1}% + \def\bf@rightcurlyspace{#1}% +} +\define@key{bytefield}{leftlabelspace}{\def\bf@leftlabelspace{#1}} +\define@key{bytefield}{rightlabelspace}{\def\bf@rightlabelspace{#1}} +\define@key{bytefield}{labelspace}{% + \def\bf@leftlabelspace{#1}% + \def\bf@rightlabelspace{#1}% +} +\define@key{bytefield}{leftcurlyshrinkage}{\def\bf@leftcurlyshrinkage{#1}} +\define@key{bytefield}{rightcurlyshrinkage}{\def\bf@rightcurlyshrinkage{#1}} +\define@key{bytefield}{curlyshrinkage}{% + \def\bf@leftcurlyshrinkage{#1}% + \def\bf@rightcurlyshrinkage{#1}% +} +\newcommand{\bf@bytefieldsetup}{\setkeys{bytefield}} +\let\bytefieldsetup=\bf@bytefieldsetup +\DeclareOption{compat1}{\bf@enter@compatibility@mode@i} +\def\bf@package@options{} +\DeclareOption*{% + \edef\next{% + \noexpand\g@addto@macro\noexpand\bf@package@options{,\CurrentOption}% + }% + \next +} +\ProcessOptions\relax +\expandafter\bf@bytefieldsetup\expandafter{\bf@package@options} \endinput %% %% End of file `bytefield.sty'. -- cgit v1.2.3