Lots more details.
[pspp] / spv-file-format.texi
index 50a94141b924452dc0ee9bd255d6c4d2acdc6d35..ed2e96092d75f27a2f5611a1a50cd0c6ca493bc1 100644 (file)
@@ -607,7 +607,12 @@ An SPV light member begins with a 39-byte header:
 Header @result{}
     01 00
     (i1 @math{|} i3)[@t{version}]
 Header @result{}
     01 00
     (i1 @math{|} i3)[@t{version}]
-    01 bool*4 int
+    bool
+    bool[@t{show-numeric-markers}]
+    bool[@t{rotate-inner-column-labels}]
+    bool[@t{rotate-outer-row-labels}]
+    bool
+    int
     int[@t{min-column-width}] int[@t{max-column-width}]
     int[@t{min-row-width}] int[@t{max-row-width}]
     int64[@t{table-id}]
     int[@t{min-column-width}] int[@t{max-column-width}]
     int[@t{min-row-width}] int[@t{max-row-width}]
     int64[@t{table-id}]
@@ -619,6 +624,18 @@ some of the other data in the member.  We will refer to ``version 1''
 and ``version 3'' later on and use v1(@dots{}) and v3(@dots{}) for
 version-specific formatting (as described previously).
 
 and ``version 3'' later on and use v1(@dots{}) and v3(@dots{}) for
 version-specific formatting (as described previously).
 
+If @code{show-numeric-markers} is 1, footnote markers are shown as
+numbers, starting from 1; otherwise, they are shown as letters,
+starting from @samp{a}.
+
+If @code{rotate-inner-column-labels} is 1, then column labels closest
+to the data are rotated to be vertical; otherwise, they are shown
+in the normal way.
+
+If @code{rotate-outer-row-labels} is 1, then row labels farthest from
+the data are rotated to be vertical; otherwise, they are shown in the
+normal way.
+
 @code{table-id} is a binary version of the @code{tableId} attribute in
 the structure member that refers to the detail member.  For example,
 if @code{tableId} is @code{-4122591256483201023}, then @code{table-id}
 @code{table-id} is a binary version of the @code{tableId} attribute in
 the structure member that refers to the detail member.  For example,
 if @code{tableId} is @code{-4122591256483201023}, then @code{table-id}
@@ -860,11 +877,24 @@ TableSettings @result{}
     bool[@t{footnote-marker-position}]
     v3(
       byte
     bool[@t{footnote-marker-position}]
     v3(
       byte
-      be32[@t{n}] byte*[@t{n}]
+      count(
+        Breakpoints[@t{row-breaks}] Breakpoints[@t{column-breaks}]
+        Keeps[@t{row-keeps}] Keeps[@t{column-keeps}]
+        PointKeeps[@t{row-keeps}] PointKeeps[@t{column-keeps}]
+      )
       bestring[@t{notes}]
       bestring[@t{table-look}]
       00...
     )
       bestring[@t{notes}]
       bestring[@t{table-look}]
       00...
     )
+
+Breakpoints @result{} be32[@t{n-breaks}] be32*[@t{n-breaks}]
+
+Keeps @result{} be32[@t{n-keeps}] Keep*@t{n-keeps}
+Keep @result{} be32[@t{offset}] be[@t{n}]
+
+PointKeeps @result{} be32[@t{n-point-keeps}] PointKeep*@t{n-point-keeps}
+PointKeep @result{} be32[@t{offset}] be32 be32
+
 @end format
 @end cartouche
 
 @end format
 @end cartouche
 
@@ -886,6 +916,20 @@ shown as numbers starting from 1.
 When @code{footnote-marker-position} is 1, footnote markers are shown
 as superscripts, otherwise as subscripts.
 
 When @code{footnote-marker-position} is 1, footnote markers are shown
 as superscripts, otherwise as subscripts.
 
