summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--guix/read-print.scm46
-rw-r--r--tests/read-print.scm22
2 files changed, 65 insertions, 3 deletions
diff --git a/guix/read-print.scm b/guix/read-print.scm
index 2b626ba2811..33ed6e3dbe1 100644
--- a/guix/read-print.scm
+++ b/guix/read-print.scm
@@ -35,6 +35,9 @@
35 vertical-space-height 35 vertical-space-height
36 canonicalize-vertical-space 36 canonicalize-vertical-space
37 37
38 page-break
39 page-break?
40
38 comment 41 comment
39 comment? 42 comment?
40 comment->string 43 comment->string
@@ -83,6 +86,18 @@
83 "Return a vertical space corresponding to a single blank line." 86 "Return a vertical space corresponding to a single blank line."
84 unit))) 87 unit)))
85 88
89(define <page-break>
90 (make-record-type '<page-break> '()
91 #:parent <blank>
92 #:extensible? #f))
93
94(define page-break? (record-predicate <page-break>))
95(define page-break
96 (let ((break ((record-type-constructor <page-break>))))
97 (lambda ()
98 break)))
99
100
86(define <comment> 101(define <comment>
87 ;; Comments. 102 ;; Comments.
88 (make-record-type '<comment> '(str margin?) 103 (make-record-type '<comment> '(str margin?)
@@ -105,12 +120,17 @@ end with newline, otherwise an error is raised."
105 (&message (message "invalid comment string"))))) 120 (&message (message "invalid comment string")))))
106 (string->comment str margin?)) 121 (string->comment str margin?))
107 122
123(define char-set:whitespace-sans-page-break
124 ;; White space, excluding #\page.
125 (char-set-difference char-set:whitespace (char-set #\page)))
126
127(define (space? chr)
128 "Return true if CHR is white space, except for page breaks."
129 (char-set-contains? char-set:whitespace-sans-page-break chr))
130
108(define (read-vertical-space port) 131(define (read-vertical-space port)
109 "Read from PORT until a non-vertical-space character is met, and return a 132 "Read from PORT until a non-vertical-space character is met, and return a
110single <vertical-space> record." 133single <vertical-space> record."
111 (define (space? chr)
112 (char-set-contains? char-set:whitespace chr))
113
114 (let loop ((height 1)) 134 (let loop ((height 1))
115 (match (read-char port) 135 (match (read-char port)
116 (#\newline (loop (+ 1 height))) 136 (#\newline (loop (+ 1 height)))
@@ -118,6 +138,15 @@ single <vertical-space> record."
118 ((? space?) (loop height)) 138 ((? space?) (loop height))
119 (chr (unread-char chr port) (vertical-space height))))) 139 (chr (unread-char chr port) (vertical-space height)))))
120 140
141(define (read-until-end-of-line port)
142 "Read white space from PORT until the end of line, included."
143 (let loop ()
144 (match (read-char port)
145 (#\newline #t)
146 ((? eof-object?) #t)
147 ((? space?) (loop))
148 (chr (unread-char chr port)))))
149
121(define (read-with-comments port) 150(define (read-with-comments port)
122 "Like 'read', but include <blank> objects when they're encountered." 151 "Like 'read', but include <blank> objects when they're encountered."
123 ;; Note: Instead of implementing this functionality in 'read' proper, which 152 ;; Note: Instead of implementing this functionality in 'read' proper, which
@@ -148,6 +177,11 @@ single <vertical-space> record."
148 (if blank-line? 177 (if blank-line?
149 (read-vertical-space port) 178 (read-vertical-space port)
150 (loop #t return))) 179 (loop #t return)))
180 ((eqv? chr #\page)
181 ;; Assume that a page break is on a line of its own and read
182 ;; subsequent white space and newline.
183 (read-until-end-of-line port)
184 (page-break))
151 ((char-set-contains? char-set:whitespace chr) 185 ((char-set-contains? char-set:whitespace chr)
152 (loop blank-line? return)) 186 (loop blank-line? return))
153 ((memv chr '(#\( #\[)) 187 ((memv chr '(#\( #\[))
@@ -444,6 +478,12 @@ FORMAT-VERTICAL-SPACE; a useful value of 'canonicalize-vertical-space'."
444 (loop (- i 1)))) 478 (loop (- i 1))))
445 (display (make-string indent #\space) port) 479 (display (make-string indent #\space) port)
446 indent) 480 indent)
481 ((? page-break?)
482 (unless delimited? (newline port))
483 (display #\page port)
484 (newline port)
485 (display (make-string indent #\space) port)
486 indent)
447 (('quote lst) 487 (('quote lst)
448 (unless delimited? (display " " port)) 488 (unless delimited? (display " " port))
449 (display "'" port) 489 (display "'" port)
diff --git a/tests/read-print.scm b/tests/read-print.scm
index f915b7e2d21..70be7754f8a 100644
--- a/tests/read-print.scm
+++ b/tests/read-print.scm
@@ -70,6 +70,21 @@
70 (read-with-comments port) 70 (read-with-comments port)
71 (read-with-comments port))))) 71 (read-with-comments port)))))
72 72
73(test-equal "read-with-comments: top-level page break"
74 (list (comment ";; Begin.\n") (vertical-space 1)
75 (page-break)
76 (comment ";; End.\n"))
77 (call-with-input-string "\
78;; Begin.
79
80
81;; End.\n"
82 (lambda (port)
83 (list (read-with-comments port)
84 (read-with-comments port)
85 (read-with-comments port)
86 (read-with-comments port)))))
87
73(test-pretty-print "(list 1 2 3 4)") 88(test-pretty-print "(list 1 2 3 4)")
74(test-pretty-print "((a . 1) (b . 2))") 89(test-pretty-print "((a . 1) (b . 2))")
75(test-pretty-print "(a b c . boom)") 90(test-pretty-print "(a b c . boom)")
@@ -229,6 +244,13 @@ mnopqrstuvwxyz.\")"
229 ;; Comment after blank line. 244 ;; Comment after blank line.
230 two)") 245 two)")
231 246
247(test-pretty-print "\
248(begin
249 break
250
251 ;; page break above
252 end)")
253
232(test-equal "pretty-print-with-comments, canonicalize-comment" 254(test-equal "pretty-print-with-comments, canonicalize-comment"
233 "\ 255 "\
234(list abc 256(list abc