Browse code
feat(markdown-server): simple server for markdown files
Ed Langley authored on 01/09/2020 21:18:07
Showing 1 changed files
Showing 1 changed files
1 | 1 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,80 @@ |
1 |
+(defpackage :fwoar.markdown-server |
|
2 |
+ (:use :cl :fw.lu :fwoar.string-utils :alexandria :serapeum)) |
|
3 |
+(in-package :fwoar.markdown-server) |
|
4 |
+ |
|
5 |
+(araneus:define-controller list-files (params) |
|
6 |
+ (declare (optimize (debug 3))) |
|
7 |
+ (uiop:directory-files (uiop:merge-pathnames* "onboarding/") "*.md")) |
|
8 |
+ |
|
9 |
+(araneus:define-view debug (model) |
|
10 |
+ (prin1-to-string model)) |
|
11 |
+ |
|
12 |
+(araneus:define-spinneret-view list-files ((files list)) |
|
13 |
+ (declare (optimize (debug 3))) |
|
14 |
+ (:html |
|
15 |
+ (:ul |
|
16 |
+ (loop for file in files |
|
17 |
+ do (:li (:a :href (format nil "/?file=~a" file) |
|
18 |
+ (princ-to-string file))))))) |
|
19 |
+ |
|
20 |
+(araneus:define-controller markdown (params) |
|
21 |
+ (format t "~&~s~%" params) |
|
22 |
+ (let* ((specified-file (cdr (assoc "file" params :test 'equal))) |
|
23 |
+ (source-file (uiop:merge-pathnames* specified-file))) |
|
24 |
+ (if (probe-file source-file) |
|
25 |
+ (cl-markdown:markdown (read-file-into-string source-file) |
|
26 |
+ :format :none) |
|
27 |
+ (araneus::switch-view 'not-found)))) |
|
28 |
+ |
|
29 |
+(araneus:define-spinneret-view not-found (model) |
|
30 |
+ (:body (:h1 "NOT FOUND"))) |
|
31 |
+ |
|
32 |
+(defmethod araneus:view :around (name model) |
|
33 |
+ (spinneret:with-html-string |
|
34 |
+ (:html |
|
35 |
+ (:head |
|
36 |
+ (:link :rel "stylesheet" :href "//cdn.rawgit.com/necolas/normalize.css/master/normalize.css") |
|
37 |
+ (:link :rel "stylesheet" :href "//cdn.rawgit.com/milligram/milligram/master/dist/milligram.min.css") |
|
38 |
+ (:style |
|
39 |
+ "body {" |
|
40 |
+ " width: 50%;" |
|
41 |
+ " max-width: 40em;" |
|
42 |
+ " margin-left: 10em;" |
|
43 |
+ " font-family: 'Lato', 'Helvetica', 'Arial', sans-serif;" |
|
44 |
+ " font-size: 20px;" |
|
45 |
+ "}" |
|
46 |
+ |
|
47 |
+ "ul {" |
|
48 |
+ " padding-left: 1em;" |
|
49 |
+ " background: rgba(0, 0, 128, 0.05);" |
|
50 |
+ "}" |
|
51 |
+ |
|
52 |
+ "li {" |
|
53 |
+ " list-style: circle outside;" |
|
54 |
+ " padding: 0.2em 0 0.2em 0.5em 0.1em;" |
|
55 |
+ " margin-left: 0.4em;" |
|
56 |
+ "}" |
|
57 |
+ |
|
58 |
+ "li:hover {" |
|
59 |
+ " background: rgba(0,0,64, 0.1);" |
|
60 |
+ "}" |
|
61 |
+ )) |
|
62 |
+ (:body |
|
63 |
+ (format spinneret:*html* (call-next-method)))))) |
|
64 |
+ |
|
65 |
+ |
|
66 |
+(araneus:define-view markdown (model) |
|
67 |
+ (cl-markdown:render-to-stream model :html nil)) |
|
68 |
+ |
|
69 |
+(defparameter *app* (make-instance 'ningle:<app>)) |
|
70 |
+(araneus:defroutes *app* |
|
71 |
+ (("/index") (araneus:as-route 'list-files)) |
|
72 |
+ (("/") (araneus:as-route 'markdown))) |
|
73 |
+ |
|
74 |
+(progn |
|
75 |
+ (let ((handlers '())) |
|
76 |
+ (defun start (&optional (port 9879)) |
|
77 |
+ (push (clack:clackup *app* :port port) |
|
78 |
+ handlers)) |
|
79 |
+ (defun stop () |
|
80 |
+ (clack:stop (pop handlers))))) |