## Re: Preceding list function

 Subject: Re: Preceding list function From: Norman Walsh Date: 08 Aug 2000 07:54:32 -0400
/ Brandon Ibach <bibach@xxxxxxxxxxxxxx> was heard to say:
|    Well, here's a possible solution (untested, mind you).  I know I
| don't have your most recent stylesheets, so I'll just quote the
| relevant function from the ones I have, with the parts that I changed
| commented.

Thanks, Brandon. In considering your solution, I couldn't convince myself
that it handled all of the various nesting cases correctly.

[...]
|    Now... the changes.  By adding orderedlist to the list of gis to
| match in the call to ancestor-member, we can narrow our search to only
| the other lists within the parent orderedlist, if there is one.  Of
| course, we need to start with the parent of the current list, to avoid
| matching the list we're in.

I wasn't, for example, sure that simply parent was looking far enough
back, since we could be nested arbitrarily deep.

Anyway, I decided to just start over. Here's what I came up with, and
it seems to work.

(define (orderedlist-listitem-number listitem)
;; return the number of listitem, taking continuation into account
(let* ((orderedlist (parent listitem))
(listitems (select-elements (children orderedlist)
(normalize "listitem")))
(continue? (equal? (attribute-string (normalize "continuation")
orderedlist)
(normalize "continues")))

;; If a list is the continuation of a previous list, we must find the
;; list that is continued in order to calculate the starting
;; item number of this list.
;;
;; Of all the lists in this component, only the following are candidates:
;; 1. Lists which precede this list
;; 2. Lists which are not ancestors of this list
;; 3. Lists that do not have ancestors that are lists which precede this one
;;
;; Of the candidates, the last one, in document order, is the preceding
;; list
(all-lists (select-elements
(descendants (ancestor-member orderedlist
(component-element-list)))
(normalize "orderedlist")))

(cand1     (if continue?
(let loop ((nl all-lists)
(prec (empty-node-list)))
(if (node-list-empty? nl)
prec
(if (node-list=? (node-list-first nl)
orderedlist)
prec
(loop (node-list-rest nl)
(node-list prec
(node-list-first nl))))))
(empty-node-list)))

(cand2     (let loop ((nl cand1)
(cand2lists (empty-node-list)))
(if (node-list-empty? nl)
cand2lists
(loop (node-list-rest nl)
(if (descendant-of? (node-list-first nl)
orderedlist)
cand2lists
(node-list cand2lists
(node-list-first nl)))))))

;; now find the last item of cand2 that is not a descendant
;; of some other element of the cand2 list.
(preclist  (let loop ((nl (node-list-reverse cand2)))
(if (node-list-empty? nl)
(empty-node-list)
(if (descendant-member-of?
(node-list-first nl)
(node-list-rest nl))
(loop (node-list-rest nl))
(node-list-first nl)))))

(precitem (if (node-list-empty? preclist)
(empty-node-list)
(node-list-last (children preclist))))
(precitem-number (if (and continue? (not (node-list-empty? precitem)))
(orderedlist-listitem-number precitem)
0)))

(+ precitem-number (child-number listitem))))

(define (descendant-member-of? node node-list)
;; return true if node is a descedant of any member of node-list
(let loop ((nl node-list))
(if (node-list-empty? nl)
#f
(if (descendant-of? (node-list-first nl) node)
#t
(loop (node-list-rest nl))))))

Be seeing you,
norm

--
Norman Walsh <ndw@xxxxxxxxxx> | The truest wild beasts live in the most
http://nwalsh.com/            | populous places.--Graci\'an

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