Sdraw:   Cons-Cell Diagrams with Pict
1 Usage
sdraw
8.17.0.6

Sdraw: Cons-Cell Diagrams with Pict🔗ℹ

Jack Rosenthal <jack@rosenth.al>

 (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:

image

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.

1 Usage🔗ℹ

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)

    image

  • 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"))

    image

    > (sdraw '(()) #:null-style (typeset-code #'null))

    image

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

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

    image

    > (sdraw '(()) #:null-style 'x)

    image

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

    image

    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)

    image

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

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

    image

    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)

    image

  • 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 '/)

    image

  • 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)

    image

  • 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))

    image

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

    image