forked from racket/scribble
-
Notifications
You must be signed in to change notification settings - Fork 0
/
spoiler1.rkt
142 lines (129 loc) · 4.32 KB
/
spoiler1.rkt
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
#lang racket
(provide spoiler-wrapper-collapsed
spoiler-default
spoiler-alt
spoiler-button-default-to-alt
spoiler-button-alt-to-default
spoiler1
spler)
(require scribble/manual
scribble/core
scribble/decode
scribble/html-properties
hyper-literate
(for-syntax syntax/parse)
scriblib/render-cond)
(define spoiler-css
#"
.spoiler-wrapper-expanded .spoiler-default,
.spoiler-wrapper-expanded .spoiler-button-default-to-alt {
display:none;
}
.spoiler-wrapper-collapsed .spoiler-alt,
.spoiler-wrapper-collapsed .spoiler-button-alt-to-default {
display:none;
}
.spoiler-button-default-to-alt,
.spoiler-button-alt-to-default {
color: #2a657e;
}
")
(define spoiler-js
(string->bytes/utf-8
#<<EOJS
function toggleSpoiler(e, doExpand) {
var expanded = function(className) {
return className.match(/\bspoiler-wrapper-expanded\b/);
};
var collapsed = function(className) {
return className.match(/\bspoiler-wrapper-collapsed\b/);
};
var found = function(className) {
return expanded(className) || collapsed(className);
};
var wrapper = e;
while (e != document && e != null && ! found(e.className)) {
e = e.parentNode;
}
e.className = e
.className
.replace(/ */g, " ")
.replace(/\bspoiler-wrapper-expanded\b/, '')
.replace(/\bspoiler-wrapper-collapsed\b/, '');
if (doExpand) {
e.className = e.className + " spoiler-wrapper-expanded";
} else {
e.className = e.className + " spoiler-wrapper-collapsed";
}
if (e.preventDefault) { e.preventDefault(); }
return false;
}
EOJS
))
(define-syntax-rule (def-style name)
(define name
(style (symbol->string 'name)
(list (css-addition spoiler-css)
(js-addition spoiler-js)
(alt-tag "div")))))
(def-style spoiler-wrapper-collapsed)
(def-style spoiler-default)
(def-style spoiler-alt)
(define (spoiler-button-default-to-alt txt)
(hyperlink
#:style (style "spoiler-button-default-to-alt"
(list (css-addition spoiler-css)
(js-addition spoiler-js)
(attributes
'([onclick . "return toggleSpoiler(this, true);"]))))
"#"
txt))
(define (spoiler-button-alt-to-default txt)
(hyperlink
#:style (style "spoiler-button-alt-to-default"
(list (css-addition spoiler-css)
(js-addition spoiler-js)
(attributes
'([onclick . "return toggleSpoiler(this, false);"]))))
"#"
txt))
(define (spoiler1 default button-default→alt button-alt→default alternate)
(nested-flow spoiler-wrapper-collapsed
(list
(paragraph (style #f '())
(spoiler-button-default-to-alt button-default→alt))
(nested-flow spoiler-default
(decode-flow default))
(paragraph (style #f '())
(spoiler-button-alt-to-default button-alt→default))
(nested-flow spoiler-alt
(decode-flow alternate)))))
(define-syntax spler
(syntax-parser
[(_ name default ... #:expanded expanded ...)
#'(begin
(chunk #:save-as ck1
#:display-only
#:button
(cond-element
[html (list " " (smaller
(spoiler-button-default-to-alt "expand")))]
[else (list)])
name
default ...)
(chunk #:save-as ck2
#:button
(cond-element
[html (list " " (smaller
(spoiler-button-alt-to-default "collapse")))]
[else (list)])
name
expanded ...)
(cond-block
[html (nested-flow spoiler-wrapper-collapsed
(list (nested-flow spoiler-default
(decode-flow (ck1)))
(nested-flow spoiler-alt
(decode-flow (ck2)))))]
[else (nested-flow (style #f '())
(decode-flow (ck2)))]))]))