Inexactitude and node-list-ref

Subject: Inexactitude and node-list-ref
From: Chris Maden <crism@xxxxxxxxxxx>
Date: Mon, 5 Apr 1999 19:15:08 -0400 (EDT)
I'm writing code to handle a vertical-mode <simplelist> in DocBook.
It should make a table, filling as many rows as possible, leaving a
partly-filled last row if necessary.  I have to process the table
cells in row order, meaning that I have to access the <member>s of the
<simplelist> out of order.

For example, a seven-<member> <simplelist> should produce this:

    A      D      F
    B      E      G
    C

The math that I'm using to determine which <member> to handle causes
Jade to complain:

jade:/usr/local/prod/sgml/dsssl/db2mif.dsl:2262:33:E: 2nd argument for
primitive "node-list-ref" of wrong type: "0" not an exact integer

The Standard notes that for inexact input, some of the functions I'm
using may return an inexact number.  Unfortunately, Jade doesn't
implement inexact->exact, so I seem to be stuck.  Can anyone suggest a
workaround, or even a cleaner algorithm?

The exact code used is below.  In short, the algorithm is as follows:

  filled-cols is the number of columns before the present one that
   would be filled completely in a vertical fill.  It is the minimum
   of the number of preceding columns and the number of columns filled
   completely when the table is completely filled.

  partial-cols is the number of columns before the present one that
   would be filled to all but the last row in a vertical fill.  It is
   the current column number (in 0-based indexing) minus filled-cols.

  rows is the number of rows in the filled table.

  row is the number of the current row, in 0-based indexing.

  The current node to process (0-based again) is:

   (filled-cols * rows) + (partial-cols * (rows-1)) + row

If there's a simpler algorithm to which Daylight Savings Time has
blinded me, please point it out.  If not, please suggest alternative
code that will return an exact value.

Thanks very much in advance,
Chris

;; cols is already defined as the number of columns in the list
;; mem-len is the number of <member>s in the list

(let* ;; rows is the number of rows we'll need for a list this long
      ((rows (ceiling (/ mem-len
                         cols)))
       ;; empties is the number of unfilled cells at the end of the
       ;; table
       (empties (- (* rows
                      cols)
                   mem-len)))
  ;; loop from 0 to mem-len - 1
  (let mem-loop
      ((index 0))
    (let* ;; col is the current column (0-based)
          ((col (modulo index
                        cols))
           ;; row is the current row (0-based)
           (row (quotient index
                          cols))
           ;; filled-cols is the number of columns completely filled
           ;; in vertical order before the current column started
           (filled-cols (min col
                             (- cols
                                empties))))
      (sosofo-append (if (= col
                            0)
                         ;; Frame-ish for the start of the row
                         (make formatting-instruction
                               data: "   <Row 
")
                         (empty-sosofo))
                     ;; here's the problem.
                     (process-node-list (node-list-ref mems
                     ;; add the number of filled columns so far
                                                       (+ (* filled-cols
                     ;; times the number of rows
                                                             rows)
                     ;; to the number of nearly-filled columns so far
                                                          (* (- col
                                                                filled-cols)
                     ;; times one less than the number of rows
                                                             (- rows
                                                                1))
                     ;; plus the current row (0-based)
                                                          row))))
      (if (or (= col
                 (- cols
                    1))
              (>= (+ index
                     1)
                  mem-len))
          ;; end the row
          (make formatting-instruction
                data: "   > # end of Row
")
          (empty-sosofo))
      ;; and loop the loop
      (if (>= (+ index
                 1)
              (node-list-length mems))
          (empty-sosofo)
          (mem-loop (+ index
                       1))))))

-- 
<!NOTATION SGML.Geek PUBLIC "-//Anonymous//NOTATION SGML Geek//EN">
<!ENTITY crism PUBLIC "-//O'Reilly//NONSGML Christopher R. Maden//EN"
"<URL>http://www.oreilly.com/people/staff/crism/ <TEL>+1.617.499.7487
<USMAIL>90 Sherman Street, Cambridge, MA 02140 USA" NDATA SGML.Geek>


 DSSSList info and archive:  http://www.mulberrytech.com/dsssl/dssslist


Current Thread