Add Licensing and Contributing
[sheep] / src / main / pkg.lisp
1 ; Copyright 2022 Frank Duncan (frank@consxy.com) under AGPL3.  See distributed LICENSE.txt.
2 (in-package #:sheep-pkg)
3
4 (defun fire-error (msg) (error (make-instance 'sheep:validation-failure :msg msg)))
5
6 (defun doc->ast (pkg)
7  (when (not (documentation pkg t)) (fire-error (format nil "Package ~A has no documentation" (package-name pkg))))
8  (labels
9   ((validate (strs)
10     (mapcar
11      (lambda (str)
12       (cond
13        ((< 120 (length str)) (fire-error (format nil "Package description longer than 120 characters: ~A" str)))
14        ((cl-ppcre:scan "^ " str) (fire-error (format nil "Package description line started with space: ~A" str)))
15        ((cl-ppcre:scan " $" str) (fire-error (format nil "Package description line ended with space: ~A" str)))))
16      strs))
17    (combine (strs)
18     (cond
19      ((not strs) (list ""))
20      ((string= "" (car strs)) (cons "" (combine (cdr strs))))
21      (t
22       (let
23        ((rest (combine (cdr strs))))
24        (cons (format nil "~A~A~A" (car strs) (if (string/= "" (car rest)) " " "") (car rest)) (cdr rest)))))))
25   (let
26    ((lines (cl-ppcre:split "\\n" (documentation pkg t))))
27    (validate lines)
28    (let
29     ((paragraphs (combine lines)))
30     (when (< 120 (length (first paragraphs))) (fire-error "First package paragraph is longer than 120 characters"))
31     (when (find "" paragraphs :test #'string=) (fire-error "Package description has two empty lines in it"))
32     (cons (package-name pkg) paragraphs)))))
33
34 (defun ast->md (ast)
35  (format nil "# Package ~A~%~%~{~A~^~%~%~}"
36   (car ast)
37   (cdr ast)))