mirror of
				https://github.com/smarty-php/smarty.git
				synced 2025-10-31 20:31:41 +01:00 
			
		
		
		
	
		
			
	
	
		
			492 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			492 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|   | ;; $Id$ | ||
|  | ;; | ||
|  | ;; This file is part of the Modular DocBook Stylesheet distribution. | ||
|  | ;; See ../README or http://nwalsh.com/docbook/dsssl/ | ||
|  | ;; | ||
|  | 
 | ||
|  | (define (chunk-element-list) | ||
|  |   (list (normalize "preface") | ||
|  | 	(normalize "chapter") | ||
|  | 	(normalize "appendix")  | ||
|  | 	(normalize "article") | ||
|  | 	(normalize "glossary") | ||
|  | 	(normalize "bibliography") | ||
|  | 	(normalize "index") | ||
|  | 	(normalize "colophon") | ||
|  | 	(normalize "setindex") | ||
|  | 	(normalize "reference") | ||
|  | 	(normalize "refentry") | ||
|  | 	(normalize "part") | ||
|  | 	(normalize "sect1")  | ||
|  | 	(normalize "section")  | ||
|  | 	(normalize "book") ;; just in case nothing else matches... | ||
|  | 	(normalize "set")  ;; sets are definitely chunks... | ||
|  | 	)) | ||
|  | 
 | ||
|  | (define (chunk-skip-first-element-list) | ||
|  |   (list (normalize "sect1") | ||
|  | 	(normalize "section"))) | ||
|  | 
 | ||
|  | (define (chunk-section-depth) | ||
|  |   1) | ||
|  | 
 | ||
