anchor.diff:  
   (defmethod print-object ((object edge) stream)
     (format stream "~A -> ~A"
  -          (id (car (nodes object)))
  -          (id (cadr (nodes object)))))    ;TODO: add attributes
  +          (string-downcase (id (car (nodes object))))
  +          (string-downcase (id (cadr (nodes object)))))) ;TODO: add attributes
   
   (defun dot-read (str)
     (string-trim-left " \n" str))
  
positive.code:     (labelurl . "labelURL")
      (tailurl . "tailURL")))
  
  (defun symbol->attr (symbol)
    "Given a symbol for an attribute, return its ID."
    (let ((special-case (assoc symbol special-ids)))
      (if special-case
          (cdr special-case)
          (string-downcase (symbol-name symbol)))))
  
  (defun id->symbol (id)
    "Given an attribute ID, return a symbol."
    (let ((special-case (rassoc id special-ids)))
      (if special-case
          (car special-case)
          (intern (string-upcase id) :cl-dot))))
  
  (defclass identified ()
    ((id :reader id :initarg :id :initform nil :type (or nil id-type))))
  
  (defclass attributed ()
    ((attributes :accessor attributes :initarg :attributes)))
  
  (defun normalize-statement (statement)
    (etypecase statement
  
negative.code:                                               (subseq statement 0 arrow))
                                               (normalize-statement
                                                (subseq statement (+ 2 arrow)))))
             (make-instance 'node :id (string-downcase statement)))))
      (cons
       (print-alist (list statement) nil nil))
      (symbol
       (normalize-statement (symbol-name statement)))))
  
  (defclass subgraph (identified)
    ((node-attrs :accessor node-attrs :initarg :node-attrs :initform nil)
     (edge-attrs :accessor edge-attrs :initarg :edge-attrs :initform nil)
     (statements :accessor statements :initarg :statements :initform nil)))
  (defmethod initialize-instance :after ((object subgraph) &key &allow-other-keys)
    (setf (statements object) (mapcar #'normalize-statement (statements object))))
  
  (defmethod print-object ((object subgraph) stream)
    (format stream
            "~:[~;strict ~]~:[~:[subgraph~;graph~]~;~*digraph~] ~:[~;~:*~A ~]~%~
             {~%~
               ~:[~;  ~:*node ~A;~%~]~
               ~:[~;  ~:*edge ~A;~%~]~
               ~{  ~A;~%~}~
             }~%"
            (graph-strict object)
            (typep object 'digraph)
            (typep object 'graph)
            (when (id object) (string-downcase (id object)))
            (when (node-attrs object) (print-alist (node-attrs object) nil))
            (when (edge-attrs object) (print-alist (edge-attrs object) nil))
            (statements object)))
  
  ;;; A graph uses --
  (defclass graph (subgraph)
    ((strict :reader graph-strict :initarg :strict :initform nil :type (or nil t))))
  
  ;;; A digraph uses ->
  (defclass digraph (graph)
  