+
+@item 31 or 58
+(These bytes begin a ValueMod.) A format string, analogous to
+@code{printf}, followed by one or more Arguments, each of which has
+one or more values. The format string uses the following syntax:
+
+@table @code
+@item \%
+@itemx \:
+@itemx \[
+@itemx \]
+Each of these expands to the character following @samp{\\}, to escape
+characters that have special meaning in format strings. These are
+effective inside and outside the @code{[@dots{}]} syntax forms
+described below.
+
+@item \n
+Expands to a new-line, inside or outside the @code{[@dots{}]} forms
+described below.
+
+@item ^@var{i}
+Expands to a formatted version of argument @var{i}, which must have
+only a single value. For example, @code{^1} expands to the first
+argument's @code{value}.
+
+@item [:@var{a}:]@var{i}
+Expands @var{a} for each of the values in @var{i}. @var{a}
+should contain one or more @code{^@var{j}} conversions, which are
+drawn from the values for argument @var{i} in order. Some examples
+from the corpus:
+
+@table @code
+@item [:^1:]1
+All of the values for the first argument, concatenated.
+
+@item [:^1\n:]1
+Expands to the values for the first argument, each followed by
+a new-line.
+
+@item [:^1 = ^2:]2
+Expands to @code{@var{x} = @var{y}} where @var{x} is the second
+argument's first value and @var{y} is its second value. (This would
+be used only if the argument has two values. If there were more
+values, the second and third values would be directly concatenated,
+which would look funny.)
+@end table
+
+@item [@var{a}:@var{b}:]@var{i}
+This extends the previous form so that the first values are expanded
+using @var{a} and later values are expanded using @var{b}. For an
+unknown reason, within @var{a} the @code{^@var{j}} conversions are
+instead written as @code{%@var{j}}. Some examples from the corpus:
+
+@table @code
+@item [%1:*^1:]1
+Expands to all of the values for the first argument, separated by
+@samp{*}.
+
+@item [%1 = %2:, ^1 = ^2:]1
+Given appropriate values for the first argument, expands to @code{X =
+1, Y = 2, Z = 3}.
+
+@item [%1:, ^1:]1
+Given appropriate values, expands to @code{1, 2, 3}.
+@end table
+@end table
+
+The format string is localized to the user's locale.
+@end table
+
+@node SPV Light Member ValueMod
+@subsection ValueMod
+
+A ValueMod can specify special modifications to a Value.
+
+@cartouche
+@format
+ValueMod @result{}
+ 31 i0 (i0 @math{|} i1 string[@t{subscript}])
+ v1(00 (i1 @math{|} i2) 00 00 int 00 00)
+ v3(count(FormatString Style ValueModUnknown))
+ @math{|} 31 i1 int[@t{footnote-number}] Format
+ @math{|} 31 i2 (00 @math{|} 01 @math{|} 02) 00 (i1 @math{|} i2 @math{|} i3) Format
+ @math{|} 31 i3 00 00 01 00 i2 Format
+ @math{|} 58
+Style @result{} 58 @math{|} 31 01? 00? 00? 00? 01 string[@t{fgcolor}] string[@t{bgcolor}] string[@t{typeface}] byte
+Format @result{} 00 00 count(FormatString Style 58)
+FormatString @result{} count((i0 (58 @math{|} 31 string))?)
+ValueModUnknown @result{} 58 @math{|} 31 i0 i0 i0 i0 01 00 (01 @math{|} 02 @math{|} 08) 00 08 00 0a 00)
+@end format
+@end cartouche
+
+The @code{footnote-number}, if present, specifies a footnote that the
+Value references. The footnote's marker is shown appended to the main
+text of the Value, as a superscript.
+
+The @code{subscript}, if present, specifies a string to append to the
+main text of the Value, as a subscript. The subscript text is a brief
+indicator, e.g.@: @samp{a} or @samp{a,b}, with its meaning indicated
+by the table caption. In this usage, subscripts are similar to
+footnotes; one apparent difference is that a Value can only reference
+one footnote but a subscript can list more than one letter.
+
+The Format, if present, is a format string for substitutions using the
+syntax explained previously. It appears to be an English-language
+version of the localized format string in the Value in which the
+Format is nested.
+
+The Style, if present, changes the style for this individual Value.
+
+@node SPV Legacy Detail Member Binary Format
+@section Legacy Detail Member Binary Format
+
+Whereas the light binary format represents everything about a given
+pivot table, the legacy binary format conceptually consists of a
+number of named sources, each of which consists of a number of named
+variables, each of which is a 1-dimensional array of numbers or
+strings or a mix. Thus, the legacy binary member format is quite
+simple.
+
+This section uses the same context-free grammar notation as in the
+previous section, with the following additions:
+
+@table @asis
+@item vAF(@var{x})
+In a version 0xaf legacy member, @var{x}; in other versions, nothing.
+(The legacy member header indicates the version; see below.)
+
+@item vB0(@var{x})
+In a version 0xb0 legacy member, @var{x}; in other versions, nothing.
+@end table
+
+A legacy detail member @file{.bin} has the following overall format:
+
+@cartouche
+@format
+LegacyBinary @result{}
+ 00 byte[@t{version}] int16[@t{n-sources}] int[@t{member-size}]
+ Metadata*[@t{n-sources}] Data*[@t{n-sources}]
+@end format
+@end cartouche
+
+@code{version} is a version number that affects the interpretation of
+some of the other data in the member. Versions 0xaf and 0xb0 are
+known. We will refer to ``version 0xaf'' and ``version 0xb0'' members
+later on.
+
+A legacy member consists of @code{n-sources} data sources, each of
+which has Metadata and Data.
+
+@code{member-size} is the size of the legacy binary member, in bytes.
+
+The following sections go into more detail.
+
+@menu
+* SPV Legacy Member Metadata::
+* SPV Legacy Member Data::
+@end menu
+
+@node SPV Legacy Member Metadata
+@subsection Metadata
+
+@cartouche
+@format
+Metadata @result{}
+ int[@t{n-data}] int[@t{n-variables}] int[@t{offset}]
+ vAF(byte*32[@t{source-name}])
+ vB0(byte*64[@t{source-name}] int[@t{x}])
+@end format
+@end cartouche
+
+A data source has @code{n-variables} variables, each with
+@code{n-data} data values.
+
+@code{source-name} is a 32- or 64-byte string padded on the right with
+zero bytes. The names that appear in the corpus are very generic:
+usually @code{tableData} for pivot table data or @code{source0} for
+chart data.
+
+A given Metadata's @code{offset} is the offset, in bytes, from the
+beginning of the member to the start of the corresponding Data. This
+allows programs to skip to the beginning of the data for a particular
+source; it is also important to determine whether a source includes
+any string data (@pxref{SPV Legacy Member Data}).
+
+The meaning of @code{x} in version 0xb0 is unknown.
+
+@node SPV Legacy Member Data
+@subsection Data
+
+@cartouche
+@format
+Data @result{} NumericData*[@t{n-variables}] StringData?
+NumericData @result{} byte*288[@t{variable-name}] double*[@t{n-data}]
+@end format
+@end cartouche
+
+Data follow the Metadata in the legacy binary format, with sources in
+the same order. Each NumericSeries begins with a @code{variable-name}
+that generally indicates its role in the pivot table, e.g.@: ``cell'',
+``cellFormat'', ``dimension0categories'', ``dimension0group0'',
+followed by the numeric data, one double per datum. A double with the
+maximum negative double @code{-DBL_MAX} represents the system-missing
+value SYSMIS.
+
+@cartouche
+@format
+StringData @result{} i1 string[@t{source-name}] Pairs Labels
+
+Pairs @result{} int[@t{n-string-vars}] PairSeries*[@t{n-string-vars}]
+PairVar @result{} string[@t{pair-var-name}] int[@t{n-pairs}] Pair*[@t{n-pairs}]
+Pair @result{} int[@t{i}] int[@t{j}]
+
+Labels @result{} int[@t{n-labels}] Label*[@t{n-labels}]
+Label @result{} int[@t{frequency}] int[@t{s}]
+@end format
+@end cartouche
+
+A source may include a mix of numeric and string data values. When a
+source includes any string data, the data values that are strings are
+set to SYSMIS in the NumericData, and StringData follows the
+NumericData. A source that contains no string data omits the
+StringData. To reliably determine whether a source includes
+StringData, the reader should check whether the offset following the
+NumericData is the offset of the next source, as indicated by its
+Metadata (or the end of the member, in the case of the last source).
+
+StringData repeats the name of the source (from Metadata).
+
+The string data overlays the numeric data. @code{n-string-vars} is
+the number of variables in the source that include string data. More
+precisely, it is the 1-based index of the last variable in the source
+that includes any string data; thus, it would be 4 if there are 5
+variables and only the fourth one includes string data.
+
+Each PairVar consists a sequence of 0 or more Pair nonterminals, each
+of which maps from a 0-based index within variable @code{i} to a
+0-based label index @code{j}, e.g.@: pair @code{i} = 2, @code{j} = 3,
+means that the third data value (with value SYSMIS) is to be replaced
+by the string of the fourth Label.
+
+The labels themselves follow the pairs. The valuable part of each
+label is the string @code{s}. Each label also includes a
+@code{frequency} that reports the number of pairs that reference it
+(although this is not useful).
+
+@node SPV Legacy Detail Member XML Format
+@section Legacy Detail Member XML Format
+
+This format is still under investigation.
+
+The design of the detail XML format is not what one would end up with
+for describing pivot tables. This is because it is a specialization
+of a much more general format (``visualization XML'' or ``VizML'')
+that can describe a wide range of visualizations. Most of this
+generality is overkill for tables, and so we end up with a funny
+subset of a general-purpose format.
+
+The important elements of the detail XML format are:
+
+@itemize @bullet
+@item
+Variables. Variables in detail XML roughly correspond to the
+dimensions in a light detail member. There is one variable for each
+dimension, plus one variable for each level of labeling along an axis.
+
+The bulk of variables are defined with @code{sourceVariable} elements.
+The data for these variables comes from the associated
+@code{tableData.bin} member. Some variables are defined, with
+@code{derivedVariable} elements, as a constant or in terms of a
+mapping function from a source variable.
+
+@item
+Assignment of variables to axes. A variable can appear as columns, or
+rows, or layers. The @code{faceting} element and its sub-elements
+describe this assignment.