|  | (define (section-element-depth #!optional (section (current-node))) | ||
|  |   (if (node-list-empty? section) | ||
|  |       0 | ||
|  |       (if (equal? (gi section) (normalize "section")) | ||
|  | 	  (length (hierarchical-number-recursive | ||
|  | 		   (normalize "section") | ||
|  | 		   section)) | ||
|  | 	  (section-element-depth (parent section))))) | ||
|  | 
 | ||
|  | (define (is-first-element nd) | ||
|  |   (equal? (child-number nd) 1)) | ||
|  | 
 | ||
|  | (define (combined-chunk? #!optional (nd (current-node))) | ||
|  |   (or | ||
|  |    ;; if it's a section and the parent element is also a section | ||
|  |    ;; and its depth is less than or equal to chunk-section-depth | ||
|  |    (and (equal? (gi nd) (normalize "section")) | ||
|  | 	(not (node-list-empty? (parent nd))) | ||
|  | 	(equal? (gi (parent nd)) (normalize "section")) | ||
|  | 	(>= (section-element-depth nd) (chunk-section-depth))) | ||
|  |    ;; if it's the first skipped chunk in a chunk | ||
|  |    (and (not (node-list-empty? nd)) | ||
|  | 	(member (gi nd) (chunk-element-list)) | ||
|  | 	(is-first-element nd) | ||
|  | 	(member (gi nd) (chunk-skip-first-element-list))) | ||
|  |    ;; or if it's a chunk in a partintro | ||
|  |    (and (member (gi nd) (chunk-element-list)) | ||
|  | 	(has-ancestor-member? nd (list (normalize "partintro")))))) | ||
|  | 
 | ||
|  | (define (chunk? #!optional (nd (current-node))) | ||
|  |   ;; 1. The (sgml-root-element) is always a chunk. | ||
|  |   ;; 2. If nochunks is #t or the dbhtml PI on the root element  | ||
|  |   ;;    specifies chunk='no', then the root element is the only | ||
|  |   ;;    chunk. | ||
|  |   ;; 3. Otherwise, elements in the chunk-element-list are chunks | ||
|  |   ;;    unless they're combined with their parent. | ||
|  |   ;; 4. Except for bibliographys, which are only chunks if they | ||
|  |   ;;    occur in book or article. | ||
|  |   ;; 5. And except for sections, which are only chunks if they | ||
|  |   ;;    are not too deep | ||
|  |   ;; | ||
|  |   (let* ((notchunk (or (and (equal? (gi nd) (normalize "bibliography")) | ||
|  | 			    (not (or (equal? (gi (parent nd)) (normalize "book")) | ||
|  | 				     (equal? (gi (parent nd)) (normalize "article"))))) | ||
|  | 		       (and (equal? (gi nd) (normalize "section")) | ||
|  | 			    (equal? (gi (parent nd)) (normalize "section")) | ||
|  | 			    (>= (section-element-depth nd) | ||
|  | 				(chunk-section-depth))))) | ||
|  | 	 (maybechunk (not notchunk))) | ||
|  |     (if (node-list=? nd (sgml-root-element)) | ||
|  | 	#t | ||
|  | 	(if (or nochunks | ||
|  | 		(equal? (dbhtml-value (sgml-root-element) "chunk") "no")) | ||
|  | 	    #f | ||
|  | 	    (if (member (gi nd) (chunk-element-list)) | ||
|  | 		(if (combined-chunk? nd) | ||
|  | 		    #f | ||
|  | 		    maybechunk) | ||
|  | 		#f))))) | ||
|  | 
 | ||
|  | (define (html-prefix nd)  | ||
|  |   (let ((dbhtml-prefix (inherited-dbhtml-value nd "prefix"))) | ||
|  |     (if dbhtml-prefix | ||
|  | 	dbhtml-prefix | ||
|  | 	%html-prefix%))) | ||
|  | 
 | ||
|  | (define (id-based-filename nd) | ||
|  |   (if (and %use-id-as-filename%  | ||
|  | 	   (attribute-string (normalize "id") nd)) | ||
|  |       (case-fold-down (attribute-string (normalize "id") nd)) | ||
|  |       #f)) | ||
|  | 
 | ||
|  | (define (book-html-base nd) | ||
|  |   (let ((number (number->string (all-element-number nd))) | ||
|  | 	;(number (pad-string (number->string 3) 2 "0")) | ||
|  | 	(prefix (html-prefix nd)) | ||
|  | 	(pibase (or | ||
|  | 		 (inherited-dbhtml-value nd "basename") | ||
|  | 		 (inherited-pi-value nd "html-basename"))) | ||
|  | 	(idbase (id-based-filename nd))) | ||
|  |     (if idbase | ||
|  | 	(string-append (if prefix prefix "") idbase) | ||
|  | 	(string-append (if prefix prefix "")  | ||
|  | 		       (if pibase pibase "book") number)))) | ||
|  | 
 | ||
|  | (define (division-html-base nd) | ||
|  |   (let* ((number (number->string (all-element-number nd))) | ||
|  | 	 (prefix (html-prefix nd)) | ||
|  | 	 (pibase (or | ||
|  | 		  (inherited-dbhtml-value nd "basename") | ||
|  | 		  (inherited-pi-value nd "html-basename"))) | ||
|  | 	 (idbase (id-based-filename nd)) | ||
|  | 	 (base   (cond (pibase pibase) | ||
|  | 		       (idbase idbase) | ||
|  | 		       ((equal? (gi nd) (normalize "set"))          "s") | ||
|  | 		       ((equal? (gi nd) (normalize "preface"))      "f") | ||
|  | 		       ((equal? (gi nd) (normalize "chapter"))      "c") | ||
|  | 		       ((equal? (gi nd) (normalize "article"))      "t") | ||
|  | 		       ((equal? (gi nd) (normalize "appendix"))     "a") | ||
|  | 		       ((equal? (gi nd) (normalize "part"))         "p") | ||
|  | 		       ((equal? (gi nd) (normalize "reference"))    "r") | ||
|  | 		       ((equal? (gi nd) (normalize "glossary"))     "g") | ||
|  | 		       ((equal? (gi nd) (normalize "bibliography")) "b") | ||
|  | 		       ((equal? (gi nd) (normalize "index"))        "i") | ||
|  | 		       ((equal? (gi nd) (normalize "setindex"))     "n") | ||
|  | 		       ((equal? (gi nd) (normalize "refentry"))     "r") | ||
|  | 		       ;; "x" is section | ||
|  | 		       (else "z")))) | ||
|  |     (if idbase | ||
|  | 	(string-append (if prefix prefix "") idbase) | ||
|  | 	(if pibase | ||
|  | 	    (string-append (if prefix prefix "") pibase number) | ||
|  | 	    (string-append (if prefix prefix "") base number))))) | ||
|  | 
 | ||
|  | (define (component-html-base nd) | ||
|  |   (division-html-base nd)) | ||
|  | 
 | ||
|  | (define (section-html-base nd) | ||
|  |   ;; Now that I'm using all-element-number, there's no point in basing | ||
|  |   ;; it off the component-html-base at all... | ||
|  |   (let* ((number (number->string (all-element-number nd))) | ||
|  | 	 (prefix (html-prefix nd)) | ||
|  | 	 (pibase (or | ||
|  | 		  (inherited-dbhtml-value nd "basename") | ||
|  | 		  (inherited-pi-value nd "html-basename"))) | ||
|  | 	 (idbase (id-based-filename nd)) | ||
|  | 	 (base   (if pibase | ||
|  | 		     (string-append (if prefix prefix "") pibase) | ||
|  | 		     (string-append (if prefix prefix "") "x")))) | ||
|  |     (if idbase | ||
|  | 	(string-append (if prefix prefix "") idbase) | ||
|  | 	(if (chunk? nd) | ||
|  | 	    (string-append base number) | ||
|  | 	    base)))) | ||
|  | 
 | ||
|  | (define (element-html-base nd) | ||
|  |   (let* ((number (number->string (all-element-number nd))) | ||
|  | 	 (prefix (html-prefix nd)) | ||
|  | 	 (pibase (or | ||
|  | 		  (inherited-dbhtml-value nd "basename") | ||
|  | 		  (inherited-pi-value nd "html-basename"))) | ||
|  | 	 (idbase (id-based-filename nd)) | ||
|  | 	 (base   (if pibase | ||
|  | 		     (string-append (if prefix prefix "") pibase) | ||
|  | 		     (string-append (if prefix prefix "")  | ||
|  | 				    (case-fold-down (gi nd)))))) | ||
|  |     (if idbase | ||
|  | 	(string-append (if prefix prefix "") idbase) | ||
|  | 	(string-append base number)))) | ||
|  | 
 | ||
|  | ;; Returns the filename of the html file that contains elemnode, without | ||
|  | ;; any leading path information | ||
|  | (define (html-base-filename #!optional (input_nd (current-node))) | ||
|  |   (let* ((nd       (chunk-parent input_nd)) | ||
|  | 	 (base     (cond ((member (gi nd) (book-element-list)) | ||
|  | 			  (book-html-base nd)) | ||
|  | 			 ((member (gi nd) (division-element-list)) | ||
|  | 			  (division-html-base nd)) | ||
|  | 			 ((member (gi nd) (component-element-list)) | ||
|  | 			  (component-html-base nd)) | ||
|  | 			 ((member (gi nd) (section-element-list)) | ||
|  | 			  (section-html-base nd)) | ||
|  | 			 (else (element-html-base input_nd)))) | ||
|  | 	 ;; If this chunk-level element isn't a chunk, get the pifile from | ||
|  | 	 ;; the parent element. | ||
|  | 	 (pifile   (if (chunk? nd) | ||
|  | 		       (or | ||
|  | 			(dbhtml-value nd "filename") | ||
|  | 			(pi-value nd "html-filename")) | ||
|  | 		       (or | ||
|  | 			(dbhtml-value (parent nd) "filename") | ||
|  | 			(pi-value (parent nd) "html-filename")))) | ||
|  | 	 (language (if %html-use-lang-in-filename% | ||
|  | 		       (if (inherited-attribute-string (normalize "lang") nd) | ||
|  | 			   (inherited-attribute-string (normalize "lang") nd) | ||
|  | 			   %default-language%) | ||
|  | 		       "")) | ||
|  | 	 (ext      (if %html-use-lang-in-filename% | ||
|  | 		       (string-append "." language %html-ext%) | ||
|  | 		       %html-ext%))) | ||
|  |     (if (and %root-filename% (node-list=? (sgml-root-element) nd)) | ||
|  | 	(string-append %root-filename% ext) | ||
|  | 	(if pifile  | ||
|  | 	    pifile | ||
|  | 	    (string-append base ext))))) | ||
|  | 
 | ||
|  | (define (root-rel-path filename #!optional (node (current-node))) | ||
|  |   ;; Return the filename relative to the root path | ||
|  |   (string-append (copy-string "../" (directory-depth (html-file node))) | ||
|  | 		 filename)) | ||
|  | 
 | ||
|  | ;; Returns the filename of the html file that contains elemnode | ||
|  | ;; | ||
|  | (define (html-file #!optional (input_nd (current-node))) | ||
|  |   (let* ((cp-nd         (chunk-parent input_nd)) | ||
|  | 	 ;; If the sgml-root-element is at a level below the chunking | ||
|  | 	 ;; level, then cp-nd will return an empty-node-list. In this | ||
|  | 	 ;; case, we want to return the root-element. | ||
|  | 	 (nd            (if (node-list-empty? cp-nd) | ||
|  | 			    (sgml-root-element) | ||
|  | 			    cp-nd)) | ||
|  | 	 (base-filename (html-base-filename nd)) | ||
|  | 	 (pidir (or | ||
|  | 		 (inherited-dbhtml-value nd "dir") | ||
|  |      		 (inherited-pi-value nd "html-dir")))) | ||
|  |     (if (and %root-filename% (node-list=? (sgml-root-element) nd)) | ||
|  | 	base-filename | ||
|  | 	(if pidir | ||
|  | 	    (string-append pidir "/" base-filename) | ||
|  | 	    base-filename)))) | ||
|  | 
 | ||
|  | (define (href-to target) | ||
|  |   ;; Return the HTML HREF for the given node.  If nochunks is true, just | ||
|  |   ;; return the fragment identifier. | ||
|  |   (let* ((id       (element-id target)) | ||
|  | 	 (curdepth (directory-depth (html-file (current-node)))) | ||
|  | 	 (entfile  (html-file target)) | ||
|  | 	 (fragid   (if (chunk? target) | ||
|  | 		     "" | ||
|  | 		     (string-append "#" id)))) | ||
|  |     (if nochunks | ||
|  | 	fragid | ||
|  | 	(string-append (copy-string "../" curdepth) entfile fragid)))) | ||
|  | 
 | ||
|  | (define (html-entity-file htmlfilename) | ||
|  |   ;; Returns the filename that should be used for _writing_ htmlfilename. | ||
|  |   ;; This may differ from the filename used in referencing it.  (The point | ||
|  |   ;; is that you can force the stylesheets to write the chunked files | ||
|  |   ;; somewhere else, if you want.) | ||
|  |   (let* ((pi-outputdir (dbhtml-value (sgml-root-element) "output-dir")) | ||
|  | 	 (outputdir    (if pi-outputdir | ||
|  | 			   pi-outputdir | ||
|  | 			   %output-dir%))) | ||
|  |     (if (and use-output-dir outputdir) | ||
|  | 	(string-append outputdir "/" htmlfilename) | ||
|  | 	htmlfilename))) | ||
|  |    | ||
|  | ;; Split node list nl at nd; return '(nodes-prev-to-nd nodes-following-nd) | ||
|  | ;; Note that nd does not appear in either return list. | ||
|  | (define (split-node-list nd nodelist) | ||
|  |   (let loop ((prev (empty-node-list))  | ||
|  | 	     (nl nodelist)) | ||
|  |     (if (node-list-empty? nl) | ||
|  | 	(list prev (empty-node-list)) | ||
|  | 	(if (node-list=? (node-list-first nl) nd) | ||
|  | 	    (list prev (node-list-rest nl)) | ||
|  | 	    (loop (node-list prev (node-list-first nl)) | ||
|  | 		  (node-list-rest nl)))))) | ||
|  | 
 | ||
|  | (define (navigate-to? nd) | ||
|  |   #t) | ||
|  | 
 | ||
|  | (define (chunk-parent #!optional (nd (current-node))) | ||
|  |   (let ((cp (let loop ((p (chunk-level-parent nd))) | ||
|  | 	      (if (or (node-list-empty? p) (chunk? p)) | ||
|  | 		  p | ||
|  | 		  (chunk-parent (parent p)))))) | ||
|  |     cp)) | ||
|  | ;    (if (node-list-empty? cp) | ||
|  | ;	;; if there's no chunk-parent, return the root node | ||
|  | ;	(sgml-root-element) | ||
|  | ;	;; otherwise, return the parent that we found | ||
|  | ;	cp))) | ||
|  | 
 | ||
|  | (define (chunk-level-parent #!optional (nd (current-node))) | ||
|  |   (ancestor-member nd (chunk-element-list))) | ||
|  | 
 | ||
|  | (define (chunk-children #!optional (nd (current-node))) | ||
|  |   (node-list-filter-by-gi (children nd) (chunk-element-list))) | ||
|  | 
 | ||
|  | (define (ifollow-by-gi nd gilist) | ||
|  |   (let loop ((next (ifollow nd))) | ||
|  |     (if (node-list-empty? next) | ||
|  | 	(empty-node-list) | ||
|  | 	(if (member (gi next) gilist) | ||
|  | 	    next | ||
|  | 	    (loop (ifollow next)))))) | ||
|  | 
 | ||
|  | (define (ipreced-by-gi nd gilist) | ||
|  |   (let loop ((prev (ipreced nd))) | ||
|  |     (if (node-list-empty? prev) | ||
|  | 	(empty-node-list) | ||
|  | 	(if (member (gi prev) gilist) | ||
|  | 	    prev | ||
|  | 	    (loop (ipreced prev)))))) | ||
|  | 
 | ||
|  | (define (last-chunk-element nd) | ||
|  |   (let ((clc (node-list-filter-by-gi (children nd) (chunk-element-list)))) | ||
|  |     (if (node-list-empty? clc) | ||
|  | 	nd | ||
|  | 	(last-chunk-element (node-list-last clc))))) | ||
|  | 
 | ||
|  | (define (next-chunk-skip-children #!optional (elem (current-node))) | ||
|  |   (let* ((nd  (chunk-level-parent elem)) | ||
|  | 	 (psl (node-list-filter-by-gi (children (parent nd))  | ||
|  | 				      (chunk-element-list))) | ||
|  | 	 (nextlist (car (cdr (split-node-list nd psl))))) | ||
|  |     (if (node-list-empty? nextlist) | ||
|  | 	(if (node-list-empty? (parent nd)) | ||
|  | 	    (empty-node-list) | ||
|  | 	    (next-chunk-skip-children (parent nd))) | ||
|  | 	(node-list-first nextlist)))) | ||
|  | 
 | ||
|  | (define (next-chunk-with-children #!optional (elem (current-node))) | ||
|  |   (let* ((nd  (chunk-level-parent elem)) | ||
|  | 	 (clc (chunk-children nd)) | ||
|  | 	 (ns  (ifollow-by-gi nd (chunk-element-list)))) | ||
|  |     (if (node-list-empty? clc) | ||
|  | 	(if (node-list-empty? ns) | ||
|  | 	    (next-chunk-skip-children (parent nd)) | ||
|  | 	    (node-list-first ns)) | ||
|  | 	;; If the first of the chunk-children (clc) of this element | ||
|  | 	;; isn't its own chunk, skip over it, otherwise it's next. | ||
|  | 	(if (chunk? (node-list-first clc)) | ||
|  | 	    (node-list-first clc) | ||
|  | 	    (next-chunk-with-children (node-list-first clc)))))) | ||
|  | ;;	    (if (> (node-list-length clc) 1) | ||
|  | ;;		(node-list-first (node-list-rest clc)) | ||
|  | ;;		(next-chunk-skip-children nd)))))) | ||
|  | 
 | ||
|  | (define (abs-prev-chunk #!optional (elem (current-node))) | ||
|  |   (let* ((nd  (chunk-parent elem)) | ||
|  | 	 (pse (ipreced-by-gi nd (chunk-element-list))) | ||
|  | 	 (ps  (chunk-parent pse))) | ||
|  |     (if (node-list-empty? ps) | ||
|  | 	(parent nd) | ||
|  | 	(last-chunk-element ps)))) | ||
|  | 
 | ||
|  | (define (prev-chunk-element #!optional (elem (current-node))) | ||
|  |   (let* ((nd   (chunk-parent elem)) | ||
|  | 	 (prev (chunk-parent (abs-prev-chunk nd)))) | ||
|  |     ;; There's a special case here.  abs-prev-chunk always returns the last | ||
|  |     ;; chunk element of the preceding element if we walk up the tree.  This | ||
|  |     ;; assures that the last section of the preceding chapter is the "prev" | ||
|  |     ;; element of the current chapter. | ||
|  |     ;; | ||
|  |     ;; However, if chunk-skip-first-element is in use, then abs-prev-chunk | ||
|  |     ;; gets fooled when it tries to find the element that precedes the | ||
|  |     ;; second child element that's in chunk-skip-first-element list. | ||
|  |     ;; | ||
|  |     ;; For example, if SECT1 is in chunk-skip-first-element then the | ||
|  |     ;; chunk that precedes the second SECT1 in a CHAPTER is the CHAPTER | ||
|  |     ;; (not the first SECT1 because the first SECT1 is "skipped",  | ||
|  |     ;; it's in the CHAPTER chunk).  Confused yet? | ||
|  |     ;; | ||
|  |     ;; Ok, now unfortunately, what abs-prev-chunk returns is the last child | ||
|  |     ;; of the CHAPTER, so instead of going from the second SECT1 to the | ||
|  |     ;; CHAPTER, we go from the second SECT1 to the last SECT1 of the CHAPTER. | ||
|  |     ;; | ||
|  |     ;; I can't think of a good way to handle this except to test for it | ||
|  |     ;; right up front.  I wonder if all this skip stuff was really worth it? | ||
|  |     ;; | ||
|  |     (if (and (member (gi elem) (chunk-skip-first-element-list)) | ||
|  | 	     (equal? (child-number elem) 2)) | ||
|  | 	;; this is the second child, the prev node is the parent. | ||
|  | 	(parent elem) | ||
|  | 	;; otherwise, do the "normal" thing to find it: | ||
|  | 	(if (node-list-empty? prev) | ||
|  | 	    prev | ||
|  | 	    (if (combined-chunk? prev) | ||
|  | 		(parent prev) | ||
|  | 		(if (and (chunk? nd) | ||
|  | 			 (chunk? prev) | ||
|  | 			 (navigate-to? prev)) | ||
|  | 		    prev | ||
|  | 		    (prev-chunk-element prev))))))) | ||
|  | 
 | ||
|  | (define (abs-prev-peer-chunk-element #!optional (elem (current-node))) | ||
|  |   ;; Returns the previous element that is a sibling or parent of the | ||
|  |   ;; current element.  Absolute in this case refers to the fact that | ||
|  |   ;; it returns the immediate predecessor without regard for whether or | ||
|  |   ;; not it is a chunk. | ||
|  |   (let* ((psibling (if (node-list-empty? (preced elem)) | ||
|  | 		       (empty-node-list) | ||
|  | 		       (node-list-last (preced elem))))) | ||
|  |     (if (node-list-empty? psibling) | ||
|  | 	(parent elem) | ||
|  | 	psibling))) | ||
|  | 
 | ||
|  | (define (prev-peer-chunk-element #!optional (elem (current-node))) | ||
|  |   (let loop ((nd (chunk-level-parent elem))) | ||
|  |     (if (node-list-empty? nd) | ||
|  | 	(empty-node-list) | ||
|  | 	(if (and (chunk? (abs-prev-peer-chunk-element nd)) | ||
|  | 		 (navigate-to? (abs-prev-peer-chunk-element nd))) | ||
|  | 	    (abs-prev-peer-chunk-element nd) | ||
|  | 	    (loop (abs-prev-peer-chunk-element nd)))))) | ||
|  | 
 | ||
|  | (define (prev-major-component-chunk-element #!optional (elem (current-node)) (in-chain #f)) | ||
|  |   ;; Return the prev major component of the document that is a sibling (or | ||
|  |   ;; ancestor) of the starting element. This is essentially 'prev-sibling'  | ||
|  |   ;; but skips over things that aren't chunks. | ||
|  |   (if (or (navigate-to? elem) in-chain) | ||
|  |       (if (member (gi elem) (major-component-element-list)) | ||
|  | 	  (if (node-list-empty? (node-list-last-element (preced elem))) | ||
|  | 	      (prev-chunk-element elem) | ||
|  | 	      (let ((nd (node-list-last-element (preced elem)))) | ||
|  | 		(if (navigate-to? nd) | ||
|  | 		    nd | ||
|  | 		    (prev-major-component-chunk-element nd #t)))) | ||
|  | 	  (ancestor-member elem (major-component-element-list))) | ||
|  |       (empty-node-list))) | ||
|  | 
 | ||
|  | (define (abs-next-chunk #!optional (elem (current-node)) (children-ok? #t)) | ||
|  |   (let* ((nd  (chunk-level-parent elem)) | ||
|  | 	 (clc (if children-ok? (chunk-children nd) (empty-node-list))) | ||
|  | 	 (ns  (ifollow-by-gi nd (chunk-element-list)))) | ||
|  |     (if (node-list-empty? clc) | ||
|  | 	(if (node-list-empty? ns) | ||
|  | 	    (if (node-list-empty? (parent nd)) | ||
|  | 		(empty-node-list) | ||
|  | 		(abs-next-chunk (parent nd) #f)) | ||
|  | 	    (node-list-first ns)) | ||
|  | 	(node-list-first clc)))) | ||
|  | 
 | ||
|  | (define (next-chunk-element #!optional (elem (current-node))) | ||
|  |   (let ((next (abs-next-chunk elem))) | ||
|  |     (if (node-list-empty? next) | ||
|  | 	(empty-node-list) | ||
|  | 	(if (chunk? next) | ||
|  | 	    (if (navigate-to? next) | ||
|  | 		next | ||
|  | 		(next-chunk-element next)) | ||
|  | 	    (next-chunk-element next))))) | ||
|  | 
 | ||
|  | (define (abs-next-peer-chunk-element #!optional (elem (current-node))) | ||
|  |   (let* ((fsibling (if (node-list-empty? (follow elem)) | ||
|  | 		       (empty-node-list) | ||
|  | 		       (node-list-first (follow elem))))) | ||
|  |     (if (node-list-empty? fsibling) | ||
|  | 	(if (node-list-empty? (parent elem)) | ||
|  | 	    (empty-node-list) | ||
|  | 	    (abs-next-peer-chunk-element (parent elem))) | ||
|  | 	fsibling))) | ||
|  | 
 | ||
|  | (define (next-peer-chunk-element #!optional (elem (current-node))) | ||
|  |   (let loop ((nd (chunk-level-parent elem))) | ||
|  |     (if (node-list-empty? nd) | ||
|  | 	(empty-node-list) | ||
|  | 	(if (and (chunk? (abs-next-peer-chunk-element nd)) | ||
|  | 		 (navigate-to? (abs-next-peer-chunk-element nd))) | ||
|  | 	    (abs-next-peer-chunk-element nd) | ||
|  | 	    (loop (abs-next-peer-chunk-element nd)))))) | ||
|  | 
 | ||
|  | (define (next-major-component-chunk-element #!optional (elem (current-node)) (in-chain #f)) | ||
|  |   ;; Return the next major component of the document that is not a descendant | ||
|  |   ;; of the starting element.  This is essentially 'next-sibling' but skips | ||
|  |   ;; over things that aren't chunks. | ||
|  |   (if (or (navigate-to? elem) in-chain) | ||
|  |       (if (member (gi elem) (major-component-element-list)) | ||
|  | 	  (if (node-list-empty? (node-list-first-element (follow elem))) | ||
|  | 	      (next-major-component-chunk-element (parent elem)) | ||
|  | 	      (let ((nd (node-list-first-element (follow elem)))) | ||
|  | 		(if (navigate-to? nd) | ||
|  | 		    nd | ||
|  | 		    (next-major-component-chunk-element nd #t)))) | ||
|  | 	  (ancestor-member elem (major-component-element-list))) | ||
|  |       (empty-node-list))) | ||
|  | 
 | ||
|  | ;; EOF dbchunk.dsl |