+ "VALIDATE-PACKAGE PKG => FAILURES
+
+ FAILURES: FAILURE*
+ FAILURE: (:failure SYMB MSG)
+
+ARGUMENTS AND VALUES:
+
+ PKG: A package symbol
+ SYMB: Symbol the check failed on
+ MSG: Message containing information about the failure
+
+DESCRIPTION:
+
+ VALIDATE-PACKAGE takes in PKG and validates that all the external symbols
+ adhere to documentation guidelines, exist, and can be parsed to be used
+ for exporting.
+
+ Only one error per symbol will be reported at a time, all concatenated to
+ a list in the aforementioned form."
+ (macrolet
+ ((with-success-check (symb &rest f)
+ `(handler-case
+ (progn ,@f :success)
+ (validation-failure (v) (list :failure ,symb (validation-failure-msg v))))))
+ (let
+ ((symbs nil))
+ (do-external-symbols (symb pkg) (push symb symbs))
+ (setf symbs (sort symbs #'string< :key #'symbol-name))
+ (remove :success
+ (append
+ (list (with-success-check pkg (docgen-pkg:doc->ast (find-package pkg))))
+ (mapcar
+ (lambda (symb)
+ (with-success-check symb
+ (case (get-symb-type symb)
+ (:function (docgen-func:doc->ast symb))
+ (:structure (docgen-struc:doc->ast symb))
+ (t (error (make-condition 'validation-failure :msg (format nil "Symbol ~A has no documentation" symb)))))))
+ symbs))))))
+
+(defun pretty-print-validate-packages (&rest pkgs)
+ "PRETTY-PRINT-VALIDATE-PACKAGES &rest PKGS => SUCCESS
+
+ PKGS: PKG*
+
+ARGUMENTS AND VALUES:
+
+ SUCCESS: Whether or not all symbols passed validation
+ PKG: A package symbol
+
+DESCRIPTION:
+
+ PRETTY-PRINT-VALIDATE-PACKAGES takes PKGS and runs validation on all of them.
+ It dumps to standard out failures as it comes upon them, finally returning
+ whether it was successful or not.
+
+ This can be used in travis tests to ensure that documentation can be generated
+ at a later date.
+
+EXAMPLES:
+
+ (pretty-print-validate-packages :pkg1 :pkg2) => t"
+ (some
+ #'identity
+ (mapcar
+ (lambda (pkg)
+ (let
+ ((failures (validate-package pkg)))
+ (mapcar
+ (lambda (failure)
+ (format t "In ~A : ~A, documentation error found:~% ~A~%" pkg (second failure) (third failure)))
+ failures)
+ (not failures)))
+ pkgs)))
+
+(defun table-of-contents (pkg)
+ (format nil "## Contents~%~%~{~{* **~A [~A](#~A)** - ~A~}~%~}"
+ (let
+ ((symbs nil))
+ (do-external-symbols (symb pkg) (push symb symbs))
+ (setf symbs (sort symbs #'string< :key #'symbol-name))