about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorCase Duckworth2023-04-03 08:57:02 -0500
committerCase Duckworth2023-04-03 08:57:02 -0500
commit42474bb6c851314d804c89b1501b49eed0e6005f (patch)
tree81d7c77b1817ade3ca8c40d17c0b5c3672c319a8
parentReorganize (diff)
downloadwikme-42474bb6c851314d804c89b1501b49eed0e6005f.tar.gz
wikme-42474bb6c851314d804c89b1501b49eed0e6005f.zip
It builds now
-rw-r--r--.dir-locals.el4
-rw-r--r--.gitignore3
-rw-r--r--Makefile15
-rw-r--r--README.txt5
-rw-r--r--main.scm8
-rw-r--r--test/birds.md5
-rw-r--r--test/template.html6
-rw-r--r--wikme-impl.scm290
-rw-r--r--wikme-module.scm275
-rw-r--r--wikme.scm56
10 files changed, 335 insertions, 332 deletions
diff --git a/.dir-locals.el b/.dir-locals.el new file mode 100644 index 0000000..9c78ce8 --- /dev/null +++ b/.dir-locals.el
@@ -0,0 +1,4 @@
1;;; Directory Local Variables -*- no-byte-compile: t -*-
2;;; For more information see (info "(emacs) Directory Variables")
3
4((scheme-mode . ((geiser-scheme-implementation . chicken))))
diff --git a/.gitignore b/.gitignore index 8270092..637f6da 100644 --- a/.gitignore +++ b/.gitignore
@@ -1,2 +1,3 @@
1wikme 1wikme
2ref/ 2*.so
3*.o
diff --git a/Makefile b/Makefile index 7b5b337..506d366 100644 --- a/Makefile +++ b/Makefile
@@ -1,11 +1,20 @@
1# wikme 1# wikme
2 2
3PREFIX = /usr/bin 3PREFIX = /usr/bin
4CSC = csc -I$(PWD)
4 5
5wikme: wikme.scm wikme-module.scm 6OBJ = wikme.scm.o
6 csc -o $@ wikme.scm
7 7
8.PHONY: install 8wikme: main.scm $(OBJ)
9 $(CSC) -o $@ $(OBJ) -uses wikme main.scm
10
11$(OBJ): wikme.scm wikme-impl.scm
12 $(CSC) -c -J wikme.scm -unit wikme -o $@
13
14.PHONY: install clean
9 15
10install: wikme 16install: wikme
11 install -Dt $(DESTDIR)$(PREFIX)/$@ $< 17 install -Dt $(DESTDIR)$(PREFIX)/$@ $<
18
19clean:
20 rm -f *.import.scm *.so *.o
diff --git a/README.txt b/README.txt index 8fd6f44..ed0c990 100644 --- a/README.txt +++ b/README.txt
@@ -7,13 +7,16 @@ requirements:
7- cmark 7- cmark
8- chicken scheme with the following eggs: 8- chicken scheme with the following eggs:
9 - cmark 9 - cmark
10 - regex
11 - srfi-13
10 - srfi-152 12 - srfi-152
11 - utf8 13 - utf8
12 14
13build: 15build:
14 16
17- ./bootstrap
15- make 18- make
16 19
17install: 20install:
18 21
19- make install 22- make install
diff --git a/main.scm b/main.scm new file mode 100644 index 0000000..c3e4554 --- /dev/null +++ b/main.scm
@@ -0,0 +1,8 @@
1(import wikme
2 (chicken process-context))
3
4(define (main args)
5 (display (wikify-links "Hi from [[wikme]]!"))
6 (newline))
7
8(main (command-line-arguments))
diff --git a/test/birds.md b/test/birds.md new file mode 100644 index 0000000..0a02800 --- /dev/null +++ b/test/birds.md
@@ -0,0 +1,5 @@
1# Birds!
2
3Birds are pretty cool, you know. It's true.
4
5Let's test a link to [[lions]] now.
diff --git a/test/template.html b/test/template.html new file mode 100644 index 0000000..3de5bf2 --- /dev/null +++ b/test/template.html
@@ -0,0 +1,6 @@
1<!DOCTYPE html>
2<title>{{ title }}</title>
3
4<body>
5 {{body}}
6</body>
diff --git a/wikme-impl.scm b/wikme-impl.scm new file mode 100644 index 0000000..2097af7 --- /dev/null +++ b/wikme-impl.scm
@@ -0,0 +1,290 @@
1;;; Wikme --- convert a directory of markdown files into a static wiki
2
3(import (chicken file)
4 (chicken file posix)
5 (chicken format)
6 (chicken io)
7 (chicken irregex)
8 (chicken pathname)
9 (chicken port)
10 (chicken process)
11 (chicken process-context)
12 (chicken string)
13 (chicken time posix)
14 (cmark)
15 (regex) ; XXX: deprecated upstream
16 (srfi-13))
17
18;;; Records
19
20(define-record-type <wiki>
21 ;;; A wiki is a collection of pages and assorted metadata.
22 (make-wiki base-url ; base URL for links
23 origin-dir ; origin directory
24 destination-dir ; destination directory
25 pages ; list of <page>s
26 defaults ; alist of default properties for pages
27 )
28 wiki?
29 (base-url wiki-base-url (setter wiki-base-url))
30 (origin-dir wiki-origin-dir (setter wiki-origin-dir))
31 (destination-dir wiki-destination-dir (setter wiki-destination-dir))
32 (pages wiki-pages (setter wiki-pages))
33 (defaults wiki-defaults (setter wiki-defaults)))
34
35(define (wiki-default-ref wiki key)
36 (alist-ref key (wiki-defaults wiki)))
37
38(define (wiki-default-set! wiki key value)
39 (set! (wiki-defaults wiki) (cons (cons key value)
40 (wiki-defaults wiki))))
41
42(define-record-type <page>
43 ;;; A wiki page is a mapping between source and body content, and between the
44 ;;; page's origin and its destination files, wrapped together with some
45 ;;; metadata.
46 (make-page source ; source markup
47 body ; rendered page body
48 origin ; source filename (relative to wiki)
49 destination ; destination file (relative to wiki)
50 template ; this page's template
51 source-transformers ; list of source transformer functions
52 path-transformers ; list of path transformers
53 wiki ; the <wiki> this page is a part of
54 meta ; alist of metadata tags
55 )
56 page?
57 (source page-source (setter page-source))
58 (body page-body (setter page-body))
59 (origin page-origin (setter page-origin))
60 (destination page-destination (setter page-destination))
61 (template page-template (setter page-template))
62 (source-transformers page-source-transformers (setter page-source-transformers))
63 (path-transformers page-path-transformers (setter page-path-transformers))
64 (wiki page-wiki (setter page-wiki))
65 (meta page-meta (setter page-meta)))
66
67(define (page-meta-ref page key)
68 ;;; Get metadata KEY from PAGE.
69 (alist-ref key (page-meta page)))
70
71(define (page-meta-set! page key value)
72 ;;; Set KEY in PAGE's metadata to VALUE.
73 (set! (page-meta page) (cons (cons key value)
74 (page-meta page))))
75
76;;; Transformers
77
78(define (transform page input transformers)
79 (let loop ((ts transformers)
80 (it input))
81 (if (null? ts)
82 it
83 (loop (cdr ts)
84 ;; This is ugly but I need it for some things (namely, `indexify').
85 ;; Transformers can add an #!optional _ parameter to ignore it.
86 ((car ts) it page)))))
87
88(define (transform-source! page)
89 ;;; Transform PAGE's source to html.
90 ;; Passes page-source through each of page-transformers in order and sets
91 ;; page-body to the result.
92 (set! (page-body page)
93 (transform page (page-source page) (page-source-transformers page))))
94
95(define (transform-path! page)
96 ;;; Transform PAGE's path from input directory to output directory.
97 ;; This will take the page-origin and transform it using
98 ;; page-path-transformers. It will then set page-destination to the result.
99 (set! (page-destination page)
100 (transform page (page-origin page) (page-path-transformers page))))
101
102;; Cmark wrapper
103(define (page-cmark->html input #!optional page)
104 (cmark->html input (page-meta-ref page 'safe)))
105
106;;; Templates
107
108(define (render-template template env)
109 ;;; Render TEMPLATE using ENV.
110 ;; TEMPLATE is a string with {{placeholders}}; ENV is an alist of key-value
111 ;; pairs to insert into the TEMPLATE's placeholders.
112 ;; XXX: Depends on the deprecated library (regex) which is just glue around
113 ;; irregex (apparently).
114 (string-substitute* template (env->replacements env)))
115
116(define (env->replacements env)
117 ;;; Convert an ENV alist of the form `((X . Y) ...) to '(("{{X}}" . "Y") ...).
118 ;; X's are template variables and Y's are the values of those variables. In
119 ;; the template, both "{{X}}" and "{{ X }}" will be replaced.
120 ;; If Y is a thunk, call it.
121 (let loop ((env env)
122 (res '()))
123 (if (null? env)
124 res
125 (let* ((this (car env))
126 (rest (cdr env))
127 (key (->string (car this)))
128 (val (if (procedure? (cdr this))
129 ((cdr this))
130 (->string (cdr this)))))
131 (loop (cdr env)
132 (append (list (cons (sprintf "{{~a}}" key) val)
133 (cons (sprintf "{{ ~a }}" key) val))
134 res))))))
135
136(define (render page)
137 (render-template (page-template page)
138 (append `((source . ,(page-source page))
139 (body . ,(page-body page))
140 (origin . ,(page-origin page))
141 (destination . ,(page-destination page)))
142 (page-meta page))))
143
144;;; Links
145
146(define wiki-link-sre
147 ;;; An SRE for [[wiki-style links|with optional titles]].
148 '(: "[["
149 (submatch-named pname (+ (~ "|")))
150 (? (submatch "|" (submatch-named ptitle (*? nonl))))
151 "]]"))
152
153(define (wikify-links text #!optional page)
154 ;;; Convert [[Wiki-style links]] to <a> tags in TEXT.
155 ;; The base url of PAGE's wiki is prepended to the generated links.
156 (irregex-replace/all wiki-link-sre
157 text
158 (lambda (m)
159 (let* ((pname (irregex-match-substring m 'pname))
160 (ptitle (or (irregex-match-substring m 'ptitle)
161 pname)))
162 (sprintf "<a href=\"~a\">~a</a>"
163 (linkify pname
164 (if page
165 (wiki-base-url
166 (page-wiki page))
167 ""))
168 ptitle)))))
169
170(define (linkify pagename base-url)
171 ;;; Turn a page name into a link suitable for an <a> tag.
172 (make-pathname (list base-url (slugify pagename))
173 "index"
174 "html"))
175
176(define (slugify str)
177 ;;; Convert STR to a 'slug', that is, another string suitable for linking.
178 ;; This function will return the input string, in sentence case, and with all
179 ;; punctuation and spaces converted to a hypen.
180 (string-capitalize
181 (string-trim-both (irregex-replace/all '(+ (~ alnum)) str "-")
182 (lambda (c)
183 (char=? c #\-)))))
184
185(define (string-capitalize str)
186 ;;; Capitalize the first word in STR, and ensure the rest of it is lowercase.
187 ;; Returns the new string.
188 (let loop ((cs (string->list str))
189 (it #f))
190 (if (null? cs)
191 (reverse-list->string it)
192 (loop (cdr cs)
193 (if it
194 (cons (char-downcase (car cs)) it)
195 (list (char-upcase (car cs))))))))
196
197(define (unslugify str)
198 ;;; Convert a SLUG back into a normal string as best as possible.
199 ;; Because information is lost in slugification, it's impossible to be sure
200 ;; that the result of this procedure is totally accurate. That is,
201 ;; slugification is not round-trippable.
202 (irregex-replace/all "-" str " "))
203
204(define (path-relativize path dir)
205 ;;; Return PATH relative to DIR.
206 ;; Currently, this doesn't do anything special if PATH begins with / or ~ ...
207 ;; it probably should.
208 (let ((path (normalize-pathname path))
209 (dir (normalize-pathname dir)))
210 (make-pathname
211 dir
212 (string-trim (string-drop path (string-prefix-length path dir))
213 (lambda (c) (char=? c #\/))))))
214
215;;; Build a page
216
217(define (file->page file wiki
218 #!key
219 (source
220 (with-input-from-file file read-string))
221 (template
222 (wiki-default-ref wiki 'template))
223 (source-transformers
224 (wiki-default-ref wiki 'source-transformers))
225 (path-transformers
226 (wiki-default-ref wiki 'path-transformers)))
227 (let ((page (make-page source
228 #f
229 (path-relativize file (wiki-origin-dir wiki))
230 #f
231 (with-input-from-file template read-string)
232 source-transformers
233 path-transformers
234 wiki
235 '())))
236 (transform-source! page)
237 (page-meta-set! page 'title (guess-title page))
238 (page-meta-set! page 'last-updated (guess-last-updated page))
239 (transform-path! page)
240 (set! (wiki-pages wiki) (cons page (wiki-pages wiki)))
241 page))
242
243(define (guess-title page)
244 ;;; Guess the title from PAGE.
245 ;; If the first line is a Markdown H1 ("# ..."), use that as the title.
246 ;; Otherwise, unslugify the basename of the PAGE file to use as the title.
247 (let* ((str (page-body page))
248 (m (irregex-match '(: "#" (* whitespace) ($ (* nonl)) (* any))
249 str)))
250 (if (irregex-match-data? m)
251 (irregex-match-substring m 1)
252 (unslugify (basename (page-origin page))))))
253
254(define (basename file)
255 (receive (_ base _) (decompose-pathname file)
256 base))
257
258(define (indexify _origin page)
259 ;;; Transform a PAGE's filename from a markdown source to an html destination.
260 (make-pathname (slugify (page-meta-ref page 'title))
261 "index"
262 "html"))
263
264(define (guess-last-updated page)
265 ;;; Guess when PAGE was last edited.
266 ;; Tries to use git, but falls back to mtime.
267 (let ((f (path-relativize (page-origin page)
268 (wiki-origin-dir (page-wiki page)))))
269 (time->string
270 (seconds->local-time
271 (or #;
272 (string->number
273 (string-trim-both
274 (with-input-from-pipe
275 (sprintf "git log -1 --format=%ct --date=unix -C ~s ~s"
276 (wiki-origin-dir (page-wiki page))
277 f)
278 read-string)))
279 (file-modification-time f))))))
280
281(define (page->file page)
282 ;;; Write PAGE to its destination file.
283 (let ((dest (make-pathname (wiki-destination-dir (page-wiki page))
284 (page-destination page))))
285 (receive (dir _ _) (decompose-pathname dest)
286 (create-directory dir 'parents))
287 (with-output-to-file dest
288 (lambda ()
289 (write-string (render page))))))
290
diff --git a/wikme-module.scm b/wikme-module.scm deleted file mode 100644 index 14167d6..0000000 --- a/wikme-module.scm +++ /dev/null
@@ -1,275 +0,0 @@
1;;;; wikme --- build a static wiki out of a folder of markdown files
2
3(import (cmark)
4 (srfi-152)
5 (utf8)
6 (chicken file)
7 (chicken file posix)
8 (chicken irregex)
9 (chicken pathname)
10 (chicken port)
11 (chicken process)
12 (chicken process-context)
13 (chicken string)
14 (chicken time posix))
15
16
17;;; Wiki
18
19(define-record-type <wiki>
20 ;;; A wiki is a collection of pages and assorted metadata.
21 (make-wiki base-url ; base URL for links
22 origin-dir ; origin directory
23 destination-dir ; destination directory
24 page-template ; template for pages
25 file-transformers ; list of filename transformers
26 transformers ; list of source transformer functions
27 pages ; list of <page>s
28 )
29 wiki?
30 (base-url wiki-base-url (setter wiki-base-url))
31 (origin-dir wiki-origin-dir (setter wiki-origin-dir))
32 (destination-dir wiki-destination-dir (setter wiki-destination-dir))
33 (page-template wiki-page-template (setter wiki-page-template))
34 (file-transformers wiki-file-transformers (setter wiki-file-transformers))
35 (transformers wiki-transformers (setter wiki-transformers))
36 (pages wiki-pages (setter wiki-pages)))
37
38(define (directory->wiki directory
39 #!key
40 base-url
41 destination-directory
42 page-template
43 (extension "md")
44 (file-transformers (list indexify))
45 (transformers (list cmark->html wikify-links)))
46 ;;; Build a <wiki> out of the markdown files in DIRECTORY.
47 ;; The given keyword arguments will fill out the other fields in the result.
48
49 (define wiki
50 (make-wiki base-url
51 directory
52 destination-directory
53 page-template
54 file-transformers
55 transformers
56 '()))
57
58 (set! (wiki-pages wiki)
59 (map (lambda (f) (file->page f wiki))
60 (glob (make-pathname directory "*.md"))))
61
62 wiki)
63
64
65;;; Pages
66
67(define-record-type <page>
68 ;;; A wiki page is a mapping between source and body content, and between the
69 ;;; page's origin and its destination files, wrapped together with some
70 ;;; metadata.
71 (make-page source ; source markup
72 body ; rendered page body
73 origin ; file containing the markup
74 destination ; destination file
75 wiki ; the <wiki> this page is a part of
76 meta ; alist of metadata tags
77 )
78 page?
79 (source page-source (setter page-source))
80 (body page-body (setter page-source))
81 (origin page-origin (setter page-origin))
82 (destination page-destination (setter page-destination))
83 (wiki page-wiki (setter page-wiki))
84 (meta page-meta (setter page-meta)))
85
86(define (page-meta-ref page key)
87 ;;; Get metadata KEY from PAGE.
88 (cdr (assq key (page-meta page))))
89
90(define (page-meta-set! page key value)
91 ;;; Set KEY in PAGE's metadata to VALUE.
92 (set! (page-meta page) (cons (cons key value)
93 (page-meta page))))
94
95(define (basename file)
96 (let-values (((_ base _) (decompose-pathname file)))
97 base))
98
99(define (indexify fname outdir)
100 ;;; Transform a FILENAME of the form ..dir/name.md to outdir/name/index.html.
101 (make-pathname (list outdir (basename fname)) "index" "html"))
102
103(define (guess-title page)
104 ;;; Guess the title from PAGE.
105 ;; If the first line is a Markdown H1 ("# ..."), use that as the title.
106 ;; Otherwise, unslugify the basename of the PAGE file to use as the title.
107 (let* ((str (page-body page))
108 (m (irregex-match '(: "#" (* whitespace) (submatch (nonl)) (* any))
109 str)))
110 (if (irregex-match-data? m)
111 (irregex-match-substring m 1)
112 (unslugify (basename (page-origin page))))))
113
114(define (guess-last-updated page)
115 ;;; Guess when PAGE was last edited.
116 ;; Tries to use git, but falls back to mtime.
117 (let ((f (page-origin page)))
118 (time->string
119 (seconds->local-time
120 (or (string->number
121 (string-trim-both
122 (with-input-from-pipe
123 (string-join '("git" "log" "-1" "--format=%ct" "--date=unix"
124 "-C" (wiki-origin-dir (page-wiki page))
125 f)
126 " ")
127 read-string)))
128 (file-modification-time f))))))
129
130(define (file->page file wiki)
131 ;;; Create a <page> from FILE in WIKI.
132 ;; Wraps make-page for easier use.
133 (define source
134 (with-input-from-file file read-string))
135 (define page
136 (make-page source
137 (apply transform source (wiki-transformers wiki))
138 file
139 (apply file-transform
140 file
141 (wiki-destination-dir wiki)
142 (wiki-file-transformers wiki))
143 wiki
144 '()))
145
146 (page-meta-set! page 'title (guess-title page))
147 (page-meta-set! page 'last-updated (guess-last-updated page))
148
149 page)
150
151
152;;; Wiki links
153
154(define wiki-link-sre
155 ;;; An SRE for [[wiki-style links|with optional titles]].
156 '(: "[["
157 (submatch-named page (+ (~ "|")))
158 (? (submatch "|" (submatch-named title (*? nonl))))
159 "]]"))
160
161(define (wikify-links text)
162 ;;; Convert [[Wiki-style links]] to HTML style in TEXT.
163 (irregex-replace/all wiki-link-sre text
164 (lambda (m)
165 (let* ((page (irregex-match-substring m 'page))
166 (title (or (irregex-match-substring m 'title)
167 page)))
168 (string-append
169 "<a href=\"" (linkify page) "\">" title "</a>")))))
170
171(define (linkify pagename)
172 ;;; Turn a page name into a link suitable for an <a> tag.
173 (string-append (base-url) "/" (slugify pagename) "/index.html"))
174
175(define (string-capitalize str)
176 ;;; Capitalize the first word in STR, and ensure the rest of it is lowercase.
177 ;; Stolen and adapted from MIT/GNU Scheme
178 (let* ((end (string-length str))
179 (str* (make-string end)))
180 (do ((i 0 (+ i 1)))
181 ((= i end))
182 (string-set! str* i ((if (= i 0) char-upcase char-downcase)
183 (string-ref str i))))
184 str*))
185
186(define (slugify str)
187 ;;; Convert STR to a 'slug', that is, another string suitable for linking.
188 ;; This function will return the input string, in sentence case, and with all
189 ;; punctuation and spaces converted to a hypen.
190 (string-capitalize
191 (string-trim-both (irregex-replace/all '(+ (~ alnum)) str "-")
192 (lambda (c)
193 (char=? c #\-)))))
194
195(define (unslugify slug)
196 ;;; Convert a SLUG back into a normal string as best as possible.
197 ;; Because information is lost in slugification, it's impossible to be sure
198 ;; that the result of this procedure is totally accurate. That is,
199 ;; slugification is not round-trippable.
200 (irregex-replace/all '("-") slug " "))
201
202
203;;; Transform source
204
205(define (transform source . transformers)
206 ;;; Transform SOURCE to html by passing it through a series of TRANSFORMERS.
207 ;; Each TRANSFORMER should be a one-argument procedure taking and returning a
208 ;; string.
209 (let loop ((transformers transformers)
210 (output source))
211 (if (null? transformers)
212 output
213 (loop (cdr transformers)
214 ((car transformers) output)))))
215
216(define (file-transform origin destination-directory . transformers)
217 ;;; Transform ORIGIN to a DESTINATION filename using TRANSFORMERS.
218 ;; Each TRANSFORMER will be called with two arguments: the ORIGIN filaname and
219 ;; the DESTINATION-DIRECTORY. It should return the transformed filename.
220 (let loop ((transformers transformers)
221 (destination origin))
222 (if (null? transformers)
223 destination
224 (loop (cdr transformers)
225 ((car transformers) origin destination-directory)))))
226
227
228;;; Templates
229
230(define (render template env)
231 ;;; Render TEMPLATE using ENV.
232 ;; TEMPLATE is a string with {{placeholders}}; ENV is an alist of key-value
233 ;; pairs to insert into the TEMPLATE's placeholders.
234 (string-substitute* template (env->replacements env)))
235
236(define (env->replacements env)
237 ;;; Convert an ENV alist of the form `((X . Y) ...) to '(("{{X}}" . "Y") ...).
238 ;; X's are template variables and Y's are the values of those variables. In
239 ;; the template, both "{{X}}" and "{{ X }}" will be replaced.
240 ;; If Y is a thunk, call it.
241 (let loop ((env env)
242 (res '()))
243 (if (null? env)
244 res
245 (let* ((this (car env))
246 (rest (cdr env))
247 (key (->string (car this)))
248 (val (if (procedure? (cdr this))
249 ((cdr this))
250 (->string (cdr this)))))
251 (loop (cdr env)
252 (append (list (cons (string-append "{{" key "}}") val)
253 (cons (string-append "{{ " key " }}") val))
254 env))))))
255
256(define (render-page template page)
257 ;;; Render PAGE with its metadata using TEMPLATE.
258 (render template `((title . ,(page-meta-ref 'title page))
259 (body . ,(page-body page))
260 (last_updated ,(page-meta-ref 'last-updated page))
261 ;; TODO: backlinks and what-not
262 )))
263
264
265;;; Wikify
266
267(define (render-wiki wiki)
268 ;;; Render the files in WIKI to disk.
269 (create-directory (wiki-destination-dir wiki) #:parents)
270 (for-each (lambda (page)
271 (with-output-to-file (page-destination page)
272 (lambda ()
273 (write-string
274 (render-page (wiki-page-template wiki) page)))))
275 (wiki-pages wiki)))
diff --git a/wikme.scm b/wikme.scm index b0a5177..10b1a1a 100644 --- a/wikme.scm +++ b/wikme.scm
@@ -1,52 +1,4 @@
1;;; wikme.scm --- build a wiki from a folder of markdown --- executable 1(module wikme *
2 2 (import scheme
3(import (args) 3 (chicken base))
4 (chicken pathname) 4 (include "wikme-impl.scm"))
5 (chicken process-context)
6 (chicken port))
7
8(include "wikme-module")
9
10
11
12(define +opts+
13 (list (args:make-option
14 (u base-url) (optional: "URL")
15 "Base URL for the generated Wiki.")
16 (args:make-option
17 (s source) (optional: "DIRECTORY")
18 "Directory containing source files (default: PWD).")
19 (args:make-option
20 (o out) (optional: "DIRECTORY")
21 "Directory in which to place rendered files (default: PWD/out).")
22 (args:make-option
23 (t template) (optional: "FILE")
24 "Template file for wiki pages (default: PWD/template.html).")))
25
26
27
28(define (usage)
29 (with-output-to-port (current-error-port)
30 (lambda ()
31 (print "Usage: " (car (argv)) " [options...]")
32 (newline)
33 (print (args:usage +opts+))))
34 (exit 1))
35
36(define (main args)
37 (receive (options operands)
38 (args:parse args +opts+)
39 (render-wiki
40 (directory->wiki
41 (or (alist-ref 'source options)
42 (current-directory))
43 #:base-url (or (alist-ref 'base-url options)
44 "https://www.example.com")
45 #:destination-directory (or (alist-ref 'out options)
46 (make-pathname
47 (current-directory) "out"))
48 #:page-template (or (alist-ref 'template options)
49 (make-pathname
50 (current-directory) "template.html"))))))
51
52(main (command-line-arguments))