Skip to content

Instantly share code, notes, and snippets.

@ElectricCoffee
Last active September 26, 2019 11:10
Show Gist options
  • Save ElectricCoffee/504ba26e928445b91a6ad13dca398cf9 to your computer and use it in GitHub Desktop.
Save ElectricCoffee/504ba26e928445b91a6ad13dca398cf9 to your computer and use it in GitHub Desktop.
(defun mk-klist (args)
"takes a plist of data and returns a keyed alist as its result.
i.e. an alist where the first element is a :keyword"
(assert (evenp (length args)) (args)
"arglist ~a is not even" args)
(loop :for (k v) :on args :by #'cddr
:do (check-type k keyword)
:collect (cons k v)))
(defun node (name &rest attrs)
"Defines a node"
`(node (:name ,name) (:options . ,(mk-klist attrs))))
(defun nodep (node)
"Checks if a list is a node"
(eq 'node (car node)))
(defun edge (arrow targets &rest attrs)
"Defines an edge. :arrow indicates the arrow style used in Graphviz, either -- or ->.
It is left open to accomodate possible future arrow styles."
`(edge (:arrow ,arrow) (:targets . ,targets) (:options . ,(mk-klist attrs))))
(defun edgep (edge)
"Checks if a list is an edge"
(eq 'edge (car edge)))
(defun has-options-p (obj)
"Checks if obj is of any type that supports the :options keyword"
(or (nodep obj) (edgep obj)))
(defun get-options (obj)
"Returns the :options alist"
(when (has-options-p obj)
(let ((pure-alist (cdr obj)))
(cdr (assoc :options pure-alist)))))
(defparameter *example-structure*
(list
(node "c" :title "C" :shape "rectangle")
(node "cpp" :title "C++" :shape "rectangle")
(edge "->" '("c" "cpp") :arrowhead "vee" :style "dashed")))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment