escape 0.0.1
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/Readme +20 -0
- data/doc_include/template/qualitysmith.rb +631 -0
- data/escape.rb +247 -0
- data/tasks/shared/shared_tasks.rb +213 -0
- metadata +53 -0
data/Readme
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
= __
|
2
|
+
|
3
|
+
[<b>Home page</b>:] http://__.rubyforge.org/
|
4
|
+
[<b>Project site</b>:] http://rubyforge.org/projects/__
|
5
|
+
[<b>Wiki</b>:] http://wiki.qualitysmith.com/__
|
6
|
+
[<b>Author</b>:] Your name
|
7
|
+
[<b>Copyright</b>:] 2007 QualitySmith, Inc.
|
8
|
+
[<b>License</b>:] {GNU General Public License}[http://www.gnu.org/copyleft/gpl.html]
|
9
|
+
|
10
|
+
== Introduction
|
11
|
+
|
12
|
+
...
|
13
|
+
|
14
|
+
== Installation
|
15
|
+
|
16
|
+
...
|
17
|
+
|
18
|
+
== Usage
|
19
|
+
|
20
|
+
...
|
@@ -0,0 +1,631 @@
|
|
1
|
+
module RDoc
|
2
|
+
module Page
|
3
|
+
|
4
|
+
FONTS = "\"Bitstream Vera Sans\", Verdana, Arial, Helvetica, sans-serif"
|
5
|
+
|
6
|
+
STYLE = <<CSS
|
7
|
+
a {
|
8
|
+
color: #00F;
|
9
|
+
text-decoration: none;
|
10
|
+
}
|
11
|
+
|
12
|
+
a:hover {
|
13
|
+
color: #77F;
|
14
|
+
text-decoration: underline;
|
15
|
+
}
|
16
|
+
|
17
|
+
body, td, p {
|
18
|
+
font-family: %fonts%;
|
19
|
+
background: #FFF;
|
20
|
+
color: #000;
|
21
|
+
margin: 0px;
|
22
|
+
font-size: small;
|
23
|
+
}
|
24
|
+
|
25
|
+
#content {
|
26
|
+
margin: 2em;
|
27
|
+
}
|
28
|
+
|
29
|
+
#description p {
|
30
|
+
margin-bottom: 0.5em;
|
31
|
+
}
|
32
|
+
|
33
|
+
.sectiontitle {
|
34
|
+
margin-top: 1em;
|
35
|
+
margin-bottom: 1em;
|
36
|
+
padding: 0.5em;
|
37
|
+
padding-left: 2em;
|
38
|
+
background: #005;
|
39
|
+
color: #FFF;
|
40
|
+
font-weight: bold;
|
41
|
+
border: 1px dotted black;
|
42
|
+
}
|
43
|
+
|
44
|
+
.attr-rw {
|
45
|
+
padding-left: 1em;
|
46
|
+
padding-right: 1em;
|
47
|
+
text-align: center;
|
48
|
+
color: #055;
|
49
|
+
}
|
50
|
+
|
51
|
+
.attr-name {
|
52
|
+
font-weight: bold;
|
53
|
+
}
|
54
|
+
|
55
|
+
.attr-desc {
|
56
|
+
}
|
57
|
+
|
58
|
+
.attr-value {
|
59
|
+
font-family: monospace;
|
60
|
+
}
|
61
|
+
|
62
|
+
.file-title-prefix {
|
63
|
+
font-size: large;
|
64
|
+
}
|
65
|
+
|
66
|
+
.file-title {
|
67
|
+
font-size: large;
|
68
|
+
font-weight: bold;
|
69
|
+
background: #005;
|
70
|
+
color: #FFF;
|
71
|
+
}
|
72
|
+
|
73
|
+
.banner {
|
74
|
+
background: #005;
|
75
|
+
color: #FFF;
|
76
|
+
border: 1px solid black;
|
77
|
+
padding: 1em;
|
78
|
+
}
|
79
|
+
|
80
|
+
.banner td {
|
81
|
+
background: transparent;
|
82
|
+
color: #FFF;
|
83
|
+
}
|
84
|
+
|
85
|
+
h1 a, h2 a, .sectiontitle a, .banner a {
|
86
|
+
color: #FF0;
|
87
|
+
}
|
88
|
+
|
89
|
+
h1 a:hover, h2 a:hover, .sectiontitle a:hover, .banner a:hover {
|
90
|
+
color: #FF7;
|
91
|
+
}
|
92
|
+
|
93
|
+
.dyn-source {
|
94
|
+
display: none;
|
95
|
+
background: #FFE;
|
96
|
+
color: #000;
|
97
|
+
border: 1px dotted black;
|
98
|
+
margin: 0.5em 2em 0.5em 2em;
|
99
|
+
padding: 0.5em;
|
100
|
+
}
|
101
|
+
|
102
|
+
.dyn-source .cmt {
|
103
|
+
color: #00F;
|
104
|
+
font-style: italic;
|
105
|
+
}
|
106
|
+
|
107
|
+
.dyn-source .kw {
|
108
|
+
color: #070;
|
109
|
+
font-weight: bold;
|
110
|
+
}
|
111
|
+
|
112
|
+
.method {
|
113
|
+
margin-left: 1em;
|
114
|
+
margin-right: 1em;
|
115
|
+
margin-bottom: 1em;
|
116
|
+
}
|
117
|
+
|
118
|
+
.description pre {
|
119
|
+
padding: 0.5em;
|
120
|
+
border: 1px dotted black;
|
121
|
+
background: #FFE;
|
122
|
+
}
|
123
|
+
|
124
|
+
.method .title {
|
125
|
+
font-family: monospace;
|
126
|
+
font-size: large;
|
127
|
+
border-bottom: 1px dashed black;
|
128
|
+
margin-bottom: 0.3em;
|
129
|
+
padding-bottom: 0.1em;
|
130
|
+
}
|
131
|
+
|
132
|
+
.method .description, .method .sourcecode {
|
133
|
+
margin-left: 1em;
|
134
|
+
}
|
135
|
+
|
136
|
+
.description p, .sourcecode p {
|
137
|
+
margin-bottom: 0.5em;
|
138
|
+
}
|
139
|
+
|
140
|
+
.method .sourcecode p.source-link {
|
141
|
+
text-indent: 0em;
|
142
|
+
margin-top: 0.5em;
|
143
|
+
}
|
144
|
+
|
145
|
+
.method .aka {
|
146
|
+
margin-top: 0.3em;
|
147
|
+
margin-left: 1em;
|
148
|
+
font-style: italic;
|
149
|
+
text-indent: 2em;
|
150
|
+
}
|
151
|
+
|
152
|
+
h1 {
|
153
|
+
padding: 1em;
|
154
|
+
border: 1px solid black;
|
155
|
+
font-size: x-large;
|
156
|
+
font-weight: bold;
|
157
|
+
color: #FFF;
|
158
|
+
background: #007;
|
159
|
+
}
|
160
|
+
|
161
|
+
h2 {
|
162
|
+
padding: 0.5em 1em 0.5em 1em;
|
163
|
+
border: 1px solid black;
|
164
|
+
font-size: large;
|
165
|
+
font-weight: bold;
|
166
|
+
color: #FFF;
|
167
|
+
background: #009;
|
168
|
+
}
|
169
|
+
|
170
|
+
h3, h4, h5, h6 {
|
171
|
+
padding: 0.2em 1em 0.2em 1em;
|
172
|
+
border: 1px dashed black;
|
173
|
+
color: #000;
|
174
|
+
background: #AAF;
|
175
|
+
}
|
176
|
+
|
177
|
+
.sourcecode > pre {
|
178
|
+
padding: 0.5em;
|
179
|
+
border: 1px dotted black;
|
180
|
+
background: #FFE;
|
181
|
+
}
|
182
|
+
|
183
|
+
CSS
|
184
|
+
|
185
|
+
XHTML_PREAMBLE = %{<?xml version="1.0" encoding="%charset%"?>
|
186
|
+
<!DOCTYPE html
|
187
|
+
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
188
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
189
|
+
}
|
190
|
+
|
191
|
+
HEADER = XHTML_PREAMBLE + <<ENDHEADER
|
192
|
+
<html>
|
193
|
+
<head>
|
194
|
+
<title>%title%</title>
|
195
|
+
<meta http-equiv="Content-Type" content="text/html; charset=%charset%" />
|
196
|
+
<link rel="stylesheet" href="%style_url%" type="text/css" media="screen" />
|
197
|
+
|
198
|
+
<script language="JavaScript" type="text/javascript">
|
199
|
+
// <![CDATA[
|
200
|
+
|
201
|
+
function toggleSource( id )
|
202
|
+
{
|
203
|
+
var elem
|
204
|
+
var link
|
205
|
+
|
206
|
+
if( document.getElementById )
|
207
|
+
{
|
208
|
+
elem = document.getElementById( id )
|
209
|
+
link = document.getElementById( "l_" + id )
|
210
|
+
}
|
211
|
+
else if ( document.all )
|
212
|
+
{
|
213
|
+
elem = eval( "document.all." + id )
|
214
|
+
link = eval( "document.all.l_" + id )
|
215
|
+
}
|
216
|
+
else
|
217
|
+
return false;
|
218
|
+
|
219
|
+
if( elem.style.display == "block" )
|
220
|
+
{
|
221
|
+
elem.style.display = "none"
|
222
|
+
link.innerHTML = "show source"
|
223
|
+
}
|
224
|
+
else
|
225
|
+
{
|
226
|
+
elem.style.display = "block"
|
227
|
+
link.innerHTML = "hide source"
|
228
|
+
}
|
229
|
+
}
|
230
|
+
|
231
|
+
function openCode( url )
|
232
|
+
{
|
233
|
+
window.open( url, "SOURCE_CODE", "width=400,height=400,scrollbars=yes" )
|
234
|
+
}
|
235
|
+
// ]]>
|
236
|
+
</script>
|
237
|
+
</head>
|
238
|
+
|
239
|
+
<body>
|
240
|
+
ENDHEADER
|
241
|
+
|
242
|
+
FILE_PAGE = <<HTML
|
243
|
+
<table border='0' cellpadding='0' cellspacing='0' width="100%" class='banner'>
|
244
|
+
<tr><td>
|
245
|
+
<table width="100%" border='0' cellpadding='0' cellspacing='0'><tr>
|
246
|
+
<td class="file-title" colspan="2"><span class="file-title-prefix">File</span><br />%short_name%</td>
|
247
|
+
<td align="right">
|
248
|
+
<table border='0' cellspacing="0" cellpadding="2">
|
249
|
+
<tr>
|
250
|
+
<td>Path:</td>
|
251
|
+
<td>%full_path%
|
252
|
+
IF:cvsurl
|
253
|
+
(<a href="%cvsurl%">CVS</a>)
|
254
|
+
ENDIF:cvsurl
|
255
|
+
</td>
|
256
|
+
</tr>
|
257
|
+
<tr>
|
258
|
+
<td>Modified:</td>
|
259
|
+
<td>%dtm_modified%</td>
|
260
|
+
</tr>
|
261
|
+
</table>
|
262
|
+
</td></tr>
|
263
|
+
</table>
|
264
|
+
</td></tr>
|
265
|
+
</table><br>
|
266
|
+
HTML
|
267
|
+
|
268
|
+
###################################################################
|
269
|
+
|
270
|
+
CLASS_PAGE = <<HTML
|
271
|
+
<table width="100%" border='0' cellpadding='0' cellspacing='0' class='banner'><tr>
|
272
|
+
<td class="file-title"><span class="file-title-prefix">%classmod%</span><br />%full_name%</td>
|
273
|
+
<td align="right">
|
274
|
+
<table cellspacing=0 cellpadding=2>
|
275
|
+
<tr valign="top">
|
276
|
+
<td>In:</td>
|
277
|
+
<td>
|
278
|
+
START:infiles
|
279
|
+
HREF:full_path_url:full_path:
|
280
|
+
IF:cvsurl
|
281
|
+
(<a href="%cvsurl%">CVS</a>)
|
282
|
+
ENDIF:cvsurl
|
283
|
+
END:infiles
|
284
|
+
</td>
|
285
|
+
</tr>
|
286
|
+
IF:parent
|
287
|
+
<tr>
|
288
|
+
<td>Parent:</td>
|
289
|
+
<td>
|
290
|
+
IF:par_url
|
291
|
+
<a href="%par_url%">
|
292
|
+
ENDIF:par_url
|
293
|
+
%parent%
|
294
|
+
IF:par_url
|
295
|
+
</a>
|
296
|
+
ENDIF:par_url
|
297
|
+
</td>
|
298
|
+
</tr>
|
299
|
+
ENDIF:parent
|
300
|
+
</table>
|
301
|
+
</td>
|
302
|
+
</tr>
|
303
|
+
</table>
|
304
|
+
HTML
|
305
|
+
|
306
|
+
###################################################################
|
307
|
+
|
308
|
+
METHOD_LIST = <<HTML
|
309
|
+
<div id="content">
|
310
|
+
IF:diagram
|
311
|
+
<table cellpadding='0' cellspacing='0' border='0' width="100%"><tr><td align="center">
|
312
|
+
%diagram%
|
313
|
+
</td></tr></table>
|
314
|
+
ENDIF:diagram
|
315
|
+
|
316
|
+
IF:description
|
317
|
+
<div class="description">%description%</div>
|
318
|
+
ENDIF:description
|
319
|
+
|
320
|
+
IF:requires
|
321
|
+
<div class="sectiontitle">Required Files</div>
|
322
|
+
<ul>
|
323
|
+
START:requires
|
324
|
+
<li>HREF:aref:name:</li>
|
325
|
+
END:requires
|
326
|
+
</ul>
|
327
|
+
ENDIF:requires
|
328
|
+
|
329
|
+
IF:toc
|
330
|
+
<div class="sectiontitle">Contents</div>
|
331
|
+
<ul>
|
332
|
+
START:toc
|
333
|
+
<li><a href="#%href%">%secname%</a></li>
|
334
|
+
END:toc
|
335
|
+
</ul>
|
336
|
+
ENDIF:toc
|
337
|
+
|
338
|
+
IF:methods
|
339
|
+
<div class="sectiontitle">Methods</div>
|
340
|
+
<ul>
|
341
|
+
START:methods
|
342
|
+
<li>HREF:aref:name:</li>
|
343
|
+
END:methods
|
344
|
+
</ul>
|
345
|
+
ENDIF:methods
|
346
|
+
|
347
|
+
IF:includes
|
348
|
+
<div class="sectiontitle">Included Modules</div>
|
349
|
+
<ul>
|
350
|
+
START:includes
|
351
|
+
<li>HREF:aref:name:</li>
|
352
|
+
END:includes
|
353
|
+
</ul>
|
354
|
+
ENDIF:includes
|
355
|
+
|
356
|
+
START:sections
|
357
|
+
IF:sectitle
|
358
|
+
<div class="sectiontitle"><a name="%secsequence%">%sectitle%</a></div>
|
359
|
+
IF:seccomment
|
360
|
+
<div class="description">
|
361
|
+
%seccomment%
|
362
|
+
</div>
|
363
|
+
ENDIF:seccomment
|
364
|
+
ENDIF:sectitle
|
365
|
+
|
366
|
+
IF:classlist
|
367
|
+
<div class="sectiontitle">Classes and Modules</div>
|
368
|
+
%classlist%
|
369
|
+
ENDIF:classlist
|
370
|
+
|
371
|
+
IF:constants
|
372
|
+
<div class="sectiontitle">Constants</div>
|
373
|
+
<table border='0' cellpadding='5'>
|
374
|
+
START:constants
|
375
|
+
<tr valign='top'>
|
376
|
+
<td class="attr-name">%name%</td>
|
377
|
+
<td>=</td>
|
378
|
+
<td class="attr-value">%value%</td>
|
379
|
+
</tr>
|
380
|
+
IF:desc
|
381
|
+
<tr valign='top'>
|
382
|
+
<td> </td>
|
383
|
+
<td colspan="2" class="attr-desc">%desc%</td>
|
384
|
+
</tr>
|
385
|
+
ENDIF:desc
|
386
|
+
END:constants
|
387
|
+
</table>
|
388
|
+
ENDIF:constants
|
389
|
+
|
390
|
+
IF:attributes
|
391
|
+
<div class="sectiontitle">Attributes</div>
|
392
|
+
<table border='0' cellpadding='5'>
|
393
|
+
START:attributes
|
394
|
+
<tr valign='top'>
|
395
|
+
<td class='attr-rw'>
|
396
|
+
IF:rw
|
397
|
+
[%rw%]
|
398
|
+
ENDIF:rw
|
399
|
+
</td>
|
400
|
+
<td class='attr-name'>%name%</td>
|
401
|
+
<td class='attr-desc'>%a_desc%</td>
|
402
|
+
</tr>
|
403
|
+
END:attributes
|
404
|
+
</table>
|
405
|
+
ENDIF:attributes
|
406
|
+
|
407
|
+
IF:method_list
|
408
|
+
START:method_list
|
409
|
+
IF:methods
|
410
|
+
<div class="sectiontitle">%type% %category% methods</div>
|
411
|
+
START:methods
|
412
|
+
<div class="method">
|
413
|
+
<div class="title">
|
414
|
+
IF:callseq
|
415
|
+
<a name="%aref%"></a><b>%callseq%</b>
|
416
|
+
ENDIF:callseq
|
417
|
+
IFNOT:callseq
|
418
|
+
<a name="%aref%"></a><b>%name%</b>%params%
|
419
|
+
ENDIF:callseq
|
420
|
+
IF:codeurl
|
421
|
+
[ <a href="javascript:openCode('%codeurl%')">source</a> ]
|
422
|
+
ENDIF:codeurl
|
423
|
+
</div>
|
424
|
+
IF:m_desc
|
425
|
+
<div class="description">
|
426
|
+
%m_desc%
|
427
|
+
</div>
|
428
|
+
ENDIF:m_desc
|
429
|
+
IF:aka
|
430
|
+
<div class="aka">
|
431
|
+
This method is also aliased as
|
432
|
+
START:aka
|
433
|
+
<a href="%aref%">%name%</a>
|
434
|
+
END:aka
|
435
|
+
</div>
|
436
|
+
ENDIF:aka
|
437
|
+
IF:sourcecode
|
438
|
+
<div class="sourcecode">
|
439
|
+
<p class="source-link">[ <a href="javascript:toggleSource('%aref%_source')" id="l_%aref%_source">show source</a> ]</p>
|
440
|
+
<div id="%aref%_source" class="dyn-source">
|
441
|
+
<pre>
|
442
|
+
%sourcecode%
|
443
|
+
</pre>
|
444
|
+
</div>
|
445
|
+
</div>
|
446
|
+
ENDIF:sourcecode
|
447
|
+
</div>
|
448
|
+
END:methods
|
449
|
+
ENDIF:methods
|
450
|
+
END:method_list
|
451
|
+
ENDIF:method_list
|
452
|
+
END:sections
|
453
|
+
</div>
|
454
|
+
HTML
|
455
|
+
|
456
|
+
FOOTER = <<ENDFOOTER
|
457
|
+
</body>
|
458
|
+
</html>
|
459
|
+
ENDFOOTER
|
460
|
+
|
461
|
+
BODY = HEADER + <<ENDBODY
|
462
|
+
!INCLUDE! <!-- banner header -->
|
463
|
+
|
464
|
+
<div id="bodyContent">
|
465
|
+
#{METHOD_LIST}
|
466
|
+
</div>
|
467
|
+
|
468
|
+
#{FOOTER}
|
469
|
+
ENDBODY
|
470
|
+
|
471
|
+
########################## Source code ##########################
|
472
|
+
|
473
|
+
SRC_PAGE = XHTML_PREAMBLE + <<HTML
|
474
|
+
<html>
|
475
|
+
<head><title>%title%</title>
|
476
|
+
<meta http-equiv="Content-Type" content="text/html; charset=%charset%">
|
477
|
+
<style>
|
478
|
+
.ruby-comment { color: green; font-style: italic }
|
479
|
+
.ruby-constant { color: #4433aa; font-weight: bold; }
|
480
|
+
.ruby-identifier { color: #222222; }
|
481
|
+
.ruby-ivar { color: #2233dd; }
|
482
|
+
.ruby-keyword { color: #3333FF; font-weight: bold }
|
483
|
+
.ruby-node { color: #777777; }
|
484
|
+
.ruby-operator { color: #111111; }
|
485
|
+
.ruby-regexp { color: #662222; }
|
486
|
+
.ruby-value { color: #662222; font-style: italic }
|
487
|
+
.kw { color: #3333FF; font-weight: bold }
|
488
|
+
.cmt { color: green; font-style: italic }
|
489
|
+
.str { color: #662222; font-style: italic }
|
490
|
+
.re { color: #662222; }
|
491
|
+
</style>
|
492
|
+
</head>
|
493
|
+
<body bgcolor="white">
|
494
|
+
<pre>%code%</pre>
|
495
|
+
</body>
|
496
|
+
</html>
|
497
|
+
HTML
|
498
|
+
|
499
|
+
########################## Index ################################
|
500
|
+
|
501
|
+
FR_INDEX_BODY = <<HTML
|
502
|
+
!INCLUDE!
|
503
|
+
HTML
|
504
|
+
|
505
|
+
FILE_INDEX = XHTML_PREAMBLE + <<HTML
|
506
|
+
<html>
|
507
|
+
<head>
|
508
|
+
<meta http-equiv="Content-Type" content="text/html; charset=%charset%">
|
509
|
+
<style>
|
510
|
+
<!--
|
511
|
+
body {
|
512
|
+
background-color: #EEE;
|
513
|
+
font-family: #{FONTS};
|
514
|
+
color: #000;
|
515
|
+
margin: 0px;
|
516
|
+
}
|
517
|
+
.banner {
|
518
|
+
background: #005;
|
519
|
+
color: #FFF;
|
520
|
+
padding: 0.2em;
|
521
|
+
font-size: small;
|
522
|
+
font-weight: bold;
|
523
|
+
text-align: center;
|
524
|
+
}
|
525
|
+
.entries {
|
526
|
+
margin: 0.25em 1em 0 1em;
|
527
|
+
font-size: x-small;
|
528
|
+
}
|
529
|
+
a {
|
530
|
+
display: block;
|
531
|
+
color: #00F;
|
532
|
+
text-decoration: none;
|
533
|
+
white-space: nowrap;
|
534
|
+
}
|
535
|
+
a:hover {
|
536
|
+
color: #77F;
|
537
|
+
text-decoration: underline;
|
538
|
+
}
|
539
|
+
input#link_search {
|
540
|
+
color: #a00;
|
541
|
+
}
|
542
|
+
input#link_search.default {
|
543
|
+
color: #888;
|
544
|
+
}
|
545
|
+
-->
|
546
|
+
</style>
|
547
|
+
<script type="text/javascript" language="javascript">
|
548
|
+
function init_frame_select() {
|
549
|
+
var opts = document.getElementById('frame_select').options;
|
550
|
+
for (i = 0; i < opts.length; i++) {
|
551
|
+
opts[i].selected = (location.href.indexOf(opts[i].value) != -1);
|
552
|
+
}
|
553
|
+
}
|
554
|
+
function do_link_search() {
|
555
|
+
var search_box = document.getElementById('link_search');
|
556
|
+
if (search_box.value == search_box.defaultValue) return;
|
557
|
+
var links = document.getElementById('entries').getElementsByTagName('a');
|
558
|
+
search = new RegExp(search_box.value, 'i');
|
559
|
+
for (i = 0; i < links.length; i++) {
|
560
|
+
links[i].style.display = search.exec(links[i].innerHTML) ? 'block' : 'none';
|
561
|
+
}
|
562
|
+
}
|
563
|
+
function clear_link_search() {
|
564
|
+
var search_box = document.getElementById('link_search');
|
565
|
+
if (search_box.value == search_box.defaultValue) search_box.value = '';
|
566
|
+
search_box.className = '';
|
567
|
+
}
|
568
|
+
function reset_link_search() {
|
569
|
+
var search_box = document.getElementById('link_search');
|
570
|
+
if (search_box.value == '') search_box.value = search_box.defaultValue;
|
571
|
+
search_box.className = 'default';
|
572
|
+
}
|
573
|
+
</script>
|
574
|
+
<base target="docwin">
|
575
|
+
</head>
|
576
|
+
<body onload="init_frame_select(); reset_link_search();">
|
577
|
+
<select id="frame_select" onchange="location.href=this.value" style="width: 100%;">
|
578
|
+
<option value="fr_class_index.html">Classes</option>
|
579
|
+
<option value="fr_file_index.html">Files</option>
|
580
|
+
<option value="fr_method_index.html">Methods</option>
|
581
|
+
</select>
|
582
|
+
<input id="link_search" class="default" type="text" onkeyup="do_link_search()" onfocus="clear_link_search()" onblur="reset_link_search()" style="width: 100%;" value="type search here..." />
|
583
|
+
<div class="banner">%list_title%</div>
|
584
|
+
<div class="entries" id="entries">
|
585
|
+
START:entries
|
586
|
+
<a href="%href%">%name%</a>
|
587
|
+
END:entries
|
588
|
+
</div>
|
589
|
+
</body></html>
|
590
|
+
HTML
|
591
|
+
|
592
|
+
CLASS_INDEX = FILE_INDEX
|
593
|
+
METHOD_INDEX = FILE_INDEX
|
594
|
+
|
595
|
+
INDEX = XHTML_PREAMBLE + <<HTML
|
596
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
597
|
+
<head>
|
598
|
+
<title>%title%</title>
|
599
|
+
<meta http-equiv="Content-Type" content="text/html; charset=%charset%">
|
600
|
+
</head>
|
601
|
+
|
602
|
+
<frameset cols="200, *">
|
603
|
+
<frame src="fr_class_index.html" name="framewin" />
|
604
|
+
<frame src="%initial_page%" name="docwin" />
|
605
|
+
</frameset>
|
606
|
+
|
607
|
+
<frameset cols="200,*">
|
608
|
+
<frame src="fr_class_index.html" name="framewin" />
|
609
|
+
IF:inline_source
|
610
|
+
<frame src="%initial_page%" name="docwin">
|
611
|
+
ENDIF:inline_source
|
612
|
+
IFNOT:inline_source
|
613
|
+
<frameset rows="80%,20%">
|
614
|
+
<frame src="%initial_page%" name="docwin">
|
615
|
+
<frame src="blank.html" name="source">
|
616
|
+
</frameset>
|
617
|
+
ENDIF:inline_source
|
618
|
+
<noframes>
|
619
|
+
<body bgcolor="white">
|
620
|
+
Click <a href="html/index.html">here</a> for a non-frames
|
621
|
+
version of this page.
|
622
|
+
</body>
|
623
|
+
</noframes>
|
624
|
+
</frameset>
|
625
|
+
|
626
|
+
</html>
|
627
|
+
HTML
|
628
|
+
|
629
|
+
end
|
630
|
+
end
|
631
|
+
|
data/escape.rb
ADDED
@@ -0,0 +1,247 @@
|
|
1
|
+
# escape.rb - escape/unescape library for several formats
|
2
|
+
#
|
3
|
+
# Copyright (C) 2006,2007 Tanaka Akira <akr@fsij.org>
|
4
|
+
#
|
5
|
+
# Redistribution and use in source and binary forms, with or without
|
6
|
+
# modification, are permitted provided that the following conditions are met:
|
7
|
+
#
|
8
|
+
# 1. Redistributions of source code must retain the above copyright notice, this
|
9
|
+
# list of conditions and the following disclaimer.
|
10
|
+
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
11
|
+
# this list of conditions and the following disclaimer in the documentation
|
12
|
+
# and/or other materials provided with the distribution.
|
13
|
+
# 3. The name of the author may not be used to endorse or promote products
|
14
|
+
# derived from this software without specific prior written permission.
|
15
|
+
#
|
16
|
+
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
17
|
+
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
18
|
+
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
19
|
+
# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
20
|
+
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
21
|
+
# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
22
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
23
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
24
|
+
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
25
|
+
# OF SUCH DAMAGE.
|
26
|
+
|
27
|
+
# Escape module provides several escape functions.
|
28
|
+
# * URI
|
29
|
+
# * HTML
|
30
|
+
# * shell command
|
31
|
+
module Escape
|
32
|
+
module_function
|
33
|
+
|
34
|
+
# Escape.shell_command composes
|
35
|
+
# a sequence of words to
|
36
|
+
# a single shell command line.
|
37
|
+
# All shell meta characters are quoted and
|
38
|
+
# the words are concatenated with interleaving space.
|
39
|
+
#
|
40
|
+
# Escape.shell_command(["ls", "/"]) #=> "ls /"
|
41
|
+
# Escape.shell_command(["echo", "*"]) #=> "echo '*'"
|
42
|
+
#
|
43
|
+
# Note that system(*command) and
|
44
|
+
# system(Escape.shell_command(command)) is roughly same.
|
45
|
+
# There are two exception as follows.
|
46
|
+
# * The first is that the later may invokes /bin/sh.
|
47
|
+
# * The second is an interpretation of an array with only one element:
|
48
|
+
# the element is parsed by the shell with the former but
|
49
|
+
# it is recognized as single word with the later.
|
50
|
+
# For example, system(*["echo foo"]) invokes echo command with an argument "foo".
|
51
|
+
# But system(Escape.shell_command(["echo foo"])) invokes "echo foo" command without arguments (and it probably fails).
|
52
|
+
def shell_command(command)
|
53
|
+
command.map {|word| shell_single_word(word) }.join(' ')
|
54
|
+
end
|
55
|
+
|
56
|
+
# Escape.shell_single_word quotes shell meta characters.
|
57
|
+
#
|
58
|
+
# The result string is always single shell word, even if
|
59
|
+
# the argument is "".
|
60
|
+
# Escape.shell_single_word("") returns "''".
|
61
|
+
#
|
62
|
+
# Escape.shell_single_word("") #=> "''"
|
63
|
+
# Escape.shell_single_word("foo") #=> "foo"
|
64
|
+
# Escape.shell_single_word("*") #=> "'*'"
|
65
|
+
def shell_single_word(str)
|
66
|
+
if str.empty?
|
67
|
+
"''"
|
68
|
+
elsif %r{\A[0-9A-Za-z+,./:=@_-]+\z} =~ str
|
69
|
+
str
|
70
|
+
else
|
71
|
+
result = ''
|
72
|
+
str.scan(/('+)|[^']+/) {
|
73
|
+
if $1
|
74
|
+
result << %q{\'} * $1.length
|
75
|
+
else
|
76
|
+
result << "'#{$&}'"
|
77
|
+
end
|
78
|
+
}
|
79
|
+
result
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# Escape.uri_segment escapes URI segment using percent-encoding.
|
84
|
+
#
|
85
|
+
# Escape.uri_segment("a/b") #=> "a%2Fb"
|
86
|
+
#
|
87
|
+
# The segment is "/"-splitted element after authority before query in URI, as follows.
|
88
|
+
#
|
89
|
+
# scheme://authority/segment1/segment2/.../segmentN?query#fragment
|
90
|
+
#
|
91
|
+
# See RFC 3986 for details of URI.
|
92
|
+
def uri_segment(str)
|
93
|
+
# pchar - pct-encoded = unreserved / sub-delims / ":" / "@"
|
94
|
+
# unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
|
95
|
+
# sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
|
96
|
+
str.gsub(%r{[^A-Za-z0-9\-._~!$&'()*+,;=:@]}n) {
|
97
|
+
'%' + $&.unpack("H2")[0].upcase
|
98
|
+
}
|
99
|
+
end
|
100
|
+
|
101
|
+
# Escape.uri_path escapes URI path using percent-encoding.
|
102
|
+
# The given path should be a sequence of (non-escaped) segments separated by "/".
|
103
|
+
# The segments cannot contains "/".
|
104
|
+
#
|
105
|
+
# Escape.uri_path("a/b/c") #=> "a/b/c"
|
106
|
+
# Escape.uri_path("a?b/c?d/e?f") #=> "a%3Fb/c%3Fd/e%3Ff"
|
107
|
+
#
|
108
|
+
# The path is the part after authority before query in URI, as follows.
|
109
|
+
#
|
110
|
+
# scheme://authority/path#fragment
|
111
|
+
#
|
112
|
+
# See RFC 3986 for details of URI.
|
113
|
+
#
|
114
|
+
# Note that this function is not appropriate to convert OS path to URI.
|
115
|
+
def uri_path(str)
|
116
|
+
str.gsub(%r{[^/]+}n) { uri_segment($&) }
|
117
|
+
end
|
118
|
+
|
119
|
+
# :stopdoc:
|
120
|
+
def html_form_fast(pairs, sep=';')
|
121
|
+
pairs.map {|k, v|
|
122
|
+
# query-chars - pct-encoded - x-www-form-urlencoded-delimiters =
|
123
|
+
# unreserved / "!" / "$" / "'" / "(" / ")" / "*" / "," / ":" / "@" / "/" / "?"
|
124
|
+
# query-char - pct-encoded = unreserved / sub-delims / ":" / "@" / "/" / "?"
|
125
|
+
# query-char = pchar / "/" / "?" = unreserved / pct-encoded / sub-delims / ":" / "@" / "/" / "?"
|
126
|
+
# unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
|
127
|
+
# sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
|
128
|
+
# x-www-form-urlencoded-delimiters = "&" / "+" / ";" / "="
|
129
|
+
k = k.gsub(%r{[^0-9A-Za-z\-\._~:/?@!\$'()*,]}n) {
|
130
|
+
'%' + $&.unpack("H2")[0].upcase
|
131
|
+
}
|
132
|
+
v = v.gsub(%r{[^0-9A-Za-z\-\._~:/?@!\$'()*,]}n) {
|
133
|
+
'%' + $&.unpack("H2")[0].upcase
|
134
|
+
}
|
135
|
+
"#{k}=#{v}"
|
136
|
+
}.join(sep)
|
137
|
+
end
|
138
|
+
# :startdoc:
|
139
|
+
|
140
|
+
# Escape.html_form composes HTML form key-value pairs as a x-www-form-urlencoded encoded string.
|
141
|
+
#
|
142
|
+
# Escape.html_form takes an array of pair of strings or
|
143
|
+
# an hash from string to string.
|
144
|
+
#
|
145
|
+
# Escape.html_form([["a","b"], ["c","d"]]) #=> "a=b&c=d"
|
146
|
+
# Escape.html_form({"a"=>"b", "c"=>"d"}) #=> "a=b&c=d"
|
147
|
+
#
|
148
|
+
# In the array form, it is possible to use same key more than once.
|
149
|
+
# (It is required for a HTML form which contains
|
150
|
+
# checkboxes and select element with multiple attribute.)
|
151
|
+
#
|
152
|
+
# Escape.html_form([["k","1"], ["k","2"]]) #=> "k=1&k=2"
|
153
|
+
#
|
154
|
+
# If the strings contains characters which must be escaped in x-www-form-urlencoded,
|
155
|
+
# they are escaped using %-encoding.
|
156
|
+
#
|
157
|
+
# Escape.html_form([["k=","&;="]]) #=> "k%3D=%26%3B%3D"
|
158
|
+
#
|
159
|
+
# The separator can be specified by the optional second argument.
|
160
|
+
#
|
161
|
+
# Escape.html_form([["a","b"], ["c","d"]], ";") #=> "a=b;c=d"
|
162
|
+
#
|
163
|
+
# See HTML 4.01 for details.
|
164
|
+
def html_form(pairs, sep='&')
|
165
|
+
r = ''
|
166
|
+
first = true
|
167
|
+
pairs.each {|k, v|
|
168
|
+
# query-chars - pct-encoded - x-www-form-urlencoded-delimiters =
|
169
|
+
# unreserved / "!" / "$" / "'" / "(" / ")" / "*" / "," / ":" / "@" / "/" / "?"
|
170
|
+
# query-char - pct-encoded = unreserved / sub-delims / ":" / "@" / "/" / "?"
|
171
|
+
# query-char = pchar / "/" / "?" = unreserved / pct-encoded / sub-delims / ":" / "@" / "/" / "?"
|
172
|
+
# unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
|
173
|
+
# sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
|
174
|
+
# x-www-form-urlencoded-delimiters = "&" / "+" / ";" / "="
|
175
|
+
r << sep if !first
|
176
|
+
first = false
|
177
|
+
k.each_byte {|byte|
|
178
|
+
ch = byte.chr
|
179
|
+
if %r{[^0-9A-Za-z\-\._~:/?@!\$'()*,]}n =~ ch
|
180
|
+
r << "%" << ch.unpack("H2")[0].upcase
|
181
|
+
else
|
182
|
+
r << ch
|
183
|
+
end
|
184
|
+
}
|
185
|
+
r << '='
|
186
|
+
v.each_byte {|byte|
|
187
|
+
ch = byte.chr
|
188
|
+
if %r{[^0-9A-Za-z\-\._~:/?@!\$'()*,]}n =~ ch
|
189
|
+
r << "%" << ch.unpack("H2")[0].upcase
|
190
|
+
else
|
191
|
+
r << ch
|
192
|
+
end
|
193
|
+
}
|
194
|
+
}
|
195
|
+
r
|
196
|
+
end
|
197
|
+
|
198
|
+
# :stopdoc:
|
199
|
+
HTML_TEXT_ESCAPE_HASH = {
|
200
|
+
'&' => '&',
|
201
|
+
'<' => '<',
|
202
|
+
'>' => '>',
|
203
|
+
}
|
204
|
+
# :startdoc:
|
205
|
+
|
206
|
+
# Escape.html_text escapes a string appropriate for HTML text using character references.
|
207
|
+
#
|
208
|
+
# It escapes 3 characters:
|
209
|
+
# * '&' to '&'
|
210
|
+
# * '<' to '<'
|
211
|
+
# * '>' to '>'
|
212
|
+
#
|
213
|
+
# Escape.html_text("abc") #=> "abc"
|
214
|
+
# Escape.html_text("a & b < c > d") #=> "a & b < c > d"
|
215
|
+
#
|
216
|
+
# This function is not appropriate for escaping HTML element attribute
|
217
|
+
# because quotes are not escaped.
|
218
|
+
def html_text(str)
|
219
|
+
str.gsub(/[&<>]/) {|ch| HTML_TEXT_ESCAPE_HASH[ch] }
|
220
|
+
end
|
221
|
+
|
222
|
+
# :stopdoc:
|
223
|
+
HTML_ATTR_ESCAPE_HASH = {
|
224
|
+
'&' => '&',
|
225
|
+
'<' => '<',
|
226
|
+
'>' => '>',
|
227
|
+
'"' => '"',
|
228
|
+
}
|
229
|
+
# :startdoc:
|
230
|
+
|
231
|
+
# Escape.html_attr encodes a string as a double-quoted HTML attribute using character references.
|
232
|
+
#
|
233
|
+
# Escape.html_attr("abc") #=> "\"abc\""
|
234
|
+
# Escape.html_attr("a&b") #=> "\"a&b\""
|
235
|
+
# Escape.html_attr("ab&<>\"c") #=> "\"ab&<>"c\""
|
236
|
+
# Escape.html_attr("a'c") #=> "\"a'c\""
|
237
|
+
#
|
238
|
+
# It escapes 4 characters:
|
239
|
+
# * '&' to '&'
|
240
|
+
# * '<' to '<'
|
241
|
+
# * '>' to '>'
|
242
|
+
# * '"' to '"'
|
243
|
+
#
|
244
|
+
def html_attr(str)
|
245
|
+
'"' + str.gsub(/[&<>"]/) {|ch| HTML_ATTR_ESCAPE_HASH[ch] } + '"'
|
246
|
+
end
|
247
|
+
end
|
@@ -0,0 +1,213 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
|
5
|
+
# *Audience*: World, QualitySmith
|
6
|
+
|
7
|
+
module SharedTasks
|
8
|
+
#---------------------------------------------------------------------------------------------------------------------------------
|
9
|
+
# Tests
|
10
|
+
|
11
|
+
# Lets you very concisely create a test task using some common default options. A block may be provided if you want to set additional options.
|
12
|
+
# *Example*:
|
13
|
+
# SharedTasks.normal_test_task
|
14
|
+
# *Audience*: World
|
15
|
+
def self.normal_test_task()
|
16
|
+
module_eval do
|
17
|
+
desc 'Run tests'
|
18
|
+
Rake::TestTask.new(:test) do |task|
|
19
|
+
task.libs << 'lib'
|
20
|
+
task.pattern = 'test/**/*_test.rb'
|
21
|
+
task.verbose = true
|
22
|
+
# To do: autorequire color library? Could do something like this once we switch to gem dependencies...
|
23
|
+
#task.ruby_opts << "-r /home/tyler/code/gemables/test_extensions/lib/test_helper.rb"
|
24
|
+
yield task if block_given?
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
#---------------------------------------------------------------------------------------------------------------------------------
|
29
|
+
# Documentation
|
30
|
+
|
31
|
+
# Generates an RDoc task for you with common options enabled, including a nicer template than the default.
|
32
|
+
# Pass it a block if you need to customize it.
|
33
|
+
# Example:
|
34
|
+
# SharedTasks.rdoc_task do |rdoc|
|
35
|
+
# rdoc.title = Project::PrettyName
|
36
|
+
# end
|
37
|
+
# *Audience*: World
|
38
|
+
def self.rdoc_task(&block)
|
39
|
+
module_eval do
|
40
|
+
#-------------------------------------------------------------------------------------------
|
41
|
+
desc 'Generate RDoc'
|
42
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
43
|
+
rdoc.rdoc_dir = 'doc'
|
44
|
+
rdoc.options <<
|
45
|
+
'--line-numbers' << # Include line numbers in the source code
|
46
|
+
'--inline-source' << # Causes "Show source" link to display source inline rather than as a popup
|
47
|
+
'--all' << # Include private methods
|
48
|
+
'--diagram' << # Include diagrams showing modules and classes.
|
49
|
+
'--accessor' << 'mattr_accessor' << # So that attributes defined with mattr_accessor will be listed
|
50
|
+
'--extension' << 'rake=rb' # Treat .rake files as files that contain Ruby code
|
51
|
+
rdoc.template = './doc_include/template/qualitysmith.rb'
|
52
|
+
rdoc.rdoc_files.include(
|
53
|
+
'Readme',
|
54
|
+
'lib/**/*.rb'
|
55
|
+
)
|
56
|
+
yield rdoc
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Put images and stuff under doc_include and you can refer to them with links such as Screenshot[link:include/screenshot1.png]
|
62
|
+
task :doc_include do
|
63
|
+
mkdir 'doc' rescue nil
|
64
|
+
cp_r 'doc_include', target = 'doc/include'
|
65
|
+
|
66
|
+
# Remove those pesky .svn directories
|
67
|
+
require 'find'
|
68
|
+
require 'fileutils'
|
69
|
+
Find.find(target) do |path|
|
70
|
+
if File.basename(path) == '.svn'
|
71
|
+
FileUtils.remove_dir(path, true)
|
72
|
+
Find.prune
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Well, I'd rather make :doc_includes a "postrequisite" for :rdoc, but unfortunately Rake doesn't seem to provide a way to specify postrequisites.
|
78
|
+
# and :clobber_rdoc (lib/rake/rdoctask.rb) does a rm_r rdoc_dir so anything we do to the directory *before* :rdoc will get wiped out.
|
79
|
+
# So... we are left with making :doc_include a prerequisite for the publishing tasks. Unless you have a better idea??
|
80
|
+
task :publish_rdoc_local => :rerdoc
|
81
|
+
task :publish_rdoc_local => :doc_include
|
82
|
+
|
83
|
+
|
84
|
+
#---------------------------------------------------------------------------------------------------------------------------------
|
85
|
+
# Packaging (creating a new version/release)
|
86
|
+
|
87
|
+
require 'rake/gempackagetask'
|
88
|
+
|
89
|
+
def release_notes; "doc_include/ReleaseNotes-#{Project::Version}"; end
|
90
|
+
|
91
|
+
def self.package_task(specification, &block)
|
92
|
+
module_eval do
|
93
|
+
Rake::GemPackageTask.new(specification) do |package|
|
94
|
+
package.need_zip = true
|
95
|
+
package.need_tar = true
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def self.inc_version(file)
|
101
|
+
module_eval do
|
102
|
+
desc "Increment version number and create release notes"
|
103
|
+
task :inc_version do
|
104
|
+
# This will be easier once we change to a YAML-based ProjectInfo file...
|
105
|
+
require 'facets/core/file/self/open_as_string'
|
106
|
+
new_version = Project::Version
|
107
|
+
File.open_as_string(file) do |contents|
|
108
|
+
contents.gsub!(/(Version *=.*?)(\d+\.\d+\.\d+)(.*)$/) do
|
109
|
+
before, version, after = $1, $2, $3
|
110
|
+
version = version.split('.')
|
111
|
+
new_version = version[0] + '.' + version[1] + '.' + (version[2].to_i+1).to_s
|
112
|
+
new_text = before + new_version + after
|
113
|
+
puts new_text
|
114
|
+
new_text
|
115
|
+
end
|
116
|
+
end
|
117
|
+
Project.const_set(:Version, new_version)
|
118
|
+
|
119
|
+
system(%(vim #{release_notes}))
|
120
|
+
sh %(svn add #{release_notes})
|
121
|
+
puts "When you're ready to commit, you can use this:"
|
122
|
+
puts "svn ci -F #{release_notes}"
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
desc "Test installing the gem locally"
|
128
|
+
# Use rake clean to force rebuilding of gem. Otherwise it may see that it has already built a gem file with that name and just try to reinstall the one we've already got.
|
129
|
+
task :gem_install => [:clean, :gem] do
|
130
|
+
# :todo:
|
131
|
+
# This should give a loud warning and require confirmation if this version already installed.
|
132
|
+
# Ask if they want to increment the version number instead (default). It doesn't cost anything to just increment the version number,
|
133
|
+
# and it's bad practice to use the same version number for two versions that are actually *different*.
|
134
|
+
# It would be okay to reinstall (--force) the current version if one is just testing something *prior* to official release.
|
135
|
+
# But once a version is released, it should never be changed. So I guess rather than checking if this version is installed locally,
|
136
|
+
# we should check some flag that we keep in ProjectVersion containing the last version number that has been published and refuse to
|
137
|
+
# rebuild a gem version that has already been released...
|
138
|
+
sh %{sudo gem install --force pkg/#{Project::Name}-#{Project::Version}.gem }
|
139
|
+
end
|
140
|
+
|
141
|
+
desc "Remove generated directories."
|
142
|
+
task :clean do
|
143
|
+
sh %(rm -rf doc/ pkg/)
|
144
|
+
end
|
145
|
+
|
146
|
+
|
147
|
+
#---------------------------------------------------------------------------------------------------------------------------------
|
148
|
+
# Publishing
|
149
|
+
|
150
|
+
require 'rake/contrib/sshpublisher'
|
151
|
+
|
152
|
+
def self.publish_task()
|
153
|
+
module_eval do
|
154
|
+
desc "Upload RDoc to RubyForge"
|
155
|
+
task :publish_rdoc => [:publish_rdoc_local] do
|
156
|
+
Rake::SshDirPublisher.new("#{ENV['RUBYFORGE_USER']}@rubyforge.org", "/var/www/gforge-projects/#{Project::RubyForgeName}", "doc").upload
|
157
|
+
end
|
158
|
+
|
159
|
+
# This can be invoked from the command line:
|
160
|
+
# rake release RUBYFORGE_USER=myuser \
|
161
|
+
# RUBYFORGE_PASSWORD=mypassword
|
162
|
+
task :verify_user do
|
163
|
+
raise "RUBYFORGE_USER environment variable not set!" unless ENV['RUBYFORGE_USER']
|
164
|
+
end
|
165
|
+
task :verify_password do
|
166
|
+
raise "RUBYFORGE_PASSWORD environment variable not set!" unless ENV['RUBYFORGE_PASSWORD']
|
167
|
+
end
|
168
|
+
|
169
|
+
desc "Publish package files on RubyForge."
|
170
|
+
task :publish_packages => [:verify_user, :verify_password, :package] do
|
171
|
+
require 'meta_project'
|
172
|
+
require 'rake/contrib/xforge'
|
173
|
+
release_files = FileList[
|
174
|
+
"pkg/#{Project::Name}-#{Project::Version}.gem",
|
175
|
+
"pkg/#{Project::Name}-#{Project::Version}.tgz",
|
176
|
+
"pkg/#{Project::Name}-#{Project::Version}.zip"
|
177
|
+
]
|
178
|
+
|
179
|
+
Rake::XForge::Release.new(MetaProject::Project::XForge::RubyForge.new(Project::RubyForgeName)) do |release|
|
180
|
+
release.user_name = ENV['RUBYFORGE_USER']
|
181
|
+
release.password = ENV['RUBYFORGE_PASSWORD']
|
182
|
+
release.files = release_files.to_a
|
183
|
+
release.package_name = "#{Project::Name}"
|
184
|
+
release.release_name = "#{Project::Name} #{Project::Version}"
|
185
|
+
release.release_changes = ''
|
186
|
+
release.release_notes = File.read(release_notes) # Probably want to put them somewhere else, but for now...
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
# *Audience*: Qualitysmith
|
193
|
+
desc "Upload RDoc to rdoc.QualitySmith.com"
|
194
|
+
task :publish_rdoc_local do
|
195
|
+
sh %{ssh commodore mkdir -p /var/www/html/rdoc/#{Project::Name} }
|
196
|
+
sh %{ssh commodore sudo chown :users -R /var/www/html/rdoc/#{Project::Name} }
|
197
|
+
sh %{ssh commodore sudo chmod g+w -R /var/www/html/rdoc/#{Project::Name} }
|
198
|
+
Rake::SshDirPublisher.new("#{ENV['USER']}@commodore", "/var/www/html/rdoc/#{Project::Name}", "doc").upload
|
199
|
+
end
|
200
|
+
|
201
|
+
|
202
|
+
#---------------------------------------------------------------------------------------------------------------------------------
|
203
|
+
# Announcing
|
204
|
+
|
205
|
+
task :commits_since_last_release do
|
206
|
+
# Look at last release number/revision
|
207
|
+
# Display log messages for all revisions since then
|
208
|
+
# Can use it to write the release notes for you
|
209
|
+
end
|
210
|
+
|
211
|
+
end # SharedTasks
|
212
|
+
|
213
|
+
include SharedTasks
|
metadata
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.2
|
3
|
+
specification_version: 1
|
4
|
+
name: escape
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.0.1
|
7
|
+
date: 2007-04-26 00:00:00 -07:00
|
8
|
+
summary: ...
|
9
|
+
require_paths:
|
10
|
+
- .
|
11
|
+
email:
|
12
|
+
homepage: http://rdoc.qualitysmith.com/escape
|
13
|
+
rubyforge_project: escape
|
14
|
+
description: ...
|
15
|
+
autorequire:
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
post_install_message:
|
29
|
+
authors:
|
30
|
+
- ...
|
31
|
+
files:
|
32
|
+
- escape.rb
|
33
|
+
- tasks/shared/shared_tasks.rb
|
34
|
+
- doc_include/template/qualitysmith.rb
|
35
|
+
- Readme
|
36
|
+
test_files: []
|
37
|
+
|
38
|
+
rdoc_options:
|
39
|
+
- --title
|
40
|
+
- escape
|
41
|
+
- --main
|
42
|
+
- Readme
|
43
|
+
- --line-numbers
|
44
|
+
extra_rdoc_files:
|
45
|
+
- Readme
|
46
|
+
executables: []
|
47
|
+
|
48
|
+
extensions: []
|
49
|
+
|
50
|
+
requirements: []
|
51
|
+
|
52
|
+
dependencies: []
|
53
|
+
|