+The Breakpoints are rows or columns after which there is a page break;
+for example, a row break of 1 requests a page break after the second
+row.  Usually no breakpoints are specified, indicating that page
+breaks should be selected automatically.
+
+The Keeps are ranges of rows or columns to be kept together without a
+page break; for example, a row Keep with @code{offset} 1 and @code{n}
+10 requests that the 10 rows starting with the second row be kept
+together.  Usually no Keeps are specified.
+
+The PointKeeps seem to be generated automatically based on
+user-specified Keeps.  They seems to indicate a conversion from rows
+or columns to pixel or point offsets.
+
 @code{notes} is a text string that contains user-specified notes.  It
 is displayed when the user hovers the cursor over the table, like
 ``alt text'' on a webpage.  It is not printed.  It is usually empty.
 @code{notes} is a text string that contains user-specified notes.  It
 is displayed when the user hovers the cursor over the table, like
 ``alt text'' on a webpage.  It is not printed.  It is usually empty.
@@ -901,33 +945,59 @@ TableSettings ends with an arbitrary number of null bytes.
 @cartouche
 @format
 Formats @result{}
 @cartouche
 @format
 Formats @result{}
-    int[@t{nwidths}] int*[@t{nwidths}]
+    int[@t{n-widths}] int*[@t{n-widths}]
     string[@t{encoding}]
     string[@t{encoding}]
-    int (00 @math{|} 01) 00 (00 @math{|} 01)
+    int[@t{current-layer}]
+    bool[@t{digit-grouping}] bool[@t{leading-zero}] bool
     int[@t{epoch}]
     byte[@t{decimal}] byte[@t{grouping}]
     CustomCurrency
     int[@t{epoch}]
     byte[@t{decimal}] byte[@t{grouping}]
     CustomCurrency
-    v1(i0)
-    v3(count(count(X5) count(X6)))
-
-CustomCurrency @result{} int[@t{n-ccs}] string*[@t{n-ccs}]
+    count(
+      v1(X0?)
+      v3(count(X1 count(X2)) count(X3))
 
 
-X5 @result{} byte*33 int[@t{n}] int*[@t{n}]
-X6 @result{}
+X0 @result{}
+    byte*14
+    string[@t{command}] string[@t{command-local}]
+    string[@t{language}] string[@t{charset}] string[@t{locale}]
+    bool 00 bool bool
+    int[@t{epoch}]
+    byte[@t{decimal}] byte[@t{grouping}]
+    CustomCurrency
+    byte[@t{missing}] bool
+
+X1 @result{}
+    byte*2
+    byte[@t{lang}]
+    byte[@t{variable-mode}]
+    byte[@t{value-mode}]
+    int*2
+    00*17
+    bool
+    01
+X2 @result{}
+    int[@t{n-heights}] int*[@t{n-heights}]
+    int[@t{n-style-map}] BlankMap*[@t{n-style-map}]
+    int[@t{n-styles}] StylePair*[@t{n-styles}]
+    count((i0 i0)?)
+StyleMap @result{} int64[@t{cell-index}] int16[@t{style-index}]
+X3 @result{}
     01 00 (03 @math{|} 04) 00 00 00
     01 00 (03 @math{|} 04) 00 00 00
-    string[@t{command}] string[@t{subcommand}]
+    string[@t{command}] string[@t{command-local}]
     string[@t{language}] string[@t{charset}] string[@t{locale}]
     string[@t{language}] string[@t{charset}] string[@t{locale}]
-    (00 @math{|} 01) 00 bool bool
+    bool 00 bool bool
     int[@t{epoch}]
     byte[@t{decimal}] byte[@t{grouping}]
     double[@t{small}] 01
     (string[@t{dataset}] string[@t{datafile}] i0 int[@t{date}] i0)?
     CustomCurrency
     byte[@t{missing}] bool (i2000000 i0)?
     int[@t{epoch}]
     byte[@t{decimal}] byte[@t{grouping}]
     double[@t{small}] 01
     (string[@t{dataset}] string[@t{datafile}] i0 int[@t{date}] i0)?
     CustomCurrency
     byte[@t{missing}] bool (i2000000 i0)?
+
+CustomCurrency @result{} int[@t{n-ccs}] string*[@t{n-ccs}]
 @end format
 @end cartouche
 
 @end format
 @end cartouche
 
-If @code{nwidths} is nonzero, then the accompanying integers are
+If @code{n-widths} is nonzero, then the accompanying integers are
 column widths as manually adjusted by the user.  (Row heights are
 computed automatically based on the widths.)
 
 column widths as manually adjusted by the user.  (Row heights are
 computed automatically based on the widths.)
 
@@ -950,6 +1020,13 @@ are @samp{.} and @samp{,}.
 @samp{'} (apostrophe), @samp{ } (space), and zero (presumably
 indicating that digits should not be grouped).
 
 @samp{'} (apostrophe), @samp{ } (space), and zero (presumably
 indicating that digits should not be grouped).
 
+@code{command} describes the statistical procedure that generated the
+output, in English.  It is not necessarily the literal syntax name of
+the procedure: for example, NPAR TESTS becomes ``Nonparametric
+Tests.''  @code{command-local} is the procedure's name, translated
+into the output language; it is often empty and, when it is not,
+sometimes the same as @code{command}.
+
 @code{dataset} is the name of the dataset analyzed to produce the
 output, e.g.@: @code{DataSet1}, and @code{datafile} the name of the
 file it was read from, e.g.@: @file{C:\Users\foo\bar.sav}.  The latter
 @code{dataset} is the name of the dataset analyzed to produce the
 output, e.g.@: @code{DataSet1}, and @code{datafile} the name of the
 file it was read from, e.g.@: @file{C:\Users\foo\bar.sav}.  The latter
@@ -971,6 +1048,9 @@ following strings are CCA through CCE format strings.  @xref{Custom
 Currency Formats,,, pspp, PSPP}.  Most commonly these are all
 @code{-,,,} but other strings occur.
 
 Currency Formats,,, pspp, PSPP}.  Most commonly these are all
 @code{-,,,} but other strings occur.
 
