Changes from V200-alpha3 of PLT.
This commit is contained in:
		
							parent
							
								
									29161884e9
								
							
						
					
					
						commit
						75633864c3
					
				|  | @ -31,6 +31,11 @@ Functions | |||
|        reads in an XML document from the given or current input port | ||||
|        XML documents contain exactly one element.  It throws an xml-read:error | ||||
|        if there isn't any element or if there are more than one element. | ||||
|         | ||||
|        Malformed xml is reported with source locations in | ||||
|        the form `l.c/o', where l is the line number, c is | ||||
|        the column number and o is the number of characters | ||||
|        from the beginning of the file. | ||||
| 
 | ||||
| > write-xml : Document [Output-port] -> Void | ||||
|        writes a document to the given or current output port, currently | ||||
|  | @ -131,50 +136,148 @@ Note: Users of the XML collection don't need to know most of these definitions. | |||
| Note: Xexpr is the only important one to understand.  Even then, | ||||
|       Processing-instructions may be ignored. | ||||
| 
 | ||||
| > Xexpr ::= String | ||||
|          |  (list* Symbol (listof (list Symbol String)) (list Xexpr)) | ||||
|          |  (cons Symbol (listof Xexpr)) ;; an element with no attributes | ||||
|          |  Symbol ;; symbolic entities such as   | ||||
|          |  Number ;; numeric entities like  | ||||
|          |  Misc | ||||
| > Xexpr = String | ||||
|         |  (list* Symbol (listof (list Symbol String)) (list Xexpr)) | ||||
|         |  (cons Symbol (listof Xexpr)) ;; an element with no attributes | ||||
|         |  Symbol ;; symbolic entities such as   | ||||
|         |  Number ;; numeric entities like  | ||||
|         |  Misc | ||||
| 
 | ||||
| > Document ::= (make-document Prolog Element (listof Processing-instruction)) | ||||
| > Document = (make-document Prolog Element (listof Processing-instruction)) | ||||
|   (define-struct document (prolog element misc)) | ||||
| 
 | ||||
| > Prolog ::= (make-prolog (listof Misc) #f) | ||||
|   (define-struct prolog (misc dtd)) | ||||
| > Prolog = (make-prolog (listof Misc) Document-type [Misc ...]) | ||||
|   (define-struct prolog (misc dtd misc2)) | ||||
|   The last field is a (listof Misc), but the maker accepts optional | ||||
|   arguments instead for backwards compatibility. | ||||
| 
 | ||||
| > Element ::= (make-element Location Location | ||||
| > Document-type = #f | (make-document-type Symbol External-dtd #f) | ||||
|   (define-struct document-type (name external inlined)) | ||||
| 
 | ||||
| > External-dtd = (make-external-dtd/public str str) | ||||
|                | (make-external-dtd/system str) | ||||
|                | #f | ||||
|   (define-struct external-dtd (system)) | ||||
|   (define-struct (external-dtd/public external-dtd) (public)) | ||||
|   (define-struct (external-dtd/system external-dtd) ()) | ||||
| 
 | ||||
| > Element = (make-element Location Location | ||||
| 			    Symbol | ||||
| 			    (listof Attribute) | ||||
| 			    (listof Content)) | ||||
|   (define-struct (element struct:source) (name attributes content)) | ||||
| 
 | ||||
| > Attribute ::= (make-attribute Location Location Symbol String) | ||||
| > Attribute = (make-attribute Location Location Symbol String) | ||||
|   (define-struct (attribute struct:source) (name value)) | ||||
| 
 | ||||
| > Content ::= Pcdata | ||||
|            |  Element | ||||
|            |  Entity | ||||
|            |  Misc | ||||
| > Content = Pcdata | ||||
|           |  Element | ||||
|           |  Entity | ||||
|           |  Misc | ||||
| 
 | ||||
|   Misc ::= Comment | ||||
|         |  Processing-instruction | ||||
|   Misc = Comment | ||||
|        |  Processing-instruction | ||||
| 
 | ||||
| > Pcdata ::= (make-pcdata Location Location String) | ||||
| > Pcdata = (make-pcdata Location Location String) | ||||
|   (define-struct (pcdata struct:source) (string)) | ||||
| 
 | ||||
| > Entity ::= (make-entity (U Nat Symbol)) | ||||
| > Entity = (make-entity (U Nat Symbol)) | ||||
|   (define-struct entity (text)) | ||||
| 
 | ||||
| > Processing-instruction ::= (make-pi Location Location String (list String)) | ||||
| > Processing-instruction = (make-pi Location Location String (list String)) | ||||
|   (define-struct (pi struct:source) (target-name instruction)) | ||||
| 
 | ||||
| > Comment ::= (make-comment String) | ||||
| > Comment = (make-comment String) | ||||
|   (define-struct comment (text)) | ||||
| 
 | ||||
|   Source ::= (make-source Location Location) | ||||
|   Source = (make-source Location Location) | ||||
|   (define-struct source (start stop)) | ||||
| 
 | ||||
|   Location ::= Nat | ||||
|             |  Symbol | ||||
|   Location = Nat | ||||
|            |  Symbol | ||||
| 
 | ||||
| 
 | ||||
| The PList Library | ||||
| ================= | ||||
| 
 | ||||
| Files: plist.ss | ||||
| 
 | ||||
| The PList library provides the ability to read and write xml documents which  | ||||
| conform to the "plist" DTD, used to store 'dictionaries' of string - value | ||||
| associations. | ||||
| 
 | ||||
| To Load | ||||
| ======= | ||||
| 
 | ||||
| (require (lib "plist.ss" "xml")) | ||||
| 
 | ||||
| Functions | ||||
| ========= | ||||
| 
 | ||||
| > read-plist : Port -> PLDict | ||||
|        reads a plist from a port, and produces a 'dict' x-expression   | ||||
| 
 | ||||
| > write-plist : PLDict Port -> Void | ||||
|        writes a plist to the given port.  May raise the exn:application:type | ||||
|        exception if the plist is badly formed. | ||||
| 
 | ||||
| Datatypes | ||||
| ========= | ||||
| 
 | ||||
| NB: all of these are subtypes of x-expression: | ||||
| 
 | ||||
| > PLDict = (list 'dict Assoc-pair ...) | ||||
| 
 | ||||
| > PLAssoc-pair = (list 'assoc-pair String PLValue) | ||||
| 
 | ||||
| > PLValue = String | ||||
| 	   | ||||
|           | (list 'true) | ||||
|           | (list 'false) | ||||
|           | (list 'integer Integer) | ||||
|           | (list 'real Real) | ||||
|           | PLDict | ||||
|           | PLArray | ||||
| 
 | ||||
| > PLArray = (list 'array PLValue ...) | ||||
| 
 | ||||
| In fact, the PList DTD also defines Data and Date types, but we're ignoring | ||||
| these for the moment. | ||||
| 
 | ||||
| Examples | ||||
| ======== | ||||
| 
 | ||||
| Here's a sample PLDict: | ||||
| 
 | ||||
| (define my-dict | ||||
|      `(dict (assoc-pair "first-key" | ||||
| 			"just a string | ||||
|                          with some whitespace in it") | ||||
| 	    (assoc-pair "second-key" | ||||
| 			(false)) | ||||
| 	    (assoc-pair "third-key" | ||||
| 			(dict )) | ||||
| 	    (assoc-pair "fourth-key" | ||||
| 			(dict (assoc-pair "inner-key" | ||||
| 					  (real 3.432)))) | ||||
| 	    (assoc-pair "fifth-key" | ||||
| 			(array (integer 14) | ||||
| 			       "another string" | ||||
| 			       (true))) | ||||
| 	    (assoc-pair "sixth-key" | ||||
| 			(array)))) | ||||
| 
 | ||||
