<?xml version='1.0'?>

<!-- ====================================================================== -->
<!-- = chapter-2.xml                                                      = -->
<!-- = standard speadsheet module guide - chapter 2                       = -->
<!-- ====================================================================== -->
<!-- = This  program  is  free  software; you  can redistribute it and/or = -->
<!-- = modify it provided that this copyright notice is kept intact.      = -->
<!-- = This program is distributed in the hope that it will be useful but = -->
<!-- = without  any  warranty;  without  even  the  implied  warranty  of = -->
<!-- = merchantability or fitness for  a  particular purpose. In no event = -->
<!-- = shall  the  copyright  holder be liable for any  direct, indirect, = -->
<!-- = incidental  or special  damages arising  in any way out of the use = -->
<!-- = of this software.                                                  = -->
<!-- ====================================================================== -->
<!-- = copyright (c) 2005-2007 - amaury darsch                            = -->
<!-- ====================================================================== -->

<chapter module="sps" number="2">
  <title>Standard spreadsheet services</title>
  
  <p>
  This chapter covers the spreadsheet objects available in the standard
  spreadsheet module. All functions and objects are part of the
  <code>afnix-sps</code> module and bounded in the
  <code>afnix:sps</code> nameset.
  </p>

  <!-- folio object -->
  <section>
    <title>Folio object</title>

    <p>
    The <code>Folio</code> object is the primary object used for
    storing data. Although, a folio is a collection of sheets, it the
    primary object that should be created when manipulating such
    collection.
    </p>

    <!-- creating a folio -->
    <subsect>
      <title>Creating a folio</title>

      <p>
      The <code>Folio</code> object is built without argument. In this
      case, the folio is empty. A predicate is available for testing
      the <code>Folio</code> object.
      </p>

      <example>
      const sps (afnix:sps:Folio)
      afnix:sps:folio-p sps # true
      </example>

      <p>
      The constructor can operate also by name or by input
      stream. With a string, a new folio those name is the argument is
      created. By stream, a new folio is created and loaded with the
      input stream data. Eventually, the folio name can be set with the
      <code>set-name</code> command and retrieved with the
      <code>get-name</code> command.
      </p>

      <example>
      const sps (afnix:sps:Folio)
      sps:set-name "planets"
      </example>
    </subsect>
  </section>

  <!-- sheet object -->
  <section>
    <title>Sheet object</title>

    <p>
    The <code>Sheet</code> object is the primary object used to store
    data in a folio. Since a <code>Folio</code> object is a collection
    of sheets, a sheet can be manipulated either by getting getting it
    from the folio or by creating it independently and adding it into
    the folio.
    </p>

    <!-- creatig a sheet -->
    <subsect>
      <title>Creating a sheet</title>

      <p>
      An empty sheet can be created simply with or without
      name. Without argument, an unnamed sheet is created. Similar to
      the <code>Folio</code> class, the sheet name can be passed at
      construction or set with the <code>set-name</code> method. As
      usual a predicate is provided. 
      </p>

      <example>
      const sht (afnix:sps:Sheet)
      afnix:sps:sheet-p sht # true
      </example>

      <p>
      When the sheet is created, it can be added to the folio
      spreadsheet with the <code>add</code> method.
      </p>

      <example>
      const sht (afnix:sps:Sheet "data")
      sps:add sht
      </example>
    </subsect>

    <!-- adding data to the sheet -->
    <subsect>
      <title>Adding data to the sheet</title>

      <p>
      The process of adding data to a sheet is a straightforward
      operation with the <code>add-data</code> method or the
      <code>add</code> method. With the <code>add-data</code> method,
      data are added as literals. With the <code>add</code> method,
      data are added with the help of a record object.
      </p>

      <example>
      sht:add-data "Mercury"   4840 "1407:36"
      sht:add-data "Venus"    12400 "5819:51"
      sht:add-data "Earth"    12756 "23:56"
      sht:add-data "Mars"      6800 "24:37"
      sht:add-data "Jupiter" 142800 "9:50"
      sht:add-data "Saturn"  120800 "10:14"
      sht:add-data "Uranus"   47600 "10:49"
      sht:add-data "Neptune"  44600 "15:40"
      sht:add-data "Pluto"     5850 "153:17"
      sht:add-data "Sedna"     1800 "960:00"
      </example>

      <p>
      Data can be imported in a sheet by importation with an input
      stream. During the importation, the serialized data are decoded
      and placed sequentially in the stream.
      </p>
    </subsect>

    <!-- sheet sorting -->
    <subsect>
      <title>Sheet sorting</title>

      <p>
      A sheet can be sorted with the <code>sort</code> method. The
      <code>sort</code> method uses the first integer argument as the
      column number. The second optional argument is a boolean
      argument that selects the sorting method which can be ascending
      (by default) or descending if the flag is false.
      </p>

      <example>
      sht:sort 0
      sht:sort 1 false
      </example>
    </subsect>
  </section>

  <!-- record object -->
  <section>
    <title>Record object</title>

    <p>
    The <code>Record</code> object is an alternative to the sheet data
    filling. With the help of the <code>add</code> method, a record
    can be added to a sheet.
    </p>

    <!-- creating a record -->
    <subsect>
      <title>Creating a record</title>

      <p>
      A record is a named object that acts as a vector of cells. The
      record name can be set either by construction or with the
      <code>set-name</code> method. As usual a predicate is provided.
      </p>

      <example>
      const rcd (afnix:sps:Record)
      afnix:sps:record-p # true
      </example>
    </subsect>

    <!-- filling a record -->
    <subsect>
      <title>Filling a record</title>
      
      <p>
      A record can be filled either with literal data or
      <code>Cell</code> objects. In the first case, the cell is
      automatically created for each literal added to the record. The
      <code>add</code> method add a cell or literal to the record.
      </p>

      <example>
      const rcd (Record)
      rcd:add "Mercury" 4840 "1407:36"
      </example>

      <p>
      For data extraction, the <code>length</code> method returns the
      record length. Data can be extracted by index with either the
      <code>get</code> or <code>map</code> method. The <code>get</code>
      method returns the record cell while the <code>map</code> method
      returns the cell literal.
      </p>
    </subsect>
  </section>

  <!-- object search-->
  <section>
    <title>Object search</title>

    <p>
    The search methodology is divided either by sheet or cells. In a
    folio, the search is done in terms of sheets while the
    construction of a cross-reference table is required for searching
    cells.
    </p>

    <!-- searching in a folio -->
    <subsect>
      <title>Searching in a folio</title>
    
      <p>
      The <code>Folio</code> object provides the primary mean to search
      for sheet. The <code>find</code> and <code>lookup</code> methods
      return a sheet by tag. The first sheet that matches the tag is
      returned by these methods. The <code>find</code> method returns
      nil if the sheet cannot be found while the <code>lookup</code>
      method throws an exception.
      </p>

      <example>
      # get a sheet by tag
      const sheet (folio:lookup "the tag")
      </example>
      
      <p>
      If there are several sheets that matched the tag,
      the <code>filter</code> method is more appropriate. 
      The <code>filter</code> method returns a new folio that contains
      the sheet that matches the requested tag.
      </p>

      <example>
      # get a sub-folio by tag
      const sf (folio:filter "the tag")
      </example>
    </subsect>

    <!-- searching for a cell -->
    <subsect>
      <title>Searching for a cell</title>
    
      <p>
      The <code>Folio</code> object also provides the method for
      building a cross-reference table. The cross-reference table is
      represented by the <code>Xref</code> object. By default, a
      complete <code>Xref</code> object table is built with
      the <code>getxref</code> folio method. Such method, scan all
      cells in the folio and add them in the cross-reference table if
      the cell has a name.
      </p>

      <example>
      # get a default xref table 
      const xref (folio:getxref)
      </example>

      <p>
      The cross-reference table can also be built by searching for
      sheet tags. With a string argument, the <code>getxref</code>
      search for all sheets that matches the tag and then build a
      cross-reference table. This method is equivalent to the
      operation of building a new folio by tag with
      the <code>filter</code> method and then building the
      cross-reference table.
      </p>

      <example>
      # get a xref table by tag
      const xref (folio:getxref "the tag")
      # another method
      const sf   (folio:filter "the tag")
      const xref (sf:getxref)
      </example>

      <p>
      A cross-reference table can also be built by cell index and/or
      record index. With a cell index, the cross-reference table is
      built by indexing the sheet column. With both the cell and
      record indexes, the cross-reference table is built by indexing
      all cells at the coordinate for all sheets.
      </p>

      <example>
      # get a xref table by cell index
      const xref (folio:getxref 0)
      # get a xref table by cell and record index
      const xref (folio:getxref 0 1)
      </example>
    </subsect>
  </section>
</chapter>
