Re: Preceding list function

Subject: Re: Preceding list function
From: Brandon Ibach <bibach@xxxxxxxxxxxxxx>
Date: Thu, 10 Aug 2000 00:18:18 -0500
Quoting Norman Walsh <ndw@xxxxxxxxxx>:
> |    1. Group I
> |       1. First
> |       2. Second
> |       3. Third
> |    Some intervening text
> |    2. Group II
> |       2. Fourth
> |       3. Fifth
> |       4. Sixth
> 
> I think that's the "right" answer for the source markup you gave.
> 
> |    o Group I
> |      1. First
> |      2. Second
> |      3. Third
> |    Some intervening text
> |    o Group II
> |      4. Fourth
> |      5. Fifth
> |      6. Sixth
> 
> Yes, and I think that would work naturally. The continuation feature
> only discriminates between ancestor orderedlists and bulleted lists
> are itemizedlists.
> 
   Hmmm...  This creates some "intuitive inconsistency", in my mind.
If the outer lists are itemizedlists, then the inner ones can be made
to continue their number properly.  If, however, the outer lists are
orderedlists, then it isn't possible to get the inner lists to
continue properly.
   If you think about it a bit, isn't the definition of the preceding
list as the one which most recently ended essentially designed to
ensure that the continuation will continue a list at the same nesting
depth?
   Perhaps the "nesting-depth-matched-continuation" behavior could be
a non-default option in the stylesheets.  Perhaps something like:

(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
	 (list-anc  (select-elements (ancestors orderedlist)
				     (normalize "orderedlist")))
	 (list-dep  (node-list-length list-anc))
	 (preclist  (let loop ((nl (children
				    (ancestor-member
				     orderedlist
				     (component-element-list))))
			       (prec (empty-node-list)))
		      (if (node-list-empty? nl)
			  prec
			  (let ((n (node-list-first nl)))
			    (if (or (not (equal? (gi n)
						 (normalize "orderedlist")))
				    (node-list-contains? list-anc n))
				(loop (node-list (children n)
						 (node-list-rest nl))
				      prec)
				(if (and %nest-depth-match-continuations%
					 (> list-dep
					    (node-list-length
					     (select-elements
					      (ancestors n)
					      (normalize "orderedlist")))))
				    (loop (node-list (children n)
						     (node-list-rest nl))
					  n)
				    (if (node-list=? orderedlist n)
					prec
					(loop (node-list-rest nl) n))))))))
	 (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))))

   I used the version of this procedure that you posted earlier with a
modified method for deriving preclist.  The loop descends the subtree
of the ancestor component element, searching for the preceding list
based on the criteria in your comment.
   We start with a nodelist, nl, containing the children of the
component element and an empty nodelist which we will use to keep
track of our "current best bet" for the preceding list, prec.  We loop
to examine each element of nl in turn.
   If the element is not an orderedlist or if it is an ancestor of the
current list, we replace it, in nl, with its children and loop.  If
the variable %nest-depth-match-continuations% is true and the nesting
depth of the list is less than the nesting depth of the current list,
then we set prec to the list, replace the list, in nl, with its
children, and loop.  Finally, if the list is the current list, then we
return whatever is currently in prec, otherwise we set prec to the
list and loop.
   With the exception of the nesting depth check, this accomplishes
the same thing as your version:
     1. Stops when we get to the current list
     2. Descends, but does not return, ancestors of the current list
     3. Does not descend lists that precede the current list
   The exception to 3, of course, is if the nesting depth check is
enabled, in which case it descends lists if they might contain a match
at the correct nesting level.  Note, however, that when such a descent
is made, we also store the list as a possible preceding list.  Thus,
if there is no list at the correct depth, the preceding list at a
smaller depth will be returned, instead.  I suppose this could be a
problem (such as a case of having a list of the correct depth, then
one too shallow, in that order, before the current list), but, then,
would it be correct to use the earlier list?  Tough to say, especially
since this whole idea seems to be outside of the scope of Docbook's
official definitions for this issue.  *sigh*
   For a change of pace, I actually tested this version. :)  It uses
two (that I recall) procedures that Jade 1.2.2 doesn't have, nor do
the version of your stylesheets that I have.  The ancestors procedure
shouldn't be hard to work around.  In fact, in the two places it's
used, its result is filtered (by select-elements) to return just the
orderedlist ancestors, so a version of your ancestor-member function
that returns all matching ancestors would work nicely.  And as for
node-list-contains?, well, I'm sure you'll figure out a good way to
handle that. :)

-Brandon :)

-Brandon :)


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


Current Thread