qed 2.1.1 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/COPYING +622 -344
- data/DIARY.rdoc +117 -0
- data/HISTORY +36 -0
- data/PROFILE +16 -0
- data/README.rdoc +69 -36
- data/REQUIRE +9 -0
- data/ROADMAP +12 -0
- data/VERSION +5 -0
- data/demo/01_demos.rdoc +56 -0
- data/demo/02_advice.rdoc +158 -0
- data/demo/03_helpers.rdoc +42 -0
- data/demo/04_fixtures.rdoc +29 -0
- data/demo/05_quote.rdoc +24 -0
- data/demo/07_toplevel.rdoc +42 -0
- data/demo/08_cross_script.rdoc +27 -0
- data/demo/09_cross_script.rdoc +27 -0
- data/demo/10_constant_lookup.rdoc +16 -0
- data/demo/applique/constant.rb +2 -0
- data/demo/applique/env.rb +5 -0
- data/demo/applique/fileutils.rb +1 -0
- data/demo/applique/markup.rb +10 -0
- data/demo/applique/quote.rb +4 -0
- data/demo/applique/toplevel.rb +15 -0
- data/demo/fixtures/data.txt +1 -0
- data/demo/fixtures/table.yml +5 -0
- data/demo/helpers/advice.rb +40 -0
- data/demo/helpers/sample.rb +4 -0
- data/demo/helpers/toplevel.rb +6 -0
- data/eg/hello_world.rdoc +15 -0
- data/{demo/error.rdoc → eg/view_error.rdoc} +0 -0
- data/{demo → eg}/website.rdoc +0 -0
- data/lib/qed.rb +20 -1
- data/lib/qed/advice.rb +4 -30
- data/lib/qed/advice/events.rb +6 -3
- data/lib/qed/advice/patterns.rb +37 -19
- data/lib/qed/applique.rb +85 -0
- data/lib/qed/command.rb +3 -5
- data/lib/qed/evaluator.rb +52 -56
- data/lib/qed/package.yml +5 -0
- data/lib/qed/parser.rb +149 -0
- data/lib/qed/profile.yml +16 -0
- data/lib/qed/reporter/{base.rb → abstract.rb} +17 -19
- data/lib/qed/reporter/bullet.rb +14 -16
- data/lib/qed/reporter/dotprogress.rb +7 -6
- data/lib/qed/reporter/html.rb +21 -3
- data/lib/qed/reporter/verbatim.rb +28 -26
- data/lib/qed/scope.rb +98 -82
- data/lib/qed/script.rb +21 -69
- data/lib/qed/session.rb +44 -3
- data/script/qedoc +2 -0
- data/script/test +2 -0
- metadata +74 -28
- data/doc/qedoc/index.html +0 -515
- data/doc/qedoc/jquery.js +0 -19
- data/meta/authors +0 -1
- data/meta/created +0 -1
- data/meta/description +0 -2
- data/meta/homepage +0 -1
- data/meta/name +0 -1
- data/meta/released +0 -1
- data/meta/repository +0 -1
- data/meta/requires +0 -5
- data/meta/ruby +0 -2
- data/meta/suite +0 -1
- data/meta/summary +0 -1
- data/meta/title +0 -1
- data/meta/version +0 -1
data/doc/qedoc/index.html
DELETED
@@ -1,515 +0,0 @@
|
|
1
|
-
<html>
|
2
|
-
<head>
|
3
|
-
<title>QED Demonstrandum</title>
|
4
|
-
|
5
|
-
<style>
|
6
|
-
#container{ margin: 0 auto; width: 800px; }
|
7
|
-
|
8
|
-
/* Debug borders */
|
9
|
-
/* p, li, dt, dd, div, pre, h1, h2, h3, h4, h5, h6 { border: 1px solid red; } */
|
10
|
-
|
11
|
-
body { font-size: 14px; line-height: 20px; margin: 1em 5% 1em 5%; font-family: Verdana, Arial, Helvetica, sans-serif; }
|
12
|
-
a { color: #336; text-decoration: underline; }
|
13
|
-
a:visited { color: #334; }
|
14
|
-
em { font-style: italic; }
|
15
|
-
strong { font-weight: bold; }
|
16
|
-
tt { color: navy; }
|
17
|
-
|
18
|
-
h1, h2, h3, h4, h5, h6 { color: #223; margin-top: 1.2em; margin-bottom: 0.5em; line-height: 1.3; }
|
19
|
-
h1 { border-bottom: 2px solid silver; }
|
20
|
-
h2 { border-bottom: 2px solid silver; padding-top: 0.5em; }
|
21
|
-
|
22
|
-
hr { color: #ccc; margin-top: 1.6em; }
|
23
|
-
|
24
|
-
p { color: #222; text-align: justify; margin-top: 0.5em; margin-bottom: 0.5em; line-height: 1.4em; }
|
25
|
-
|
26
|
-
pre { padding: 10; margin: 0; font-family: monospace; font-size: 0.9em; }
|
27
|
-
pre.pass { color: green; }
|
28
|
-
pre.fail { color: red; }
|
29
|
-
pre.error { color: red; font-weight: bold; }
|
30
|
-
|
31
|
-
span#author { color: #527bbd; font-weight: bold; font-size: 1.1em; }
|
32
|
-
span#email { }
|
33
|
-
span#revision { }
|
34
|
-
|
35
|
-
div#footer { font-size: small; border-top: 2px solid silver; padding-top: 0.5em; margin-top: 4.0em; }
|
36
|
-
div#footer-text { float: left; padding-bottom: 0.5em; }
|
37
|
-
div#footer-badges { float: right; padding-bottom: 0.5em; }
|
38
|
-
|
39
|
-
/* Block element content. */
|
40
|
-
div.content { padding: 0; }
|
41
|
-
|
42
|
-
/* Block element titles. */
|
43
|
-
h1.title { font-weight: bold; text-align: left; font-size: 3em; margin-top: 1.0em; margin-bottom: 0.5em; }
|
44
|
-
|
45
|
-
/* Block element titles. */
|
46
|
-
div.title, caption.title { font-weight: bold; text-align: left; margin-top: 1.0em; margin-bottom: 0.5em; }
|
47
|
-
div.title + * { margin-top: 0; }
|
48
|
-
td div.title:first-child { margin-top: 0.0em; }
|
49
|
-
div.content div.title:first-child { margin-top: 0.0em; }
|
50
|
-
div.content + div.title { margin-top: 0.0em; }
|
51
|
-
div.sidebarblock > div.content { background: #ffffee; border: 1px solid silver; padding: 0.5em; }
|
52
|
-
|
53
|
-
img { border-style: none; }
|
54
|
-
|
55
|
-
dl { margin-top: 0.8em; margin-bottom: 0.8em; }
|
56
|
-
dt { margin-top: 0.5em; margin-bottom: 0; font-style: italic; }
|
57
|
-
dd > *:first-child { margin-top: 0; }
|
58
|
-
ul, ol { list-style-position: outside; }
|
59
|
-
|
60
|
-
thead { font-weight: bold; }
|
61
|
-
tfoot { font-weight: bold; }
|
62
|
-
</style>
|
63
|
-
|
64
|
-
<!-- TODO: only include if these files exists -->
|
65
|
-
<link href="../assets/styles/spec.css" type="text/css" rel="stylesheet">
|
66
|
-
<!-- spec.css might be a problem with clobber -->
|
67
|
-
<link href="spec.css" type="text/css" rel="stylesheet">
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
<!-- JQuery is needed -->
|
72
|
-
<script src="jquery.js" type="text/javascript" language="javascript"></script>
|
73
|
-
|
74
|
-
</head>
|
75
|
-
|
76
|
-
<body>
|
77
|
-
|
78
|
-
<!-- Side Table of Contents -->
|
79
|
-
<div id="sidebar" style="position: fixed; top: 10; right: 10; background: white;">
|
80
|
-
<a href="javascript: toc_toggle();">
|
81
|
-
<img src="img/icon/book.jpg" height="30px;" style="border: none;" alt="TOC" align="right"/>
|
82
|
-
</a>
|
83
|
-
|
84
|
-
<div id="toc_side" class="toc">
|
85
|
-
</div>
|
86
|
-
</div>
|
87
|
-
|
88
|
-
<div id="container">
|
89
|
-
<div id="header">
|
90
|
-
<img src="img/icon/book.jpg" align="left" style="padding-right: 10px;" alt=""/>
|
91
|
-
|
92
|
-
<h1 class="title">QED Demonstrandum</h1>
|
93
|
-
|
94
|
-
<h1>Table of Contents</h1>
|
95
|
-
|
96
|
-
<div class="toc">
|
97
|
-
</div>
|
98
|
-
</div>
|
99
|
-
|
100
|
-
<div id="content">
|
101
|
-
<body>
|
102
|
-
<h1>Demonstrations</h1>
|
103
|
-
<h2>Standard Sections</h2>
|
104
|
-
<p>
|
105
|
-
QED demos are light-weight specification documents, highly suitable to
|
106
|
-
interface-driven design. The documents are divided up into clauses
|
107
|
-
separated by blank lines. Clauses that are flush to the left margin are
|
108
|
-
always explanation or comment clauses. Indented clauses are always
|
109
|
-
executable code.
|
110
|
-
</p>
|
111
|
-
<p>
|
112
|
-
Each code section is executed in order of appearance, within a rescue
|
113
|
-
wrapper that captures any failures or errors. If neither a failure or error
|
114
|
-
occur then the code gets a “pass”.
|
115
|
-
</p>
|
116
|
-
<p>
|
117
|
-
For example, the following passes:
|
118
|
-
</p>
|
119
|
-
<pre>
|
120
|
-
(2 + 2).assert == 4
|
121
|
-
</pre>
|
122
|
-
<p>
|
123
|
-
While the following would “fail”, as indicated by the raising
|
124
|
-
of an Assertion error:
|
125
|
-
</p>
|
126
|
-
<pre>
|
127
|
-
expect Assertion do
|
128
|
-
(2 + 2).assert == 5
|
129
|
-
end
|
130
|
-
</pre>
|
131
|
-
<p>
|
132
|
-
And this would have raised a NameError:
|
133
|
-
</p>
|
134
|
-
<pre>
|
135
|
-
expect NameError do
|
136
|
-
nobody_knows_method
|
137
|
-
end
|
138
|
-
</pre>
|
139
|
-
<h2>Neutral Code Blocks</h2>
|
140
|
-
<p>
|
141
|
-
There is no means of specifying that a code clause is neutral code, i.e.
|
142
|
-
that it should be executed but not tested. Thus far, such a feature has
|
143
|
-
proven to be a YAGNI.
|
144
|
-
</p>
|
145
|
-
<h2>Defining Custom Assertions</h2>
|
146
|
-
<p>
|
147
|
-
The context in which the QED code is run is a self-extended module, thus
|
148
|
-
reusable macros can be created simply by defining a method.
|
149
|
-
</p>
|
150
|
-
<pre>
|
151
|
-
def assert_integer(x)
|
152
|
-
x.assert.is_a? Integer
|
153
|
-
end
|
154
|
-
</pre>
|
155
|
-
<p>
|
156
|
-
Now lets try out our new macro definition.
|
157
|
-
</p>
|
158
|
-
<pre>
|
159
|
-
assert_integer(4)
|
160
|
-
</pre>
|
161
|
-
<p>
|
162
|
-
Let’s prove that it can also fail:
|
163
|
-
</p>
|
164
|
-
<pre>
|
165
|
-
expect Assertion do
|
166
|
-
assert_integer("IV")
|
167
|
-
end
|
168
|
-
</pre>
|
169
|
-
</body>
|
170
|
-
<body>
|
171
|
-
<h1>Advice</h1>
|
172
|
-
<p>
|
173
|
-
Advice are wrapper methods that augment demonstrations. They are used to
|
174
|
-
keep demonstrations clean of extraneous, repetitive and merely
|
175
|
-
adminstrative code that the reader does not need to see over and over.
|
176
|
-
</p>
|
177
|
-
<h2>Before and After</h2>
|
178
|
-
<p>
|
179
|
-
QED supports <b>before</b> and <b>after</b> clauses in a specification
|
180
|
-
through the use of Before and After code blocks. These blocks are executed
|
181
|
-
at the beginning and at the end of each indicated step.
|
182
|
-
</p>
|
183
|
-
<p>
|
184
|
-
We use a <b>before</b> clause if we want to setup some code at the start of
|
185
|
-
each code step.
|
186
|
-
</p>
|
187
|
-
<pre>
|
188
|
-
a, z = nil, nil
|
189
|
-
|
190
|
-
Before do
|
191
|
-
a = "BEFORE"
|
192
|
-
end
|
193
|
-
</pre>
|
194
|
-
<p>
|
195
|
-
And an <b>after</b> clause to teardown objects after a code step.
|
196
|
-
</p>
|
197
|
-
<pre>
|
198
|
-
After do
|
199
|
-
z = "AFTER"
|
200
|
-
end
|
201
|
-
</pre>
|
202
|
-
<p>
|
203
|
-
Notice we assigned <tt>a</tt> and <tt>z</tt> before the block. This was to
|
204
|
-
ensure their visibility in the scope later. Now, lets verify that the
|
205
|
-
<b>before</b> and <b>after</b> clauses work.
|
206
|
-
</p>
|
207
|
-
<pre>
|
208
|
-
a.assert == "BEFORE"
|
209
|
-
|
210
|
-
a = "A"
|
211
|
-
z = "Z"
|
212
|
-
</pre>
|
213
|
-
<p>
|
214
|
-
And now.
|
215
|
-
</p>
|
216
|
-
<pre>
|
217
|
-
z.assert == "AFTER"
|
218
|
-
</pre>
|
219
|
-
<p>
|
220
|
-
There can be more than one before and after clause at a time. If we define
|
221
|
-
a new <b>before</b> or <b>after</b> clause later in the document, it will
|
222
|
-
be appended to the current list of clauses in use.
|
223
|
-
</p>
|
224
|
-
<p>
|
225
|
-
As a demonstration of this:
|
226
|
-
</p>
|
227
|
-
<pre>
|
228
|
-
b = nil
|
229
|
-
|
230
|
-
Before do
|
231
|
-
b = "BEFORE AGAIN"
|
232
|
-
end
|
233
|
-
</pre>
|
234
|
-
<p>
|
235
|
-
We will see it is the case.
|
236
|
-
</p>
|
237
|
-
<pre>
|
238
|
-
b.assert == "BEFORE AGAIN"
|
239
|
-
</pre>
|
240
|
-
<p>
|
241
|
-
Only use <b>before</b> and <b>after</b> clauses when necessary
|
242
|
-
—specifications are generally more readable without them. Indeed,
|
243
|
-
some developers make a policy of avoiding them altogether. YMMV.
|
244
|
-
</p>
|
245
|
-
<h2>Caveats of Before and After</h2>
|
246
|
-
<p>
|
247
|
-
Instead of using Before and After clauses, it is wiser to define a reusable
|
248
|
-
setup method. For example, in the helper if we define a method such as
|
249
|
-
#prepare_example.
|
250
|
-
</p>
|
251
|
-
<pre>
|
252
|
-
def prepare_example
|
253
|
-
"Hello, World!"
|
254
|
-
end
|
255
|
-
</pre>
|
256
|
-
<p>
|
257
|
-
Then we can reuse it in later code blocks.
|
258
|
-
</p>
|
259
|
-
<pre>
|
260
|
-
example = prepare_example
|
261
|
-
example.assert == "Hello, World!"
|
262
|
-
</pre>
|
263
|
-
<p>
|
264
|
-
The advantage to this is that it gives the reader an indication of what is
|
265
|
-
going on behind the scenes, rather the having an object just magically
|
266
|
-
appear.
|
267
|
-
</p>
|
268
|
-
<h2>Event Targets</h2>
|
269
|
-
<p>
|
270
|
-
There is a small set of advice targets that do not come before or after an
|
271
|
-
event, rather they occur <b>upon</b> a particular event. These include
|
272
|
-
<tt>:load</tt> and <tt>:unload</tt>, for when a new helper is loaded;
|
273
|
-
<tt>:pass</tt>, <tt>:fail</tt> and <tt>:error</tt> for when a code block
|
274
|
-
passes, fails or raises an error; and <tt>:tag</tt> which is a low-level
|
275
|
-
target triggered upon parsing each element in the HTML conversion of the
|
276
|
-
demonstration.
|
277
|
-
</p>
|
278
|
-
<p>
|
279
|
-
These event targets can be advised by calling the <tt>When</tt> method with
|
280
|
-
the target type as an argument along with the code block to be run when the
|
281
|
-
event is triggered.
|
282
|
-
</p>
|
283
|
-
<pre>
|
284
|
-
x = []
|
285
|
-
|
286
|
-
When(:tag) do |element|
|
287
|
-
x << element.text.strip if element.name == 'li'
|
288
|
-
end
|
289
|
-
</pre>
|
290
|
-
<p>
|
291
|
-
Not let see it is worked:
|
292
|
-
</p>
|
293
|
-
<ul>
|
294
|
-
<li>SampleA
|
295
|
-
|
296
|
-
</li>
|
297
|
-
<li>SampleB
|
298
|
-
|
299
|
-
</li>
|
300
|
-
<li>SampleC
|
301
|
-
|
302
|
-
</li>
|
303
|
-
</ul>
|
304
|
-
<p>
|
305
|
-
So <tt>x</tt> should now contain these three list samples.
|
306
|
-
</p>
|
307
|
-
<pre>
|
308
|
-
x.assert == [ 'SampleA', 'SampleB', 'SampleC' ]
|
309
|
-
</pre>
|
310
|
-
<h2>Pattern Matchers</h2>
|
311
|
-
<p>
|
312
|
-
QED also supports comment match triggers. With the <tt>When</tt> method one
|
313
|
-
can define procedures to run when a given pattern matches comment text. For
|
314
|
-
example:
|
315
|
-
</p>
|
316
|
-
<pre>
|
317
|
-
When 'given a setting @a equal to (((\d+)))' do |n|
|
318
|
-
@a = n.to_i
|
319
|
-
end
|
320
|
-
</pre>
|
321
|
-
<p>
|
322
|
-
Now, @a will be set to 1 whenever a comment like this one contains,
|
323
|
-
“given a setting @a equal to 1”.
|
324
|
-
</p>
|
325
|
-
<pre>
|
326
|
-
@a.assert == 1
|
327
|
-
</pre>
|
328
|
-
<p>
|
329
|
-
A string pattern is translated into a regular expression. In fact, you can
|
330
|
-
use a regular expression if you need more control over the match. When
|
331
|
-
using a string all spaces are converted to <tt>\s+</tt> and anything within
|
332
|
-
double-parenthesis is treated as raw regular expression. Since the above
|
333
|
-
example has (((\d+))), the actual regular expression contains
|
334
|
-
<tt>(\d+)</tt>, so any number can be used. For example, “given a
|
335
|
-
setting @a equal to 2”.
|
336
|
-
</p>
|
337
|
-
<pre>
|
338
|
-
@a.assert == 2
|
339
|
-
</pre>
|
340
|
-
<p>
|
341
|
-
Typically you will want to put triggers is helper files, rather then place
|
342
|
-
them directly in the demonstration document.
|
343
|
-
</p>
|
344
|
-
<p>
|
345
|
-
This concludes the basic overview of QED’s specification system,
|
346
|
-
which is itself a QED document. Yes, we eat our own dog food.
|
347
|
-
</p>
|
348
|
-
</body>
|
349
|
-
<body>
|
350
|
-
<h1>Helpers</h1>
|
351
|
-
<p>
|
352
|
-
There are two ways to load advice scripts. Either per demonstration or
|
353
|
-
globally. Per demonstration helpers apply only to the current
|
354
|
-
demonstration. Global helpers apply to all demonstrations.
|
355
|
-
</p>
|
356
|
-
<h2>Global Helpers</h2>
|
357
|
-
<p>
|
358
|
-
Global helpers are loaded at the start of a session and apply equally to
|
359
|
-
all demonstrations in a suite.
|
360
|
-
</p>
|
361
|
-
<h2>Local Helpers</h2>
|
362
|
-
<p>
|
363
|
-
Helper scripts can be written just a demonstration scripts, or they can be
|
364
|
-
defined as pure Ruby scripts. Either way they are loaded per-demonstration
|
365
|
-
by using specially marked links.
|
366
|
-
</p>
|
367
|
-
<p>
|
368
|
-
For example, because this link, <a href="qed://helpers/advice.rb">Advice</a>, begins with <tt>require:</tt>,
|
369
|
-
it will be used to load a global helper. We can see this with the
|
370
|
-
following:
|
371
|
-
</p>
|
372
|
-
<pre>
|
373
|
-
pudding.assert.include?('load advice.rb')
|
374
|
-
</pre>
|
375
|
-
<p>
|
376
|
-
No where in the demonstration have we defined <tt>pudding</tt>, but it has
|
377
|
-
been defined for us in the advice.rb helper script.
|
378
|
-
</p>
|
379
|
-
<p>
|
380
|
-
We can also see that the generic When clause in our advice helper is
|
381
|
-
keeping count of descriptions. Since the helper script was loaded three
|
382
|
-
paragraphs back, the count will be 3.
|
383
|
-
</p>
|
384
|
-
<pre>
|
385
|
-
count.assert == 3
|
386
|
-
</pre>
|
387
|
-
<p>
|
388
|
-
Helpers are vital to building test-demonstration suites for applications.
|
389
|
-
But here again, only use them as necessary. The more helpers you use the
|
390
|
-
more difficult your demos will be to follow.
|
391
|
-
</p>
|
392
|
-
</body>
|
393
|
-
<body>
|
394
|
-
<h1>Fixtures</h1>
|
395
|
-
<h2>Flat-file Data</h2>
|
396
|
-
<p>
|
397
|
-
When creating testable demonstrations, there are times when sizable chunks
|
398
|
-
of data are needed. It is convenient to store such data in separate files.
|
399
|
-
The <tt>Data</tt> method makes is easy to load such files.
|
400
|
-
</p>
|
401
|
-
<pre>
|
402
|
-
Data('fixtures/data.txt').assert =~ /dolor/
|
403
|
-
</pre>
|
404
|
-
<p>
|
405
|
-
All files are found relative to the location of current document.
|
406
|
-
</p>
|
407
|
-
<h2>Tabular Data</h2>
|
408
|
-
<p>
|
409
|
-
The <tt>Table</tt> method is similar to the <tt>Data</tt> method except
|
410
|
-
that it expects a YAML file, and it can take a block to iterate the data
|
411
|
-
over. This makes it easy to test tables of examples.
|
412
|
-
</p>
|
413
|
-
<p>
|
414
|
-
The arity of the table block corresponds to the number of columns in each
|
415
|
-
row of the table. Each row is assigned in turn and run through the coded
|
416
|
-
step. Consider the following example:
|
417
|
-
</p>
|
418
|
-
<p>
|
419
|
-
Every row in the <a href="http://table.yml">table.yml table</a> will be
|
420
|
-
assigned to the block parameters and run through the subsequent assertion.
|
421
|
-
</p>
|
422
|
-
<pre>
|
423
|
-
Table 'fixtures/table.yml' do |x, y|
|
424
|
-
x.upcase.assert == y
|
425
|
-
end
|
426
|
-
</pre>
|
427
|
-
</body>
|
428
|
-
|
429
|
-
</div>
|
430
|
-
</div>
|
431
|
-
|
432
|
-
</body>
|
433
|
-
|
434
|
-
</html>
|
435
|
-
|
436
|
-
<script src="../assets/scripts/spec.js" type="text/javascript" language="javascript"></script>
|
437
|
-
|
438
|
-
<script type="text/javascript" language="javascript">
|
439
|
-
/*****************************************************************
|
440
|
-
* $.toc()
|
441
|
-
* by rebecca murphey
|
442
|
-
* rmurphey gmail com
|
443
|
-
*
|
444
|
-
* This function is called on its own and takes as an argument
|
445
|
-
* a list of selectors with which it will build a table of
|
446
|
-
* contents.
|
447
|
-
*
|
448
|
-
* The first selector will make up the top level of the TOC;
|
449
|
-
* the second selector will make up the second level of the TOC;
|
450
|
-
* etc.
|
451
|
-
*
|
452
|
-
* This function returns a div containing nested unordered lists;
|
453
|
-
* each list item is linked to an anchor tag added before the item
|
454
|
-
* on the page.
|
455
|
-
*
|
456
|
-
* usage: $.toc('h1,h2,h3').prependTo('body');
|
457
|
-
************************************************************************/
|
458
|
-
(function($) {
|
459
|
-
$.toc = function(tocList) {
|
460
|
-
$(tocList).addClass('jquery-toc');
|
461
|
-
var tocListArray = tocList.split(',');
|
462
|
-
$.each(tocListArray, function(i,v) { tocListArray[i] = $.trim(v); });
|
463
|
-
var $elements = $('.jquery-toc');
|
464
|
-
$('body').append('<div></div>');
|
465
|
-
var $toc = $('body div:last');
|
466
|
-
var lastLevel = 1;
|
467
|
-
$toc.append('<ul class="jquery-toc-1"></ul>');
|
468
|
-
$elements.each(function() {
|
469
|
-
var $e = $(this);
|
470
|
-
var text = $e.text();
|
471
|
-
var anchor = text.replace(/ /g,'-');
|
472
|
-
$e.before('<a name="' + anchor + '"></a>');
|
473
|
-
var level;
|
474
|
-
$.each(tocListArray, function(i,v) {
|
475
|
-
if (v.match(' ')) {
|
476
|
-
var vArray = v.split(' ');
|
477
|
-
var e = vArray[vArray.length - 1];
|
478
|
-
} else { e = v; }
|
479
|
-
if ($e.is(e)) { level = i+1; }
|
480
|
-
});
|
481
|
-
var className = 'jquery-toc-' + level;
|
482
|
-
var li = '<li><a href="#' + anchor + '">' + text + '</a></li>';
|
483
|
-
if (level == lastLevel) {
|
484
|
-
$('ul.' + className + ':last',$toc).append(li);
|
485
|
-
} else if (level > lastLevel) {
|
486
|
-
var parentLevel = level - 1;
|
487
|
-
var parentClassName = 'jquery-toc-' + parentLevel;
|
488
|
-
$('ul.' + parentClassName + ':last',$toc).
|
489
|
-
append('<ul class="' + className + '"></ul>');
|
490
|
-
$('ul.' + className + ':last',$toc).append(li);
|
491
|
-
} else if (level < lastLevel) {
|
492
|
-
$('ul.' + className + ':last',$toc).append(li);
|
493
|
-
}
|
494
|
-
lastLevel = level;
|
495
|
-
});
|
496
|
-
var $toc_ul = $('ul.jquery-toc-1',$toc);
|
497
|
-
$toc.remove();
|
498
|
-
return($toc_ul);
|
499
|
-
}
|
500
|
-
})(jQuery);
|
501
|
-
</script>
|
502
|
-
|
503
|
-
<script>
|
504
|
-
function toc_toggle() {
|
505
|
-
$('#toc_side').toggle();
|
506
|
-
$("pre").addClass("pass");
|
507
|
-
$("pre:contains('FAIL:')").addClass("fail");
|
508
|
-
$("pre:contains('ERROR:')").addClass("error");
|
509
|
-
};
|
510
|
-
|
511
|
-
$.toc('#content h1,h2,h3,h4').appendTo('.toc');
|
512
|
-
|
513
|
-
toc_toggle();
|
514
|
-
</script>
|
515
|
-
|