#lang scribble/doc @(require "mz.ss") @title{Printer Extension} @defthing[prop:custom-write struct-type-property?]{ Associates a procedure to a structure type to used by the default printer to @scheme[display] or @scheme[write] (or @scheme[print]) instances of the structure type. @moreref["structprops"]{structure type properties} The procedure for a @scheme[prop:custom-write] value takes three arguments: the structure to be printed, the target port, and a boolean that is @scheme[#t] for @scheme[write] mode and @scheme[#f] for @scheme[display] mode. The procedure should print the value to the given port using @scheme[write], @scheme[display], @scheme[fprintf], @scheme[write-special], etc. The write handler, display handler, and print handler are specially configured for a port given to a custom-write procedure. Printing to the port through @scheme[display], @scheme[write], or @scheme[print] prints a value recursively with sharing annotations. To avoid a recursive print (i.e., to print without regard to sharing with a value currently being printed), print instead to a string or pipe and transfer the result to the target port using @scheme[write-string] and @scheme[write-special]. To recursively print but to a port other than the one given to the custom-write procedure, copy the given port's write handler, display handler, and print handler to the other port. The port given to a custom-write handler is not necessarily the actual target port. In particular, to detect cycles and sharing, the printer invokes a custom-write procedure with a port that records recursive prints, and does not retain any other output. Recursive print operations may trigger an escape from the call to the custom-write procedure (e.g., for pretty-printing where a tentative print attempt overflows the line, or for printing error output of a limited width). The following example definition of a @scheme[tuple] type includes custom-write procedures that print the tuple's list content using angle brackets in @scheme[write] mode and no brackets in @scheme[display] mode. Elements of the tuple are printed recursively, so that graph and cycle structure can be represented. @defexamples[ (define (tuple-print tuple port write?) (when write? (write-string "<" port)) (let ([l (tuple-ref tuple 0)]) (unless (zero? (vector-length l)) ((if write? write display) (vector-ref l 0) port) (for-each (lambda (e) (write-string ", " port) ((if write? write display) e port)) (cdr (vector->list l))))) (when write? (write-string ">" port))) (define-values (s:tuple make-tuple tuple? tuple-ref tuple-set!) (make-struct-type 'tuple #f 1 0 #f (list (cons prop:custom-write tuple-print)))) (display (make-tuple #(1 2 "a"))) (let ([t (make-tuple (vector 1 2 "a"))]) (vector-set! (tuple-ref t 0) 0 t) (write t)) ] } @defproc[(custom-write? [v any/c]) boolean?]{ Returns @scheme[#t] if @scheme[v] has the @scheme[prop:custom-write] property, @scheme[#f] otherwise.} @defproc[(custom-write-accessor [v custom-write?]) (custom-write? output-port? boolean?. -> . any)]{ Returns the custom-write procedure associated with @scheme[v].}