...
Getty Ritter
9 years ago
2 | 2 | |
3 | 3 | redo-ifchange generate.scm |
4 | 4 | TEMP=$(mktemp -u -p $(pwd) tmpXXXXXX) |
5 |
csc -t |
|
5 | csc -t -static generate.scm -o $TEMP | |
6 | 6 | mv $TEMP.c $3 |
1 | 1 | #!/bin/sh |
2 | 2 | |
3 | redo-ifchange generate.c telml.c | |
4 | 3 | GCC=x86_64-linux-musl-gcc |
5 | ${GCC} -static generate.c telml.c -o $3 -I/usr/include/chicken -L/usr/lib -Wl,-R"/usr/lib" -lchicken -lm -ldl | |
4 | FLAGS="-static -I/usr/include/chicken -L/usr/lib -Wl,-R/usr/lib -lchicken -lm -ldl -fno-strict-aliasing -fwrapv -DHAVE_CHICKEN_CONFIG_H -DC_ENABLE_PTABLES -mtune=generic -O2 -pipe -fstack-protector-strong -D_FORTIFY_SOURCE=2 -g" | |
5 | SOURCES="generate.c telml.c libs.c" | |
6 | ||
7 | redo-ifchange ${SOURCES} | |
8 | # ${GCC} generate.c telml.c -o $3 -static -I/usr/include/chicken -L/usr/lib -Wl,-R"/usr/lib" -lchicken -lm -ldl | |
9 | ${GCC} ${SOURCES} -o $3 ${FLAGS} |
1 | (require-extension scss) | |
2 | (require-extension sxml-serializer) | |
3 |
( |
|
1 | (declare (uses libs)) | |
2 | (declare (uses telml)) | |
4 | 3 | |
4 | ; (require-extension scss) | |
5 | ; (require-extension sxml-serializer) | |
6 | ; (require-extension matchable) | |
7 | ||
8 | (load "libs.scm") | |
5 | 9 | (load "telml.scm") |
6 | 10 | |
7 | 11 | (define (pairs lst) |
8 | (match lst | |
9 | [ (x . (y . rst)) (cons (list x y) (pairs rst)) ] | |
10 |
|
|
12 | (if (or (null? lst) (null? (cdr lst))) '() | |
13 | (cons (list (car lst) (cadr lst)) (cddr lst)))) | |
11 | 14 | |
12 | 15 | ;; template-ey things and style things |
13 | 16 | |
14 | 17 | (define stylesheet |
15 | '(css | |
16 | (body | |
17 | (font-family "\"Arial\", \"Helvetica\", sans-serif") | |
18 | (font-size 15pt)) | |
18 | '((body | |
19 | (font-family "fira, \"Arial\", \"Helvetica\", sans-serif") | |
20 | (font-size 15pt) | |
21 | (background-color "#eeeeee") | |
22 | (counter-reset sidenote-counter)) | |
19 | 23 | |
20 | 24 | ((= class all) |
21 | 25 | (width 600px) |
25 | 29 | |
26 | 30 | ((= class menu) |
27 | 31 | (color "#0f0f0f")) |
32 | ||
33 | ((= class main) | |
34 | (text-align justify) | |
35 | (line-height 150%)) | |
28 | 36 | |
29 | 37 | ((= class menu-index:before) (content "\"/ \"")) |
30 | 38 | ((= class menu-archive:before) (content "\"^ \"")) |
41 | 49 | (padding-left 100px) |
42 | 50 | (padding-right 100px)) |
43 | 51 | |
44 |
((= class sideno |
|
52 | ((= class sidenote) | |
45 | 53 | (float right) |
46 | 54 | (clear right) |
47 | 55 | (margin-right -60%) |
48 |
( |
|
56 | (font-size 12pt) | |
57 | (line-height 130%) | |
58 | (width 50%)) | |
49 | 59 | |
60 | ((= class sidenote-number) | |
61 | (counter-increment sidenote-counter)) | |
62 | ||
63 | ((&& (= class sidenote-number:after) (= class sidenote:before)) | |
64 | (content "counter(sidenote-counter) \" \"") | |
65 | (position relative) | |
66 | (vertical-align baseline) | |
67 | (color "#ff0000")) | |
68 | ||
69 | ((= class sidenote-number:after) | |
70 | (content "counter(sidenote-counter) \" \"") | |
71 | (top -0.5rem) | |
72 | (left -0.1rem) | |
73 | (font-size: 0.9rem)) | |
74 | ||
75 | ((= class sidenote:before) | |
76 | (content "counter(sidenote-counter) \". \"") | |
77 | (position absolute) | |
78 | (-webkit-transform "translateX(-100%) translateX(-0.25rem)") | |
79 | (-ms-transform "translateX(-100%) translateX(-0.25rem)") | |
80 | (transform "translateX(-100%) translateX(-0.25rem)")))) | |
81 | ||
82 | ;; the SXML chunk representing the navigation menu | |
50 | 83 | (define menu |
51 | 84 | (let ((menu-item |
52 | 85 | (lambda (name url) |
58 | 91 | ,(menu-item "tags" "/tags/") |
59 | 92 | ,(menu-item "about" "/about/")))) |
60 | 93 | |
94 | ;; The SXML chunk representing a page on the site | |
61 | 95 | (define (page title content) |
62 | 96 | `(html |
63 | 97 | (head |
64 | 98 | (meta (@ (http-equiv "Content-Type") |
65 | 99 | (content "application/xhtml+xml; charset=utf-8;"))) |
66 | 100 | (style (@ (type "text/css")) ,(scss->css stylesheet)) |
101 | (script (@ (type "text/javascript") | |
102 | (src "https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"))) | |
67 | 103 | (title ,(string-append "what happens when computer: " title))) |
68 | 104 | (div (@ (class "all")) |
69 | 105 | (div (@ (class "header")) |
72 | 108 | (div (@ (class "main")) ,content) |
73 | 109 | (div (@ (class "footer")) "© 2015 getty ritter")))) |
74 | 110 | |
75 | (define (main title file) | |
76 | (display (serialize-sxml (page title (translate-file file))))) | |
111 | ;; actually load and generate the relevant files | |
112 | (define (main pg file) | |
113 | (let* ((page-source (translate-file file)) | |
114 | (telml (cdr page-source)) | |
115 | (meta (car page-source)) | |
116 | (title (if meta (cadr meta) pg))) | |
117 | (display (serialize-sxml (page title telml))))) | |
77 | 118 | |
78 |
( |
|
119 | (apply main (command-line-arguments)) |
1 | #!/bin/bash -e | |
2 | ||
3 | redo-ifchange telml.scm | |
4 | TEMP=$(mktemp -u -p $(pwd) tmpXXXXXX) | |
5 | csc -t telml.scm -o $TEMP | |
6 | mv $TEMP.c $3 |
1 |
( |
|
1 | (declare (unit telml)) | |
2 | ||
2 | 3 | (require-extension srfi-13) |
3 | 4 | (require-extension srfi-14) |
4 | 5 | (require-extension utils) |
6 | 7 | (define (mk-stream s) |
7 | 8 | (let ((lst (string->list s))) |
8 | 9 | (lambda (msg) |
9 | (match msg | |
10 | [ 'next (match lst | |
11 | [ (x . xs) (begin (set! lst xs) x) ] | |
12 | [ '() #f ]) ] | |
13 | [ 'peek (match lst | |
14 | [ (x . xs) x ] | |
15 | [ '() #f ]) ] | |
16 | [ 'done (null? lst) ])))) | |
10 | (cond ((eq? 'next msg) | |
11 | (if (null? lst) | |
12 | #f | |
13 | (let ((x (car lst))) | |
14 | (set! lst (cdr lst)) | |
15 | x))) | |
16 | ((eq? 'peek msg) | |
17 | (if (null? lst) #f (car lst))) | |
18 | ((eq? 'peek2 msg) | |
19 | (if (or (null? lst) (null? (cdr lst))) #f | |
20 | (cadr lst))) | |
21 | ((eq? 'done msg) (null? lst)))))) | |
17 | 22 | |
18 | 23 | (define (special-char? c) |
19 | 24 | (or (eq? c #\\) |
47 | 52 | |
48 | 53 | (define (parse-text) |
49 | 54 | (define (go) |
50 | (if (special-char? (s 'peek)) | |
51 | '() | |
52 |
|
|
55 | (cond ((and (eq? (s 'peek) #\\) (special-char? (s 'peek2))) | |
56 | (begin (s 'next) (cons (s 'next) (go)))) | |
57 | ((special-char? (s 'peek)) '()) | |
58 | (else | |
59 | (let ((c (s 'next))) (cons c (go)))))) | |
53 | 60 | (list->string (go))) |
54 | 61 | |
55 | 62 | (define (skip-whitespace) |
67 | 74 | (if (eq? (s 'peek) #\}) |
68 | 75 | '() |
69 | 76 | (let ((f (parse-fragment-list))) |
70 | (match (s 'peek) | |
71 | [ #\| (begin (s 'next) (cons f (parse-args))) ] | |
72 | [ #\} (list f) ] | |
73 | [ x (abort (cons 'unreachable x)) ])))) | |
77 | (cond ((eq? (s 'peek) #\|) (begin (s 'next) (cons f (parse-args)))) | |
78 | ((eq? (s 'peek) #\}) (list f)) | |
79 | (else (abort 'unreachable)))))) | |
74 | 80 | |
75 | 81 | (define (parse-fragment) |
76 | 82 | (let ((c (s 'peek))) |
95 | 101 | (simple-tag 'strong) |
96 | 102 | (simple-tag 'li) |
97 | 103 | (simple-tag 'code) |
98 | (list-tag 'p) | |
99 | (list-tag 'ul) | |
104 | (simple-tag 'h1) | |
105 | (simple-tag 'h2) | |
106 | (list-tag 'p) | |
107 | (list-tag 'ul) | |
108 | (list-tag 'ol) | |
109 | (simple-tag 'blockquote) | |
110 | (cons 'comment (lambda _ "")) | |
100 | 111 | (cons 'link (lambda (url name) |
101 | 112 | `(a (@ (href ,(apply string-append url))) ,name))) |
102 |
(cons 'sidenote (lambda (arg) `( |
|
113 | (cons 'sidenote (lambda (arg) `(span (@ (class sidenote)) ,arg))) | |
114 | (cons 'ref (lambda (name) | |
115 | `(label (@ (for ,name) (class "sidenote-number")))))))) | |
116 | ||
117 | (define (partition doc lst) | |
118 | (cond ((null? doc) (reverse lst)) | |
119 | ((not (car doc)) (partition (cdr doc) (cons '() lst))) | |
120 | (else (partition (cdr doc) | |
121 | (cons (append (car lst) (list (car doc))) | |
122 | (cdr lst)))))) | |
123 | ||
124 | (define (gather-para document) | |
125 | (define (split-string text) | |
126 | (let ((i (string-contains text "\n\n"))) | |
127 | (if (not i) (list text) | |
128 | (cons (string-take text i) | |
129 | (cons #f (split-string (string-drop text (+ i 2)))))))) | |
130 | (define (go doc) | |
131 | (cond ((null? doc) '()) | |
132 | ((not (string? (car doc))) | |
133 | (cons (car doc) (go (cdr doc)))) | |
134 | (else | |
135 | (append (split-string (car doc)) (go (cdr doc)))))) | |
136 | (partition (go document) '(()))) | |
137 | ||
103 | 138 | |
104 | 139 | (define (telml->sxml telml tags) |
105 | (let ((rec (lambda (arg) (telml->sxml arg tags)))) | |
106 | (cond ((string? telml) telml) | |
107 | ((symbol? (car telml)) | |
108 | (let ((args (map rec (cdr telml))) | |
109 | (func (cdr (assoc (car telml) tags)))) | |
110 | (apply func args))) | |
140 | (define (rec arg) | |
141 | (cond ((string? arg) arg) | |
142 | ((symbol? (car arg)) | |
143 | (let ((args (map rec (cdr arg))) | |
144 | (func (assoc (car arg) tags))) | |
145 | (if func | |
146 | (apply (cdr func) args) | |
147 | (abort (format #f "Unknown tag: `~a`" (car arg)))))) | |
111 | 148 | (else |
112 |
(map rec |
|
149 | (map rec arg)))) | |
150 | (let ((meta (if (and (not (null? telml)) | |
151 | (not (null? (car telml))) | |
152 | (eq? (caar telml) 'meta)) | |
153 | (caadar telml) | |
154 | #f)) | |
155 | (body (if (and (not (null? telml)) | |
156 | (not (null? (car telml))) | |
157 | (eq? (caar telml) 'meta)) | |
158 | (cdr telml) | |
159 | telml))) | |
160 | (cons (if meta (call-with-input-string meta read) '()) | |
161 | (map (lambda (x) | |
162 | (cons 'p (rec x))) | |
163 | (gather-para body))))) | |
113 | 164 | |
114 | 165 | (define (translate-file filename) |
115 | 166 | (telml->sxml (parse (read-all filename)) basic-tag-list)) |