Add documentation and generator.
[sheep] / src / main / struc.lisp
1 (in-package #:docgen-struc)
2
3 (defun fire-error (msg) (error (make-instance 'docgen:validation-failure :msg msg)))
4
5 (defun doc->ast (struc)
6  (labels
7   ((validate (strs)
8     (mapcar
9      (lambda (str)
10       (cond
11        ((< 120 (length str)) (fire-error (format nil "Structure description longer than 120 characters: ~A" str)))
12        ((cl-ppcre:scan "^ " str) (fire-error (format nil "Structure description line started with space: ~A" str)))
13        ((cl-ppcre:scan " $" str) (fire-error (format nil "Structure description line ended with space: ~A" str)))))
14      strs))
15    (combine (strs)
16     (cond
17      ((not strs) (list ""))
18      ((string= "" (car strs)) (cons "" (combine (cdr strs))))
19      (t
20       (let
21        ((rest (combine (cdr strs))))
22        (cons (format nil "~A~A~A" (car strs) (if (string/= "" (car rest)) " " "") (car rest)) (cdr rest)))))))
23   (let
24    ((lines (cl-ppcre:split "\\n" (documentation struc 'structure))))
25    (validate lines)
26    (let
27     ((paragraphs (combine lines)))
28     (when (find "" paragraphs :test #'string=) (fire-error "Structure description has two empty lines in it"))
29     (cons
30      (cond
31       ((typep (make-instance struc) 'condition) :condition)
32       (t :struct))
33      (cons struc paragraphs))))))
34
35 (defun ast->md (ast)
36  (format nil "## ~@(~A~) ~A~%~%~{~A~%~^~%~}"
37   (first ast)
38   (second ast)
39   (cddr ast)))
40
41 (defun ast->category-name (ast)
42  (case (first ast)
43   (:condition "condition")
44   (t "structure")))
45
46 (defun ast->short-name (ast)
47  (format nil "~(~A~)" (second ast)))
48
49 (defun ast->link (ast)
50  (format nil "~(~A-~A~)" (first ast) (second ast)))
51
52 (defun ast->short-desc (ast)
53  (third ast))