| Let's write it to disk: | ||||
| 
 | ||||
|    (call-with-output-file "/Users/clements/tmp.plist" | ||||
|      (lambda (port) | ||||
|        (write-plist my-dict port)) | ||||
|      'truncate) | ||||
| 
 | ||||
| Let's read it back from the disk: | ||||
| 
 | ||||
|    (define new-dict | ||||
|      (call-with-input-file "/Users/clements/tmp.plist" | ||||
|        (lambda (port) | ||||
| 	 (read-plist port)))) | ||||
| 
 | ||||
|  |  | |||
|  | @ -106,9 +106,12 @@ | |||
| 
 | ||||
| 
 | ||||
| ;;; HACK! | ||||
| (define (make-parameter val) | ||||
|   (lambda () | ||||
|     val)) | ||||
| (define (make-parameter val . maybe-guard) | ||||
|   (if (null? maybe-guard) | ||||
|       (lambda () | ||||
| 	val) | ||||
|       (lambda () | ||||
| 	((car maybe-guard) val)))) | ||||
| 
 | ||||
| (define (list* . args) | ||||
|   (if (null? (cdr args)) | ||||
|  |  | |||
|  | @ -1,118 +1,3 @@ | |||
| ; Taken directly from the SRFI document. | ||||
| 
 | ||||
| (define-syntax let-values | ||||
|   (syntax-rules () | ||||
|     ((let-values (?binding ...) ?body0 ?body1 ...) | ||||
|      (let-values "bind" (?binding ...) () (begin ?body0 ?body1 ...))) | ||||
|      | ||||
|     ((let-values "bind" () ?tmps ?body) | ||||
|      (let ?tmps ?body)) | ||||
|      | ||||
|     ((let-values "bind" ((?b0 ?e0) ?binding ...) ?tmps ?body) | ||||
|      (let-values "mktmp" ?b0 ?e0 () (?binding ...) ?tmps ?body)) | ||||
|      | ||||
|     ((let-values "mktmp" () ?e0 ?args ?bindings ?tmps ?body) | ||||
|      (call-with-values  | ||||
|        (lambda () ?e0) | ||||
|        (lambda ?args | ||||
|          (let-values "bind" ?bindings ?tmps ?body)))) | ||||
|      | ||||
|     ((let-values "mktmp" (?a . ?b) ?e0 (?arg ...) ?bindings (?tmp ...) ?body) | ||||
|      (let-values "mktmp" ?b ?e0 (?arg ... x) ?bindings (?tmp ... (?a x)) ?body)) | ||||
|      | ||||
|     ((let-values "mktmp" ?a ?e0 (?arg ...) ?bindings (?tmp ...) ?body) | ||||
|      (call-with-values | ||||
|        (lambda () ?e0) | ||||
|        (lambda (?arg ... . x) | ||||
|          (let-values "bind" ?bindings (?tmp ... (?a x)) ?body)))))) | ||||
| 
 | ||||
| (define-syntax let*-values | ||||
|   (syntax-rules () | ||||
|     ((let*-values () ?body0 ?body1 ...) | ||||
|      (begin ?body0 ?body1 ...)) | ||||
| 
 | ||||
|     ((let*-values (?binding0 ?binding1 ...) ?body0 ?body1 ...) | ||||
|      (let-values (?binding0) | ||||
|        (let*-values (?binding1 ...) ?body0 ?body1 ...))))) | ||||
| 
 | ||||
| (define (add1 x) (+ x 1)) | ||||
| (define-syntax when | ||||
|   (syntax-rules  | ||||
|    () | ||||
|    ((when test expr ...) | ||||
|     (if test (begin expr ...))))) | ||||
| 
 | ||||
| (define-syntax unless | ||||
|   (syntax-rules | ||||
|    () | ||||
|    ((unless test expr ...) | ||||
|     (if (not test) (begin expr ...))))) | ||||
| 
 | ||||
| (define (sub1 x)  | ||||
|   (- x 1)) | ||||
| 
 | ||||
| (define (void . a)  | ||||
|   (if #f #f)) | ||||
| 
 | ||||
| (define-syntax begin0 | ||||
|   (syntax-rules | ||||
|    () | ||||
|    ((begin0 expr1 expr ...) | ||||
|     (let ((r expr1)) | ||||
|       (begin expr ...) | ||||
|       r)))) | ||||
| 
 | ||||
| (define andmap | ||||
|   (lambda (f list0 . lists) | ||||
|     (if (null? list0) | ||||
| 	(and) | ||||
| 	(let loop ((lists (cons list0 lists))) | ||||
| 	  (if (null? (cdr (car lists))) | ||||
| 	      (apply f (map car lists)) | ||||
| 	      (and (apply f (map car lists)) | ||||
| 		   (loop (map cdr lists)))))))) | ||||
| (define null '()) | ||||
| 
 | ||||
| ; stolen from mzlib/functior.ss | ||||
| (define (quicksort l less-than) | ||||
|   (let* ((v (list->vector l)) | ||||
| 	 (count (vector-length v))) | ||||
|     (let loop ((min 0)(max count)) | ||||
|       (if (< min (sub1 max)) | ||||
| 	  (let ((pval (vector-ref v min))) | ||||
| 	    (let pivot-loop ((pivot min) | ||||
| 			     (pos (add1 min))) | ||||
| 	      (if (< pos max) | ||||
| 		  (let ((cval (vector-ref v pos))) | ||||
| 		    (if (less-than cval pval) | ||||
| 			(begin | ||||
| 			  (vector-set! v pos (vector-ref v pivot)) | ||||
|                                (vector-set! v pivot cval) | ||||
|                                (pivot-loop (add1 pivot) (add1 pos))) | ||||
| 			(pivot-loop pivot (add1 pos)))) | ||||
| 		  (if (= min pivot) | ||||
| 		      (loop (add1 pivot) max) | ||||
| 		      (begin | ||||
| 			(loop min pivot) | ||||
| 			(loop pivot max)))))))) | ||||
|     (vector->list v))) | ||||
| 
 | ||||
| ;;; HACK! | ||||
| (define call/ec call-with-current-continuation) | ||||
| (define-syntax let/ec | ||||
|   (syntax-rules | ||||
|    () | ||||
|    ((let/ec k expr ...) | ||||
|     (call-with-current-continuation (lambda (k) expr ...))))) | ||||
| 
 | ||||
| 
 | ||||
| ;;; HACK! | ||||
| (define (make-parameter val) | ||||
|   (lambda () | ||||
|     val)) | ||||
| 
 | ||||
| ;;;;;;;;;;; | ||||
| 
 | ||||
| ;; Token ::= Contents | Start-tag | End-tag | Eof | ||||
| 
 | ||||
| (define read-comments (make-parameter #f)) | ||||
|  | @ -137,7 +22,7 @@ | |||
|                        (error 'read-xml "extra stuff at end of document ~a" end-of-file)) | ||||
|                      misc1)))) | ||||
| 
 | ||||
| ;; read-misc : Input-port (-> Nat) -> (listof Misc) Token | ||||
| ;; read-misc : Input-port (-> Location) -> (listof Misc) Token | ||||
| (define (read-misc in pos) | ||||
|   (let read-more () | ||||
|     (let ((x (lex in pos))) | ||||
|  | @ -149,7 +34,7 @@ | |||
|          (read-more)) | ||||
|         (else (values null x)))))) | ||||
| 
 | ||||
| ;; read-element : Start-tag Input-port (-> Nat) -> Element | ||||
| ;; read-element : Start-tag Input-port (-> Location) -> Element | ||||
| (define (read-element start in pos) | ||||
|   (let ((name (start-tag-name start)) | ||||
|         (a (source-start start)) | ||||
|  | @ -160,12 +45,19 @@ | |||
|        (let ((x (lex in pos))) | ||||
|          (cond | ||||
|            ((eof-object? x) | ||||
|             (error 'read-xml "unclosed ~a tag at [~a ~a]" name a b)) | ||||
|             (error 'read-xml "unclosed ~a tag at [~a ~a]" name  | ||||
| 		   (format-source a) | ||||
| 		   (format-source b))) | ||||
|            ((start-tag? x) (cons (read-element x in pos) (read-content))) | ||||
|            ((end-tag? x) | ||||
|             (unless (eq? name (end-tag-name x)) | ||||
|               (error 'read-xml "start tag ~a at [~a ~a] doesn't match end tag ~a at [~a ~a]" | ||||
|                      name a b (end-tag-name x) (source-start x) (source-stop x))) | ||||
| 		     name | ||||
| 		     (format-source a) | ||||
| 		     (format-source b) | ||||
| 		     (end-tag-name x) | ||||
| 		     (format-source (source-start x)) | ||||
| 		     (format-source (source-stop x)))) | ||||
|             null) | ||||
|            ((entity? x) (cons (expand-entity x) (read-content))) | ||||
|            ((comment? x) (if (read-comments) | ||||
|  | @ -191,7 +83,7 @@ | |||
|     ((apos) "'") | ||||
|     (else #f))) | ||||
| 
 | ||||
| ;; lex : Input-port (-> Nat) -> Token | ||||
| ;; lex : Input-port (-> Location) -> Token | ||||
| (define (lex in pos) | ||||
|   (let ((c (peek-char in))) | ||||
|     (cond | ||||
|  | @ -200,7 +92,7 @@ | |||
|       ((eq? c #\<) (lex-tag-cdata-pi-comment in pos)) | ||||
|       (else (lex-pcdata in pos))))) | ||||
| 
 | ||||
| ;; lex-entity : Input-port (-> Nat) -> Entity | ||||
| ;; lex-entity : Input-port (-> Location) -> Entity | ||||
| (define (lex-entity in pos) | ||||
|   (let ((start (pos))) | ||||
|     (read-char in) | ||||
|  | @ -221,7 +113,7 @@ | |||
|                        (lex-error in pos "expected ; at the end of an entity"))))))) | ||||
|       (make-entity start (pos) data)))) | ||||
| 
 | ||||
| ;; lex-tag-cdata-pi-comment : Input-port (-> Nat) -> Start-tag | Element | End-tag | Pcdata | Pi | Comment | ||||
| ;; lex-tag-cdata-pi-comment : Input-port (-> Location) -> Start-tag | Element | End-tag | Pcdata | Pi | Comment | ||||
| (define (lex-tag-cdata-pi-comment in pos) | ||||
|   (let ((start (pos))) | ||||
|     (read-char in) | ||||
|  | @ -268,9 +160,9 @@ | |||
|               (lex-error in pos "expected > to close empty element ~a" name)) | ||||
|             (make-element start (pos) name attrs null)) | ||||
|            ((#\>) (make-start-tag start (pos) name attrs)) | ||||
|            (else (lex-error in pos "expected / or > to close tag ~a" name)))))))) | ||||
|            (else (lex-error in pos "expected / or > to close tag `~a'" name)))))))) | ||||
| 
 | ||||
