mirror of
				https://github.com/smarty-php/smarty.git
				synced 2025-11-04 06:11:37 +01:00 
			
		
		
		
	
		
			
	
	
		
			420 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			420 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 
								 | 
							
								;; $Id$
							 | 
						||
| 
								 | 
							
								;;
							 | 
						||
| 
								 | 
							
								;; This file is part of the Modular DocBook Stylesheet distribution.
							 | 
						||
| 
								 | 
							
								;; See ../README or http://www.berkshire.net/~norm/dsssl/
							 | 
						||
| 
								 | 
							
								;;
							 | 
						||
| 
								 | 
							
								;; Table support completely reimplemented by norm 15/16 Nov 1997.
							 | 
						||
| 
								 | 
							
								;; Adapted from print support.
							 | 
						||
| 
								 | 
							
								;;
							 | 
						||
| 
								 | 
							
								;; ======================================================================
							 | 
						||
| 
								 | 
							
								;;
							 | 
						||
| 
								 | 
							
								;; This code is intended to implement the SGML Open Exchange Table Model
							 | 
						||
| 
								 | 
							
								;; (http://www.sgmlopen.org/sgml/docs/techpubs.htm) as far as is possible
							 | 
						||
| 
								 | 
							
								;; in HTML.  There are a few areas where this code probably fails to 
							 | 
						||
| 
								 | 
							
								;; perfectly implement the model:
							 | 
						||
| 
								 | 
							
								;;
							 | 
						||
| 
								 | 
							
								;; - Mixed column width units (4*+2pi) are not supported.
							 | 
						||
| 
								 | 
							
								;; - The behavior that results from mixing relative units with 
							 | 
						||
| 
								 | 
							
								;;   absolute units has not been carefully considered.
							 | 
						||
| 
								 | 
							
								;;
							 | 
						||
| 
								 | 
							
								;; ======================================================================
							 | 
						||
| 
								 | 
							
								;; 
							 | 
						||
| 
								 | 
							
								;; My goal in reimplementing the table model was to provide correct
							 | 
						||
| 
								 | 
							
								;; formatting in tables that use MOREROWS. The difficulty is that
							 | 
						||
| 
								 | 
							
								;; correct formatting depends on calculating the column into which
							 | 
						||
| 
								 | 
							
								;; an ENTRY will fall.
							 | 
						||
| 
								 | 
							
								;;
							 | 
						||
| 
								 | 
							
								;; This is a non-trivial problem because MOREROWS can hang down from
							 | 
						||
| 
								 | 
							
								;; preceding rows and ENTRYs may specify starting columns (skipping
							 | 
						||
| 
								 | 
							
								;; preceding ones).
							 | 
						||
| 
								 | 
							
								;;
							 | 
						||
| 
								 | 
							
								;; A simple, elegant recursive algorithm exists. Unfortunately it 
							 | 
						||
| 
								 | 
							
								;; requires calculating the column number of every preceding cell 
							 | 
						||
| 
								 | 
							
								;; in the entire table. Without memoization, performance is unacceptable
							 | 
						||
| 
								 | 
							
								;; even in relatively small tables (5x5, for example).
							 | 
						||
| 
								 | 
							
								;;
							 | 
						||
| 
								 | 
							
								;; In order to avoid recursion, the algorithm used below is one that
							 | 
						||
| 
								 | 
							
								;; works forward from the beginning of the table and "passes along"
							 | 
						||
| 
								 | 
							
								;; the relevant information (column number of the preceding cell and
							 | 
						||
| 
								 | 
							
								;; overhang from the MOREROWS in preceding rows).
							 | 
						||
| 
								 | 
							
								;;
							 | 
						||
| 
								 | 
							
								;; Unfortunately, this means that element construction rules
							 | 
						||
| 
								 | 
							
								;; can't always be used to fire the appropriate rule.  Instead,
							 | 
						||
| 
								 | 
							
								;; each TGROUP has to process each THEAD/BODY/FOOT explicitly.
							 | 
						||
| 
								 | 
							
								;; And each of those must process each ROW explicitly, then each
							 | 
						||
| 
								 | 
							
								;; ENTRY/ENTRYTBL explicitly.
							 | 
						||
| 
								 | 
							
								;;
							 | 
						||
| 
								 | 
							
								;; ----------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								;;
							 | 
						||
| 
								 | 
							
								;; I attempted to simplify this code by relying on inheritence from
							 | 
						||
| 
								 | 
							
								;; table-column flow objects, but that wasn't entirely successful.
							 | 
						||
| 
								 | 
							
								;; Horizontally spanning cells didn't seem to inherit from table-column
							 | 
						||
| 
								 | 
							
								;; flow objects that didn't specify equal spanning.  There seemed to
							 | 
						||
| 
								 | 
							
								;; be other problems as well, but they could have been caused by coding
							 | 
						||
| 
								 | 
							
								;; errors on my part.
							 | 
						||
| 
								 | 
							
								;; 
							 | 
						||
| 
								 | 
							
								;; Anyway, by the time I understood how I could use table-column
							 | 
						||
| 
								 | 
							
								;; flow objects for inheritence, I'd already implemented all the
							 | 
						||
| 
								 | 
							
								;; machinery below to "work it out by hand".  
							 | 
						||
| 
								 | 
							
								;;
							 | 
						||
| 
								 | 
							
								;; ======================================================================
							 | 
						||
| 
								 | 
							
								;; NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE 
							 | 
						||
| 
								 | 
							
								;; ----------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								;; A fairly large chunk of this code is in dbcommon.dsl!
							 | 
						||
| 
								 | 
							
								;; ======================================================================
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								;; Default for COLSEP/ROWSEP if unspecified
							 | 
						||
| 
								 | 
							
								(define %cals-rule-default% "0")
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								;; Default for VALIGN if unspecified
							 | 
						||
| 
								 | 
							
								(define %cals-valign-default% "TOP")
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								;; ======================================================================
							 | 
						||
| 
								 | 
							
								;; Convert colwidth units into table-unit measurements
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(define (colwidth-length lenstr)
							 | 
						||
| 
								 | 
							
								  (if (string? lenstr)
							 | 
						||
| 
								 | 
							
								      (let ((number (length-string-number-part lenstr))
							 | 
						||
| 
								 | 
							
									    (units  (length-string-unit-part lenstr)))
							 | 
						||
| 
								 | 
							
									(if (or (string=? units "*") (string=? number ""))
							 | 
						||
| 
								 | 
							
									    ;; relative units or no number, give up
							 | 
						||
| 
								 | 
							
									    0pt
							 | 
						||
| 
								 | 
							
									    (if (string=? units "")
							 | 
						||
| 
								 | 
							
										;; no units, default to pixels
							 | 
						||
| 
								 | 
							
										(* (string->number number) 1px)
							 | 
						||
| 
								 | 
							
										(let* ((unum  (string->number number))
							 | 
						||
| 
								 | 
							
										       (uname (case-fold-down units)))
							 | 
						||
| 
								 | 
							
										  (case uname
							 | 
						||
| 
								 | 
							
										    (("mm") (* unum 1mm))
							 | 
						||
| 
								 | 
							
										    (("cm") (* unum 1cm))
							 | 
						||
| 
								 | 
							
										    (("in") (* unum 1in))
							 | 
						||
| 
								 | 
							
										    (("pi") (* unum 1pi))
							 | 
						||
| 
								 | 
							
										    (("pt") (* unum 1pt))
							 | 
						||
| 
								 | 
							
										    (("px") (* unum 1px))
							 | 
						||
| 
								 | 
							
										    ;; unrecognized units; use pixels
							 | 
						||
| 
								 | 
							
										    (else   (* unum 1px)))))))
							 | 
						||
| 
								 | 
							
								      ;; lenstr is not a string...probably #f
							 | 
						||
| 
								 | 
							
								      0pt))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(define (cals-relative-colwidth? colwidth)
							 | 
						||
| 
								 | 
							
								  (if (string? colwidth)
							 | 
						||
| 
								 | 
							
								      (let ((strlen (string-length colwidth)))
							 | 
						||
| 
								 | 
							
									(if (string=? colwidth "*")
							 | 
						||
| 
								 | 
							
									    #t
							 | 
						||
| 
								 | 
							
									    (string=? (substring colwidth (- strlen 1) strlen) "*")))
							 | 
						||
| 
								 | 
							
								      #f))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(define (cals-relative-colwidth colwidth)
							 | 
						||
| 
								 | 
							
								  (let ((number (length-string-number-part colwidth))
							 | 
						||
| 
								 | 
							
									(units  (length-string-unit-part colwidth)))
							 | 
						||
| 
								 | 
							
								    (if (string=? units "*")
							 | 
						||
| 
								 | 
							
									(if (string=? number "")
							 | 
						||
| 
								 | 
							
									    1
							 | 
						||
| 
								 | 
							
									    (string->number number))
							 | 
						||
| 
								 | 
							
									0)))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(define (cell-relative-colwidth cell relative)
							 | 
						||
| 
								 | 
							
								  (let* ((tgroup (find-tgroup cell)))
							 | 
						||
| 
								 | 
							
								    (let loop ((colspecs (select-elements (children tgroup)
							 | 
						||
| 
								 | 
							
													  (normalize "colspec")))
							 | 
						||
| 
								 | 
							
									       (reltotal 0))
							 | 
						||
| 
								 | 
							
								      (if (node-list-empty? colspecs)
							 | 
						||
| 
								 | 
							
									  (string-append (number->string (round (* (/ relative reltotal) 100))) "%")
							 | 
						||
| 
								 | 
							
									  (loop (node-list-rest colspecs) 
							 | 
						||
| 
								 | 
							
										(+ reltotal (cals-relative-colwidth 
							 | 
						||
| 
								 | 
							
											     (colspec-colwidth 
							 | 
						||
| 
								 | 
							
											      (node-list-first colspecs)))))))))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(define (cell-colwidth cell colnum)
							 | 
						||
| 
								 | 
							
								  (let* ((entry     (ancestor-member cell (list (normalize "entry") 
							 | 
						||
| 
								 | 
							
														(normalize "entrytbl"))))
							 | 
						||
| 
								 | 
							
									 (colspec   (find-colspec-by-number colnum))
							 | 
						||
| 
								 | 
							
									 (colwidth  (colspec-colwidth colspec))
							 | 
						||
| 
								 | 
							
									 (width     (round (/ (colwidth-length colwidth) 1px))))
							 | 
						||
| 
								 | 
							
								    (if (node-list-empty? colspec)
							 | 
						||
| 
								 | 
							
									""
							 | 
						||
| 
								 | 
							
									(if (and (equal? (hspan entry) 1) colwidth)
							 | 
						||
| 
								 | 
							
									    (if (cals-relative-colwidth? colwidth)
							 | 
						||
| 
								 | 
							
										(cell-relative-colwidth cell (cals-relative-colwidth colwidth))
							 | 
						||
| 
								 | 
							
										(number->string width))
							 | 
						||
| 
								 | 
							
									    ""))))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								;; ======================================================================
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(define (cell-align cell colnum)
							 | 
						||
| 
								 | 
							
								  (let* ((entry     (ancestor-member cell (list (normalize "entry") 
							 | 
						||
| 
								 | 
							
														(normalize "entrytbl"))))
							 | 
						||
| 
								 | 
							
									 (tgroup    (find-tgroup entry))
							 | 
						||
| 
								 | 
							
									 (spanname  (attribute-string (normalize "spanname") entry))
							 | 
						||
| 
								 | 
							
									 (calsalign (if (attribute-string (normalize "align") entry)
							 | 
						||
| 
								 | 
							
											(attribute-string (normalize "align") entry)
							 | 
						||
| 
								 | 
							
											(if (and spanname 
							 | 
						||
| 
								 | 
							
												 (spanspec-align (find-spanspec spanname)))
							 | 
						||
| 
								 | 
							
											    (spanspec-align (find-spanspec spanname))
							 | 
						||
| 
								 | 
							
											    (if (colspec-align (find-colspec-by-number colnum))
							 | 
						||
| 
								 | 
							
												(colspec-align (find-colspec-by-number colnum))
							 | 
						||
| 
								 | 
							
												(if (tgroup-align tgroup)
							 | 
						||
| 
								 | 
							
												    (tgroup-align tgroup)
							 | 
						||
| 
								 | 
							
												    (normalize "left")))))))
							 | 
						||
| 
								 | 
							
								    (cond
							 | 
						||
| 
								 | 
							
								     ((equal? calsalign (normalize "left")) "LEFT")
							 | 
						||
| 
								 | 
							
								     ((equal? calsalign (normalize "center")) "CENTER")
							 | 
						||
| 
								 | 
							
								     ((equal? calsalign (normalize "right")) "RIGHT")
							 | 
						||
| 
								 | 
							
								     (else "LEFT"))))
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								(define (cell-valign cell colnum)
							 | 
						||
| 
								 | 
							
								  (let* ((entry      (ancestor-member cell (list (normalize "entry")
							 | 
						||
| 
								 | 
							
														 (normalize "entrytbl"))))
							 | 
						||
| 
								 | 
							
									 (row        (ancestor (normalize "row") entry))
							 | 
						||
| 
								 | 
							
									 (tbody      (ancestor-member cell (list (normalize "tbody") 
							 | 
						||
| 
								 | 
							
														 (normalize "thead") (normalize "tfoot"))))
							 | 
						||
| 
								 | 
							
									 (tgroup     (find-tgroup entry))
							 | 
						||
| 
								 | 
							
									 (calsvalign (if (attribute-string (normalize "valign") entry)
							 | 
						||
| 
								 | 
							
											 (attribute-string (normalize "valign") entry)
							 | 
						||
| 
								 | 
							
											 (if (attribute-string (normalize "valign") row)
							 | 
						||
| 
								 | 
							
											     (attribute-string (normalize "valign") row)
							 | 
						||
| 
								 | 
							
											     (if (attribute-string (normalize "valign") tbody)
							 | 
						||
| 
								 | 
							
												 (attribute-string (normalize "valign") tbody)
							 | 
						||
| 
								 | 
							
												 %cals-valign-default%)))))
							 | 
						||
| 
								 | 
							
								    (cond
							 | 
						||
| 
								 | 
							
								     ((equal? calsvalign (normalize "top")) "TOP")
							 | 
						||
| 
								 | 
							
								     ((equal? calsvalign (normalize "middle")) "MIDDLE")
							 | 
						||
| 
								 | 
							
								     ((equal? calsvalign (normalize "bottom")) "BOTTOM")
							 | 
						||
| 
								 | 
							
								     (else "MIDDLE"))))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								;; ======================================================================
							 | 
						||
| 
								 | 
							
								;; Element rules
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(element tgroup
							 | 
						||
| 
								 | 
							
								  (let* ((wrapper   (parent (current-node)))
							 | 
						||
| 
								 | 
							
									 (frameattr (attribute-string (normalize "frame") wrapper))
							 | 
						||
| 
								 | 
							
									 (pgwide    (attribute-string (normalize "pgwide") wrapper))
							 | 
						||
| 
								 | 
							
									 (footnotes (select-elements (descendants (current-node)) 
							 | 
						||
| 
								 | 
							
												     (normalize "footnote")))
							 | 
						||
| 
								 | 
							
									 (border (if (equal? frameattr (normalize "none"))
							 | 
						||
| 
								 | 
							
										     '(("BORDER" "0"))
							 | 
						||
| 
								 | 
							
										     '(("BORDER" "1"))))
							 | 
						||
| 
								 | 
							
									 (width (if (equal? pgwide "1")
							 | 
						||
| 
								 | 
							
										    (list (list "WIDTH" ($table-width$)))
							 | 
						||
| 
								 | 
							
										    '()))
							 | 
						||
| 
								 | 
							
									 (head (select-elements (children (current-node)) (normalize "thead")))
							 | 
						||
| 
								 | 
							
									 (body (select-elements (children (current-node)) (normalize "tbody")))
							 | 
						||
| 
								 | 
							
									 (feet (select-elements (children (current-node)) (normalize "tfoot"))))
							 | 
						||
| 
								 | 
							
								    (make element gi: "TABLE"
							 | 
						||
| 
								 | 
							
									  attributes: (append
							 | 
						||
| 
								 | 
							
										       border
							 | 
						||
| 
								 | 
							
										       width
							 | 
						||
| 
								 | 
							
										       (if %cals-table-class%
							 | 
						||
| 
								 | 
							
											   (list (list "CLASS" %cals-table-class%))
							 | 
						||
| 
								 | 
							
											   '()))
							 | 
						||
| 
								 | 
							
									  (process-node-list head)
							 | 
						||
| 
								 | 
							
									  (process-node-list body)
							 | 
						||
| 
								 | 
							
									  (process-node-list feet)
							 | 
						||
| 
								 | 
							
									  (make-table-endnotes))))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(element entrytbl ;; sortof like a tgroup...
							 | 
						||
| 
								 | 
							
								  (let* ((wrapper   (parent (parent (parent (parent (current-node))))))
							 | 
						||
| 
								 | 
							
									 ;;	     table   tgroup  tbody   row  
							 | 
						||
| 
								 | 
							
									 (frameattr (attribute-string (normalize "frame") wrapper))
							 | 
						||
| 
								 | 
							
									 (tgrstyle  (attribute-string (normalize "tgroupstyle")))
							 | 
						||
| 
								 | 
							
									 (border    (if (and (or (equal? frameattr (normalize "none"))
							 | 
						||
| 
								 | 
							
												 (equal? tgrstyle (normalize "noborder")))
							 | 
						||
| 
								 | 
							
											     (not (equal? tgrstyle (normalize "border"))))
							 | 
						||
| 
								 | 
							
											'(("BORDER" "0"))
							 | 
						||
| 
								 | 
							
											'(("BORDER" "1"))))
							 | 
						||
| 
								 | 
							
									 (head (select-elements (children (current-node)) (normalize "thead")))
							 | 
						||
| 
								 | 
							
									 (body (select-elements (children (current-node)) (normalize "tbody"))))
							 | 
						||
| 
								 | 
							
								    (make element gi: "TABLE"
							 | 
						||
| 
								 | 
							
									  attributes: (append
							 | 
						||
| 
								 | 
							
										       border
							 | 
						||
| 
								 | 
							
										       (if %cals-table-class%
							 | 
						||
| 
								 | 
							
											   (list (list "CLASS" %cals-table-class%))
							 | 
						||
| 
								 | 
							
											   '()))
							 | 
						||
| 
								 | 
							
									  (process-node-list head)
							 | 
						||
| 
								 | 
							
									  (process-node-list body))))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(element colspec
							 | 
						||
| 
								 | 
							
								  (empty-sosofo))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(element spanspec
							 | 
						||
| 
								 | 
							
								  (empty-sosofo))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(element thead
							 | 
						||
| 
								 | 
							
								  (if %html40%
							 | 
						||
| 
								 | 
							
								      (make element gi: "THEAD"
							 | 
						||
| 
								 | 
							
									    ($process-table-body$ (current-node)))
							 | 
						||
| 
								 | 
							
								      ($process-table-body$ (current-node))))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(element tfoot
							 | 
						||
| 
								 | 
							
								  (if %html40%
							 | 
						||
| 
								 | 
							
								      (make element gi: "TFOOT"
							 | 
						||
| 
								 | 
							
									    ($process-table-body$ (current-node)))
							 | 
						||
| 
								 | 
							
								      ($process-table-body$ (current-node))))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(element tbody
							 | 
						||
| 
								 | 
							
								  (if %html40%
							 | 
						||
| 
								 | 
							
								      (make element gi: "TBODY"
							 | 
						||
| 
								 | 
							
									    ($process-table-body$ (current-node)))
							 | 
						||
| 
								 | 
							
								      ($process-table-body$ (current-node))))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(element row
							 | 
						||
| 
								 | 
							
								  (empty-sosofo)) ;; this should never happen, they're processed explicitly
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(element entry
							 | 
						||
| 
								 | 
							
								  (empty-sosofo)) ;; this should never happen, they're processed explicitly
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								;; ======================================================================
							 | 
						||
| 
								 | 
							
								;; Functions that handle processing of table bodies, rows, and cells
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(define ($process-table-body$ body)
							 | 
						||
| 
								 | 
							
								  (let* ((tgroup (find-tgroup body))
							 | 
						||
| 
								 | 
							
									 (cols   (string->number (attribute-string (normalize "cols") 
							 | 
						||
| 
								 | 
							
														   tgroup))))
							 | 
						||
| 
								 | 
							
								    (let loop ((rows (select-elements (children body) (normalize "row")))
							 | 
						||
| 
								 | 
							
									       (overhang (constant-list 0 cols)))
							 | 
						||
| 
								 | 
							
								      (if (node-list-empty? rows)
							 | 
						||
| 
								 | 
							
									  (empty-sosofo)
							 | 
						||
| 
								 | 
							
									  (make sequence
							 | 
						||
| 
								 | 
							
									    ($process-row$ (node-list-first rows) overhang)
							 | 
						||
| 
								 | 
							
									    (loop (node-list-rest rows)
							 | 
						||
| 
								 | 
							
										  (update-overhang (node-list-first rows) overhang)))))))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(define ($process-row$ row overhang)
							 | 
						||
| 
								 | 
							
								  (let* ((tgroup (find-tgroup row))
							 | 
						||
| 
								 | 
							
									 (rowcells (node-list-filter-out-pis (children row)))
							 | 
						||
| 
								 | 
							
									 (maxcol (string->number (attribute-string (normalize "cols") tgroup)))
							 | 
						||
| 
								 | 
							
									 (lastentry (node-list-last rowcells))
							 | 
						||
| 
								 | 
							
									 (table  (ancestor-member tgroup (list (normalize "table")
							 | 
						||
| 
								 | 
							
													       (normalize "informaltable"))))
							 | 
						||
| 
								 | 
							
									 (rowsep (if (attribute-string (normalize "rowsep") row)
							 | 
						||
| 
								 | 
							
										     (attribute-string (normalize "rowsep") row)
							 | 
						||
| 
								 | 
							
										     (if (attribute-string (normalize "rowsep") tgroup)
							 | 
						||
| 
								 | 
							
											 (attribute-string (normalize "rowsep") tgroup)
							 | 
						||
| 
								 | 
							
											 (if (attribute-string (normalize "rowsep") table)
							 | 
						||
| 
								 | 
							
											     (attribute-string (normalize "rowsep") table)
							 | 
						||
| 
								 | 
							
											     %cals-rule-default%))))
							 | 
						||
| 
								 | 
							
									 (after-row-border (if rowsep
							 | 
						||
| 
								 | 
							
											       (> (string->number rowsep) 0)
							 | 
						||
| 
								 | 
							
											       #f)))
							 | 
						||
| 
								 | 
							
								    (make element gi: "TR"
							 | 
						||
| 
								 | 
							
									  (let loop ((cells rowcells)
							 | 
						||
| 
								 | 
							
										     (prevcell (empty-node-list)))
							 | 
						||
| 
								 | 
							
									    (if (node-list-empty? cells)
							 | 
						||
| 
								 | 
							
										(empty-sosofo)
							 | 
						||
| 
								 | 
							
										(make sequence
							 | 
						||
| 
								 | 
							
										  ($process-cell$ (node-list-first cells) 
							 | 
						||
| 
								 | 
							
												  prevcell overhang)
							 | 
						||
| 
								 | 
							
										  (loop (node-list-rest cells) 
							 | 
						||
| 
								 | 
							
											(node-list-first cells)))))
							 | 
						||
| 
								 | 
							
									  
							 | 
						||
| 
								 | 
							
									  ;; add any necessary empty cells to the end of the row
							 | 
						||
| 
								 | 
							
									  (let loop ((colnum (overhang-skip overhang
							 | 
						||
| 
								 | 
							
													    (+ (cell-column-number 
							 | 
						||
| 
								 | 
							
														lastentry overhang)
							 | 
						||
| 
								 | 
							
													       (hspan lastentry)))))
							 | 
						||
| 
								 | 
							
									    (if (> colnum maxcol)
							 | 
						||
| 
								 | 
							
										(empty-sosofo)
							 | 
						||
| 
								 | 
							
										(make sequence
							 | 
						||
| 
								 | 
							
										  (make element gi: "TD"
							 | 
						||
| 
								 | 
							
											(make entity-ref name: "nbsp"))
							 | 
						||
| 
								 | 
							
										  (loop (overhang-skip overhang (+ colnum 1)))))))))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(define (empty-cell? entry) 
							 | 
						||
| 
								 | 
							
								  ;; Return #t if and only if entry is empty (or contains only PIs)
							 | 
						||
| 
								 | 
							
								  (let loop ((nl (children entry)))
							 | 
						||
| 
								 | 
							
								    (if (node-list-empty? nl)
							 | 
						||
| 
								 | 
							
									#t
							 | 
						||
| 
								 | 
							
									(let* ((node       (node-list-first nl))
							 | 
						||
| 
								 | 
							
									       (nodeclass  (node-property 'class-name node))
							 | 
						||
| 
								 | 
							
									       (nodechar   (if (equal? nodeclass 'data-char)
							 | 
						||
| 
								 | 
							
											       (node-property 'char node)
							 | 
						||
| 
								 | 
							
											       #f))
							 | 
						||
| 
								 | 
							
									       (whitespace? (and (equal? nodeclass 'data-char)
							 | 
						||
| 
								 | 
							
												(or (equal? nodechar #\space)
							 | 
						||
| 
								 | 
							
												    (equal? (data node) "	")
							 | 
						||
| 
								 | 
							
												    (equal? (data node) "
")
							 | 
						||
| 
								 | 
							
												    (equal? (data node) "
")))))
							 | 
						||
| 
								 | 
							
									  (if (not (or (equal? (node-property 'class-name node) 'pi)
							 | 
						||
| 
								 | 
							
										       whitespace?))
							 | 
						||
| 
								 | 
							
									      #f
							 | 
						||
| 
								 | 
							
									      (loop (node-list-rest nl)))))))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(define ($process-cell$ entry preventry overhang)
							 | 
						||
| 
								 | 
							
								  (let* ((colnum (cell-column-number entry overhang))
							 | 
						||
| 
								 | 
							
									 (lastcellcolumn (if (node-list-empty? preventry)
							 | 
						||
| 
								 | 
							
											     0
							 | 
						||
| 
								 | 
							
											     (- (+ (cell-column-number preventry overhang)
							 | 
						||
| 
								 | 
							
												   (hspan preventry))
							 | 
						||
| 
								 | 
							
												1)))
							 | 
						||
| 
								 | 
							
									 (lastcolnum (if (> lastcellcolumn 0)
							 | 
						||
| 
								 | 
							
											 (overhang-skip overhang lastcellcolumn)
							 | 
						||
| 
								 | 
							
											 0))
							 | 
						||
| 
								 | 
							
									 (htmlgi (if (have-ancestor? (normalize "tbody") entry)
							 | 
						||
| 
								 | 
							
										     "TD"
							 | 
						||
| 
								 | 
							
										     "TH")))
							 | 
						||
| 
								 | 
							
								    (make sequence
							 | 
						||
| 
								 | 
							
								      (if (node-list-empty? (preced entry))
							 | 
						||
| 
								 | 
							
									  (if (attribute-string (normalize "id") (parent entry))
							 | 
						||
| 
								 | 
							
									      (make element gi: "A"
							 | 
						||
| 
								 | 
							
										    attributes: (list
							 | 
						||
| 
								 | 
							
												 (list
							 | 
						||
| 
								 | 
							
												  "NAME"
							 | 
						||
| 
								 | 
							
												  (attribute-string (normalize "id")
							 | 
						||
| 
								 | 
							
														    (parent entry))))
							 | 
						||
| 
								 | 
							
										    (empty-sosofo))
							 | 
						||
| 
								 | 
							
									      (empty-sosofo))
							 | 
						||
| 
								 | 
							
									  (empty-sosofo))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      (if (attribute-string (normalize "id") entry)
							 | 
						||
| 
								 | 
							
									  (make element gi: "A"
							 | 
						||
| 
								 | 
							
										attributes: (list
							 | 
						||
| 
								 | 
							
											     (list
							 | 
						||
| 
								 | 
							
											      "NAME"
							 | 
						||
| 
								 | 
							
											      (attribute-string (normalize "id") entry)))
							 | 
						||
| 
								 | 
							
										(empty-sosofo))
							 | 
						||
| 
								 | 
							
									  (empty-sosofo))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      ;; This is a little bit complicated.  We want to output empty cells
							 | 
						||
| 
								 | 
							
								      ;; to skip over missing data.  We start count at the column number
							 | 
						||
| 
								 | 
							
								      ;; arrived at by adding 1 to the column number of the previous entry
							 | 
						||
| 
								 | 
							
								      ;; and skipping over any MOREROWS overhanging entrys.  Then for each
							 | 
						||
| 
								 | 
							
								      ;; iteration, we add 1 and skip over any overhanging entrys.
							 | 
						||
| 
								 | 
							
								      (let loop ((count (overhang-skip overhang (+ lastcolnum 1))))
							 | 
						||
| 
								 | 
							
									(if (>= count colnum)
							 | 
						||
| 
								 | 
							
									    (empty-sosofo)
							 | 
						||
| 
								 | 
							
									    (make sequence
							 | 
						||
| 
								 | 
							
									      (make element gi: htmlgi
							 | 
						||
| 
								 | 
							
										    (make entity-ref name: "nbsp")
							 | 
						||
| 
								 | 
							
								;;		  (literal (number->string lastcellcolumn) ", ")
							 | 
						||
| 
								 | 
							
								;;		  (literal (number->string lastcolnum) ", ")
							 | 
						||
| 
								 | 
							
								;;		  (literal (number->string (hspan preventry)) ", ")
							 | 
						||
| 
								 | 
							
								;;		  (literal (number->string colnum ", "))
							 | 
						||
| 
								 | 
							
								;;		  ($debug-pr-overhang$ overhang)
							 | 
						||
| 
								 | 
							
										    )
							 | 
						||
| 
								 | 
							
									      (loop (overhang-skip overhang (+ count 1))))))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								;      (if (equal? (gi entry) (normalize "entrytbl"))
							 | 
						||
| 
								 | 
							
								;	  (make element gi: htmlgi
							 | 
						||
| 
								 | 
							
								;		(literal "ENTRYTBL not supported."))
							 | 
						||
| 
								 | 
							
									  (make element gi: htmlgi
							 | 
						||
| 
								 | 
							
										attributes: (append
							 | 
						||
| 
								 | 
							
											     (if (> (hspan entry) 1)
							 | 
						||
| 
								 | 
							
												 (list (list "COLSPAN" (number->string (hspan entry))))
							 | 
						||
| 
								 | 
							
												 '())
							 | 
						||
| 
								 | 
							
											     (if (> (vspan entry) 1)
							 | 
						||
| 
								 | 
							
												 (list (list "ROWSPAN" (number->string (vspan entry))))
							 | 
						||
| 
								 | 
							
												 '())
							 | 
						||
| 
								 | 
							
											     (if (equal? (cell-colwidth entry colnum) "")
							 | 
						||
| 
								 | 
							
												 '()
							 | 
						||
| 
								 | 
							
												 (list (list "WIDTH" (cell-colwidth entry colnum))))
							 | 
						||
| 
								 | 
							
											     (list (list "ALIGN" (cell-align entry colnum)))
							 | 
						||
| 
								 | 
							
											     (list (list "VALIGN" (cell-valign entry colnum))))
							 | 
						||
| 
								 | 
							
										(if (empty-cell? entry) 
							 | 
						||
| 
								 | 
							
										    (make entity-ref name: "nbsp")
							 | 
						||
| 
								 | 
							
										    (if (equal? (gi entry) (normalize "entrytbl"))
							 | 
						||
| 
								 | 
							
											(process-node-list entry)
							 | 
						||
| 
								 | 
							
											(process-node-list (children entry))))))))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								;; EOF dbtable.dsl
							 | 
						||
| 
								 | 
							
								
							 |