-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathdemo.html
221 lines (181 loc) · 6.39 KB
/
demo.html
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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html>
<head>
<meta charset="UTF-8">
<title>coding.js</title>
<link rel="stylesheet" type="text/css" href="deps/codemirror/lib/codemirror.css" />
<link rel="stylesheet" type="text/css" href="coding.css" />
<link rel="stylesheet" type="text/css" href="base.css" />
<script src="deps/codemirror/lib/codemirror.js"></script>
<script src="deps/codemirror/mode/scheme/scheme.js"></script>
<script src="deps/jquery.min.js"></script>
<script src="coding.js"> </script>
<script>
var c = new CodingJS();
</script>
</head>
<body>
<div id="main" style="width: 80%; margin-left: 10%">
<h3> Introduction </h3>
<p> coding.js and web-worker-interpreters make it possible for you to make your tutorial, blog post or textbook interactive. Writing code fragments that your users can <em>edit</em> and <em>run</em> is as easy as calling the <tt>prompt</tt> function with the id of the div element your code lives in.
<div class="two-up">
<div class="two-left">
<br> <br>
<div id="scheme-plus-1">
(+ 137 349)
</div>
<script> c.prompt("scheme-plus-1"); </script>
</div>
<div class="two-right">
<pre>
<div id="scheme-plus-1">
(+ 137 349)
</div>
<script>
c.prompt("scheme-plus-1");
</script>
</pre>
</div>
</div>
<p> try editing the <tt>(+ 137 349)</tt>, then press Ctrl-Enter and watch the evaluated answer (originally <tt>486</tt>) change.
<h3> Including coding.js </h3>
<p> To use coding.js on your own website, simply clone the <a href="https://github.com/yuanchenyang/coding-js"> coding-js </a> github project and include the coding.js file. We can create a <tt>CodingJS</tt> object, which by default to a scheme interpreter.
<pre style="margin-left: 3em">
<script src="coding.js"> </script>
<script>
c = CodingJS();
</script>
</pre>
<p> In this example, the language is set to scheme, so coding.js invokes a scheme interpreter behind the scenes whenever your user edits your code. The interpreter path is the relative path to the directory coding.js lives in and is used to load additional files (as the files are loaded relative to this page and not coding.js). For instance if you place coding.js in a <tt>js/ext/</tt> subdirectory, and want to use the language <tt>logic</tt>, do this instead.
<pre style="margin-left: 3em">
<script src="js/ext/coding.js"> </script>
<script>
c = CodingJS("js/ext", "logic");
</script>
</pre>
<h3> Dependency management </h3>
<p>Often, code fragments depend on each other. We have a prompt with a function definition:</p>
<div class="two-up">
<div class="two-left">
<br> <br>
<div id="scheme-define-factorial">
(define (factorial n)
(if (= n 0)
1
(* n (factorial (- n 1)))))
</div>
<script>
c.prompt("scheme-define-factorial");
</script>
</div>
<div class="two-right">
<pre>
<div id="scheme-define-factorial">
(define (factorial n)
(if (= n 0)
1
(* n (factorial (- n 1)))))
</div>
<script>
c.prompt("scheme-define-factorial");
</script>
</pre>
</div>
</div>
<p>We can reuse this definition of <tt>factorial</tt> in other code fragments:</p>
<div class="two-up">
<div class="two-left">
<br>
<div id="scheme-factorial">
(factorial 10)
</div>
<script>
c.prompt("scheme-factorial", ["scheme-define-factorial"]);
</script>
</div>
<div class="two-right">
<pre>
<div id="scheme-factorial">
(factorial 10);
</div>
<script>
c.prompt("scheme-factorial", ["scheme-define-factorial"]);
</script>
</pre>
</div>
</div>
<p> This is done by passing an additional argument to <tt>prompt</tt>, an array which lists the id's of all the dependencies. When a dependency is updated, everything that depends on it is changed as well; try modifying the definition of <tt>factorial</tt> and watch the call to <tt>(factorial 10)</tt> change.
<h3> Related functions </h3>
<p> <tt>prompt</tt> is part of a family of functions designed to be used "as-is". The other functions in the family introduce slight variations on <tt>prompt</tt>. They include <tt>frozen_prompt</tt>, <tt>no_output_prompt</tt>, <tt>no_output_frozen_prompt</tt> and <tt>hidden_prompt</tt>.
<p> <tt>frozen_prompt</tt> makes a prompt that is not editable. Useful for exercise where users must wirte some definition for a function to be true.
<div class="two-up">
<div class="two-left">
<br>
<div id="scheme-define-x-10">
(define x 10)
</div>
<div id="scheme-square-x">
(* x x)
</div>
<script>
c.prompt("scheme-define-x-10");
c.frozen_prompt("scheme-square-x", ["scheme-define-x-10"]);
</script>
</div>
<div class="two-right">
<pre>
<div id="scheme-define-x-10">
(define x 10)
</div>
<div id="scheme-square-x">
(define x 10)
(* x x);
</div>
<script>
c.prompt("scheme-define-x-10");
c.frozen_prompt("scheme-square-x", ["scheme-define-x-10"]);
</script>
</pre>
</div>
</div>
<p> <tt>no_output_prompt</tt> suppresses the output, so only the code is visible. It is not very useful.
<p> <tt>no_output_frozen_prompt</tt> is a frozen prompt that suppresses output. It is useful for showing off language features as it suppresses error messages.
<div class="two-up">
<div class="two-left">
<br>
<div id="scheme-if-syntax">
(if <predicate> <consequent> <alternative>)
</div>
<script>
c.no_output_frozen_prompt("scheme-if-syntax");
</script>
</div>
<div class="two-right">
<pre>
<div id="scheme-factorial">
(if <predicate> <consequent> <alternative>)
</div>
<script>
c.no_output_frozen_prompt("scheme-if-syntax");
</script>
</pre>
</div>
</div>
<p> Lastly, <tt>hidden_prompt</tt> makes both the code and the output invisible, and can be used for exercise scaffolding, black-box functions, etc.
<h3> Internals </h3>
<p> This example demonstrates using some internal functions. <tt>make_editable</tt> causes a div to be converted into a CodeMirror editor instance, preloaded with the code it contained.
<div id="scheme-number">
486
</div>
<script>
c.make_editable("scheme-number");
</script>
<p> the <tt>compute</tt> function calls a scheme (or language of your choice) interpreter, and in fact we can get all our functionality by binding it to the <tt>onBlur</tt> event listener that CodeMirror gives us.
<div id="scheme-number-output" class="output"> </div>
<script>
c.editor_of["scheme-number"].setOption('onBlur', function() {
return compute("scheme-number");
});
</script>
</body>
</html>