+@code{missing} is the character used to indicate that a cell contains
+a missing value.  It is always observed as @samp{.}.
+
 @node SPV Light Member Dimensions
 @subsection Dimensions
 
 @node SPV Light Member Dimensions
 @subsection Dimensions
 
@@ -985,8 +1065,8 @@ DimUnknown @result{}
     byte[@t{d1}]
     (00 @math{|} 01 @math{|} 02)[@t{d2}]
     (i0 @math{|} i2)[@t{d3}]
     byte[@t{d1}]
     (00 @math{|} 01 @math{|} 02)[@t{d2}]
     (i0 @math{|} i2)[@t{d3}]
-    (00 @math{|} 01)[@t{d4}]
-    (00 @math{|} 01)[@t{d5}]
+    bool[@t{d4}]
+    bool[@t{d5}]
     01
     int[@t{d6}]
 @end format
     01
     int[@t{d6}]
 @end format
@@ -1016,7 +1096,7 @@ are really categories; the others just serve as grouping constructs.
 Category @result{} Value[@t{name}] (Leaf @math{|} Group)
 Leaf @result{} 00 00 00 i2 int[@t{index}] i0
 Group @result{}
 Category @result{} Value[@t{name}] (Leaf @math{|} Group)
 Leaf @result{} 00 00 00 i2 int[@t{index}] i0
 Group @result{}
-    (00 @math{|} 01)[@t{merge}] 00 01 (i0 @math{|} i2)[@t{data}]
+    bool[@t{merge}] 00 01 (i0 @math{|} i2)[@t{data}]
     i-1 int[@t{n-subcategories}] Category*[@t{n-subcategories}]
 @end format
 @end cartouche
     i-1 int[@t{n-subcategories}] Category*[@t{n-subcategories}]
 @end format
 @end cartouche