| ;; lex-attributes : Input-port (-> Nat) -> (listof Attribute) | ||||
| ;; lex-attributes : Input-port (-> Location) -> (listof Attribute) | ||||
| (define (lex-attributes in pos) | ||||
|   (quicksort (let loop () | ||||
|                (skip-space in) | ||||
|  | @ -285,7 +177,7 @@ | |||
|                    ((eq? na nb) (lex-error in pos "duplicated attribute name ~a" na)) | ||||
|                    (else (string<? (symbol->string na) (symbol->string nb)))))))) | ||||
| 
 | ||||
| ;; lex-attribute : Input-port (-> Nat) -> Attribute | ||||
| ;; lex-attribute : Input-port (-> Location) -> Attribute | ||||
| (define (lex-attribute in pos) | ||||
|   (let ((start (pos)) | ||||
|         (name (lex-name in pos))) | ||||
|  | @ -321,7 +213,7 @@ | |||
|         (read-char in) | ||||
|         (loop))))) | ||||
| 
 | ||||
| ;; lex-pcdata : Input-port (-> Nat) -> Pcdata | ||||
| ;; lex-pcdata : Input-port (-> Location) -> Pcdata | ||||
| ;; deviation - disallow ]]> "for compatability" with SGML, sec 2.4 XML spec  | ||||
| (define (lex-pcdata in pos) | ||||
|   (let ((start (pos)) | ||||
|  | @ -338,7 +230,7 @@ | |||
|                  (pos) | ||||
|                  (list->string data)))) | ||||
| 
 | ||||
