7.1

## Sdraw: Cons-Cell Diagrams with Pict

 (require sdraw) package: sdraw

Cons-cell diagrams (also called box-and-pointer diagrams) are often used to visually depict pairs and lists, typically in an educational context. For example,a cons-cell diagram for the list '(1 (2 3) 4) can be seen below:

Sdraw can be used to automatically create these diagrams using Pict. Inspiration for sdraw comes from the SDRAW program included with David S. Touretzky’s Common Lisp: A Gentle Introduction to Symbolic Computation. Like Touretzky’s program, circular lists and other graph-like structures are supported.

### 1Usage

There is only one function provided by sdraw:

procedure

 (sdraw obj [ #:cell-border-color cell-border-color #:cell-inside-color cell-inside-color #:arrow-color arrow-color #:arrow-thickness arrow-thickness #:arrow-head-size arrow-head-size #:arrow-point-size arrow-point-size #:object-padding object-padding #:cell-inside-size cell-inside-size #:cell-inside-radius cell-inside-radius #:cell-border-radius cell-border-radius #:cell-border-width cell-border-width #:vertical-spacing vertical-spacing #:horizontal-spacing horizontal-spacing #:etc-pict etc-pict #:null-style null-style #:null-thickness null-thickness #:max-depth max-depth #:max-width max-width #:reference-label reference-label]) → pict?
obj : any/c
cell-border-color : color/c = "Black"
cell-inside-color : color/c = "White"
arrow-color : color/c = "Black"
arrow-thickness : real? = 2.5
arrow-head-size : real? = 7.5
arrow-point-size : real? = 7.5
object-padding : real? = 1
cell-inside-size : real? = 15
cell-inside-radius : real? = 1.5
cell-border-radius : real? = 1.5
cell-border-width : real? = 2
vertical-spacing : real? = 25
horizontal-spacing : real? = 40
etc-pict : pict-convertible? = (text "etc.")
 null-style : (or/c pict-convertible? '/ '|\| 'x) = (typeset-code #'())
null-thickness : real? = 2.5
max-depth : (or/c +inf.0 natural-number/c) = +inf.0
max-width : (or/c +inf.0 natural-number/c) = +inf.0
 reference-label : (-> string? pict-convertible?) = default-reference-label
Draws a cons-cell diagram of obj. obj can either be a datum or a syntax object. If a syntax object is given, it will be converted to a datum using syntax->datum.

Pairs are drawn as a box, with arrows going down and right for the car and cdr respectively. If a pict-convertible? is given, it will be drawn directly. Otherwise, it will be converted to a pict? using typeset-code.

Various optional keyword arguments can be given to sdraw to customize the appearance:

• Limiting size: For large objects, you may wish to limit the amount of pairs drawn. Using max-depth and max-width, you can specify how far deep or out will be drawn before pairs are replaced by etc-pict.

Example:
 > (sdraw (expand '(case a [(b c) #t] [else #f])) #:max-width 3 #:max-depth 2)

• Null style: By default, null will be represented by an arrow to (). However, other styles are common practice. For example, in SICP, null is represented using a slash thru the containing pair.

null-style may specify an alternative pict-convertible? to show. For example:

Examples:
 > (sdraw '(nconc result) #:null-style (text "NIL")) > (sdraw '(()) #:null-style (typeset-code #'null))

Alternatively, null-style may specify one of three in-cell styles:

Examples:
 > (sdraw '(()) #:null-style '/) > (sdraw '(()) #:null-style 'x) > (sdraw '(()) #:null-style '|\|)

Finally, use the null-thickness option to adjust the width of the lines used to draw in-cell styles (the option has no effect when null-style is pict-convertible?):

Example:
 > (sdraw '(1 2) #:null-style '/ #:null-thickness 0.5)

• Spacing: Use the horizontal-spacing and vertical-spacing options.

Example:
 > (sdraw '(a b) #:horizontal-spacing 100 #:vertical-spacing 10)

To add space around the text and any other drawn pictures, use the object-padding option:

Examples:
 > (require pict/face) > (define happy (scale (face 'happy) 0.2)) > (sdraw `(1 ,happy (,happy . ,happy) . 2) #:object-padding 15)

• Cell style: Use the cell-border-color, cell-inside-color, cell-inside-size, cell-inside-radius, cell-border-radius, and cell-border-width options.

Example:
 > (sdraw '(a b) #:cell-inside-color "Green" #:cell-border-color "Purple" #:cell-inside-size 20 #:cell-inside-radius 10 #:cell-border-radius 10 #:cell-border-width 3 #:null-style '/)

• Arrow style: arrow-color, arrow-thickness, arrow-head-size, and arrow-point-size can be used to adjust the size of the arrows.

Example:
 > (sdraw '(+ (* 2 3) 4) #:arrow-color "Purple" #:arrow-thickness 1 #:arrow-head-size 5 #:arrow-point-size 10)

• Reference labels style: Customization of labels for circular and graph-like structures can be done by passing a function which takes a string? and produces a pict-convertible? for reference-label. By default, a simple black label with white text is used:

Examples:
> (require racket)
 > (sdraw (with-input-from-string "#0=(#0# #1=(#0# . #1#) #1#)" read))

 > (sdraw (with-input-from-string "#0=(#0# #1=(#0# . #1#) #1#)" read) #:reference-label text)