Add documentation and generator. 0.1
authorFrank Duncan <frank@kank.net>
Thu, 13 Aug 2015 10:06:41 +0000 (05:06 -0500)
committerFrank Duncan <frank@kank.net>
Thu, 13 Aug 2015 11:41:25 +0000 (06:41 -0500)
README.md
bin/generatedocs.sh [new file with mode: 0755]
bin/travis.lisp
resources/success1.lisp
resources/success1.md
src/main/docgen.lisp
src/main/func.lisp
src/main/package.lisp
src/main/struc.lisp
src/test/main.lisp
wiki

index c059be9e2b54a1ba891c95a59475855899a86a93..3d8714a02b839d29ea44e9f1a01de76502703095 100644 (file)
--- a/README.md
+++ b/README.md
@@ -1,3 +1,72 @@
 # Common Lisp Document Generator
 
 # Common Lisp Document Generator
 
-Enforcement of documentation guidelines for my Common Lisp Projects, as well as conversion to markdown for github repositories.
+Enforcement of documentation guidelines for my Common Lisp Projects, as well as conversion to markdown for my github repositories.
+
+I wish I had aspirations for this being some standard that someone else might follow, but realistically I'm just irritated at my own laziness with regard to documentation, so I wrote a solution.  The forceful nature of the validator is really just because I didn't want to write a smarter parser.  As an added bonus, all the docs now look the same when I look at them in the repl, so that's kind of nice.
+
+## Usage
+
+See the [wiki](https://github.com/frankduncan/docgen/wiki) for usage information (generated by this package).
+
+To see how that page was created, take a look at bin/generatedocs.sh
+
+## Package documentation
+
+Packages are documented by sections broken up by one empty line, with the first section limited to 120 characters.
+
+## Structure/Condition documentation
+
+Requirements are the same as the package
+
+## Function documentation
+
+Functions should follow the template:
+
+````
+FUNC PATH => RESULT
+
+  RESULT: SUCCESS-RESULTS | FAILURE-RESULT
+  SUCCESS-RESULTS: SUCCESS-RESULT*
+  SUCCESS-RESULT: (:success FILENAME)
+  FAILURE-RESULT: (:failure FILENAME MSG)
+
+ARGUMENTS AND VALUES:
+
+  PATH: a pathname
+  FILENAME: the file this func was run on
+  MSG: a string containing the failure message
+
+DESCRIPTION:
+
+  FUNC runs all the things against a file located at PATH and returns
+  as soon as the first func error is found.
+
+EXAMPLES:
+
+  (func #P\"path/to/file.lisp\" t) => (:success \"path/to/file.lisp\")
+  (func #P\"path/to/error.lisp\" nil) => (:failure \"path/to/error.lisp\" \"Error msg\")
+````
+
+There are four sections to each function definition:
+
+### Header section
+
+Arguments should all be upper case, but &rest, &optional, and &key should be lower case.  Arguments are seperated by a space.
+
+Results should also be upper case, and in the case of values, separated by commas.
+
+Types can be further elucidated by providing more information either as a list of options seperated by pipes, a tuple contained in parens, or a list denoted by an *
+
+### Arguments and values section:
+
+All the types that weren't broken down into subtypes must be explained.  The form is type name in all upper case, a colon, then a description.  That description can have upper case type names in it which will then get italicized later.
+
+### Description
+
+Descriptins should be indented two spaces, and not longer than 120 characters wide.  Like the arguments and values, upper cased types will be italicized later.
+
+### Examples
+
+This section is optional.
+
+Examples are of the form:  example-code => example result
diff --git a/bin/generatedocs.sh b/bin/generatedocs.sh
new file mode 100755 (executable)
index 0000000..69ceeff
--- /dev/null
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+sbcl \
+  --eval "(asdf:load-system :docgen)" \
+  --eval "(format t \"----~%\")" \
+  --eval "(format t \"~A\" (docgen:export-package :docgen))" \
+  --eval "(quit)" 2> /dev/null | sed -n '/^----$/,$p' | tail -n +2 > wiki/Home.md
index 6a3ed0f3c313805e9d084a9d595b6a8ebf9f5097..608bdca649fd31f32296d981b391d7dbd279ff30 100644 (file)
 (when (not (syntax-checker:pretty-print-check-directory "src"))
  (format t "~c[1;31mFailed style check!~c[0m~%" #\Esc #\Esc)
  (sb-ext:exit :code 1))
 (when (not (syntax-checker:pretty-print-check-directory "src"))
  (format t "~c[1;31mFailed style check!~c[0m~%" #\Esc #\Esc)
  (sb-ext:exit :code 1))
+(format t "~c[1;32m- Style Passed!~c[0m~%" #\Esc #\Esc)
 
 
-(format t "~c[1;32mSuccess!~c[0m~%" #\Esc #\Esc)
+(format t "~%~c[1;33mChecking Docs~c[0m~%" #\Esc #\Esc)
+(when (not (docgen:pretty-print-validate-packages :docgen))
+ (format t "~c[1;31mFailed doc check!~c[0m~%" #\Esc #\Esc)
+ (sb-ext:exit :code 1))
+(format t "~c[1;32m- Doc Check Passed!~c[0m~%" #\Esc #\Esc)
+
+(format t "~c[1;30m--------------~c[0m~%" #\Esc #\Esc)
+(format t "~c[1;32mBuild Success!~c[0m~%" #\Esc #\Esc)
 (sb-ext:exit :code 0)
 (sb-ext:exit :code 0)
index 338b5b63afe3f13d72291159ef76b4a480749bcb..716dda6e8429c872f37aca487185fc3537b5a433 100644 (file)
@@ -58,7 +58,7 @@ ARGUMENTS AND VALUES:
 
 DESCRIPTION:
 
 
 DESCRIPTION:
 
-  NOARGS runs all the things against a file and returns
+  RESULT-LIST runs all the things against a file and returns
   as soon as the first func error is found."
   nil)
 
   as soon as the first func error is found."
   nil)
 
index c3a91d1b82072f2ee7488d8dfbece2653a74ecb1..f0bf81d29f40ac795351dba5c0d97445644a0639 100644 (file)
@@ -4,6 +4,18 @@ This defines a simple successful package.
 
 This is should all get pulled in and the markdown.md should be equal to success1.md.
 
 
 This is should all get pulled in and the markdown.md should be equal to success1.md.
 
+## Contents
+
+* **function [func-that-does-stuff](#function-func-that-does-stuff)** - _func-that-does-stuff_ runs all the things against a file and returns as soon as the first func error is found.
+* **function [has-keywords](#function-has-keywords)** - _has-keywords_ runs all the things against a file and returns as soon as the first func error is found.
+* **function [has-no-examples](#function-has-no-examples)** - _has-no-examples_ runs all the things against a file and returns as soon as the first func error is found.
+* **function [has-optional](#function-has-optional)** - _has-optional_ runs all the things against a file and returns as soon as the first func error is found.
+* **function [has-rest](#function-has-rest)** - _has-rest_ runs all the things against a file and returns as soon as the first func error is found.
+* **function [noargs](#function-noargs)** - _noargs_ runs all the things against a file and returns as soon as the first func error is found.
+* **function [result-list](#function-result-list)** - _result-list_ runs all the things against a file and returns as soon as the first func error is found.
+* **condition [test-condition](#condition-test-condition)** - Simple documentation.
+* **function [values-result](#function-values-result)** - _values-result_ runs all the things against a file and returns as soon as the first func error is found.
+
 ## Function **FUNC-THAT-DOES-STUFF**
 
 #### Syntax:
 ## Function **FUNC-THAT-DOES-STUFF**
 
 #### Syntax:
@@ -160,7 +172,7 @@ _msg_---a string containing the failure message
 
 #### Description:
 
 
 #### Description:
 
-NOARGS runs all the things against a file and returns as soon as the first func error is found.
+_result-list_ runs all the things against a file and returns as soon as the first func error is found.
 
 ## Condition TEST-CONDITION
 
 
 ## Condition TEST-CONDITION
 
index b3d251e907e0b1c30867bc6dd1f53a878eaa86d9..655b6bd9a2332a6f5a04f0f47cc56baf2ca4c2e3 100644 (file)
@@ -1,6 +1,7 @@
 (in-package #:docgen)
 
 (in-package #:docgen)
 
-(define-condition validation-failure nil ((msg :initarg :msg :reader validation-failure-msg)))
+(define-condition validation-failure nil ((msg :initarg :msg :reader validation-failure-msg))
+ (:documentation "Used internally for docgen parts to signal a validation error."))
 
 (defun get-symb-type (symb)
  (cond
 
 (defun get-symb-type (symb)
  (cond
   ((documentation symb 'function) :function)))
 
 (defun validate-package (pkg)
   ((documentation symb 'function) :function)))
 
 (defun validate-package (pkg)
+ "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
  (macrolet
-  ((with-success-check (&rest f)
+  ((with-success-check (symb &rest f)
     `(handler-case
       (progn ,@f :success)
     `(handler-case
       (progn ,@f :success)
-      (validation-failure (v) (list :failure (validation-failure-msg v))))))
+      (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
   (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 (docgen-pkg:doc->ast (find-package pkg))))
+     (list (with-success-check pkg (docgen-pkg:doc->ast (find-package pkg))))
      (mapcar
       (lambda (symb)
      (mapcar
       (lambda (symb)
-       (with-success-check
+       (with-success-check symb
         (case (get-symb-type symb)
          (:function (docgen-func:doc->ast symb))
          (:structure (docgen-struc:doc->ast symb))
         (case (get-symb-type symb)
          (:function (docgen-func:doc->ast symb))
          (:structure (docgen-struc:doc->ast symb))
       symbs))))))
 
 (defun pretty-print-validate-packages (&rest pkgs)
       symbs))))))
 
 (defun pretty-print-validate-packages (&rest pkgs)
- (mapcar
-  (lambda (pkg)
-   (let
-    ((failures (validate-package pkg)))
-    (mapcar
-     (lambda (failure)
-      (format t "In package ~A, documentation error found:~%  ~A" pkg (cadr failure)))
-     failures)
-    (not failures)))
-  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))
+   (mapcar
+    (lambda (symb)
+     (case (get-symb-type symb)
+      (:function
+       (list
+        (docgen-func:ast->category-name (docgen-func:doc->ast symb))
+        (docgen-func:ast->short-name (docgen-func:doc->ast symb))
+        (docgen-func:ast->link (docgen-func:doc->ast symb))
+        (docgen-func:ast->short-desc (docgen-func:doc->ast symb))))
+      (:structure
+       (list
+        (docgen-struc:ast->category-name (docgen-struc:doc->ast symb))
+        (docgen-struc:ast->short-name (docgen-struc:doc->ast symb))
+        (docgen-struc:ast->link (docgen-struc:doc->ast symb))
+        (docgen-struc:ast->short-desc (docgen-struc:doc->ast symb))))))
+    symbs))))
 
 (defun export-package (pkg)
 
 (defun export-package (pkg)
+ "EXPORT-PACKAGE PKG => MARKDOWN
+
+ARGUMENTS AND VALUES:
+
+  PKG: A package symbol
+  MARKDOWN: A string containing the markdown representation of this packages documentation
+
+DESCRIPTION:
+
+  EXPORT-PACKAGE takes in PKG and converts all the documentation for the symbols
+  into markdown with the hope of emulating the hyperspec style.
+
+  It should only be run after the package has been validated, as it assumes that
+  all documentation it gets will be valid."
  (let
   ((symbs nil))
   (do-external-symbols (symb pkg) (push symb symbs))
   (setf symbs (sort symbs #'string< :key #'symbol-name))
   (with-output-to-string (str)
    (format str "~A~%~%" (docgen-pkg:ast->md (docgen-pkg:doc->ast (find-package pkg))))
  (let
   ((symbs nil))
   (do-external-symbols (symb pkg) (push symb symbs))
   (setf symbs (sort symbs #'string< :key #'symbol-name))
   (with-output-to-string (str)
    (format str "~A~%~%" (docgen-pkg:ast->md (docgen-pkg:doc->ast (find-package pkg))))
+   (format str "~A~%" (table-of-contents pkg))
    (format str "~{~A~^~%~}"
     (mapcar
      (lambda (symb)
    (format str "~{~A~^~%~}"
     (mapcar
      (lambda (symb)
-      (format t "HAHAHAH ~A ~A~%" symb (get-symb-type symb))
       (case (get-symb-type symb)
        (:function (docgen-func:ast->md (docgen-func:doc->ast symb)))
        (:structure (docgen-struc:ast->md (docgen-struc:doc->ast symb)))))
       (case (get-symb-type symb)
        (:function (docgen-func:ast->md (docgen-func:doc->ast symb)))
        (:structure (docgen-struc:ast->md (docgen-struc:doc->ast symb)))))
index d3540a6a7f97f4b712cd1a218bc720bc6afa6513..b3926a12be7156be199689ff4c4dad9cbe969313 100644 (file)
    (format-args-and-values (get-section :arguments-and-values))
    (format-description (get-section :description))
    (format-examples (get-section :examples)))))
    (format-args-and-values (get-section :arguments-and-values))
    (format-description (get-section :description))
    (format-examples (get-section :examples)))))
+
+(defun ast->category-name (ast)
+ (declare (ignore ast))
+ "function")
+
+(defun ast->short-name (ast)
+ (format nil "~(~A~)" (second (find :function ast :key #'car))))
+
+(defun ast->link (ast)
+ (format nil "function-~(~A~)" (second (find :function ast :key #'car))))
+
+(defun ast->short-desc (ast)
+ (format-text (car (cadr (find :description ast :key #'car)))))
index 00c3bb7faf1c23398001c795653870a98091018a..119922bc26a4f5849963add7f22d077b71fdd746 100644 (file)
@@ -1,11 +1,16 @@
 (defpackage #:docgen (:use :cl)
 (defpackage #:docgen (:use :cl)
- (:export #:validate-package #:export-package #:validation-failure #:pretty-print-validate-packages))
+ (:export #:validate-package #:export-package #:validation-failure #:pretty-print-validate-packages)
+ (:documentation "Main docgen package.
+
+Use docgen to validate that documentation strings on external symbols adhere to
+a strict format and exist, so that they can be output to markdown format, while
+looking decent when used within a common lisp process."))
 
 (defpackage #:docgen-func (:use :cl)
 
 (defpackage #:docgen-func (:use :cl)
- (:export #:doc->ast #:ast->md))
+ (:export #:doc->ast #:ast->md #:ast->link #:ast->short-name #:ast->short-desc #:ast->category-name))
 
 (defpackage #:docgen-pkg (:use :cl)
  (:export #:doc->ast #:ast->md))
 
 (defpackage #:docgen-struc (:use :cl)
 
 (defpackage #:docgen-pkg (:use :cl)
  (:export #:doc->ast #:ast->md))
 
 (defpackage #:docgen-struc (:use :cl)
- (:export #:doc->ast #:ast->md))
+ (:export #:doc->ast #:ast->md #:ast->link #:ast->short-name #:ast->short-desc #:ast->category-name))
index a616ee97cbff9fd7f63118cbf8cc9c8d693e0556..6a792ed470608e2c9a1c80a258b3ab1d5c1e0e7b 100644 (file)
   (first ast)
   (second ast)
   (cddr ast)))
   (first ast)
   (second ast)
   (cddr ast)))
+
+(defun ast->category-name (ast)
+ (case (first ast)
+  (:condition "condition")
+  (t "structure")))
+
+(defun ast->short-name (ast)
+ (format nil "~(~A~)" (second ast)))
+
+(defun ast->link (ast)
+ (format nil "~(~A-~A~)" (first ast) (second ast)))
+
+(defun ast->short-desc (ast)
+ (third ast))
index a73dd7bac468278c8ede478c842736f19bdc24a6..572636ef8441419a4781a0698a7c53ca35609e8b 100644 (file)
@@ -70,6 +70,6 @@
 
 (defsuccesstest :success1 "resources/success1.lisp" "resources/success1.md")
 (deffailuretest :emptydocs "resources/emptydocs.lisp"
 
 (defsuccesstest :success1 "resources/success1.lisp" "resources/success1.md")
 (deffailuretest :emptydocs "resources/emptydocs.lisp"
'((:failure "Package EMPTYDOCS has no documentation")
-   (:failure "Symbol NO-DOC-CONDITION has no documentation")
-   (:failure "Symbol NO-DOC-FUNC has no documentation")))
`((:failure :emptydocs "Package EMPTYDOCS has no documentation")
+   (:failure ,(intern "NO-DOC-CONDITION" :emptydocs) "Symbol NO-DOC-CONDITION has no documentation")
+   (:failure ,(intern "NO-DOC-FUNC" :emptydocs) "Symbol NO-DOC-FUNC has no documentation")))
diff --git a/wiki b/wiki
index 1a8916ff9faac67cbb461da9cc939d8bee63bf25..06c150fca744ae5052741ca676e09d7081d0eefe 160000 (submodule)
--- a/wiki
+++ b/wiki
@@ -1 +1 @@
-Subproject commit 1a8916ff9faac67cbb461da9cc939d8bee63bf25
+Subproject commit 06c150fca744ae5052741ca676e09d7081d0eefe