| ;; lex-name : Input-port (-> Nat) -> Symbol | ||||
| ;; lex-name : Input-port (-> Location) -> Symbol | ||||
| (define (lex-name in pos) | ||||
|   (let ((c (read-char in))) | ||||
|     (unless (name-start? c) | ||||
|  | @ -351,7 +243,7 @@ | |||
|                    (cons (read-char in) (lex-rest))) | ||||
|                   (else null)))))))) | ||||
| 
 | ||||
| ;; skip-dtd : Input-port (-> Nat) -> Void | ||||
| ;; skip-dtd : Input-port (-> Location) -> Void | ||||
| (define (skip-dtd in pos) | ||||
|   (let skip () | ||||
|     (case (non-eof read-char in pos) | ||||
|  | @ -380,7 +272,7 @@ | |||
|       (eq? ch #\.) | ||||
|       (eq? ch #\-))) | ||||
| 
 | ||||
| ;; read-until : Char Input-port (-> Nat) -> String | ||||
| ;; read-until : Char Input-port (-> Location) -> String | ||||
| ;; discards the stop character, too | ||||
| (define (read-until char in pos) | ||||
|   (list->string | ||||
|  | @ -390,14 +282,14 @@ | |||
|          ((eq? c char) null) | ||||
|          (else (cons c (read-more)))))))) | ||||
| 
 | ||||
| ;; non-eof : (Input-port -> (U Char Eof)) Input-port (-> Nat) -> Char | ||||
| ;; non-eof : (Input-port -> (U Char Eof)) Input-port (-> Location) -> Char | ||||
| (define (non-eof f in pos) | ||||
|   (let ((c (f in))) | ||||
|     (cond | ||||
|       ((eof-object? c) (lex-error in pos "unexpected eof")) | ||||
|       (else c)))) | ||||
| 
 | ||||
| ;; gen-read-until-string : String -> Input-port (-> Nat) -> String | ||||
| ;; gen-read-until-string : String -> Input-port (-> Location) -> String | ||||
| ;; uses Knuth-Morris-Pratt from | ||||
| ;; Introduction to Algorithms, Cormen, Leiserson, and Rivest, pages 869-876 | ||||
| ;; discards stop from input | ||||
|  | @ -436,13 +328,15 @@ | |||
| (define lex-pi-data (gen-read-until-string "?>")) | ||||
| (define lex-cdata-contents (gen-read-until-string "]]>")) | ||||
| 
 | ||||
| ;; positionify : Input-port -> Input-port (-> Nat) | ||||
| ;; positionify : Input-port -> Input-port (-> Location) | ||||
| 
 | ||||
| ;; Well, this really depends on scsh-0.6 | ||||
| ;; For S48 you probably need to do something completely different | ||||
| 
 | ||||
| (define (positionify in) | ||||
|   (let ((n 0); port-limit as absolute value | ||||
|   (let ((line 1) | ||||
| 	(char 0) | ||||
| 	(offset 0) | ||||
| 	(old-handler (port-handler in))) | ||||
|     (let ((handler (make-buffered-input-port-handler | ||||
| 		    (port-handler-discloser old-handler) | ||||
|  | @ -452,17 +346,32 @@ | |||
| 			     ((port-handler-buffer-proc old-handler)  | ||||
| 			      data buffer start needed))) | ||||
| 			(if (number? res) | ||||
| 			    (set! n (+ n res))) | ||||
| 			    (begin | ||||
| 			      (set! char (add1 char)) | ||||
| 			      (set! offset (add1 offset)) | ||||
| 			      (let ((c (peek-char in))) | ||||
| 				(when (equal? c #\newline) | ||||
| 				      (set! line (+ line 1)) | ||||
| 				      (set! char 0)) | ||||
| 				c))) | ||||
| 			res)) | ||||
| 		    (port-handler-ready? old-handler) | ||||
| 		    (port-handler-steal old-handler)))) | ||||
|       (set-port-handler! in handler) | ||||
|       (values in | ||||
| 	      (lambda () | ||||
| 		(- n (- (port-limit in) (port-index in)))))))) | ||||
| 		(make-location line char offset)))))) | ||||
| ;		(- n (- (port-limit in) (port-index in)))))))) | ||||
| 
 | ||||
