-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgenerate.scm
More file actions
161 lines (144 loc) · 5.61 KB
/
generate.scm
File metadata and controls
161 lines (144 loc) · 5.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
(import (scheme base) (scheme char) (scheme cxr) (scheme file)
(scheme read) (scheme write))
(define (append-map f xs)
(let loop ((acc '()) (xs xs))
(if (null? xs) acc (loop (append acc (f (car xs))) (cdr xs)))))
(define (read-all)
(let loop ((xs '()))
(let ((x (read)))
(if (eof-object? x) (reverse xs) (loop (cons x xs))))))
(define (written x)
(call-with-port (open-output-string)
(lambda (out) (write x out) (get-output-string out))))
(define (display-sxml x)
(define (display* . xs) (for-each display xs))
(define (display-char char)
(let* ((cc (char->integer char))
(ok? (case char ((#\& #\< #\> #\") #f) (else (<= #x20 cc #x7e)))))
(if ok? (display char) (display* "&#" cc ";"))))
(define (display-attribute attribute)
(display* " " (car attribute) "=\"")
(string-for-each display-char (cadr attribute))
(display "\""))
(cond ((pair? x)
(display* "<" (car x))
(let ((body (cond ((and (pair? (cdr x))
(pair? (cadr x))
(eq? '@ (car (cadr x))))
(for-each display-attribute (cdr (cadr x)))
(cddr x))
(else (cdr x)))))
(display ">")
(for-each display-sxml body)
(unless (memq (car x) '(meta))
(display* "</" (car x) ">"))))
((string? x)
(string-for-each display-char x))
(else (error "Bad:" x))))
(define dialects-of-lisp
'((common-lisp "Common Lisp")
(emacs-lisp "Emacs Lisp")
(scheme "Scheme")
(racket "Racket")
(clojure "Clojure")))
(define dialects-of-ml
'((standard-ml "Standard ML")
(ocaml "OCaml")
(fsharp "F#")
(elm "Elm")))
(define languages
(append dialects-of-lisp
dialects-of-ml))
(define language-id car)
(define language-title cadr)
(define group-title cadr)
(define group-procedures cddr)
(define (procedure-purpose proc)
(cadr (or (assoc 'purpose (cdr proc))
(error "No purpose"))))
(define (procedure-in-fold kons acc proc)
(let loop ((acc acc) (pairs (cdr proc)))
(if (null? pairs) acc
(let ((pair (car pairs)))
(loop (if (eq? 'in (car pair))
(kons (cadr pair) (caddr pair) acc)
acc)
(cdr pairs))))))
(define (procedure-in goal-language proc)
(or (procedure-in-fold (lambda (language translation match)
(or match (and (eq? goal-language language)
translation)))
#f proc)
""))
(define (procedure-unknown-languages proc)
(let ((known (map language-id languages)))
(procedure-in-fold (lambda (language translation unknown)
(if (member language known) unknown
(cons language unknown)))
'() proc)))
(define (stringify x)
(cond ((string? x) x)
((symbol? x) (symbol->string x))
((list? x) (written x))
(else (error "Huh?"))))
(define (big-table)
(let ((groups (with-input-from-file "rosetta.lisp" read-all)))
`(table
(tr (th (@ (class "hidden")))
(th (@ (colspan ,(number->string (length dialects-of-lisp)))
(class "lisp"))
"Lisp")
(th (@ (colspan ,(number->string (length dialects-of-ml)))
(class "ml"))
"ML"))
(tr (th (@ (class "hidden")))
,@(map (lambda (language) `(th ,(language-title language)))
languages))
,@(append-map
(lambda (group)
`((tr (th (@ (colspan ,(number->string (+ 1 (length languages))))
(class "group"))
,(group-title group)))
,@(map
(lambda (proc)
(let ((unknown (procedure-unknown-languages proc)))
(unless (null? unknown) (error "Unknown:" unknown)))
`(tr (td ,(procedure-purpose proc))
,@(map (lambda (language)
(let ((x (procedure-in (language-id language)
proc)))
`(td (@ (class ,(if (assoc (language-id language)
dialects-of-lisp)
"lisp"
"ml")))
(code ,(stringify x)))))
languages)))
(group-procedures group))))
groups))))
(define (display-page)
(let ((title "Lisp/ML Rosetta Stone"))
(display "<!doctype html>")
(display-sxml
`(html
(@ (lang "en"))
(head
(title ,title)
(meta (@ (charset "UTF-8")))
(style ""
"body { font-family: sans-serif; background-color: beige;"
" max-width: 40em; margin: 12px; }"
"table { border-collapse: collapse; }"
"table, th, td { border: 1px solid black; }"
"th, td { vertical-align: top; padding: 2px; }"
"th.group { background-color: sandybrown; }"
"th.hidden { border: 0; }"
".red { background-color: sandybrown; }"
"th.lisp { background-color: lightgreen; }"
"td.lisp { background-color: lightgreen; }"
"th.ml { background-color: lightblue; }"
"td.ml { background-color: lightblue; }"))
(body
(h1 ,title)
,(big-table))))
(newline)))
(with-output-to-file "index.html" display-page)