1@c PSPP - a program for statistical analysis.
2@c Copyright (C) 2019 Free Software Foundation, Inc.
3@c Permission is granted to copy, distribute and/or modify this document
4@c under the terms of the GNU Free Documentation License, Version 1.3
5@c or any later version published by the Free Software Foundation;
6@c with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
7@c A copy of the license is included in the section entitled "GNU
8@c Free Documentation License".
9@c
10
11@node SPSS Viewer File Format
12@appendix SPSS Viewer File Format
13
14SPSS Viewer or @file{.spv} files, here called SPV files, are written
15by SPSS 16 and later to represent the contents of its output editor.
16This chapter documents the format, based on examination of a corpus of
17about 8,000 files from a variety of sources.  This description is
18detailed enough to both read and write SPV files.
19
20SPSS 15 and earlier versions instead use @file{.spo} files, which have
21a completely different output format based on the Microsoft Compound
22Document Format.  This format is not documented here.
23
24An SPV file is a Zip archive that can be read with @command{zipinfo}
25and @command{unzip} and similar programs.  The final member in the Zip
26archive is the @dfn{manifest}, a file named
27@file{META-INF/MANIFEST.MF}.  This structure makes SPV files resemble
28Java ``JAR'' files (and ODF files), but whereas a JAR manifest
29contains a sequence of colon-delimited key/value pairs, an SPV
30manifest contains the string @samp{allowPivoting=true}, without a
31new-line.  PSPP uses this string to identify an SPV file; it is
32invariant across the corpus.@footnote{SPV files always begin with the
337-byte sequence 50 4b 03 04 14 00 08, but this is not a useful magic
34number because most Zip archives start the same way.}
35
36The rest of the members in an SPV file's Zip archive fall into two
37categories: @dfn{structure} and @dfn{detail} members.  Structure
38member names begin with @file{outputViewer@var{nnnnnnnnnn}}, where
39each @var{n} is a decimal digit, and end with @file{.xml}, and often
40include the string @file{_heading} in between.  Each of these members
41represents some kind of output item (a table, a heading, a block of
42text, etc.) or a group of them.  The member whose output goes at the
43beginning of the document is numbered 0, the next member in the output
44is numbered 1, and so on.
45
46Structure members contain XML.  This XML is sometimes self-contained,
47but it often references detail members in the Zip archive, which are
48named as follows:
49
50@table @asis
51@item @file{@var{prefix}_table.xml} and @file{@var{prefix}_tableData.bin}
52@itemx @file{@var{prefix}_lightTableData.bin}
53The structure of a table plus its data.  Older SPV files pair a
54@file{@var{prefix}_table.xml} file that describes the table's
55structure with a binary @file{@var{prefix}_tableData.bin} file that
56gives its data.  Newer SPV files (the majority of those in the corpus)
57instead include a single @file{@var{prefix}_lightTableData.bin} file
58that incorporates both into a single binary format.
59
60@item @file{@var{prefix}_warning.xml} and @file{@var{prefix}_warningData.bin}
61@itemx @file{@var{prefix}_lightWarningData.bin}
62Same format used for tables, with a different name.
63
64@item @file{@var{prefix}_notes.xml} and @file{@var{prefix}_notesData.bin}
65@itemx @file{@var{prefix}_lightNotesData.bin}
66Same format used for tables, with a different name.
67
68@item @file{@var{prefix}_chartData.bin} and @file{@var{prefix}_chart.xml}
69The structure of a chart plus its data.  Charts do not have a
70``light'' format.
71
72@item @file{@var{prefix}_pmml.scf}
73@itemx @file{@var{prefix}_stats.scf}
74@item @file{@var{prefix}_model.xml}
75Not yet investigated.  The corpus contains few examples.
76@end table
77
78The @file{@var{prefix}} in the names of the detail members is
79typically an 11-digit decimal number that increases for each item,
80tending to skip values.  Older SPV files use different naming
81conventions.  Structure member refer to detail members by name, and so
82their exact names do not matter to readers as long as they are unique.
83
84SPSS tolerates corrupted Zip archives that Zip reader libraries tend
85to reject.  These can be fixed up with @command{zip -FF}.
86
87@menu
88* SPV Structure Member Format::
89* SPV Light Detail Member Format::
90* SPV Legacy Detail Member Binary Format::
91* SPV Legacy Detail Member XML Format::
92@end menu
93
94@node SPV Structure Member Format
95@section Structure Member Format
96
97A structure member lays out the high-level structure for a group of
98output items such as heading, tables, and charts.  Structure members
99do not include the details of tables and charts but instead refer to
100them by their member names.
101
102Structure members' XML files claim conformance with a collection of
103XML Schemas.  These schemas are distributed, under a nonfree license,
104with SPSS binaries.  Fortunately, the schemas are not necessary to
105understand the structure members.  The schemas can even
106be deceptive because they document elements and attributes that are
107not in the corpus and do not document elements and attributes that are
108commonly found in the corpus.
109
110Structure members use a different XML namespace for each schema, but
111these namespaces are not entirely consistent.  In some SPV files, for
112example, the @code{viewer-tree} schema is associated with namespace
113@indicateurl{http://xml.spss.com/spss/viewer-tree} and in others with
114@indicateurl{http://xml.spss.com/spss/viewer/viewer-tree} (note the
115additional @file{viewer/}).  Under either name, the schema URIs are
116not resolvable to obtain the schemas themselves.
117
118One may ignore all of the above in interpreting a structure member.
119The actual XML has a simple and straightforward form that does not
120require a reader to take schemas or namespaces into account.  A
121structure member's root is @code{heading} element, which contains
122@code{heading} or @code{container} elements (or a mix), forming a
123tree.  In turn, @code{container} holds a @code{label} and one more
124child, usually @code{text} or @code{table}.
125
126The following sections document the elements found in structure
127members in a context-free grammar-like fashion.  Consider the
128following example, which specifies the attributes and content for the
129@code{container} element:
130
131@example
132container
133   :visibility=(visible | hidden)
134   :page-break-before=(always)?
135   :text-align=(left | center)?
136   :width=dimension
137=> label (table | container_text | graph | model | object | image | tree)
138@end example
139
140Each attribute specification begins with @samp{:} followed by the
141attribute's name.  If the attribute's value has an easily specified
142form, then @samp{=} and its description follows the name.  Finally, if
143the attribute is optional, the specification ends with @samp{?}.  The
144following value specifications are defined:
145
146@table @code
147@item (@var{a} | @var{b} | @dots{})
148One of the listed literal strings.  If only one string is listed, it
149is the only acceptable value.  If @code{OTHER} is listed, then any
150string not explicitly listed is also accepted.
151
152@item bool
153Either @code{true} or @code{false}.
154
155@item dimension
156A floating-point number followed by a unit, e.g.@: @code{10pt}.  Units
157in the corpus include @code{in} (inch), @code{pt} (points, 72/inch),
158@code{px} (``device-independent pixels'', 96/inch), and @code{cm}.  If
159the unit is omitted then points should be assumed.  The number and
160unit may be separated by white space.
161
162The corpus also includes localized names for units.  A reader must
163understand these to properly interpret the dimension:
164
165@table @asis
166@item inch
167@code{인치}, @code{pol.}, @code{cala}, @code{cali}
168
169@item point
170@code{пт}
171
172@item centimeter
173@code{см}
174@end table
175
176@item real
177A floating-point number.
178
179@item int
180An integer.
181
182@item color
183A color in one of the forms @code{#@var{rr}@var{gg}@var{bb}} or
184@code{@var{rr}@var{gg}@var{bb}}, or the string @code{transparent}, or
185one of the standard Web color names.
186
187@item ref
188@item ref @var{element}
189@itemx ref(@var{elem1} | @var{elem2} | @dots{})
190The name from the @code{id} attribute in some element.  If one or more
191elements are named, the name must refer to one of those elements,
192otherwise any element is acceptable.
193@end table
194
195All elements have an optional @code{id} attribute.  If present, its
196value must be unique.  In practice many elements are assigned
197@code{id} attributes that are never referenced.
198
199The content specification for an element supports the following
200syntax:
201
202@table @code
203@item @var{element}
204An element.
205
206@item @var{a} @var{b}
207@var{a} followed by @var{b}.
208
209@item @var{a} | @var{b} | @var{c}
210One of @var{a} or @var{b} or @var{c}.
211
212@item @var{a}?
213Zero or one instances of @var{a}.
214
215@item @var{a}*
216Zero or more instances of @var{a}.
217
218@item @var{b}+
219One or more instances of @var{a}.
220
221@item (@var{subexpression})
222Grouping for a subexpression.
223
224@item EMPTY
225No content.
226
227@item TEXT
228Text and CDATA.
229@end table
230
231Element and attribute names are sometimes suffixed by another name in
232square brackets to distinguish different uses of the same name.  For
233example, structure XML has two @code{text} elements, one inside
234@code{container}, the other inside @code{pageParagraph}.  The former
235is defined as @code{text[container_text]} and referenced as
236@code{container_text}, the latter defined as
237@code{text[pageParagraph_text]} and referenced as
238@code{pageParagraph_text}.
239
240This language is used in the PSPP source code for parsing structure
241and detail XML members.  Refer to
242@file{src/output/spv/structure-xml.grammar} and
243@file{src/output/spv/detail-xml.grammar} for the full grammars.
244
245The following example shows the contents of a typical structure member
246for a @cmd{DESCRIPTIVES} procedure.  A real structure member is not
247indented.  This example also omits most attributes, all XML namespace
248information, and the CSS from the embedded HTML:
249
250@example
251<?xml version="1.0" encoding="utf-8"?>
252<heading>
253  <label>Output</label>
254  <heading commandName="Descriptives">
255    <label>Descriptives</label>
256    <container>
257      <label>Title</label>
258      <text commandName="Descriptives" type="title">
259        <html lang="en">
260<![CDATA[<head><style type="text/css">...</style></head><BR>Descriptives]]>
261        </html>
262      </text>
263    </container>
264    <container visibility="hidden">
265      <label>Notes</label>
266      <table commandName="Descriptives" subType="Notes" type="note">
267        <tableStructure>
268          <dataPath>00000000001_lightNotesData.bin</dataPath>
269        </tableStructure>
270      </table>
271    </container>
272    <container>
273      <label>Descriptive Statistics</label>
274      <table commandName="Descriptives" subType="Descriptive Statistics"
275             type="table">
276        <tableStructure>
277          <dataPath>00000000002_lightTableData.bin</dataPath>
278        </tableStructure>
279      </table>
280    </container>
281  </heading>
282</heading>
283@end example
284
285@menu
286* SPV Structure heading Element::
287* SPV Structure label Element::
288* SPV Structure container Element::
289* SPV Structure text Element (Inside @code{container})::
290* SPV Structure html Element::
291* SPV Structure table Element::
292* SPV Structure graph Element::
293* SPV Structure model Element::
294* SPV Structure tree Element::
295* SPV Structure Path Elements::
296* SPV Structure pageSetup Element::
297* SPV Structure @code{text} Element (Inside @code{pageParagraph})::
298@end menu
299
300@node SPV Structure heading Element
301@subsection The @code{heading} Element
302
303@example
304heading[root_heading]
305   :creator-version?
306   :creator?
307   :creation-date-time?
308   :lockReader=bool?
309   :schemaLocation?
310=> label pageSetup? (container | heading)*
311
312heading
313   :creator-version?
314   :commandName?
315   :visibility[heading_visibility]=(collapsed)?
316   :locale?
317   :olang?
318=> label (container | heading)*
319@end example
320
321The root of a structure member is a @code{heading}, which represents a
322section of output beginning with a title (the @code{label}) and
323ordinarily followed by content containers or further nested
324(sub)-sections of output.  Unlike heading elements in HTML and other
325common document formats, which precede the content that they head,
326@code{heading} contains the elements that appear below the heading.
327
328The document root heading, only, may contain a @code{pageSetup}
329element.
330
331The following attributes have been observed on both document root and
332nested @code{heading} elements.
333
334@defvr {Attribute} creator-version
335The version of the software that created this SPV file.  A string of
336the form @code{xxyyzzww} represents software version xx.yy.zz.ww,
337e.g.@: @code{21000001} is version 21.0.0.1.  Trailing pairs of zeros
338are sometimes omitted, so that @code{21}, @code{210000}, and
339@code{21000000} are all version 21.0.0.0 (and the corpus contains all
340three of those forms).
341@end defvr
342
343@noindent
344The following attributes have been observed on document root
345@code{heading} elements only:
346
347@defvr {Attribute} @code{creator}
348The directory in the file system of the software that created this SPV
349file.
350@end defvr
351
352@defvr {Attribute} @code{creation-date-time}
353The date and time at which the SPV file was written, in a
354locale-specific format, e.g.@: @code{Friday, May 16, 2014 6:47:37 PM
355PDT} or @code{lunedì 17 marzo 2014 3.15.48 CET} or even @code{Friday,
356December 5, 2014 5:00:19 o'clock PM EST}.
357@end defvr
358
359@defvr {Attribute} @code{lockReader}
360Whether a reader should be allowed to edit the output.  The possible
361values are @code{true} and @code{false}.  The value @code{false} is by
362far the most common.
363@end defvr
364
365@defvr {Attribute} @code{schemaLocation}
366This is actually an XML Namespace attribute.  A reader may ignore it.
367@end defvr
368
369@noindent
370The following attributes have been observed only on nested
371@code{heading} elements:
372
373@defvr {Attribute} @code{commandName}
374A locale-invariant identifier for the command that produced the
375output, e.g.@: @code{Frequencies}, @code{T-Test}, @code{Non Par Corr}.
376@end defvr
377
378@defvr {Attribute} @code{visibility}
379To what degree the output represented by the element is visible.
380@end defvr
381
382@defvr {Attribute} @code{locale}
383The locale used for output, in Windows format, which is similar to the
384format used in Unix with the underscore replaced by a hyphen, e.g.@:
385@code{en-US}, @code{en-GB}, @code{el-GR}, @code{sr-Cryl-RS}.
386@end defvr
387
388@defvr {Attribute} @code{olang}
389The output language, e.g.@: @code{en}, @code{it}, @code{es},
390@code{de}, @code{pt-BR}.
391@end defvr
392
393@node SPV Structure label Element
394@subsection The @code{label} Element
395
396@example
397label => TEXT
398@end example
399
400Every @code{heading} and @code{container} holds a @code{label} as its
401first child.  The root @code{heading} in a structure member always
402contains the string ``Output'' (localized).  Otherwise, the text in
403@code{label} describes what it labels, often by naming the statistical
404procedure that was executed, e.g.@: ``Frequencies'' or ``T-Test''.
405Labels are often very generic, especially within a @code{container},
406e.g.@: ``Title'' or ``Warnings'' or ``Notes''.  Label text is
407localized according to the output language, e.g.@: in Italian a
408frequency table procedure is labeled ``Frequenze''.
409
410The corpus contains a few examples of empty labels, ones that contain
411no text.
412
413@node SPV Structure container Element
414@subsection The @code{container} Element
415
416@example
417container
418   :visibility=(visible | hidden)
419   :page-break-before=(always)?
420   :text-align=(left | center)?
421   :width=dimension
422=> label (table | container_text | graph | model | object | image | tree)
423@end example
424
425A @code{container} serves to contain and label a @code{table},
426@code{text}, or other kind of item.
427
428This element has the following attributes.
429
430@defvr {Attribute} @code{visibility}
431Whether the container's content is displayed.  ``Notes'' tables are
432often hidden; other data is usually
433@end defvr
434
435@defvr {Attribute} @code{text-align}
436Alignment of text within the container.  Observed with nested
437@code{table} and @code{text} elements.
438@end defvr
439
440@defvr {Attribute} @code{width}
441The width of the container, e.g.@: @code{1097px}.
442@end defvr
443
444@node SPV Structure text Element (Inside @code{container})
445@subsection The @code{text} Element (Inside @code{container})
446
447@example
448text[container_text]
449  :type[text_type]=(title | log | text | page-title)
450  :commandName?
451  :creator-version?
452=> html
453@end example
454
455This @code{text} element is nested inside a @code{container}.  There
456is a different @code{text} element that is nested inside a
457@code{pageParagraph}.
458
459This element has the following attributes.
460
461@defvr {Attribute} @code{type}
462The semantics of the text.
463@end defvr
464
465@defvr {Attribute} @code{commandName}
466As on the @code{heading} element.  For output not specific to a
467command, this is simply @code{log}.  The corpus contains one example
468of where @code{commandName} is present but set to the empty string.
469@end defvr
470
471@defvr {Attribute} @code{creator-version}
472As on the @code{heading} element.
473@end defvr
474
475@node SPV Structure html Element
476@subsection The @code{html} Element
477
478@example
479html :lang=(en) => TEXT
480@end example
481
482The element contains an HTML document as text (or, in practice, as
483CDATA).  In some cases, the document starts with @code{<html>} and
484ends with @code{</html>}; in others the @code{html} element is
485implied.  Generally the HTML includes a @code{head} element with a CSS
486stylesheet.  The HTML body often begins with @code{<BR>}.
487
488The HTML document uses only the following elements:
489
490@table @code
491@item html
492Sometimes, the document is enclosed with
493@code{<html>}@dots{}@code{</html>}.
494
495@item br
496The HTML body often begins with @code{<BR>} and may contain it as well.
497
498@item b
499@itemx i
500@itemx u
501Styling.
502
503@item font
504The attributes @code{face}, @code{color}, and @code{size} are
505observed.  The value of @code{color} takes one of the forms
506@code{#@var{rr}@var{gg}@var{bb}} or @code{rgb (@var{r}, @var{g},
507@var{b})}.  The value of @code{size} is a number between 1 and 7,
508inclusive.
509@end table
510
511The CSS in the corpus is simple.  To understand it, a parser only
512needs to be able to skip white space, @code{<!--}, and @code{-->}, and
513parse style only for @code{p} elements.  Only @code{font-weight},
514@code{font-style}, @code{font-decoration}, @code{font-family}, and
515@code{font-size} matter.
516
517This element has the following attributes.
518
519@defvr {Attribute} @code{lang}
520This always contains @code{en} in the corpus.
521@end defvr
522
523@node SPV Structure table Element
524@subsection The @code{table} Element
525
526@example
527table
528   :VDPId?
529   :ViZmlSource?
530   :activePageId=int?
531   :commandName
532   :creator-version?
533   :displayFiltering=bool?
534   :maxNumCells=int?
535   :orphanTolerance=int?
536   :rowBreakNumber=int?
537   :subType
538   :tableId
539   :tableLookId?
540   :type[table_type]=(table | note | warning)
541=> tableProperties? tableStructure
542
543tableStructure => path? dataPath csvPath?
544@end example
545
546This element has the following attributes.
547
548@defvr {Attribute} @code{commandName}
549As on the @code{heading} element.
550@end defvr
551
552@defvr {Attribute} @code{type}
553One of @code{table}, @code{note}, or @code{warning}.
554@end defvr
555
556@defvr {Attribute} @code{subType}
557The locale-invariant command ID for the particular kind of output that
558this table represents in the procedure.  This can be the same as
559@code{commandName} e.g.@: @code{Frequencies}, or different, e.g.@:
560@code{Case Processing Summary}.  Generic subtypes @code{Notes} and
561@code{Warnings} are often used.
562@end defvr
563
564@defvr {Attribute} @code{tableId}
565A number that uniquely identifies the table within the SPV file,
566typically a large negative number such as @code{-4147135649387905023}.
567@end defvr
568
569@defvr {Attribute} @code{creator-version}
570As on the @code{heading} element.  In the corpus, this is only present
571for version 21 and up and always includes all 8 digits.
572@end defvr
573
574@xref{SPV Detail Legacy Properties}, for details on the
575@code{tableProperties} element.
576
577@node SPV Structure graph Element
578@subsection The @code{graph} Element
579
580@example
581graph
582   :VDPId?
583   :ViZmlSource?
584   :commandName?
585   :creator-version?
586   :dataMapId?
587   :dataMapURI?
588   :editor?
589   :refMapId?
590   :refMapURI?
591   :csvFileIds?
592   :csvFileNames?
593=> dataPath? path csvPath?
594@end example
595
596This element represents a graph.  The @code{dataPath} and @code{path}
597elements name the Zip members that give the details of the graph.
598Normally, both elements are present; there is only one counterexample
599in the corpus.
600
601@code{csvPath} only appears in one SPV file in the corpus, for two
602graphs.  In these two cases, @code{dataPath}, @code{path}, and
603@code{csvPath} all appear.  These @code{csvPath} name Zip members with
604names of the form @file{@var{number}_csv.bin}, where @var{number} is a
605many-digit number and the same as the @code{csvFileIds}.  The named
606Zip members are CSV text files (despite the @file{.bin} extension).
607The CSV files are encoded in UTF-8 and begin with a U+FEFF byte-order
608marker.
609
610@node SPV Structure model Element
611@subsection The @code{model} Element
612
613@example
614model
615   :PMMLContainerId?
616   :PMMLId
617   :StatXMLContainerId
618   :VDPId
619   :auxiliaryViewName
620   :commandName
621   :creator-version
622   :mainViewName
623=> ViZml? dataPath? path | pmmlContainerPath statsContainerPath
624
625pmmlContainerPath => TEXT
626
627statsContainerPath => TEXT
628
629ViZml :viewName? => TEXT
630@end example
631
632This element represents a model.  The @code{dataPath} and @code{path}
633elements name the Zip members that give the details of the model.
634Normally, both elements are present; there is only one counterexample
635in the corpus.
636
637The details are unexplored.  The @code{ViZml} element contains base-64
638encoded text, that decodes to a binary format with some embedded text
639strings, and @code{path} names an Zip member that contains XML.
640Alternatively, @code{pmmlContainerPath} and @code{statsContainerPath}
641name Zip members with @file{.scf} extension.
642
643@node SPV Structure tree Element
644@subsection The @code{tree} Element
645
646@example
647tree
648   :commandName
649   :creator-version
650   :name
651   :type
652=> dataPath path
653@end example
654
655This element represents a tree.  The @code{dataPath} and @code{path}
656elements name the Zip members that give the details of the tree.
657The details are unexplored.
658
659@node SPV Structure Path Elements
660@subsection Path Elements
661
662@example
663dataPath => TEXT
664
665path => TEXT
666
667csvPath => TEXT
668@end example
669
670These element contain the name of the Zip members that hold details
671for a container.  For tables:
672
673@itemize @bullet
674@item
675When a ``light'' format is used, only @code{dataPath} is present, and
676it names a @file{.bin} member of the Zip file that has @code{light} in
677its name, e.g.@: @code{0000000001437_lightTableData.bin} (@pxref{SPV
678Light Detail Member Format}).
679
680@item
681When the legacy format is used, both are present.  In this case,
682@code{dataPath} names a Zip member with a legacy binary format that
683contains relevant data (@pxref{SPV Legacy Detail Member Binary
684Format}), and @code{path} names a Zip member that uses an XML format
685(@pxref{SPV Legacy Detail Member XML Format}).
686@end itemize
687
688Graphs normally follow the legacy approach described above.  The
689corpus contains one example of a graph with @code{path} but not
690@code{dataPath}.  The reason is unexplored.
691
692Models use @code{path} but not @code{dataPath}.  @xref{SPV Structure
693graph Element}, for more information.
694
695These elements have no attributes.
696
697@node SPV Structure pageSetup Element
698@subsection The @code{pageSetup} Element
699
700@example
701pageSetup
702   :initial-page-number=int?
703   :chart-size=(as-is | full-height | half-height | quarter-height | OTHER)?
704   :margin-left=dimension?
705   :margin-right=dimension?
706   :margin-top=dimension?
707   :margin-bottom=dimension?
708   :paper-height=dimension?
709   :paper-width=dimension?
710   :reference-orientation?
711   :space-after=dimension?
712=> pageHeader pageFooter
713
714pageHeader => pageParagraph?
715
716pageFooter => pageParagraph?
717
718pageParagraph => pageParagraph_text
719@end example
720
721The @code{pageSetup} element has the following attributes.
722
723@defvr {Attribute} @code{initial-page-number}
724The page number to put on the first page of printed output.  Usually
725@code{1}.
726@end defvr
727
728@defvr {Attribute} @code{chart-size}
729One of the listed, self-explanatory chart sizes,
730@code{quarter-height}, or a localization (!) of one of these (e.g.@:
731@code{dimensione attuale}, @code{Wie vorgegeben}).
732@end defvr
733
734@defvr {Attribute} @code{margin-left}
735@defvrx {Attribute} @code{margin-right}
736@defvrx {Attribute} @code{margin-top}
737@defvrx {Attribute} @code{margin-bottom}
738Margin sizes, e.g.@: @code{0.25in}.
739@end defvr
740
741@defvr {Attribute} @code{paper-height}
742@defvrx {Attribute} @code{paper-width}
743Paper sizes.
744@end defvr
745
746@defvr {Attribute} @code{reference-orientation}
747Indicates the orientation of the output page.  Either @code{0deg}
748(portrait) or @code{90deg} (landscape),
749@end defvr
750
751@defvr {Attribute} @code{space-after}
752The amount of space between printed objects, typically @code{12pt}.
753@end defvr
754
755@node SPV Structure @code{text} Element (Inside @code{pageParagraph})
756@subsection The @code{text} Element (Inside @code{pageParagraph})
757
758@example
759text[pageParagraph_text] :type=(title | text) => TEXT
760@end example
761
762This @code{text} element is nested inside a @code{pageParagraph}.  There
763is a different @code{text} element that is nested inside a
764@code{container}.
765
766The element is either empty, or contains CDATA that holds almost-XHTML
767text: in the corpus, either an @code{html} or @code{p} element.  It is
768@emph{almost}-XHTML because the @code{html} element designates the
769default namespace as
770@indicateurl{http://xml.spss.com/spss/viewer/viewer-tree} instead of
771an XHTML namespace, and because the CDATA can contain substitution
772variables.  The following variables are supported:
773
774@table @code
775@item &[Date]
776@itemx &[Time]
777The current date or time in the preferred format for the locale.
778
779@item &[Head1]
780@itemx &[Head2]
781@itemx &[Head3]
782@itemx &[Head4]
783First-, second-, third-, or fourth-level heading.
784
785@item &[PageTitle]
786The page title.
787
788@item &[Filename]
789Name of the output file.
790
791@item &[Page]
792The page number.
793@end table
794
795@code{&[Page]} for the page number and @code{&[PageTitle]} for the
796page title.
797
798Typical contents (indented for clarity):
799
800@example
801<html xmlns="http://xml.spss.com/spss/viewer/viewer-tree">
802    <head></head>
803    <body>
804        <p style="text-align:right; margin-top: 0">Page &[Page]</p>
805    </body>
806</html>
807@end example
808
809This element has the following attributes.
810
811@defvr {Attribute} @code{type}
812Always @code{text}.
813@end defvr
814
815@node SPV Light Detail Member Format
816@section Light Detail Member Format
817
818This section describes the format of ``light'' detail @file{.bin}
819members.  These members have a binary format which we describe here in
820terms of a context-free grammar using the following conventions:
821
822@table @asis
823@item NonTerminal @result{} @dots{}
824Nonterminals have CamelCaps names, and @result{} indicates a
825production.  The right-hand side of a production is often broken
826across multiple lines.  Break points are chosen for aesthetics only
827and have no semantic significance.
828
829@item 00, 01, @dots{}, ff.
830A bytes with a fixed value, written as a pair of hexadecimal digits.
831
832@item i0, i1, @dots{}, i9, i10, i11, @dots{}
833@itemx ib0, ib1, @dots{}, ib9, ib10, ib11, @dots{}
834A 32-bit integer in little-endian or big-endian byte order,
835respectively, with a fixed value, written in decimal.  Prefixed by
836@samp{i} for little-endian or @samp{ib} for big-endian.
837
838@item byte
839A byte.
840
841@item bool
842A byte with value 0 or 1.
843
844@item int16
845@itemx be16
846A 16-bit unsigned integer in little-endian or big-endian byte order,
847respectively.
848
849@item int32
850@itemx be32
851A 32-bit unsigned integer in little-endian or big-endian byte order,
852respectively.
853
854@item int64
855@itemx be64
856A 64-bit unsigned integer in little-endian or big-endian byte order,
857respectively.
858
859@item double
860A 64-bit IEEE floating-point number.
861
862@item float
863A 32-bit IEEE floating-point number.
864
865@item string
866@itemx bestring
867A 32-bit unsigned integer, in little-endian or big-endian byte order,
868respectively, followed by the specified number of bytes of character
869data.  (The encoding is indicated by the Formats nonterminal.)
870
871@item @var{x}?
872@var{x} is optional, e.g.@: 00? is an optional zero byte.
873
874@item @var{x}*@var{n}
875@var{x} is repeated @var{n} times, e.g.@: byte*10 for ten arbitrary bytes.
876
877@item @var{x}[@var{name}]
878Gives @var{x} the specified @var{name}.  Names are used in textual
879explanations.  They are also used, also bracketed, to indicate counts,
880e.g.@: @code{int32[n] byte*[n]} for a 32-bit integer followed by the
881specified number of arbitrary bytes.
882
883@item @var{a} @math{|} @var{b}
884Either @var{a} or @var{b}.
885
886@item (@var{x})
887Parentheses are used for grouping to make precedence clear, especially
888in the presence of @math{|}, e.g.@: in 00 (01 @math{|} 02 @math{|} 03)
88900.
890
891@item count(@var{x})
892@itemx becount(@var{x})
893A 32-bit unsigned integer, in little-endian or big-endian byte order,
894respectively, that indicates the number of bytes in @var{x}, followed
895by @var{x} itself.
896
897@item v1(@var{x})
898In a version 1 @file{.bin} member, @var{x}; in version 3, nothing.
899(The @file{.bin} header indicates the version.)
900
901@item v3(@var{x})
902In a version 3 @file{.bin} member, @var{x}; in version 1, nothing.
903@end table
904
905PSPP uses this grammar to parse light detail members.  See
906@file{src/output/spv/light-binary.grammar} in the PSPP source tree for
907the full grammar.
908
909Little-endian byte order is far more common in this format, but a few
910pieces of the format use big-endian byte order.
911
912Light detail members express linear units in two ways: points (pt), at
91372/inch, and ``device-independent pixels'' (px), at 96/inch.  To
914convert from pt to px, multiply by 1.33 and round up.  To convert
915from px to pt, divide by 1.33 and round down.
916
917A ``light'' detail member @file{.bin} consists of a number of sections
918concatenated together, terminated by an optional byte 01:
919
920@example
921LightMember =>
922    Header Titles Footnotes
923    Areas Borders PrintSettings TableSettings Formats
924    Dimensions Axes Cells
925    01?
926@end example
927
928The following sections go into more detail.
929
930@menu
931* SPV Light Member Header::
932* SPV Light Member Titles::
933* SPV Light Member Footnotes::
934* SPV Light Member Areas::
935* SPV Light Member Borders::
936* SPV Light Member Print Settings::
937* SPV Light Member Table Settings::
938* SPV Light Member Formats::
939* SPV Light Member Dimensions::
940* SPV Light Member Categories::
941* SPV Light Member Axes::
942* SPV Light Member Cells::
943* SPV Light Member Value::
944* SPV Light Member ValueMod::
945@end menu
946
947@node SPV Light Member Header
948@subsection Header
949
950An SPV light member begins with a 39-byte header:
951
952@example
953Header =>
954    01 00
955    (i1 @math{|} i3)[version]
956    bool[x0]
957    bool[x1]
958    bool[rotate-inner-column-labels]
959    bool[rotate-outer-row-labels]
960    bool[x2]
961    int32[x3]
962    int32[min-col-width] int32[max-col-width]
963    int32[min-row-width] int32[max-row-width]
964    int64[table-id]
965@end example
966
967@code{version} is a version number that affects the interpretation of
968some of the other data in the member.  We will refer to ``version 1''
969and ``version 3'' later on and use v1(@dots{}) and v3(@dots{}) for
970version-specific formatting (as described previously).
971
972If @code{rotate-inner-column-labels} is 1, then column labels closest
973to the data are rotated to be vertical; otherwise, they are shown
974in the normal way.
975
976If @code{rotate-outer-row-labels} is 1, then row labels farthest from
977the data are rotated to be vertical; otherwise, they are shown in the
978normal way.
979
980@code{table-id} is a binary version of the @code{tableId} attribute in
981the structure member that refers to the detail member.  For example,
982if @code{tableId} is @code{-4122591256483201023}, then @code{table-id}
983would be 0xc6c99d183b300001.
984
985@code{min-col-width} is the minimum width that a column will be
986assigned automatically.  @code{max-col-width} is the maximum width
987that a column will be assigned to accommodate a long column label.
988@code{min-row-width} and @code{max-row-width} are a similar range for
989the width of row labels.  All of these measurements are in 1/96 inch
990units (called a ``device independent pixel'' unit in Windows).
991
992The meaning of the other variable parts of the header is not known.  A
993writer may safely use version 3, true for @code{x0}, false for
994@code{x1}, true for @code{x2}, and 0x15 for @code{x3}.
995
996@node SPV Light Member Titles
997@subsection Titles
998
999@example
1000Titles =>
1001    Value[title] 01?
1002    Value[subtype] 01? 31
1003    Value[user-title] 01?
1004    (31 Value[corner-text] @math{|} 58)
1005    (31 Value[caption] @math{|} 58)
1006@end example
1007
1008The Titles follow the Header and specify the table's title, caption,
1009and corner text.
1010
1011The @code{user-title} is shown above the title and reflects any user
1012editing of the title text or style.  The @code{title} is the title
1013originally generated by the procedure.  Both of these are appropriate
1014for presentation and localized to the user's language.  For example,
1015for a frequency table, @code{title} and @code{user-title} normally
1016name the variable and @code{c} is simply ``Frequencies''.
1017
1018@code{subtype} is the same as the @code{subType} attribute in the
1019@code{table} structure XML element that referred to this member.
1020@xref{SPV Structure table Element}, for details.
1021
1022The @code{corner-text}, if present, is shown in the upper-left corner
1023of the table, above the row headings and to the left of the column
1024headings.  It is usually absent.  Corner text prevents row dimension
1025labels from being displayed above the dimension's group and category
1026labels (see @code{show-row-labels-in-corner}).
1027
1028The @code{caption}, if present, is shown below the table.
1029@code{caption} reflects user editing of the caption.
1030
1031@node SPV Light Member Footnotes
1032@subsection Footnotes
1033
1034@example
1035Footnotes => int32[n-footnotes] Footnote*[n-footnotes]
1036Footnote => Value[text] (58 @math{|} 31 Value[marker]) int32[show]
1037@end example
1038
1039Each footnote has @code{text} and an optional custom @code{marker}
1040(such as @samp{*}).
1041
1042@code{show} is a 32-bit signed integer.  It is positive to show the
1043footnote or negative to hide it.  Its magnitude is often 1, and in
1044other cases tends to be the number of references to the footnote.
1045
1046@node SPV Light Member Areas
1047@subsection Areas
1048
1049@example
1050Areas => 00? Area*8
1051Area =>
1052    byte[index] 31
1053    string[typeface] float[size] int32[style] bool[underline]
1054    int32[halign] int32[valign]
1055    string[fg-color] string[bg-color]
1056    bool[alternate] string[alt-fg-color] string[alt-bg-color]
1057    v3(int32[left-margin] int32[right-margin] int32[top-margin] int32[bottom-margin])
1058@end example
1059
1060Each Area represents the style for a different area of the table, in
1061the following order: title, caption, footer, corner, column labels,
1062row labels, data, and layers.
1063
1064@code{index} is the 1-based index of the Area, i.e. 1 for the first
1065Area, through 8 for the final Area.
1066
1067@code{typeface} is the string name of the font used in the area.  In
1068the corpus, this is @code{SansSerif} in over 99% of instances and
1069@code{Times New Roman} in the rest.
1070
1071@code{size} is the size of the font, in px (@pxref{SPV Light Detail
1072Member Format}) The most common size in the corpus is 12 px.  Even
1073though @code{size} has a floating-point type, in the corpus its values
1074are always integers.
1075
1076@code{style} is a bit mask.  Bit 0 (with value 1) is set for bold, bit
10771 (with value 2) is set for italic.
1078
1079@code{underline} is 1 if the font is underlined, 0 otherwise.
1080
1081@code{halign} specifies horizontal alignment: 0 for center, 2 for
1082left, 4 for right, 61453 for decimal, 64173 for mixed.  Mixed
1083alignment varies according to type: string data is left-justified,
1084numbers and most other formats are right-justified.
1085
1086@code{valign} specifies vertical alignment: 0 for center, 1 for top, 3
1087for bottom.
1088
1089@code{fg-color} and @code{bg-color} are the foreground color and
1090background color, respectively.  In the corpus, these are always
1091@code{#000000} and @code{#ffffff}, respectively.
1092
1093@code{alternate} is 1 if rows should alternate colors, 0 if all rows
1094should be the same color.  When @code{alternate} is 1,
1095@code{alt-fg-color} and @code{alt-bg-color} specify the colors for the
1096alternate rows; otherwise they are empty strings.
1097
1098@code{left-margin}, @code{right-margin}, @code{top-margin}, and
1099@code{bottom-margin} are measured in px.
1100
1101@node SPV Light Member Borders
1102@subsection Borders
1103
1104@example
1105Borders =>
1106    count(
1107        ib1[endian]
1108        be32[n-borders] Border*[n-borders]
1109        bool[show-grid-lines]
1110        00 00 00)
1111
1112Border =>
1113    be32[border-type]
1114    be32[stroke-type]
1115    be32[color]
1116@end example
1117
1118The Borders reflect how borders between regions are drawn.
1119
1120The fixed value of @code{endian} can be used to validate the
1121endianness.
1122
1123@code{show-grid-lines} is 1 to draw grid lines, otherwise 0.
1124
1125Each Border describes one kind of border.  @code{n-borders} seems to
1126always be 19.  Each @code{border-type} appears once (although in an
1127unpredictable order) and correspond to the following borders:
1128
1129@table @asis
1130@item 0
1131Title.
1132@item 1@dots{}4
1133Left, top, right, and bottom outer frame.
1134@item 5@dots{}8
1135Left, top, right, and bottom inner frame.
1136@item 9, 10
1137Left and top of data area.
1138@item 11, 12
1139Horizontal and vertical dimension rows.
1140@item 13, 14
1141Horizontal and vertical dimension columns.
1142@item 15, 16
1143Horizontal and vertical category rows.
1144@item 17, 18
1145Horizontal and vertical category columns.
1146@end table
1147
1148@code{stroke-type} describes how a border is drawn, as one of:
1149
1150@table @asis
1151@item 0
1152No line.
1153@item 1
1154Solid line.
1155@item 2
1156Dashed line.
1157@item 3
1158Thick line.
1159@item 4
1160Thin line.
1161@item 5
1162Double line.
1163@end table
1164
1165@code{color} is an RGB color.  Bits 24--31 are alpha, bits 16--23 are
1166red, 8--15 are green, 0--7 are blue.  An alpha of 255 indicates an
1167opaque color, therefore opaque black is 0xff000000.
1168
1169@node SPV Light Member Print Settings
1170@subsection Print Settings
1171
1172@example
1173PrintSettings =>
1174    count(
1175        ib1[endian]
1176        bool[all-layers]
1177        bool[paginate-layers]
1178        bool[fit-width]
1179        bool[fit-length]
1180        bool[top-continuation]
1181        bool[bottom-continuation]
1182        be32[n-orphan-lines]
1183        bestring[continuation-string])
1184@end example
1185
1186The PrintSettings reflect settings for printing.  The fixed value of
1187@code{endian} can be used to validate the endianness.
1188
1189@code{all-layers} is 1 to print all layers, 0 to print only the
1190visible layers.
1191
1192@code{paginate-layers} is 1 to print each layer at the start of a new
1193page, 0 otherwise.  (This setting is honored only @code{all-layers} is
11941, since otherwise only one layer is printed.)
1195
1196@code{fit-width} and @code{fit-length} control whether the table is
1197shrunk to fit within a page's width or length, respectively.
1198
1199@code{n-orphan-lines} is the minimum number of rows or columns to put
1200in one part of a table that is broken across pages.
1201
1202If @code{top-continuation} is 1, then @code{continuation-string} is
1203printed at the top of a page when a table is broken across pages for
1204printing; similarly for @code{bottom-continuation} and the bottom of a
1205page.  Usually, @code{continuation-string} is empty.
1206
1207@node SPV Light Member Table Settings
1208@subsection Table Settings
1209
1210@example
1211TableSettings =>
1212    count(
1213      v3(
1214        ib1[endian]
1215        be32[x5]
1216        be32[current-layer]
1217        bool[omit-empty]
1218        bool[show-row-labels-in-corner]
1219        bool[show-alphabetic-markers]
1220        bool[footnote-marker-superscripts]
1221        byte[x6]
1222        becount(
1223          Breakpoints[row-breaks] Breakpoints[column-breaks]
1224          Keeps[row-keeps] Keeps[column-keeps]
1225          PointKeeps[row-point-keeps] PointKeeps[column-point-keeps]
1226        )
1227        bestring[notes]
1228        bestring[table-look]
1229        00...))
1230
1231Breakpoints => be32[n-breaks] be32*[n-breaks]
1232
1233Keeps => be32[n-keeps] Keep*[n-keeps]
1234Keep => be32[offset] be32[n]
1235
1236PointKeeps => be32[n-point-keeps] PointKeep*[n-point-keeps]
1237PointKeep => be32[offset] be32 be32
1238@end example
1239
1240The TableSettings reflect display settings.  The fixed value of
1241@code{endian} can be used to validate the endianness.
1242
1243@code{current-layer} is the displayed layer.  The interpretation when
1244there is more than one layer dimension is not yet known.
1245
1246If @code{omit-empty} is 1, empty rows or columns (ones with nothing in
1247any cell) are hidden; otherwise, they are shown.
1248
1249If @code{show-row-labels-in-corner} is 1, then row labels are shown in
1250the upper left corner; otherwise, they are shown nested.
1251
1252If @code{show-alphabetic-markers} is 1, markers are shown as letters
1253(e.g.@: @samp{a}, @samp{b}, @samp{c}, @dots{}); otherwise, they are
1254shown as numbers starting from 1.
1255
1256When @code{footnote-marker-superscripts} is 1, footnote markers are shown
1257as superscripts, otherwise as subscripts.
1258
1259The Breakpoints are rows or columns after which there is a page break;
1260for example, a row break of 1 requests a page break after the second
1261row.  Usually no breakpoints are specified, indicating that page
1262breaks should be selected automatically.
1263
1264The Keeps are ranges of rows or columns to be kept together without a
1265page break; for example, a row Keep with @code{offset} 1 and @code{n}
126610 requests that the 10 rows starting with the second row be kept
1267together.  Usually no Keeps are specified.
1268
1269The PointKeeps seem to be generated automatically based on
1270user-specified Keeps.  They seems to indicate a conversion from rows
1271or columns to pixel or point offsets.
1272
1273@code{notes} is a text string that contains user-specified notes.  It
1274is displayed when the user hovers the cursor over the table, like
1275``alt text'' on a webpage.  It is not printed.  It is usually empty.
1276
1277@code{table-look} is the name of a SPSS ``TableLook'' table style,
1278such as ``Default'' or ``Academic''; it is often empty.
1279
1280TableSettings ends with an arbitrary number of null bytes.  A writer
1281may safely write 82 null bytes.
1282
1283A writer may safely use 4 for @code{x5} and 0 for @code{x6}.
1284
1285@node SPV Light Member Formats
1286@subsection Formats
1287
1288@example
1289Formats =>
1290    int32[n-widths] int32*[n-widths]
1291    string[locale]
1292    int32[current-layer]
1293    bool bool bool
1294    Y0
1295    CustomCurrency
1296    count(
1297      v1(X0?)
1298      v3(count(X1 count(X2)) count(X3)))
1299Y0 => int32[epoch] byte[decimal] byte[grouping]
1300CustomCurrency => int32[n-ccs] string*[n-ccs]
1301@end example
1302
1303If @code{n-widths} is nonzero, then the accompanying integers are
1304column widths as manually adjusted by the user.
1305
1306@code{locale} is a locale including an encoding, such as
1307@code{en_US.windows-1252} or @code{it_IT.windows-1252}.  The rest of
1308the character strings in the member use this encoding.  The encoding
1309string is itself encoded in US-ASCII.
1310
1311@code{epoch} is the year that starts the epoch.  A 2-digit year is
1312interpreted as belonging to the 100 years beginning at the epoch.  The
1313default epoch year is 69 years prior to the current year; thus, in
13142017 this field by default contains 1948.  In the corpus, @code{epoch}
1315ranges from 1943 to 1948, plus some contain -1.
1316
1317@code{decimal} is the decimal point character.  The observed values
1318are @samp{.} and @samp{,}.
1319
1320@code{grouping} is the grouping character.  Usually, it is @samp{,} if
1321@code{decimal} is @samp{.}, and vice versa.  Other observed values are
1322@samp{'} (apostrophe), @samp{ } (space), and zero (presumably
1323indicating that digits should not be grouped).
1324
1325@code{n-ccs} is observed as either 0 or 5.  When it is 5, the
1326following strings are CCA through CCE format strings.  @xref{Custom
1327Currency Formats,,, pspp, PSPP}.  Most commonly these are all
1328@code{-,,,} but other strings occur.
1329
1330@subsubheading X0
1331
1332X0 only appears, optionally, in version 1 members.
1333
1334@example
1335X0 => byte*14 Y1 Y2
1336Y1 =>
1337    string[command] string[command-local]
1338    string[language] string[charset] string[locale]
1339    bool bool bool bool
1340    Y0
1341Y2 => CustomCurrency byte[missing] bool[x17]
1342@end example
1343
1344@code{command} describes the statistical procedure that generated the
1345output, in English.  It is not necessarily the literal syntax name of
1346the procedure: for example, NPAR TESTS becomes ``Nonparametric
1347Tests.''  @code{command-local} is the procedure's name, translated
1348into the output language; it is often empty and, when it is not,
1349sometimes the same as @code{command}.
1350
1351@code{dataset} is the name of the dataset analyzed to produce the
1352output, e.g.@: @code{DataSet1}, and @code{datafile} the name of the
1353file it was read from, e.g.@: @file{C:\Users\foo\bar.sav}.  The latter
1354is sometimes the empty string.
1355
1356@code{missing} is the character used to indicate that a cell contains
1357a missing value.  It is always observed as @samp{.}.
1358
1359X0 repeats @code{decimal}, @code{grouping}, CustomCurrency, and
1360@code{missing} already included in Formats.
1361
1362A writer may safely use false for @code{x17}.
1363
1364@subsubheading X1
1365
1366X1 only appears in version 3 members.
1367
1368@example
1369X1 =>
1370    bool byte[x15] bool[x16]
1371    byte[lang]
1372    byte[show-variables]
1373    byte[show-values]
1374    int32[x18] int32[x19]
1375    00*17
1376    bool[x20]
1377    bool[show-caption]
1378@end example
1379
1380@code{lang} may indicate the language in use.  Some values seem to be
13810: @t{en}, 1: @t{de}, 2: @t{es}, 3: @t{it}, 5: @t{ko}, 6: @t{pl}, 8:
1382@t{zh-tw}, 10: @t{pt_BR}, 11: @t{fr}.  The @code{locale} in Formats
1383and the @code{language}, @code{charset}, and @code{locale} in X0 are
1384more likely to be useful in practice.
1385
1386@code{show-variables} determines how variables are displayed by
1387default.  A value of 1 means to display variable names, 2 to display
1388variable labels when available, 3 to display both (name followed by
1389label, separated by a space).  The most common value is 0, which
1390probably means to use a global default.
1391
1392@code{show-values} is a similar setting for values.  A value of 1
1393means to display the value, 2 to display the value label when
1394available, 3 to display both.  Again, the most common value is 0,
1395which probably means to use a global default.
1396
1397@code{show-caption} is true to show the caption, false to hide it.
1398
1399A writer may safely use false for @code{x14}, 1 for @code{x15}, false
1400for @code{x16}, -1 for @code{x18} and @code{x19}, and false for
1401@code{x20}.
1402
1403@subsubheading X2
1404
1405X2 only appears in version 3 members.
1406
1407@example
1408X2 =>
1409    int32[n-row-heights] int32*[n-row-heights]
1410    int32[n-style-map] StyleMap*[n-style-map]
1411    int32[n-styles] StylePair*[n-styles]
1412    count((i0 i0)?)
1413StyleMap => int64[cell-index] int16[style-index]
1414@end example
1415
1416If present, @code{n-row-heights} and the accompanying integers are row
1417heights as manually adjusted by the user.
1418
1419The rest of X2 specifies styles for data cells.  At first glance this
1420is odd, because each data cell can have its own style embedded as part
1421of the data, but in practice X2 specifies a style for a cell only if
1422that cell is empty (and thus does not appear in the data at all).
1423Each StyleMap specifies the index of a blank cell, calculated the same
1424was as in the Cells (@pxref{SPV Light Member Cells}), along with a
14250-based index into the accompanying StylePair array.
1426
1427A writer may safely omit the optional @code{i0 i0} inside the
1428@code{count(@dots{})}.
1429
1430@subsubheading X3
1431
1432X3 only appears in version 3 members.
1433
1434@example
1435X3 =>
1436    01 00 byte[x21] 00 00 00
1437    Y1
1438    double[small] 01
1439    (string[dataset] string[datafile] i0 int32[date] i0)?
1440    Y2
1441    (int32[x22] i0)?
1442@end example
1443
1444@code{date} is a date, as seconds since the epoch, i.e.@: since
1445January 1, 1970.  Pivot tables within an SPV file often have dates a
1446few minutes apart, so this is probably a creation date for the table
1447rather than for the file.
1448
1449X3 repeats @code{decimal}, @code{grouping}, CustomCurrency, and
1450@code{missing} already included in Formats.  @code{command},
1451@code{command-local}, @code{language}, @code{charset}, and
1452@code{locale} have the same meaning as in X0.
1453
1454@code{small} is a small real number, e.g.@: .001.  Numbers smaller
1455than this in absolute value are displayed in scientific notation.
1456
1457Sometimes @code{dataset}, @code{datafile}, and @code{date} are present
1458and other times they are absent.  The reader can distinguish by
1459assuming that they are present and then checking whether the
1460presumptive @code{dataset} contains a null byte (a valid string never
1461will).
1462
1463@code{x22} is usually 0 or 2000000.
1464
1465A writer may safely use 4 for @code{x21} and omit @code{x22} and the
1466other optional bytes at the end.
1467
1468@node SPV Light Member Dimensions
1469@subsection Dimensions
1470
1471A pivot table presents multidimensional data.  A Dimension identifies
1472the categories associated with each dimension.
1473
1474@example
1475Dimensions => int32[n-dims] Dimension*[n-dims]
1476Dimension =>
1477    Value[name] DimProperties
1478    int32[n-categories] Category*[n-categories]
1479DimProperties =>
1480    byte[x1]
1481    byte[x2]
1482    int32[x3]
1483    bool[hide-dim-label]
1484    bool[hide-all-labels]
1485    01 int32[dim-index]
1486@end example
1487
1488@code{name} is the name of the dimension, e.g.@: @code{Variables},
1489@code{Statistics}, or a variable name.
1490
1491The meanings of @code{x1} and @code{x3} are unknown.  @code{x1} is
1492usually 0 but many other values have been observed.  A writer may
1493safely use 0 for @code{x1} and 2 for @code{x3}.
1494
1495@code{x2} is 0, 1, or 2.  For a pivot table with @var{L} layer
1496dimensions, @var{R} row dimensions, and @var{C} column dimensions,
1497@code{x2} is 2 for the first @var{L} dimensions, 0 for the next
1498@var{R} dimensions, and 1 for the remaining @var{C} dimensions.  This
1499does not mean that the layer dimensions must be presented first,
1500followed by the row dimensions, followed by the column dimensions---on
1501the contrary, they are frequently in a different order---but @code{x2}
1502must follow this pattern to prevent the pivot table from being
1503misinterpreted.
1504
1505If @code{hide-dim-label} is 00, the pivot table displays a label for
1506the dimension itself.  Because usually the group and category labels
1507are enough explanation, it is usually 01.
1508
1509If @code{hide-all-labels} is 01, the pivot table omits all labels for
1510the dimension, including group and category labels.  It is usually 00.
1511When @code{hide-all-labels} is 01, @code{show-dim-label} is ignored.
1512
1513@code{dim-index} is usually the 0-based index of the dimension, e.g.@:
15140 for the first dimension, 1 for the second, and so on.  Sometimes it
1515is -1.  There is no visible difference.
1516
1517@node SPV Light Member Categories
1518@subsection Categories
1519
1520Categories are arranged in a tree.  Only the leaf nodes in the tree
1521are really categories; the others just serve as grouping constructs.
1522
1523@example
1524Category => Value[name] (Leaf @math{|} Group)
1525Leaf => 00 00 00 i2 int32[leaf-index] i0
1526Group =>
1527    bool[merge] 00 01 int32[x23]
1528    i-1 int32[n-subcategories] Category*[n-subcategories]
1529@end example
1530
1531@code{name} is the name of the category (or group).
1532
1533A Leaf represents a leaf category.  The Leaf's @code{leaf-index} is a
1534nonnegative integer unique within the Dimension and less than
1535@code{n-categories} in the Dimension.  If the user does not sort or
1536rearrange the categories, then @code{leaf-index} starts at 0 for the
1537first Leaf in the dimension and increments by 1 with each successive
1538Leaf.  If the user does sorts or rearrange the categories, then the
1539order of categories in the file reflects that change and
1540@code{leaf-index} reflects the original order.
1541
1542Occasionally a dimension has no leaf categories at all.  A table that
1543contains such a dimension necessarily has no data at all.
1544
1545A Group is a group of nested categories.  Usually a Group contains at
1546least one Category, so that @code{n-subcategories} is positive, but a
1547few Groups with @code{n-subcategories} 0 has been observed.
1548
1549If a Group's @code{merge} is 00, the most common value, then the group
1550is really a distinct group that should be represented as such in the
1551visual representation and user interface.  If @code{merge} is 01, the
1552categories in this group should be shown and treated as if they were
1553direct children of the group's containing group (or if it has no
1554parent group, then direct children of the dimension), and this group's
1555name is irrelevant and should not be displayed.  (Merged groups can be
1556nested!)
1557
1558(For writing an SPV file, there is no need to use the @code{merge}
1559feature unless it is convenient.)
1560
1561A Group's @code{x23} appears to be i2 when all of the categories
1562within a group are leaf categories that directly represent data values
1563for a variable (e.g.@: in a frequency table or crosstabulation, a group
1564of values in a variable being tabulated) and i0 otherwise.  A writer
1565may safely write a constant 0 in this field.
1566
1567@node SPV Light Member Axes
1568@subsection Axes
1569
1570After the dimensions come assignment of each dimension to one of the
1571axes: layers, rows, and columns.
1572
1573@example
1574Axes =>
1575    int32[n-layers] int32[n-rows] int32[n-columns]
1576    int32*[n-layers] int32*[n-rows] int32*[n-columns]
1577@end example
1578
1579The values of @code{n-layers}, @code{n-rows}, and @code{n-columns}
1580each specifies the number of dimensions displayed in layers, rows, and
1581columns, respectively.  Any of them may be zero.  Their values sum to
1582@code{n-dimensions} from Dimensions (@pxref{SPV Light Member
1583Dimensions}).
1584
1585The following @code{n-dimensions} integers, in three groups, are a
1586permutation of the 0-based dimension numbers.  The first
1587@code{n-layers} integers specify each of the dimensions represented by
1588layers, the next @code{n-rows} integers specify the dimensions
1589represented by rows, and the final @code{n-columns} integers specify
1590the dimensions represented by columns.  When there is more than one
1591dimension of a given kind, the inner dimensions are given first.
1592
1593@node SPV Light Member Cells
1594@subsection Cells
1595
1596The final part of an SPV light member contains the actual data.
1597
1598@example
1599Cells => int32[n-cells] Cell*[n-cells]
1600Cell => int64[index] v1(00?) Value
1601@end example
1602
1603A Cell consists of an @code{index} and a Value.  Suppose there are
1604@math{d} dimensions, numbered 1 through @math{d} in the order given in
1605the Dimensions previously, and that dimension @math{i}, has @math{n_i}
1606categories.  Consider the cell at coordinates @math{x_i}, @math{1 \le
1607i \le d}, and note that @math{0 \le x_i < n_i}.  Then the index is
1608calculated by the following algorithm:
1609
1610@display
1611let @i{index} = 0
1612for each @math{i} from 1 to @math{d}:
1613    @i{index} = (@math{n_i \times} @i{index}) @math{+} @math{x_i}
1614@end display
1615
1616For example, suppose there are 3 dimensions with 3, 4, and 5
1617categories, respectively.  The cell at coordinates (1, 2, 3) has
1618index @math{5 \times (4 \times (3 \times 0 + 1) + 2) + 3 = 33}.
1619Within a given dimension, the index is the @code{leaf-index} in a Leaf.
1620
1621@node SPV Light Member Value
1622@subsection Value
1623
1624Value is used throughout the SPV light member format.  It boils down
1625to a number or a string.
1626
1627@example
1628Value => 00? 00? 00? 00? RawValue
1629RawValue =>
1630    01 ValueMod int32[format] double[x]
1631  @math{|} 02 ValueMod int32[format] double[x]
1632    string[var-name] string[value-label] byte[show]
1633  @math{|} 03 string[local] ValueMod string[id] string[c] bool[fixed]
1634  @math{|} 04 ValueMod int32[format] string[value-label] string[var-name]
1635    byte[show] string[s]
1636  @math{|} 05 ValueMod string[var-name] string[var-label] byte[show]
1637  @math{|} ValueMod string[template] int32[n-args] Argument*[n-args]
1638Argument =>
1639    i0 Value
1640  @math{|} int32[x] i0 Value*[x]      /* x > 0 */
1641@end example
1642
1643There are several possible encodings, which one can distinguish by the
1644first nonzero byte in the encoding.
1645
1646@table @asis
1647@item 01
1648The numeric value @code{x}, intended to be presented to the user
1649formatted according to @code{format}, which is in the format described
1650for system files, except that format 40 is a synonym for F format
1651instead of MTIME.  @xref{System File Output Formats}, for details.
1652Most commonly, @code{format} has width 40 (the maximum).
1653
1654An @code{x} with the maximum negative double value @code{-DBL_MAX}
1655represents the system-missing value SYSMIS.  (HIGHEST and LOWEST have
1656not been observed.)  @xref{System File Format}, for more about these
1657special values.
1658
1659@item 02
1660Similar to @code{01}, with the additional information that @code{x} is
1661a value of variable @code{var-name} and has value label
1662@code{value-label}.  Both @code{var-name} and @code{value-label} can
1663be the empty string, the latter very commonly.
1664
1665@code{show} determines whether to show the numeric value or the value
1666label.  A value of 1 means to show the value, 2 to show the label, 3
1667to show both, and 0 means to use the default specified in
1668@code{show-values} (@pxref{SPV Light Member Formats}).
1669
1670@item 03
1671A text string, in two forms: @code{c} is in English, and sometimes
1672abbreviated or obscure, and @code{local} is localized to the user's
1673locale.  In an English-language locale, the two strings are often the
1674same, and in the cases where they differ, @code{local} is more
1675appropriate for a user interface, e.g.@: @code{c} of ``Not a PxP table
1676for MCN...'' versus @code{local} of ``Computed only for a PxP table,
1677where P must be greater than 1.''
1678
1679@code{c} and @code{local} are always either both empty or both
1680nonempty.
1681
1682@code{id} is a brief identifying string whose form seems to resemble a
1683programming language identifier, e.g.@: @code{cumulative_percent} or
1684@code{factor_14}.  It is not unique.
1685
1686@code{fixed} is 00 for text taken from user input, such as syntax
1687fragment, expressions, file names, data set names, and 01 for fixed
1688text strings such as names of procedures or statistics.  In the former
1689case, @code{id} is always the empty string; in the latter case,
1690@code{id} is still sometimes empty.
1691
1692@item 04
1693The string value @code{s}, intended to be presented to the user
1694formatted according to @code{format}.  The format for a string is not
1695too interesting, and the corpus contains many clearly invalid formats
1696like A16.39 or A255.127 or A134.1, so readers should probably ignore
1697the format entirely.
1698
1699@code{s} is a value of variable @code{var-name} and has value label
1700@code{value-label}.  @code{var-name} is never empty but
1701@code{value-label} is commonly empty.
1702
1703@code{show} has the same meaning as in the encoding for 02.
1704
1705@item 05
1706Variable @code{var-name}, which is rarely observed as empty in the
1707corpus, with variable label @code{var-label}, which is often empty.
1708
1709@code{show} determines whether to show the variable name or the
1710variable label.  A value of 1 means to show the name, 2 to show the
1711label, 3 to show both, and 0 means to use the default specified in
1712@code{show-variables} (@pxref{SPV Light Member Formats}).
1713
1714@item otherwise
1715When the first byte of a RawValue is not one of the above, the
1716RawValue starts with a ValueMod, whose syntax is described in the next
1717section.  (A ValueMod always begins with byte 31 or 58.)
1718
1719This case is a template string, analogous to @code{printf}, followed
1720by one or more Arguments, each of which has one or more values.  The
1721template string is copied directly into the output except for the
1722following special syntax,
1723
1724@table @code
1725@item \%
1726@itemx \:
1727@itemx \[
1728@itemx \]
1729Each of these expands to the character following @samp{\\}, to escape
1730characters that have special meaning in template strings.  These are
1731effective inside and outside the @code{[@dots{}]}  syntax forms
1732described below.
1733
1734@item \n
1735Expands to a new-line, inside or outside the @code{[@dots{}]} forms
1736described below.
1737
1738@item ^@var{i}
1739Expands to a formatted version of argument @var{i}, which must have
1740only a single value.  For example, @code{^1} expands to the first
1741argument's @code{value}.
1742
1743@item [:@var{a}:]@var{i}
1744Expands @var{a} for each of the values in @var{i}.  @var{a}
1745should contain one or more @code{^@var{j}} conversions, which are
1746drawn from the values for argument @var{i} in order.  Some examples
1747from the corpus:
1748
1749@table @code
1750@item [:^1:]1
1751All of the values for the first argument, concatenated.
1752
1753@item [:^1\n:]1
1754Expands to the values for the first argument, each followed by
1755a new-line.
1756
1757@item [:^1 = ^2:]2
1758Expands to @code{@var{x} = @var{y}} where @var{x} is the second
1759argument's first value and @var{y} is its second value.  (This would
1760be used only if the argument has two values.  If there were more
1761values, the second and third values would be directly concatenated,
1762which would look funny.)
1763@end table
1764
1765@item [@var{a}:@var{b}:]@var{i}
1766This extends the previous form so that the first values are expanded
1767using @var{a} and later values are expanded using @var{b}.  For an
1768unknown reason, within @var{a} the @code{^@var{j}} conversions are
1769instead written as @code{%@var{j}}.  Some examples from the corpus:
1770
1771@table @code
1772@item [%1:*^1:]1
1773Expands to all of the values for the first argument, separated by
1774@samp{*}.
1775
1776@item [%1 = %2:, ^1 = ^2:]1
1777Given appropriate values for the first argument, expands to @code{X =
17781, Y = 2, Z = 3}.
1779
1780@item [%1:, ^1:]1
1781Given appropriate values, expands to @code{1, 2, 3}.
1782@end table
1783@end table
1784
1785The template string is localized to the user's locale.
1786@end table
1787
1788A writer may safely omit all of the optional 00 bytes at the beginning
1789of a Value, except that it should write a single 00 byte before a
1790templated Value.
1791
1792@node SPV Light Member ValueMod
1793@subsection ValueMod
1794
1795A ValueMod can specify special modifications to a Value.
1796
1797@example
1798ValueMod =>
1799    58
1800  @math{|} 31
1801    int32[n-refs] int16*[n-refs]
1802    int32[n-subscripts] string*[n-subscripts]
1803    v1(00 (i1 | i2) 00? 00? int32 00? 00?)
1804    v3(count(TemplateString StylePair))
1805
1806TemplateString => count((count((i0 (58 @math{|} 31 55))?) (58 @math{|} 31 string[id]))?)
1807
1808StylePair =>
1809    (31 FontStyle | 58)
1810    (31 CellStyle | 58)
1811
1812FontStyle =>
1813    bool[bold] bool[italic] bool[underline] bool[show]
1814    string[fg-color] string[bg-color]
1815    string[typeface] byte[size]
1816
1817CellStyle =>
1818    int32[halign] int32[valign] double[decimal-offset]
1819    int16[left-margin] int16[right-margin]
1820    int16[top-margin] int16[bottom-margin]
1821@end example
1822
1823A ValueMod that begins with ``31'' specifies special modifications to
1824a Value.
1825
1826Each of the @code{n-refs} integers is a reference to a Footnote
1827(@pxref{SPV Light Member Footnotes}) by 0-based index.  Footnote
1828markers are shown appended to the main text of the Value, as
1829superscripts.
1830
1831The @code{subscripts}, if present, are strings to append to the main
1832text of the Value, as subscripts.  Each subscript text is a brief
1833indicator, e.g.@: @samp{a} or @samp{b}, with its meaning indicated by
1834the table caption.  When multiple subscripts are present, they are
1835displayed separated by commas.
1836
1837The @code{id} inside the TemplateString, if present, is a template
1838string for substitutions using the syntax explained previously.  It
1839appears to be an English-language version of the localized template
1840string in the Value in which the Template is nested.  A writer may
1841safely omit the optional fixed data in TemplateString.
1842
1843FontStyle and CellStyle, if present, change the style for this
1844individual Value.  In FontStyle, @code{bold}, @code{italic}, and
1845@code{underline} control the particular style.  @code{show} is
1846ordinarily 1; if it is 0, then the cell data is not shown.
1847@code{fg-color} and @code{bg-color} are strings in the format
1848@code{#rrggbb}, e.g.@: @code{#ff0000} for red or @code{#ffffff} for
1849white.  The empty string is occasionally observed also.  The
1850@code{size} is a font size in units of 1/128 inch.
1851
1852In CellStyle, @code{halign} is 0 for center, 2 for left, 4 for right,
18536 for decimal, 0xffffffad for mixed.  For decimal alignment,
1854@code{decimal-offset} is the decimal point's offset from the right
1855side of the cell, in pt (@pxref{SPV Light Detail Member Format}).
1856@code{valign} specifies vertical alignment: 0 for center, 1 for top, 3
1857for bottom.  @code{left-margin}, @code{right-margin},
1858@code{top-margin}, and @code{bottom-margin} are in pt.
1859
1860@node SPV Legacy Detail Member Binary Format
1861@section Legacy Detail Member Binary Format
1862
1863Whereas the light binary format represents everything about a given
1864pivot table, the legacy binary format conceptually consists of a
1865number of named sources, each of which consists of a number of named
1866variables, each of which is a 1-dimensional array of numbers or
1867strings or a mix.  Thus, the legacy binary member format is quite
1868simple.
1869
1870This section uses the same context-free grammar notation as in the
1871previous section, with the following additions:
1872
1873@table @asis
1874@item vAF(@var{x})
1875In a version 0xaf legacy member, @var{x}; in other versions, nothing.
1876(The legacy member header indicates the version; see below.)
1877
1878@item vB0(@var{x})
1879In a version 0xb0 legacy member, @var{x}; in other versions, nothing.
1880@end table
1881
1882A legacy detail member @file{.bin} has the following overall format:
1883
1884@example
1885LegacyBinary =>
1886    00 byte[version] int16[n-sources] int32[member-size]
1887    Metadata*[n-sources]
1888    #Data*[n-sources]
1889    #Strings?
1890@end example
1891
1892@code{version} is a version number that affects the interpretation of
1893some of the other data in the member.  Versions 0xaf and 0xb0 are
1894known.  We will refer to ``version 0xaf'' and ``version 0xb0'' members
1895later on.
1896
1897A legacy member consists of @code{n-sources} data sources, each of
1898which has Metadata and Data.
1899
1900@code{member-size} is the size of the legacy binary member, in bytes.
1901
1902The Data and Strings above are commented out because the Metadata has
1903some oddities that mean that the Data sometimes seems to start at
1904an unexpected place.  The following section goes into detail.
1905
1906@menu
1907* SPV Legacy Member Metadata::
1908* SPV Legacy Member Numeric Data::
1909* SPV Legacy Member String Data::
1910@end menu
1911
1912@node SPV Legacy Member Metadata
1913@subsection Metadata
1914
1915@example
1916Metadata =>
1917    int32[n-values] int32[n-variables] int32[data-offset]
1918    vAF(byte*28[source-name])
1919    vB0(byte*64[source-name] int32[x])
1920@end example
1921
1922A data source has @code{n-variables} variables, each with
1923@code{n-values} data values.
1924
1925@code{source-name} is a 28- or 64-byte string padded on the right with
19260-bytes.  The names that appear in the corpus are very generic:
1927usually @code{tableData} for pivot table data or @code{source0} for
1928chart data.
1929
1930A given Metadata's @code{data-offset} is the offset, in bytes, from
1931the beginning of the member to the start of the corresponding Data.
1932This allows programs to skip to the beginning of the data for a
1933particular source.  In every case in the corpus, the Data follow the
1934Metadata in the same order, but it is important to use
1935@code{data-offset} instead of reading sequentially through the file
1936because of the exception described below.
1937
1938One SPV file in the corpus has legacy binary members with version 0xb0
1939but a 28-byte @code{source-name} field (and only a single source).  In
1940practice, this means that the 64-byte @code{source-name} used in
1941version 0xb0 has a lot of 0-bytes in the middle followed by the
1942@code{variable-name} of the following Data.  As long as a reader
1943treats the first 0-byte in the @code{source-name} as terminating the
1944string, it can properly interpret these members.
1945
1946The meaning of @code{x} in version 0xb0 is unknown.
1947
1948@node SPV Legacy Member Numeric Data
1949@subsection Numeric Data
1950
1951@example
1952Data => Variable*[n-variables]
1953Variable => byte*288[variable-name] double*[n-values]
1954@end example
1955
1956Data follow the Metadata in the legacy binary format, with sources in
1957the same order (but readers should use the @code{data-offset} in
1958Metadata records, rather than reading sequentially).  Each Variable
1959begins with a @code{variable-name} that generally indicates its role
1960in the pivot table, e.g.@: ``cell'', ``cellFormat'',
1961``dimension0categories'', ``dimension0group0'', followed by the
1962numeric data, one double per datum.  A double with the maximum
1963negative double @code{-DBL_MAX} represents the system-missing value
1964SYSMIS.
1965
1966@node SPV Legacy Member String Data
1967@subsection String Data
1968
1969@example
1970Strings => SourceMaps[maps] Labels
1971
1972SourceMaps => int32[n-maps] SourceMap*[n-maps]
1973
1974SourceMap => string[source-name] int32[n-variables] VariableMap*[n-variables]
1975VariableMap => string[variable-name] int32[n-data] DatumMap*[n-data]
1976DatumMap => int32[value-idx] int32[label-idx]
1977
1978Labels => int32[n-labels] Label*[n-labels]
1979Label => int32[frequency] string[label]
1980@end example
1981
1982Each variable may include a mix of numeric and string data values.  If
1983a legacy binary member contains any string data, Strings is present;
1984otherwise, it ends just after the last Data element.
1985
1986The string data overlays the numeric data.  When a variable includes
1987any string data, its Variable represents the string values with a
1988SYSMIS or NaN placeholder.  (Not all such values need be
1989placeholders.)
1990
1991Each SourceMap provides a mapping between SYSMIS or NaN values in source
1992@code{source-name} and the string data that they represent.
1993@code{n-variables} is the number of variables in the source that
1994include string data.  More precisely, it is the 1-based index of the
1995last variable in the source that includes any string data; thus, it
1996would be 4 if there are 5 variables and only the fourth one includes
1997string data.
1998
1999A VariableMap repeats its variable's name, but variables are always
2000present in the same order as the source, starting from the first
2001variable, without skipping any even if they have no string values.
2002Each VariableMap contains DatumMap nonterminals, each of which maps
2003from a 0-based index within its variable's data to a 0-based label
2004index, e.g.@: pair @code{value-idx} = 2, @code{label-idx} = 3, means
2005that the third data value (which must be SYSMIS or NaN) is to be
2006replaced by the string of the fourth Label.
2007
2008The labels themselves follow the pairs.  The valuable part of each
2009label is the string @code{label}.  Each label also includes a
2010@code{frequency} that reports the number of DatumMaps that reference
2011it (although this is not useful).
2012
2013@node SPV Legacy Detail Member XML Format
2014@section Legacy Detail Member XML Format
2015
2016The design of the detail XML format is not what one would end up with
2017for describing pivot tables.  This is because it is a special case
2018of a much more general format (``visualization XML'' or ``VizML'')
2019that can describe a wide range of visualizations.  Most of this
2020generality is overkill for tables, and so we end up with a funny
2021subset of a general-purpose format.
2022
2023An XML Schema for VizML is available, distributed with SPSS binaries,
2024under a nonfree license.  It contains documentation that is
2025occasionally helpful.
2026
2027This section describes the detail XML format using the same notation
2028already used for the structure XML format (@pxref{SPV Structure Member
2029Format}).  See @file{src/output/spv/detail-xml.grammar} in the PSPP
2030source tree for the full grammar that it uses for parsing.
2031
2032The important elements of the detail XML format are:
2033
2034@itemize @bullet
2035@item
2036Variables.  @xref{SPV Detail Variable Elements}.
2037
2038@item
2039Assignment of variables to axes.  A variable can appear as columns, or
2040rows, or layers.  The @code{faceting} element and its sub-elements
2041describe this assignment.
2042
2043@item
2044Styles and other annotations.
2045@end itemize
2046
2047This description is not detailed enough to write legacy tables.
2048Instead, write tables in the light binary format.
2049
2050@menu
2051* SPV Detail visualization Element::
2052* SPV Detail Variable Elements::
2053* SPV Detail extension Element::
2054* SPV Detail graph Element::
2055* SPV Detail location Element::
2056* SPV Detail faceting Element::
2057* SPV Detail facetLayout Element::
2058* SPV Detail label Element::
2059* SPV Detail setCellProperties Element::
2060* SPV Detail setFormat Element::
2061* SPV Detail interval Element::
2062* SPV Detail style Element::
2063* SPV Detail labelFrame Element::
2064* SPV Detail Legacy Properties::
2065@end menu
2066
2067@node SPV Detail visualization Element
2068@subsection The @code{visualization} Element
2069
2070@example
2071visualization
2072   :creator
2073   :date
2074   :lang
2075   :name
2076   :style[style_ref]=ref style
2077   :type
2078   :version
2079   :schemaLocation?
2080=> visualization_extension?
2081   userSource
2082   (sourceVariable | derivedVariable)+
2083   categoricalDomain?
2084   graph
2085   labelFrame[lf1]*
2086   container?
2087   labelFrame[lf2]*
2088   style+
2089   layerController?
2090
2091extension[visualization_extension]
2092   :numRows=int?
2093   :showGridline=bool?
2094   :minWidthSet=(true)?
2095   :maxWidthSet=(true)?
2096=> EMPTY
2097
2098userSource :missing=(listwise | pairwise)? => EMPTY
2099
2100categoricalDomain => variableReference simpleSort
2101
2102simpleSort :method[sort_method]=(custom) => categoryOrder
2103
2104container :style=ref style => container_extension? location+ labelFrame*
2105
2106extension[container_extension] :combinedFootnotes=(true) => EMPTY
2107
2108layerController
2109   :source=(tableData)
2110   :target=ref label?
2111=> EMPTY
2112@end example
2113
2114The @code{visualization} element is the root of detail XML member.  It
2115has the following attributes:
2116
2117@defvr {Attribute} creator
2118The version of the software that created this SPV file, as a string of
2119the form @code{xxyyzz}, which represents software version xx.yy.zz,
2120e.g.@: @code{160001} is version 16.0.1.  The corpus includes major
2121versions 16 through 19.
2122@end defvr
2123
2124@defvr {Attribute} date
2125The date on the which the file was created, as a string of the form
2126@code{YYYY-MM-DD}.
2127@end defvr
2128
2129@defvr {Attribute} lang
2130The locale used for output, in Windows format, which is similar to the
2131format used in Unix with the underscore replaced by a hyphen, e.g.@:
2132@code{en-US}, @code{en-GB}, @code{el-GR}, @code{sr-Cryl-RS}.
2133@end defvr
2134
2135@defvr {Attribute} name
2136The title of the pivot table, localized to the output language.
2137@end defvr
2138
2139@defvr {Attribute} style
2140The base style for the pivot table.  In every example in the corpus,
2141the @code{style} element has no attributes other than @code{id}.
2142@end defvr
2143
2144@defvr {Attribute} type
2145A floating-point number.  The meaning is unknown.
2146@end defvr
2147
2148@defvr {Attribute} version
2149The visualization schema version number.  In the corpus, the value is
2150one of 2.4, 2.5, 2.7, and 2.8.
2151@end defvr
2152
2153The @code{userSource} element has no visible effect.
2154
2155The @code{extension} element as a child of @code{visualization} has
2156the following attributes.
2157
2158@defvr {Attribute} numRows
2159An integer that presumably defines the number of rows in the displayed
2160pivot table.
2161@end defvr
2162
2163@defvr {Attribute} showGridline
2164Always set to @code{false} in the corpus.
2165@end defvr
2166
2167@defvr {Attribute} minWidthSet
2168@defvrx {Attribute} maxWidthSet
2169Always set to @code{true} in the corpus.
2170@end defvr
2171
2172The @code{extension} element as a child of @code{container} has the
2173following attribute
2174
2175@defvr {Attribute} combinedFootnotes
2176Meaning unknown.
2177@end defvr
2178
2179The @code{categoricalDomain} and @code{simpleSort} elements have no
2180visible effect.
2181
2182The @code{layerController} element has no visible effect.
2183
2184@node SPV Detail Variable Elements
2185@subsection Variable Elements
2186
2187A ``variable'' in detail XML is a 1-dimensional array of data.  Each
2188element of the array may, independently, have string or numeric
2189content.  All of the variables in a given detail XML member either
2190have the same number of elements or have zero elements.
2191
2192Two different elements define variables and their content:
2193
2194@table @code
2195@item sourceVariable
2196These variables' data comes from the associated @code{tableData.bin}
2197member.
2198
2199@item derivedVariable
2200These variables are defined in terms of a mapping function from a
2201source variable, or they are empty.
2202@end table
2203
2204A variable named @code{cell} always exists.  This variable holds the
2205data displayed in the table.
2206
2207Variables in detail XML roughly correspond to the dimensions in a
2208light detail member.  Each dimension has the following variables with
2209stylized names, where @var{n} is a number for the dimension starting
2210from 0:
2211
2212@table @code
2213@item dimension@var{n}categories
2214The dimension's leaf categories (@pxref{SPV Light Member Categories}).
2215
2216@item dimension@var{n}group0
2217Present only if the dimension's categories are grouped, this variable
2218holds the group labels for the categories.  Grouping is inferred
2219through adjacent identical labels.  Categories that are not part of a
2220group have empty-string data in this variable.
2221
2222@item dimension@var{n}group1
2223Present only if the first-level groups are further grouped, this
2224variable holds the labels for the second-level groups.  There can be
2225additional variables with further levels of grouping.
2226
2227@item dimension@var{n}
2228An empty variable.
2229@end table
2230
2231Determining the data for a (non-empty) variable is a multi-step
2232process:
2233
2234@enumerate
2235@item
2236Draw initial data from its source, for a @code{sourceVariable}, or
2237from another named variable, for a @code{derivedVariable}.
2238
2239@item
2240Apply mappings from @code{valueMapEntry} elements within the
2241@code{derivedVariable} element, if any.
2242
2243@item
2244Apply mappings from @code{relabel} elements within a @code{format} or
2245@code{stringFormat} element in the @code{sourceVariable} or
2246@code{derivedVariable} element, if any.
2247
2248@item
2249If the variable is a @code{sourceVariable} with a @code{labelVariable}
2250attribute, and there were no mappings to apply in previous steps, then
2251replace each element of the variable by the corresponding value in the
2252label variable.
2253@end enumerate
2254
2255A single variable's data can be modified in two of the steps, if both
2256@code{valueMapEntry} and @code{relabel} are used.  The following
2257example from the corpus maps several integers to 2, then maps 2 in
2258turn to the string ``Input'':
2259
2260@example
2261<derivedVariable categorical="true" dependsOn="dimension0categories"
2262                 id="dimension0group0map" value="map(dimension0group0)">
2263  <stringFormat>
2264    <relabel from="2" to="Input"/>
2265    <relabel from="10" to="Missing Value Handling"/>
2266    <relabel from="14" to="Resources"/>
2267    <relabel from="0" to=""/>
2268    <relabel from="1" to=""/>
2269    <relabel from="13" to=""/>
2270  </stringFormat>
2271  <valueMapEntry from="2;3;5;6;7;8;9" to="2"/>
2272  <valueMapEntry from="10;11" to="10"/>
2273  <valueMapEntry from="14;15" to="14"/>
2274  <valueMapEntry from="0" to="0"/>
2275  <valueMapEntry from="1" to="1"/>
2276  <valueMapEntry from="13" to="13"/>
2277</derivedVariable>
2278@end example
2279
2280@menu
2281* SPV Detail sourceVariable Element::
2282* SPV Detail derivedVariable Element::
2283* SPV Detail valueMapEntry Element::
2284@end menu
2285
2286@node SPV Detail sourceVariable Element
2287@subsubsection The @code{sourceVariable} Element
2288
2289@example
2290sourceVariable
2291   :id
2292   :categorical=(true)
2293   :source
2294   :domain=ref categoricalDomain?
2295   :sourceName
2296   :dependsOn=ref sourceVariable?
2297   :label?
2298   :labelVariable=ref sourceVariable?
2299=> variable_extension* (format | stringFormat)?
2300@end example
2301
2302This element defines a variable whose data comes from the
2303@file{tableData.bin} member that corresponds to this @file{.xml}.
2304
2305This element has the following attributes.
2306
2307@defvr {Attribute} id
2308An @code{id} is always present because this element exists to be
2309referenced from other elements.
2310@end defvr
2311
2312@defvr {Attribute} categorical
2313Always set to @code{true}.
2314@end defvr
2315
2316@defvr {Attribute} source
2317Always set to @code{tableData}, the @code{source-name} in the
2318corresponding @file{tableData.bin} member (@pxref{SPV Legacy Member
2319Metadata}).
2320@end defvr
2321
2322@defvr {Attribute} sourceName
2323The name of a variable within the source, corresponding to the
2324@code{variable-name} in the @file{tableData.bin} member (@pxref{SPV
2325Legacy Member Numeric Data}).
2326@end defvr
2327
2328@defvr {Attribute} label
2329The variable label, if any.
2330@end defvr
2331
2332@defvr {Attribute} labelVariable
2333The @code{variable-name} of a variable whose string values correspond
2334one-to-one with the values of this variable and are suitable for use
2335as value labels.
2336@end defvr
2337
2338@defvr {Attribute} dependsOn
2339This attribute doesn't affect the display of a table.
2340@end defvr
2341
2342@node SPV Detail derivedVariable Element
2343@subsubsection The @code{derivedVariable} Element
2344
2345@example
2346derivedVariable
2347   :id
2348   :categorical=(true)
2349   :value
2350   :dependsOn=ref sourceVariable?
2351=> variable_extension* (format | stringFormat)? valueMapEntry*
2352@end example
2353
2354Like @code{sourceVariable}, this element defines a variable whose
2355values can be used elsewhere in the visualization.  Instead of being
2356read from a data source, the variable's data are defined by a
2357mathematical expression.
2358
2359This element has the following attributes.
2360
2361@defvr {Attribute} id
2362An @code{id} is always present because this element exists to be
2363referenced from other elements.
2364@end defvr
2365
2366@defvr {Attribute} categorical
2367Always set to @code{true}.
2368@end defvr
2369
2370@defvr {Attribute} value
2371An expression that defines the variable's value.  In theory this could
2372be an arbitrary expression in terms of constants, functions, and other
2373variables, e.g.@: @math{(@var{var1} + @var{var2}) / 2}.  In practice,
2374the corpus contains only the following forms of expressions:
2375
2376@table @code
2377@item constant(0)
2378@itemx constant(@var{variable})
2379All zeros.  The reason why a variable is sometimes named is unknown.
2380Sometimes the ``variable name'' has spaces in it.
2381
2382@item map(@var{variable})
2383Transforms the values in the named @var{variable} using the
2384@code{valueMapEntry}s contained within the element.
2385@end table
2386@end defvr
2387
2388@defvr {Attribute} dependsOn
2389This attribute doesn't affect the display of a table.
2390@end defvr
2391
2392@node SPV Detail valueMapEntry Element
2393@subsubsection The @code{valueMapEntry} Element
2394
2395@example
2396valueMapEntry :from :to => EMPTY
2397@end example
2398
2399A @code{valueMapEntry} element defines a mapping from one or more
2400values of a source expression to a target value.  (In the corpus, the
2401source expression is always just the name of a variable.)  Each target
2402value requires a separate @code{valueMapEntry}.  If multiple source
2403values map to the same target value, they can be combined or separate.
2404
2405In the corpus, all of the source and target values are integers.
2406
2407@code{valueMapEntry} has the following attributes.
2408
2409@defvr {Attribute} from
2410A source value, or multiple source values separated by semicolons,
2411e.g.@: @code{0} or @code{13;14;15;16}.
2412@end defvr
2413
2414@defvr {Attribute} to
2415The target value, e.g.@: @code{0}.
2416@end defvr
2417
2418@node SPV Detail extension Element
2419@subsection The @code{extension} Element
2420
2421This is a general-purpose ``extension'' element.  Readers that don't
2422understand a given extension should be able to safely ignore it.  The
2423attributes on this element, and their meanings, vary based on the
2424context.  Each known usage is described separately below.  The current
2425extensions use attributes exclusively, without any nested elements.
2426
2427@subsubheading @code{container} Parent Element
2428
2429@example
2430extension[container_extension] :combinedFootnotes=(true) => EMPTY
2431@end example
2432
2433With @code{container} as its parent element, @code{extension} has the
2434following attributes.
2435
2436@defvr {Attribute} combinedFootnotes
2437Always set to @code{true} in the corpus.
2438@end defvr
2439
2440@subsubheading @code{sourceVariable} and @code{derivedVariable} Parent Element
2441
2442@example
2443extension[variable_extension] :from :helpId => EMPTY
2444@end example
2445
2446With @code{sourceVariable} or @code{derivedVariable} as its parent
2447element, @code{extension} has the following attributes.  A given
2448parent element often contains several @code{extension} elements that
2449specify the meaning of the source data's variables or sources, e.g.@:
2450
2451@example
2452<extension from="0" helpId="corrected_model"/>
2453<extension from="3" helpId="error"/>
2454<extension from="4" helpId="total_9"/>
2455<extension from="5" helpId="corrected_total"/>
2456@end example
2457
2458More commonly they are less helpful, e.g.@:
2459
2460@example
2461<extension from="0" helpId="notes"/>
2462<extension from="1" helpId="notes"/>
2463<extension from="2" helpId="notes"/>
2464<extension from="5" helpId="notes"/>
2465<extension from="6" helpId="notes"/>
2466<extension from="7" helpId="notes"/>
2467<extension from="8" helpId="notes"/>
2468<extension from="12" helpId="notes"/>
2469<extension from="13" helpId="no_help"/>
2470<extension from="14" helpId="notes"/>
2471@end example
2472
2473@defvr {Attribute} from
2474An integer or a name like ``dimension0''.
2475@end defvr
2476
2477@defvr {Attribute} helpId
2478An identifier.
2479@end defvr
2480
2481@node SPV Detail graph Element
2482@subsection The @code{graph} Element
2483
2484@example
2485graph
2486   :cellStyle=ref style
2487   :style=ref style
2488=> location+ coordinates faceting facetLayout interval
2489
2490coordinates => EMPTY
2491@end example
2492
2493@code{graph} has the following attributes.
2494
2495@defvr {Attribute} cellStyle
2496@defvrx {Attribute} style
2497Each of these is the @code{id} of a @code{style} element (@pxref{SPV
2498Detail style Element}).  The former is the default style for
2499individual cells, the latter for the entire table.
2500@end defvr
2501
2502@node SPV Detail location Element
2503@subsection The @code{location} Element
2504
2505@example
2506location
2507   :part=(height | width | top | bottom | left | right)
2508   :method=(sizeToContent | attach | fixed | same)
2509   :min=dimension?
2510   :max=dimension?
2511   :target=ref (labelFrame | graph | container)?
2512   :value?
2513=> EMPTY
2514@end example
2515
2516Each instance of this element specifies where some part of the table
2517frame is located.  All the examples in the corpus have four instances
2518of this element, one for each of the parts @code{height},
2519@code{width}, @code{left}, and @code{top}.  Some examples in the
2520corpus add a fifth for part @code{bottom}, even though it is not clear
2521how all of @code{top}, @code{bottom}, and @code{height} can be honored
2522at the same time.  In any case, @code{location} seems to have little
2523importance in representing tables; a reader can safely ignore it.
2524
2525@defvr {Attribute} part
2526The part of the table being located.
2527@end defvr
2528
2529@defvr {Attribute} method
2530How the location is determined:
2531
2532@table @code
2533@item sizeToContent
2534Based on the natural size of the table.  Observed only for
2535parts @code{height} and @code{width}.
2536
2537@item attach
2538Based on the location specified in @code{target}.  Observed only for
2539parts @code{top} and @code{bottom}.
2540
2541@item fixed
2542Using the value in @code{value}.  Observed only for parts @code{top},
2543@code{bottom}, and @code{left}.
2544
2545@item same
2546Same as the specified @code{target}.  Observed only for part
2547@code{left}.
2548@end table
2549@end defvr
2550
2551@defvr {Attribute} min
2552Minimum size.  Only observed with value @code{100pt}.  Only observed
2553for part @code{width}.
2554@end defvr
2555
2556@defvr {Dependent} target
2557Required when @code{method} is @code{attach} or @code{same}, not
2558observed otherwise.  This identifies an element to attach to.
2559Observed with the ID of @code{title}, @code{footnote}, @code{graph},
2560and other elements.
2561@end defvr
2562
2563@defvr {Dependent} value
2564Required when @code{method} is @code{fixed}, not observed otherwise.
2565Observed values are @code{0%}, @code{0px}, @code{1px}, and @code{3px}
2566on parts @code{top} and @code{left}, and @code{100%} on part
2567@code{bottom}.
2568@end defvr
2569
2570@node SPV Detail faceting Element
2571@subsection The @code{faceting} Element
2572
2573@example
2574faceting => layer[layers1]* cross layer[layers2]*
2575
2576cross => (unity | nest) (unity | nest)
2577
2578unity => EMPTY
2579
2580nest => variableReference[vars]+
2581
2582variableReference :ref=ref (sourceVariable | derivedVariable) => EMPTY
2583
2584layer
2585   :variable=ref (sourceVariable | derivedVariable)
2586   :value
2587   :visible=bool?
2588   :method[layer_method]=(nest)?
2589   :titleVisible=bool?
2590=> EMPTY
2591@end example
2592
2593The @code{faceting} element describes the row, column, and layer
2594structure of the table.  Its @code{cross} child determines the row and
2595column structure, and each @code{layer} child (if any) represents a
2596layer.  Layers may appear before or after @code{cross}.
2597
2598The @code{cross} element describes the row and column structure of the
2599table.  It has exactly two children, the first of which describes the
2600table's columns and the second the table's rows.  Each child is a
2601@code{nest} element if the table has any dimensions along the axis in
2602question, otherwise a @code{unity} element.
2603
2604A @code{nest} element contains of one or more dimensions listed from
2605innermost to outermost, each represented by @code{variableReference}
2606child elements.  Each variable in a dimension is listed in order.
2607@xref{SPV Detail Variable Elements}, for information on the variables
2608that comprise a dimension.
2609
2610A @code{nest} can contain a single dimension, e.g.:
2611
2612@example
2613<nest>
2614  <variableReference ref="dimension0categories"/>
2615  <variableReference ref="dimension0group0"/>
2616  <variableReference ref="dimension0"/>
2617</nest>
2618@end example
2619
2620@noindent
2621A @code{nest} can contain multiple dimensions, e.g.:
2622
2623@example
2624<nest>
2625  <variableReference ref="dimension1categories"/>
2626  <variableReference ref="dimension1group0"/>
2627  <variableReference ref="dimension1"/>
2628  <variableReference ref="dimension0categories"/>
2629  <variableReference ref="dimension0"/>
2630</nest>
2631@end example
2632
2633A @code{nest} may have no dimensions, in which case it still has one
2634@code{variableReference} child, which references a
2635@code{derivedVariable} whose @code{value} attribute is
2636@code{constant(0)}.  In the corpus, such a @code{derivedVariable} has
2637@code{row} or @code{column}, respectively, as its @code{id}.  This is
2638equivalent to using a @code{unity} element in place of @code{nest}.
2639
2640A @code{variableReference} element refers to a variable through its
2641@code{ref} attribute.
2642
2643Each @code{layer} element represents a dimension, e.g.:
2644
2645@example
2646<layer value="0" variable="dimension0categories" visible="true"/>
2647<layer value="dimension0" variable="dimension0" visible="false"/>
2648@end example
2649
2650@noindent
2651@code{layer} has the following attributes.
2652
2653@defvr {Attribute} variable
2654Refers to a @code{sourceVariable} or @code{derivedVariable} element.
2655@end defvr
2656
2657@defvr {Attribute} value
2658The value to select.  For a category variable, this is always
2659@code{0}; for a data variable, it is the same as the @code{variable}
2660attribute.
2661@end defvr
2662
2663@defvr {Attribute} visible
2664Whether the layer is visible.  Generally, category layers are visible
2665and data layers are not, but sometimes this attribute is omitted.
2666@end defvr
2667
2668@defvr {Attribute} method
2669When present, this is always @code{nest}.
2670@end defvr
2671
2672@node SPV Detail facetLayout Element
2673@subsection The @code{facetLayout} Element
2674
2675@example
2676facetLayout => tableLayout setCellProperties[scp1]*
2677               facetLevel+ setCellProperties[scp2]*
2678
2679tableLayout
2680   :verticalTitlesInCorner=bool
2681   :style=ref style?
2682   :fitCells=(ticks both)?
2683=> EMPTY
2684@end example
2685
2686The @code{facetLayout} element and its descendants control styling for
2687the table.
2688
2689Its @code{tableLayout} child has the following attributes
2690
2691@defvr {Attribute} verticalTitlesInCorner
2692If true, in the absence of corner text, row headings will be displayed
2693in the corner.
2694@end defvr
2695
2696@defvr {Attribute} style
2697Refers to a @code{style} element.
2698@end defvr
2699
2700@defvr {Attribute} fitCells
2701Meaning unknown.
2702@end defvr
2703
2704@subsubheading The @code{facetLevel} Element
2705
2706@example
2707facetLevel :level=int :gap=dimension? => axis
2708
2709axis :style=ref style => label? majorTicks
2710
2711majorTicks
2712   :labelAngle=int
2713   :length=dimension
2714   :style=ref style
2715   :tickFrameStyle=ref style
2716   :labelFrequency=int?
2717   :stagger=bool?
2718=> gridline?
2719
2720gridline
2721   :style=ref style
2722   :zOrder=int
2723=> EMPTY
2724@end example
2725
2726Each @code{facetLevel} describes a @code{variableReference} or
2727@code{layer}, and a table has one @code{facetLevel} element for
2728each such element.  For example, an SPV detail member that contains
2729four @code{variableReference} elements and two @code{layer} elements
2730will contain six @code{facetLevel} elements.
2731
2732In the corpus, @code{facetLevel} elements and the elements that they
2733describe are always in the same order.  The correspondence may also be
2734observed in two other ways.  First, one may use the @code{level}
2735attribute, described below.  Second, in the corpus, a
2736@code{facetLevel} always has an @code{id} that is the same as the
2737@code{id} of the element it describes with @code{_facetLevel}
2738appended.  One should not formally rely on this, of course, but it is
2739usefully indicative.
2740
2741@defvr {Attribute} level
2742A 1-based index into the @code{variableReference} and @code{layer}
2743elements, e.g.@: a @code{facetLayout} with a @code{level} of 1
2744describes the first @code{variableReference} in the SPV detail member,
2745and in a member with four @code{variableReference} elements, a
2746@code{facetLayout} with a @code{level} of 5 describes the first
2747@code{layer} in the member.
2748@end defvr
2749
2750@defvr {Attribute} gap
2751Always observed as @code{0pt}.
2752@end defvr
2753
2754Each @code{facetLevel} contains an @code{axis}, which in turn may
2755contain a @code{label} for the @code{facetLevel} (@pxref{SPV Detail
2756label Element}) and does contain a @code{majorTicks} element.
2757
2758@defvr {Attribute} labelAngle
2759Normally 0.  The value -90 causes inner column or outer row labels to
2760be rotated vertically.
2761@end defvr
2762
2763@defvr {Attribute} style
2764@defvrx {Attribute} tickFrameStyle
2765Each refers to a @code{style} element.  @code{style} is the style of
2766the tick labels, @code{tickFrameStyle} the style for the frames around
2767the labels.
2768@end defvr
2769
2770@node SPV Detail label Element
2771@subsection The @code{label} Element
2772
2773@example
2774label
2775   :style=ref style
2776   :textFrameStyle=ref style?
2777   :purpose=(title | subTitle | subSubTitle | layer | footnote)?
2778=> text+ | descriptionGroup
2779
2780descriptionGroup
2781   :target=ref faceting
2782   :separator?
2783=> (description | text)+
2784
2785description :name=(variable | value) => EMPTY
2786
2787text
2788   :usesReference=int?
2789   :definesReference=int?
2790   :position=(subscript | superscript)?
2791   :style=ref style
2792=> TEXT
2793@end example
2794
2795This element represents a label on some aspect of the table.
2796
2797@defvr {Attribute} style
2798@defvrx {Attribute} textFrameStyle
2799Each of these refers to a @code{style} element.  @code{style} is the
2800style of the label text, @code{textFrameStyle} the style for the frame
2801around the label.
2802@end defvr
2803
2804@defvr {Attribute} purpose
2805The kind of entity being labeled.
2806@end defvr
2807
2808A @code{descriptionGroup} concatenates one or more elements to form a
2809label.  Each element can be a @code{text} element, which contains
2810literal text, or a @code{description} element that substitutes a value
2811or a variable name.
2812
2813@defvr {Attribute} target
2814The @code{id} of an element being described.  In the corpus, this is
2815always @code{faceting}.
2816@end defvr
2817
2818@defvr {Attribute} separator
2819A string to separate the description of multiple groups, if the
2820@code{target} has more than one.  In the corpus, this is always a
2821new-line.
2822@end defvr
2823
2824Typical contents for a @code{descriptionGroup} are a value by itself:
2825@example
2826<description name="value"/>
2827@end example
2828@noindent or a variable and its value, separated by a colon:
2829@example
2830<description name="variable"/><text>:</text><description name="value"/>
2831@end example
2832
2833A @code{description} is like a macro that expands to some property of
2834the target of its parent @code{descriptionGroup}.  The @code{name}
2835attribute specifies the property.
2836
2837@node SPV Detail setCellProperties Element
2838@subsection The @code{setCellProperties} Element
2839
2840@example
2841setCellProperties
2842   :applyToConverse=bool?
2843=> (setStyle | setFrameStyle | setFormat | setMetaData)* union[union_]?
2844@end example
2845
2846The @code{setCellProperties} element sets style properties of cells or
2847row or column labels.
2848
2849Interpreting @code{setCellProperties} requires answering two
2850questions: which cells or labels to style, and what styles to use.
2851
2852@subsubheading Which Cells?
2853
2854@example
2855union => intersect+
2856
2857intersect => where+ | intersectWhere | alternating | EMPTY
2858
2859where
2860   :variable=ref (sourceVariable | derivedVariable)
2861   :include
2862=> EMPTY
2863
2864intersectWhere
2865   :variable=ref (sourceVariable | derivedVariable)
2866   :variable2=ref (sourceVariable | derivedVariable)
2867=> EMPTY
2868
2869alternating => EMPTY
2870@end example
2871
2872When @code{union} is present with @code{intersect} children, each of
2873those children specifies a group of cells that should be styled, and
2874the total group is all those cells taken together.  When @code{union}
2875is absent, every cell is styled.  One attribute on
2876@code{setCellProperties} affects the choice of cells:
2877
2878@defvr {Attribute} applyToConverse
2879If true, this inverts the meaning of the cell selection: the selected
2880cells are the ones @emph{not} designated.  This is confusing, given
2881the additional restrictions of @code{union}, but in the corpus
2882@code{applyToConverse} is never present along with @code{union}.
2883@end defvr
2884
2885An @code{intersect} specifies restrictions on the cells to be matched.
2886Each @code{where} child specifies which values of a given variable to
2887include.  The attributes of @code{intersect} are:
2888
2889@defvr {Attribute} variable
2890Refers to a variable, e.g.@: @code{dimension0categories}.  Only
2891``categories'' variables make sense here, but other variables, e.g.@:
2892@code{dimension0group0map}, are sometimes seen.  The reader may ignore
2893these.
2894@end defvr
2895
2896@defvr {Attribute} include
2897A value, or multiple values separated by semicolons,
2898e.g.@: @code{0} or @code{13;14;15;16}.
2899@end defvr
2900
2901PSPP ignores @code{setCellProperties} when @code{intersectWhere} is
2902present.
2903
2904@subsubheading What Styles?
2905
2906@example
2907setStyle
2908   :target=ref (labeling | graph | interval | majorTicks)
2909   :style=ref style
2910=> EMPTY
2911
2912setMetaData :target=ref graph :key :value => EMPTY
2913
2914setFormat
2915   :target=ref (majorTicks | labeling)
2916   :reset=bool?
2917=> format | numberFormat | stringFormat+ | dateTimeFormat | elapsedTimeFormat
2918
2919setFrameStyle
2920   :style=ref style
2921   :target=ref majorTicks
2922=> EMPTY
2923@end example
2924
2925The @code{set*} children of @code{setCellProperties} determine the
2926styles to set.
2927
2928When @code{setCellProperties} contains a @code{setFormat} whose
2929@code{target} references a @code{labeling} element, or if it contains
2930a @code{setStyle} that references a @code{labeling} or @code{interval}
2931element, the @code{setCellProperties} sets the style for table cells.
2932The format from the @code{setFormat}, if present, replaces the cells'
2933format.  The style from the @code{setStyle} that references
2934@code{labeling}, if present, replaces the label's font and cell
2935styles, except that the background color is taken instead from the
2936@code{interval}'s style, if present.
2937
2938When @code{setCellProperties} contains a @code{setFormat} whose
2939@code{target} references a @code{majorTicks} element, or if it
2940contains a @code{setStyle} whose @code{target} references a
2941@code{majorTicks}, or if it contains a @code{setFrameStyle} element,
2942the @code{setCellProperties} sets the style for row or column labels.
2943In this case, the @code{setCellProperties} always contains a single
2944@code{where} element whose @code{variable} designates the variable
2945whose labels are to be styled.  The format from the @code{setFormat},
2946if present, replaces the labels' format.  The style from the
2947@code{setStyle} that references @code{majorTicks}, if present,
2948replaces the labels' font and cell styles, except that the background
2949color is taken instead from the @code{setFrameStyle}'s style, if
2950present.
2951
2952When @code{setCellProperties} contains a @code{setStyle} whose
2953@code{target} references a @code{graph} element, and one that
2954references a @code{labeling} element, and the @code{union} element
2955contains @code{alternating}, the @code{setCellProperties} sets the
2956alternate foreground and background colors for the data area.  The
2957foreground color is taken from the style referenced by the
2958@code{setStyle} that targets the @code{graph}, the background color
2959from the @code{setStyle} for @code{labeling}.
2960
2961A reader may ignore a @code{setCellProperties} that only contains
2962@code{setMetaData}, as well as @code{setMetaData} within other
2963@code{setCellProperties}.
2964
2965A reader may ignore a @code{setCellProperties} whose only @code{set*}
2966child is a @code{setStyle} that targets the @code{graph} element.
2967
2968@subsubheading The @code{setStyle} Element
2969
2970@example
2971setStyle
2972   :target=ref (labeling | graph | interval | majorTicks)
2973   :style=ref style
2974=> EMPTY
2975@end example
2976
2977This element associates a style with the target.
2978
2979@defvr {Attribute} target
2980The @code{id} of an element whose style is to be set.
2981@end defvr
2982
2983@defvr {Attribute} style
2984The @code{id} of a @code{style} element that identifies the style to
2985set on the target.
2986@end defvr
2987
2988@node SPV Detail setFormat Element
2989@subsection The @code{setFormat} Element
2990
2991@example
2992setFormat
2993   :target=ref (majorTicks | labeling)
2994   :reset=bool?
2995=> format | numberFormat | stringFormat+ | dateTimeFormat | elapsedTimeFormat
2996@end example
2997
2998This element sets the format of the target, ``format'' in this case
2999meaning the SPSS print format for a variable.
3000
3001The details of this element vary depending on the schema version, as
3002declared in the root @code{visualization} element's @code{version}
3003attribute (@pxref{SPV Detail visualization Element}).  A reader can
3004interpret the content without knowing the schema version.
3005
3006The @code{setFormat} element itself has the following attributes.
3007
3008@defvr {Attribute} target
3009Refers to an element whose style is to be set.
3010@end defvr
3011
3012@defvr {Attribute} reset
3013If this is @code{true}, this format replaces the target's previous
3014format.  If it is @code{false}, the modifies the previous format.
3015@end defvr
3016
3017@menu
3018* SPV Detail numberFormat Element::
3019* SPV Detail stringFormat Element::
3020* SPV Detail dateTimeFormat Element::
3021* SPV Detail elapsedTimeFormat Element::
3022* SPV Detail format Element::
3023* SPV Detail affix Element::
3024@end menu
3025
3026@node SPV Detail numberFormat Element
3027@subsubsection The @code{numberFormat} Element
3028
3029@example
3030numberFormat
3031   :minimumIntegerDigits=int?
3032   :maximumFractionDigits=int?
3033   :minimumFractionDigits=int?
3034   :useGrouping=bool?
3035   :scientific=(onlyForSmall | whenNeeded | true | false)?
3036   :small=real?
3037   :prefix?
3038   :suffix?
3039=> affix*
3040@end example
3041
3042Specifies a format for displaying a number.  The available options are
3043a superset of those available from PSPP print formats.  PSPP chooses a
3044print format type for a @code{numberFormat} as follows:
3045
3046@enumerate
3047@item
3048If @code{scientific} is @code{true}, uses @code{E} format.
3049
3050@item
3051If @code{prefix} is @code{$}, uses @code{DOLLAR} format.
3052
3053@item
3054If @code{suffix} is @code{%}, uses @code{PCT} format.
3055
3056@item
3057If @code{useGrouping} is @code{true}, uses @code{COMMA} format.
3058
3059@item
3060Otherwise, uses @code{F} format.
3061@end enumerate
3062
3063For translating to a print format, PSPP uses
3064@code{maximumFractionDigits} as the number of decimals, unless that
3065attribute is missing or out of the range [0,15], in which case it uses
30662 decimals.
3067
3068@defvr {Attribute} minimumIntegerDigits
3069Minimum number of digits to display before the decimal point.  Always
3070observed as @code{0}.
3071@end defvr
3072
3073@defvr {Attribute} maximumFractionDigits
3074@defvrx {Attribute} minimumFractionDigits
3075Maximum or minimum, respectively, number of digits to display after
3076the decimal point.  The observed values of each attribute range from 0
3077to 9.
3078@end defvr
3079
3080@defvr {Attribute} useGrouping
3081Whether to use the grouping character to group digits in large
3082numbers.
3083@end defvr
3084
3085@defvr {Attribute} scientific
3086This attribute controls when and whether the number is formatted in
3087scientific notation.  It takes the following values:
3088
3089@table @code
3090@item onlyForSmall
3091Use scientific notation only when the number's magnitude is smaller
3092than the value of the @code{small} attribute.
3093
3094@item whenNeeded
3095Use scientific notation when the number will not otherwise fit in the
3096available space.
3097
3098@item true
3099Always use scientific notation.  Not observed in the corpus.
3100
3101@item false
3102Never use scientific notation.  A number that won't otherwise fit will
3103be replaced by an error indication (see the @code{errorCharacter}
3104attribute).  Not observed in the corpus.
3105@end table
3106@end defvr
3107
3108@defvr {Attribute} small
3109Only present when the @code{scientific} attribute is
3110@code{onlyForSmall}, this is a numeric magnitude below which the
3111number will be formatted in scientific notation.  The values @code{0}
3112and @code{0.0001} have been observed.  The value @code{0} seems like a
3113pathological choice, since no real number has a magnitude less than 0;
3114perhaps in practice such a choice is equivalent to setting
3115@code{scientific} to @code{false}.
3116@end defvr
3117
3118@defvr {Attribute} prefix
3119@defvrx {Attribute} suffix
3120Specifies a prefix or a suffix to apply to the formatted number.  Only
3121@code{suffix} has been observed, with value @samp{%}.
3122@end defvr
3123
3124@node SPV Detail stringFormat Element
3125@subsubsection The @code{stringFormat} Element
3126
3127@example
3128stringFormat => relabel* affix*
3129
3130relabel :from=real :to => EMPTY
3131@end example
3132
3133The @code{stringFormat} element specifies how to display a string.  By
3134default, a string is displayed verbatim, but @code{relabel} can change
3135it.
3136
3137The @code{relabel} element appears as a child of @code{stringFormat}
3138(and of @code{format}, when it is used to format strings).  It
3139specifies how to display a given value.  It is used to implement value
3140labels and to display the system-missing value in a human-readable
3141way.  It has the following attributes:
3142
3143@defvr {Attribute} from
3144The value to map.  In the corpus this is an integer or the
3145system-missing value @code{-1.797693134862316E300}.
3146@end defvr
3147
3148@defvr {Attribute} to
3149The string to display in place of the value of @code{from}.  In the
3150corpus this is a wide variety of value labels; the system-missing
3151value is mapped to @samp{.}.
3152@end defvr
3153
3154@node SPV Detail dateTimeFormat Element
3155@subsubsection The @code{dateTimeFormat} Element
3156
3157@example
3158dateTimeFormat
3159   :baseFormat[dt_base_format]=(date | time | dateTime)
3160   :separatorChars?
3161   :mdyOrder=(dayMonthYear | monthDayYear | yearMonthDay)?
3162   :showYear=bool?
3163   :yearAbbreviation=bool?
3164   :showQuarter=bool?
3165   :quarterPrefix?
3166   :quarterSuffix?
3167   :showMonth=bool?
3168   :monthFormat=(long | short | number | paddedNumber)?
3169   :showWeek=bool?
3170   :weekPadding=bool?
3171   :weekSuffix?
3172   :showDayOfWeek=bool?
3173   :dayOfWeekAbbreviation=bool?
3174   :dayPadding=bool?
3175   :dayOfMonthPadding=bool?
3176   :hourPadding=bool?
3177   :minutePadding=bool?
3178   :secondPadding=bool?
3179   :showDay=bool?
3180   :showHour=bool?
3181   :showMinute=bool?
3182   :showSecond=bool?
3183   :showMillis=bool?
3184   :dayType=(month | year)?
3185   :hourFormat=(AMPM | AS_24 | AS_12)?
3186=> affix*
3187@end example
3188
3189This element appears only in schema version 2.5 and earlier
3190(@pxref{SPV Detail visualization Element}).
3191
3192Data to be formatted in date formats is stored as strings in legacy
3193data, in the format @code{yyyy-mm-ddTHH:MM:SS.SSS} and must be parsed
3194and reformatted by the reader.
3195
3196The following attribute is required.
3197
3198@defvr {Attribute} baseFormat
3199Specifies whether a date and time are both to be displayed, or just
3200one of them.
3201@end defvr
3202
3203Many of the attributes' meanings are obvious.  The following seem to
3204be worth documenting.
3205
3206@defvr {Attribute} separatorChars
3207Exactly four characters.  In order, these are used for: decimal point,
3208grouping, date separator, time separator.  Always @samp{.,-:}.
3209@end defvr
3210
3211@defvr {Attribute} mdyOrder
3212Within a date, the order of the days, months, and years.
3213@code{dayMonthYear} is the only observed value, but one would expect
3214that @code{monthDayYear} and @code{yearMonthDay} to be reasonable as
3215well.
3216@end defvr
3217
3218@defvr {Attribute} showYear
3219@defvrx {Attribute} yearAbbreviation
3220Whether to include the year and, if so, whether the year should be
3221shown abbreviated, that is, with only 2 digits.  Each is @code{true}
3222or @code{false}; only values of @code{true} and @code{false},
3223respectively, have been observed.
3224@end defvr
3225
3226@defvr {Attribute} showMonth
3227@defvrx {Attribute} monthFormat
3228Whether to include the month (@code{true} or @code{false}) and, if so,
3229how to format it.  @code{monthFormat} is one of the following:
3230
3231@table @code
3232@item long
3233The full name of the month, e.g.@: in an English locale,
3234@code{September}.
3235
3236@item short
3237The abbreviated name of the month, e.g.@: in an English locale,
3238@code{Sep}.
3239
3240@item number
3241The number representing the month, e.g.@: 9 for September.
3242
3243@item paddedNumber
3244A two-digit number representing the month, e.g.@: 09 for September.
3245@end table
3246
3247Only values of @code{true} and @code{short}, respectively, have been
3248observed.
3249@end defvr
3250
3251@defvr {Attribute} dayType
3252This attribute is always @code{month} in the corpus, specifying that
3253the day of the month is to be displayed; a value of @code{year} is
3254supposed to indicate that the day of the year, where 1 is January 1,
3255is to be displayed instead.
3256@end defvr
3257
3258@defvr {Attribute} hourFormat
3259@code{hourFormat}, if present, is one of:
3260
3261@table @code
3262@item AMPM
3263The time is displayed with an @code{am} or @code{pm} suffix, e.g.@:
3264@code{10:15pm}.
3265
3266@item AS_24
3267The time is displayed in a 24-hour format, e.g.@: @code{22:15}.
3268
3269This is the only value observed in the corpus.
3270
3271@item AS_12
3272The time is displayed in a 12-hour format, without distinguishing
3273morning or evening, e.g.@: @code{10;15}.
3274@end table
3275
3276@code{hourFormat} is sometimes present for @code{elapsedTime} formats,
3277which is confusing since a time duration does not have a concept of AM
3278or PM.  This might indicate a bug in the code that generated the XML
3279in the corpus, or it might indicate that @code{elapsedTime} is
3280sometimes used to format a time of day.
3281@end defvr
3282
3283For a @code{baseFormat} of @code{date}, PSPP chooses a print format
3284type based on the following rules:
3285
3286@enumerate
3287@item
3288If @code{showQuarter} is true: @code{QYR}.
3289
3290@item
3291Otherwise, if @code{showWeek} is true: @code{WKYR}.
3292
3293@item
3294Otherwise, if @code{mdyOrder} is @code{dayMonthYear}:
3295
3296@enumerate a
3297@item
3298If @code{monthFormat} is @code{number} or @code{paddedNumber}: @code{EDATE}.
3299
3300@item
3301Otherwise: @code{DATE}.
3302@end enumerate
3303
3304@item
3305Otherwise, if @code{mdyOrder} is @code{yearMonthDay}: @code{SDATE}.
3306
3307@item
3308Otherwise, @code{ADATE}.
3309@end enumerate
3310
3311For a @code{baseFormat} of @code{dateTime}, PSPP uses @code{YMDHMS} if
3312@code{mdyOrder} is @code{yearMonthDay} and @code{DATETIME} otherwise.
3313For a @code{baseFormat} of @code{time}, PSPP uses @code{DTIME} if
3314@code{showDay} is true, otherwise @code{TIME} if @code{showHour} is
3315true, otherwise @code{MTIME}.
3316
3317For a @code{baseFormat} of @code{date}, the chosen width is the
3318minimum for the format type, adding 2 if @code{yearAbbreviation} is
3319false or omitted.  For other base formats, the chosen width is the
3320minimum for its type, plus 3 if @code{showSecond} is true, plus 4 more
3321if @code{showMillis} is also true.  Decimals are 0 by default, or 3
3322if @code{showMillis} is true.
3323
3324@node SPV Detail elapsedTimeFormat Element
3325@subsubsection The @code{elapsedTimeFormat} Element
3326
3327@example
3328elapsedTimeFormat
3329   :baseFormat[dt_base_format]=(date | time | dateTime)
3330   :dayPadding=bool?
3331   :hourPadding=bool?
3332   :minutePadding=bool?
3333   :secondPadding=bool?
3334   :showYear=bool?
3335   :showDay=bool?
3336   :showHour=bool?
3337   :showMinute=bool?
3338   :showSecond=bool?
3339   :showMillis=bool?
3340=> affix*
3341@end example
3342
3343This element specifies the way to display a time duration.
3344
3345Data to be formatted in elapsed time formats is stored as strings in
3346legacy data, in the format @code{H:MM:SS.SSS}, with additional hour
3347digits as needed for long durations, and must be parsed and
3348reformatted by the reader.
3349
3350The following attribute is required.
3351
3352@defvr {Attribute} baseFormat
3353Specifies whether a day and a time are both to be displayed, or just
3354one of them.
3355@end defvr
3356
3357The remaining attributes specify exactly how to display the elapsed
3358time.
3359
3360For @code{baseFormat} of @code{time}, PSPP converts this element to
3361print format type @code{DTIME}; otherwise, if @code{showHour} is true,
3362to @code{TIME}; otherwise, to @code{MTIME}.  The chosen width is the
3363minimum for the chosen type, adding 3 if @code{showSecond} is true,
3364adding 4 more if @code{showMillis} is also true.  Decimals are 0 by
3365default, or 3 if @code{showMillis} is true.
3366
3367@node SPV Detail format Element
3368@subsubsection The @code{format} Element
3369
3370@example
3371format
3372   :baseFormat[f_base_format]=(date | time | dateTime | elapsedTime)?
3373   :errorCharacter?
3374   :separatorChars?
3375   :mdyOrder=(dayMonthYear | monthDayYear | yearMonthDay)?
3376   :showYear=bool?
3377   :showQuarter=bool?
3378   :quarterPrefix?
3379   :quarterSuffix?
3380   :yearAbbreviation=bool?
3381   :showMonth=bool?
3382   :monthFormat=(long | short | number | paddedNumber)?
3383   :dayPadding=bool?
3384   :dayOfMonthPadding=bool?
3385   :showWeek=bool?
3386   :weekPadding=bool?
3387   :weekSuffix?
3388   :showDayOfWeek=bool?
3389   :dayOfWeekAbbreviation=bool?
3390   :hourPadding=bool?
3391   :minutePadding=bool?
3392   :secondPadding=bool?
3393   :showDay=bool?
3394   :showHour=bool?
3395   :showMinute=bool?
3396   :showSecond=bool?
3397   :showMillis=bool?
3398   :dayType=(month | year)?
3399   :hourFormat=(AMPM | AS_24 | AS_12)?
3400   :minimumIntegerDigits=int?
3401   :maximumFractionDigits=int?
3402   :minimumFractionDigits=int?
3403   :useGrouping=bool?
3404   :scientific=(onlyForSmall | whenNeeded | true | false)?
3405   :small=real?
3406   :prefix?
3407   :suffix?
3408   :tryStringsAsNumbers=bool?
3409   :negativesOutside=bool?
3410=> relabel* affix*
3411@end example
3412
3413This element is the union of all of the more-specific format elements.
3414It is interpreted in the same way as one of those format elements,
3415using @code{baseFormat} to determine which kind of format to use.
3416
3417There are a few attributes not present in the more specific formats:
3418
3419@defvr {Attribute} tryStringsAsNumbers
3420When this is @code{true}, it is supposed to indicate that string
3421values should be parsed as numbers and then displayed according to
3422numeric formatting rules.  However, in the corpus it is always
3423@code{false}.
3424@end defvr
3425
3426@defvr {Attribute} negativesOutside
3427If true, the negative sign should be shown before the prefix; if
3428false, it should be shown after.
3429@end defvr
3430
3431@node SPV Detail affix Element
3432@subsubsection The @code{affix} Element
3433
3434@example
3435affix
3436   :definesReference=int
3437   :position=(subscript | superscript)
3438   :suffix=bool
3439   :value
3440=> EMPTY
3441@end example
3442
3443This defines a suffix (or, theoretically, a prefix) for a formatted
3444value.  It is used to insert a reference to a footnote.  It has the
3445following attributes:
3446
3447@defvr {Attribute} definesReference
3448This specifies the footnote number as a natural number: 1 for the
3449first footnote, 2 for the second, and so on.
3450@end defvr
3451
3452@defvr {Attribute} position
3453Position for the footnote label.  Always @code{superscript}.
3454@end defvr
3455
3456@defvr {Attribute} suffix
3457Whether the affix is a suffix (@code{true}) or a prefix
3458(@code{false}).  Always @code{true}.
3459@end defvr
3460
3461@defvr {Attribute} value
3462The text of the suffix or prefix.  Typically a letter, e.g.@: @code{a}
3463for footnote 1, @code{b} for footnote 2, @enddots{}  The corpus
3464contains other values: @code{*}, @code{**}, and a few that begin with
3465at least one comma: @code{,b}, @code{,c}, @code{,,b}, and @code{,,c}.
3466@end defvr
3467
3468@node SPV Detail interval Element
3469@subsection The @code{interval} Element
3470
3471@example
3472interval :style=ref style => labeling footnotes?
3473
3474labeling
3475   :style=ref style?
3476   :variable=ref (sourceVariable | derivedVariable)
3477=> (formatting | format | footnotes)*
3478
3479formatting :variable=ref (sourceVariable | derivedVariable) => formatMapping*
3480
3481formatMapping :from=int => format?
3482
3483footnotes
3484   :superscript=bool?
3485   :variable=ref (sourceVariable | derivedVariable)
3486=> footnoteMapping*
3487
3488footnoteMapping :definesReference=int :from=int :to => EMPTY
3489@end example
3490
3491The @code{interval} element and its descendants determine the basic
3492formatting and labeling for the table's cells.  These basic styles are
3493overridden by more specific styles set using @code{setCellProperties}
3494(@pxref{SPV Detail setCellProperties Element}).
3495
3496The @code{style} attribute of @code{interval} itself may be ignored.
3497
3498The @code{labeling} element may have a single @code{formatting} child.
3499If present, its @code{variable} attribute refers to a variable whose
3500values are format specifiers as numbers, e.g. value 0x050802 for F8.2.
3501However, the numbers are not actually interpreted that way.  Instead,
3502each number actually present in the variable's data is mapped by a
3503@code{formatMapping} child of @code{formatting} to a @code{format}
3504that specifies how to display it.
3505
3506The @code{labeling} element may also have a @code{footnotes} child
3507element.  The @code{variable} attribute of this element refers to a
3508variable whose values are comma-delimited strings that list the
35091-based indexes of footnote references.  (Cells without any footnote
3510references are numeric 0 instead of strings.)
3511
3512Each @code{footnoteMapping} child of the @code{footnotes} element
3513defines the footnote marker to be its @code{to} attribute text for the
3514footnote whose 1-based index is given in its @code{definesReference}
3515attribute.
3516
3517@node SPV Detail style Element
3518@subsection The @code{style} Element
3519
3520@example
3521style
3522   :color=color?
3523   :color2=color?
3524   :labelAngle=real?
3525   :border-bottom=(solid | thick | thin | double | none)?
3526   :border-top=(solid | thick | thin | double | none)?
3527   :border-left=(solid | thick | thin | double | none)?
3528   :border-right=(solid | thick | thin | double | none)?
3529   :border-bottom-color?
3530   :border-top-color?
3531   :border-left-color?
3532   :border-right-color?
3533   :font-family?
3534   :font-size?
3535   :font-weight=(regular | bold)?
3536   :font-style=(regular | italic)?
3537   :font-underline=(none | underline)?
3538   :margin-bottom=dimension?
3539   :margin-left=dimension?
3540   :margin-right=dimension?
3541   :margin-top=dimension?
3542   :textAlignment=(left | right | center | decimal | mixed)?
3543   :labelLocationHorizontal=(positive | negative | center)?
3544   :labelLocationVertical=(positive | negative | center)?
3545   :decimal-offset=dimension?
3546   :size?
3547   :width?
3548   :visible=bool?
3549=> EMPTY
3550@end example
3551
3552A @code{style} element has an effect only when it is referenced by
3553another element to set some aspect of the table's style.  Most of the
3554attributes are self-explanatory.  The rest are described below.
3555
3556@defvr {Attribute} {color}
3557In some cases, the text color; in others, the background color.
3558@end defvr
3559
3560@defvr {Attribute} {color2}
3561Not used.
3562@end defvr
3563
3564@defvr {Attribute} {labelAngle}
3565Normally 0.  The value -90 causes inner column or outer row labels to
3566be rotated vertically.
3567@end defvr
3568
3569@defvr {Attribute} {labelLocationHorizontal}
3570Not used.
3571@end defvr
3572
3573@defvr {Attribute} {labelLocationVertical}
3574The value @code{positive} corresponds to vertically aligning text to
3575the top of a cell, @code{negative} to the bottom, @code{center} to the
3576middle.
3577@end defvr
3578
3579@node SPV Detail labelFrame Element
3580@subsection The @code{labelFrame} Element
3581
3582@example
3583labelFrame :style=ref style => location+ label? paragraph?
3584
3585paragraph :hangingIndent=dimension? => EMPTY
3586@end example
3587
3588A @code{labelFrame} element specifies content and style for some
3589aspect of a table.  Only @code{labelFrame} elements that have a
3590@code{label} child are important.  The @code{purpose} attribute in the
3591@code{label} determines what the @code{labelFrame} affects:
3592
3593@table @code
3594@item title
3595The table's title and its style.
3596
3597@item subTitle
3598The table's caption and its style.
3599
3600@item footnote
3601The table's footnotes and the style for the footer area.
3602
3603@item layer
3604The style for the layer area.
3605
3606@item subSubTitle
3607Ignored.
3608@end table
3609
3610The @code{style} attribute references the style to use for the area.
3611
3612The @code{label}, if present, specifies the text to put into the title
3613or caption or footnotes.  For footnotes, the label has two @code{text}
3614children for every footnote, each of which has a @code{usesReference}
3615attribute identifying the 1-based index of a footnote.  The first,
3616third, fifth, @dots{} @code{text} child specifies the content for a
3617footnote; the second, fourth, sixth, @dots{} child specifies the
3618marker.  Content tends to end in a new-line, which the reader may wish
3619to trim; similarly, markers tend to end in @samp{.}.
3620
3621The @code{paragraph}, if present, may be ignored, since it is always
3622empty.
3623
3624@node SPV Detail Legacy Properties
3625@subsection Legacy Properties
3626
3627The detail XML format has features for styling most of the aspects of
3628a table.  It also inherits defaults for many aspects from structure
3629XML, which has the following @code{tableProperties} element:
3630
3631@example
3632tableProperties
3633=> generalProperties footnoteProperties cellFormatProperties borderProperties printingProperties
3634
3635generalProperties
3636   :hideEmptyRows=bool?
3637   :maximumColumnWidth=dimension?
3638   :maximumRowWidth=dimension?
3639   :minimumColumnWidth=dimension?
3640   :minimumRowWidth=dimension?
3641   :rowDimensionLabels=(inCorner | nested)?
3642=> EMPTY
3643
3644footnoteProperties
3645   :markerPosition=(superscript | subscript)?
3646   :numberFormat=(alphabetic | numeric)?
3647=> EMPTY
3648
3649cellFormatProperties => cell_style+
3650
3651any[cell_style]
3652   :alternatingColor=color?
3653   :alternatingTextColor=color?
3654=> style
3655
3656style
3657   :color=color?
3658   :color2=color?
3659   :font-family?
3660   :font-size?
3661   :font-style=(regular | italic)?
3662   :font-weight=(regular | bold)?
3663   :labelLocationVertical=(positive | negative | center)?
3664   :margin-bottom=dimension?
3665   :margin-left=dimension?
3666   :margin-right=dimension?
3667   :margin-top=dimension?
3668   :textAlignment=(left | right | center | decimal | mixed)?
3669   :decimal-offset=dimension?
3670=> EMPTY
3671
3672borderProperties => border_style+
3673
3674any[border_style]
3675   :borderStyleType=(none | solid | dashed | thick | thin | double)?
3676   :color=color?
3677=> EMPTY
3678
3679printingProperties
3680   :printAllLayers=bool?
3681   :rescaleLongTableToFitPage=bool?
3682   :rescaleWideTableToFitPage=bool?
3683   :windowOrphanLines=int?
3684   :continuationText?
3685   :continuationTextAtBottom=bool?
3686   :continuationTextAtTop=bool?
3687   :printEachLayerOnSeparatePage=bool?
3688=> EMPTY
3689@end example
3690