| ;; lex-error : Input-port String (-> Nat) TST* -> alpha | ||||
| ;; lex-error : Input-port String (-> Location) TST* -> alpha | ||||
| (define (lex-error in pos str . rest) | ||||
|   (error 'lex-error " at positon:" (pos) str rest)) | ||||
|   (error 'lex-error " at position:" (format-source (pos)) str rest)) | ||||
| 
 | ||||
| ;; format-source : Location -> string | ||||
| ;; to format the source location for an error message | ||||
| (define (format-source loc) | ||||
|   (if (location? loc) | ||||
|       (format #f "~a.~a/~a" (location-line loc) (location-char loc) (location-offset loc)) | ||||
|       (format #f "~a" loc))) | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,8 +1,15 @@ | |||
| ;; Location ::= Nat | Symbol | ||||
| ; Location = (make-location Nat Nat) | Symbol | ||||
| (define-record-type location :location | ||||
|   (make-location line char offset) | ||||
|   location? | ||||
|   (line location-line) | ||||
|   (char location-char) | ||||
|   (offset location-offset)) | ||||
| 
 | ||||
| ;; Source ::= (make-source Location Location) | ||||
| (define-record-type source :source | ||||
|   (make-source start stop) | ||||
|   source? | ||||
|   really-source? | ||||
|   (start really-source-start) | ||||
|   (stop really-source-stop)) | ||||
|   | ||||
|  | @ -26,6 +33,16 @@ | |||
| 	((end-tag? obj) (end-tag-stop obj)) | ||||
| 	(else (really-source-stop obj)))) | ||||
| 
 | ||||
| (define (does-any-satisfy? preds obj) | ||||
|     (if (null? preds) | ||||
| 	#f | ||||
| 	(or ((car preds) obj) (does-any-satisfy? (cdr preds) obj)))) | ||||
| 
 | ||||
| (define (source? obj) | ||||
|   (does-any-satisfy? (list really-source? element? attribute? pcdata?  | ||||
| 			   entity? pi? start-tag? end-tag?) | ||||
| 		     obj)) | ||||
| 
 | ||||
| ;; Document ::= (make-document Prolog Element (listof Misc)) | ||||
| (define-record-type document :document | ||||
|   (make-document prolog element misc) | ||||
|  | @ -34,12 +51,64 @@ | |||
|   (element document-element) | ||||
|   (misc document-misc)) | ||||
| 
 | ||||
| ;; Prolog ::= (make-prolog (listof Misc) #f) | ||||
|       ; Prolog = (make-prolog (listof Misc) Document-type [Misc ...]) | ||||
|       ; The Misc items after the Document-type are optional arguments to maintain | ||||
|       ; backward compatability with older versions of the XML library. | ||||
|       ;(define-struct prolog (misc dtd misc2)) | ||||
| 
 | ||||
| (define-record-type prolog :prolog | ||||
|   (make-prolog misc dtd) | ||||
|   (really-make-prolog misc dtd misc2) | ||||
|   prolog? | ||||
|   (misc prolog-misc) | ||||
|   (dtd prolog-dtd)) | ||||
|   (dtd prolog-dtd) | ||||
|   (misc2 prolog-misc2)) | ||||
| 
 | ||||
| (define (make-prolog misc dtd misc2) | ||||
|   (really-make-prolog misc dtd misc2)) | ||||
| 
 | ||||
| ;;; Document-type = (make-document-type sym External-dtd #f) | ||||
| ;;;               | #f | ||||
| 
 | ||||
| (define-record-type document-type :document-type | ||||
|   (make-document-type name external inlined) | ||||
|   really-document-type? | ||||
|   (name document-type-name) | ||||
|   (external document-type-external) | ||||
|   (inlined document-type-inlined)) | ||||
| 
 | ||||
| ;;; External-dtd = (make-external-dtd/public str str) | ||||
| ;;;              | (make-external-dtd/system str) | ||||
| ;;;              | #f | ||||
| (define-record-type external-dtd :external-dtd | ||||
|   (make-external-dtd system) | ||||
|   really-external-dtd? | ||||
|   (system really-external-dtd-system)) | ||||
| 
 | ||||
| (define (external-dtd-system external-dtd) | ||||
|   (cond ((really-external-dtd? external-dtd) | ||||
| 	 (really-external-dtd-system external-dtd)) | ||||
| 	((external-dtd/public? external-dtd) | ||||
| 	 (external-dtd/public-system external-dtd)) | ||||
| 	((external-dtd/system? external-dtd) | ||||
| 	 (external-dtd/system-system external-dtd)) | ||||
| 	(else (error "bottom of external-dtd-system" external-dtd)))) | ||||
| 
 | ||||
| (define (external-dtd? obj) | ||||
|   (does-any-satisfy? (list really-external-dtd? external-dtd/public?  | ||||
| 			   external-dtd/system?) | ||||
| 		     obj)) | ||||
| 
 | ||||
| (define-record-type external-dtd/public :external-dtd/public | ||||
|   (make-external-dtd/public system public) | ||||
|   external-dtd/public? | ||||
|   (system external-dtd/public-system) | ||||
|   (public external-dtd/public-public)) | ||||
| 
 | ||||
| (define-record-type external-dtd/system :external-dtd/system | ||||
|   (make-external-dtd/system system) | ||||
|   external-dtd/system? | ||||
|   (system external-dtd/system-system)) | ||||
| 
 | ||||
| 
 | ||||
| ;; Element ::= (make-element Location Location Symbol (listof Attribute) (listof Content)) | ||||
| (define-record-type element :element | ||||
|  |  | |||
|  | @ -3,7 +3,12 @@ | |||
| ;;(define empty-tag-shorthand (make-parameter void)) | ||||
| 
 | ||||
| ;; (empty-tag-shorthand) : (U 'always 'never (listof Symbol)) | ||||
| (define empty-tag-shorthand (make-parameter 'always)) | ||||
| (define empty-tag-shorthand  | ||||
|   (make-parameter 'always  | ||||
| 		  (lambda (x) | ||||
| 		    (if (or (eq? x 'always) (eq? x 'never) (and (list? x) (andmap symbol? x))) | ||||
| 			x | ||||
| 			(error 'empty-tag-shorthand "expected 'always, 'never, or a list of symbols: received ~a" x))))) | ||||
| 
 | ||||
| (define html-empty-tags '(param meta link isindex input img hr frame col br basefont base area)) | ||||
| 
 | ||||
|  | @ -16,7 +21,8 @@ | |||
| 
 | ||||
| ;; gen-write/display-xml/content : (Nat Output-port -> Void) -> Content [Output-Port]-> Void | ||||
| (define (gen-write/display-xml/content dent) | ||||
|   (var-argify (lambda (c out) (write-xml-content c 0 dent out)))) | ||||
|   (var-argify (lambda (c out)  | ||||
| 		(write-xml-content c 0 dent out)))) | ||||
| 
 | ||||
| ;; indent : Nat Output-port -> Void | ||||
| (define (indent n out) | ||||
|  | @ -35,9 +41,28 @@ | |||
| ;; gen-write/display-xml : (Content [Output-port] -> Void) -> Document [Output-port] -> Void | ||||
| (define (gen-write/display-xml output-content) | ||||
|   (var-argify (lambda (doc out) | ||||
|                 (display-outside-misc (prolog-misc (document-prolog doc)) out) | ||||
|                 (output-content (document-element doc) out) | ||||
|                 (display-outside-misc (document-misc doc) out)))) | ||||
| 		(let ((prolog (document-prolog doc))) | ||||
| 		  (display-outside-misc (prolog-misc prolog) out) | ||||
| 		  (display-dtd (prolog-dtd prolog) out) | ||||
| 		  (display-outside-misc (prolog-misc2 prolog) out)) | ||||
| 		(output-content (document-element doc) out) | ||||
| 		(display-outside-misc (document-misc doc) out)))) | ||||
| 
 | ||||
| ; display-dtd : document-type oport -> void | ||||
| (define (display-dtd dtd out) | ||||
|   (when dtd | ||||
| 	(fprintf out "<!DOCTYPE ~a" (document-type-name dtd)) | ||||
| 	(let ((external (document-type-external dtd))) | ||||
| 	  (cond | ||||
| 	   ((external-dtd/public? external) | ||||
| 	    (fprintf out " PUBLIC \"~a\" \"~a\"" | ||||
| 		     (external-dtd/public-public external) | ||||
| 		     (external-dtd-system external))) | ||||
| 	   ((external-dtd/system? external) | ||||
| 	    (fprintf out " SYSTEM \"~a\"" (external-dtd-system external))) | ||||
| 	   ((not external) (void)))) | ||||
| 	(display ">" out) | ||||
| 	(newline out))) | ||||
| 
 | ||||
| ;; write-xml : Document [Output-port] -> Void | ||||
| (define write-xml (gen-write/display-xml write-xml/content)) | ||||
|  | @ -50,7 +75,8 @@ | |||
|   (for-each (lambda (x) | ||||
|               ((cond | ||||
|                  ((comment? x) write-xml-comment) | ||||
|                  ((pi? x) write-xml-pi)) x 0 void out) | ||||
|                  ((pi? x) write-xml-pi) | ||||
| 		 (else (error "bottom " x))) x 0 void out) | ||||
|               (newline out)) | ||||
|             misc)) | ||||
|    | ||||
|  |  | |||
|  | @ -1,8 +1,13 @@ | |||
| (define-interface xml-structures-interface | ||||
|   (export source-start | ||||
| 	  source-stop | ||||
| 	  make-location location? location-line location-char location-offset | ||||
| 	  make-document document? document-prolog document-element document-misc | ||||
| 	  make-prolog prolog? prolog-misc prolog-dtd | ||||
| 	  make-prolog prolog? prolog-misc prolog-dtd prolog-misc2  | ||||
| 	  make-document-type document-type-name document-type-external  | ||||
| 	  external-dtd-system external-dtd/system? | ||||
| 	  make-external-dtd/public external-dtd/public? external-dtd/public-public  | ||||
| 	  make-external-dtd/system  | ||||
| 	  make-element element? element-name element-attributes element-content | ||||
| 	  make-attribute attribute? attribute-name attribute-value | ||||
| 	  make-pcdata pcdata? pcdata-string | ||||
|  | @ -15,6 +20,7 @@ | |||
| 
 | ||||
| (define-structure xml-structures xml-structures-interface | ||||
|   (open scheme | ||||
| 	signals | ||||
| 	extended-ports | ||||
| 	define-record-types) | ||||
|   (files structures)) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 mainzelm
						mainzelm