@@ -1106,7 +1186,7 @@ RawValue @result{}
     01 ValueMod int[@t{format}] double[@t{x}]
   @math{|} 02 ValueMod int[@t{format}] double[@t{x}]
     string[@t{varname}] string[@t{vallab}] (01 @math{|} 02 @math{|} 03)
     01 ValueMod int[@t{format}] double[@t{x}]
   @math{|} 02 ValueMod int[@t{format}] double[@t{x}]
     string[@t{varname}] string[@t{vallab}] (01 @math{|} 02 @math{|} 03)
-  @math{|} 03 string[@t{local}] ValueMod string[@t{id}] string[@t{c}] (00 @math{|} 01)[@t{type}]
+  @math{|} 03 string[@t{local}] ValueMod string[@t{id}] string[@t{c}] bool[@t{type}]
   @math{|} 04 ValueMod int[@t{format}] string[@t{vallab}] string[@t{varname}]
     (01 @math{|} 02 @math{|} 03) string[@t{s}]
   @math{|} 05 ValueMod string[@t{varname}] string[@t{varlabel}] (01 @math{|} 02 @math{|} 03)
   @math{|} 04 ValueMod int[@t{format}] string[@t{vallab}] string[@t{varname}]
     (01 @math{|} 02 @math{|} 03) string[@t{s}]
   @math{|} 05 ValueMod string[@t{varname}] string[@t{varlabel}] (01 @math{|} 02 @math{|} 03)
@@ -1261,13 +1341,26 @@ A ValueMod can specify special modifications to a Value.
 ValueMod @result{}
     31 i0 (i0 @math{|} i1 string[@t{subscript}])
     v1(00 (i1 @math{|} i2) 00 00 int 00 00)
 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))
+    v3(count(FormatString StylePair))
   @math{|} 31 int[@t{n-refs}] int16*[@t{n-refs}] Format
   @math{|} 58
   @math{|} 31 int[@t{n-refs}] int16*[@t{n-refs}] Format
   @math{|} 58
-Style @result{} 58 @math{|} 31 01? 00? 00? 00? 01 string[@t{fgcolor}] string[@t{bgcolor}] string[@t{typeface}] byte[@t{size}]
+
 Format @result{} 00 00 count(FormatString Style 58)
 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)
+FormatString @result{} count((count((i0 58)?) (58 @math{|} 31 string))?)
+
+StylePair @result{}
+    (31 Style | 58)
+    (31 Style2 | 58)
+
+Style @result{}
+    bool[@t{bold}] bool[@t{italic}] bool[@t{underline}] bool[@t{show}]
+    string[@t{fgcolor}] string[@t{bgcolor}]
+    string[@t{typeface}] byte[@t{size}]
+
+Style2 @result{}
+    int[@t{halign}] int[@t{valign}] double[@t{offset}]
+    int16[@t{left-margin}] int16[@t{right-margin}]
+    int16[@t{top-margin}] int16[@t{bottom-margin}]
 @end format
 @end cartouche
 
 @end format
 @end cartouche
 
@@ -1287,8 +1380,22 @@ 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.
 
 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.
-The @code{size} is a font size in units of 1/96 inch.
+Style and Style2, if present, change the style for this individual
+Value.  @code{bold}, @code{italic}, and @code{underline} control the
+particular style.  @code{fgcolor} and @code{bgcolor} are strings, such
+as @code{#ffffff}.  The @code{size} is a font size in units of 1/96
+inch.
+
+@code{halign} is 0 for center, 2 for left, 4 for right, 6 for decimal,
+0xffffffad for mixed.  For decimal alignment, @code{offset} is the
+decimal point's offset from the right side of the cell, in units of
+1/72 inch.
+
+@code{valign} specifies vertical alignment: 0 for center, 1 for top, 3
+for bottom.
+
+@code{left-margin}, @code{right-margin}, @code{top-margin}, and
+@code{bottom-margin} are in units of 1/72 inch.
 
 @node SPV Legacy Detail Member Binary Format
 @section Legacy Detail Member Binary Format
 
 @node SPV Legacy Detail Member Binary Format
 @section Legacy Detail Member Binary Format