Skip to content

Commit

Permalink
Add arrowheads and reference SICP box-and-pointer diagrams (#8)
Browse files Browse the repository at this point in the history
  • Loading branch information
zainab-ali committed Dec 19, 2021
1 parent 972ba44 commit 00bdaf9
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 3 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ A cons cell explorer.
[![GPL v3](https://img.shields.io/badge/license-GPL_v3-green.svg)](http://www.gnu.org/licenses/gpl-3.0.txt)
[![Melpa](https://melpa.org/packages/pair-tree-badge.svg)](https://melpa.org/#/pair-tree)

`M-x pair-tree` is a learning tool for visualizing Emacs Lisp lists.
`M-x pair-tree` is a learning tool for visualizing Emacs Lisp lists. It builds an explorable box‑and‑pointer diagram for cons cells.

If you're baffled by `cons` and confused by `cdaadr` you might want to give it a spin.

Expand Down Expand Up @@ -64,3 +64,5 @@ You can navigate the tree with the arrow keys. The minibuffer shows the most con
If you're learning about lists, be sure to read [the GNU Emacs manual](https://www.gnu.org/software/emacs/manual/html_node/elisp/Lists.html#Lists). You may want to check out [dash.el](https://github.com/magnars/dash.el), the excellent list library used in this package.

Racket is an excellent programming language to learn in. If you're using it, take a look at [the Sdraw cons cell visualizer](https://docs.racket-lang.org/sdraw/index.html) instead.

If you're keen to dive deeply into box‑and‑pointer diagrams, have a read through [Structure and Interpretation of Computer Programs by Ableson and Sussman](https://mitpress.mit.edu/sites/default/files/sicp/full-text/book/book-Z-H-15.html#%_sec_2.2).
27 changes: 25 additions & 2 deletions pair-tree.el
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@

;;; Commentary:

;; This library creates an explorable box diagram for a given list.
;; This is helpful for learning about linked-list structures in Elisp.
;; This library creates an explorable box and pointer diagram for a
;; given list. This is helpful for learning about linked-list
;; structures in Elisp.

;;; Code:

Expand Down Expand Up @@ -331,6 +332,9 @@ Returns an assoc list of `pair-tree--pos' to regions."

(defconst pair-tree--stroke-width 5 "The width of branch lines and leaf outlines.")

(defconst pair-tree--arrowhead-length 3 "The length of the arrowheads on branch lines in units of stroke width.")
(defconst pair-tree--arrowhead-id "arrow" "The id of the arrowhead svg marker.")

(defun pair-tree--char-height ()
"The height in pt of a character in an SVG.
This is taken from the default font height."
Expand Down Expand Up @@ -362,6 +366,7 @@ The VAL can be any object. It is formatted as an sexp and trimmed to
(mid (/ len 2.0))
(svg (svg-create len len
:stroke-width pair-tree--stroke-width)))
(pair-tree--image-svg-branch-arrowhead svg)
(pcase (pair-tree--category-of char)
('hanging-leaf (pair-tree--image-svg-circle svg mid val))
('lying-leaf (pair-tree--image-svg-circle svg mid val))
Expand All @@ -380,6 +385,7 @@ LEG is a cons cell of the x and y distance to move."
(lineto (,leg)))
:stroke-color (face-attribute 'default ':foreground)
:stroke-width pair-tree--stroke-width
:marker-end (format "url(#%s)" pair-tree--arrowhead-id)
:relative t))

(defun pair-tree--image-svg-circle (svg mid val)
Expand All @@ -405,6 +411,23 @@ Prints the VAL within the circle."
:x x-offset
:y y-offset)))

(defun pair-tree--image-svg-branch-arrowhead (svg)
"Declare an arrowhead marker in SVG. This is placed at the end of each branch."
(svg--def
svg
(dom-node
'marker
`((id . ,pair-tree--arrowhead-id)
(viewBox . "0 0 10 10")
(refX . 10)
(refY . 5)
(markerWidth . ,pair-tree--arrowhead-length)
(markerHeight . ,pair-tree--arrowhead-length)
(orient . auto))
(dom-node 'path `((d . "M 0 0 L 10 5 L 0 10 z")
(fill . ,(face-attribute 'default ':foreground)))))))


(defun pair-tree--display-image (char &optional val)
"Return a string of CHAR with a display property set to an SVG image.
VAL is displayed in the image, if present."
Expand Down

0 comments on commit 00bdaf9

Please sign in to comment.