allison 2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,317 @@
1
+
2
+ // Allison 3 template
3
+ // Copyright 2007 Cloudburst LLC, all rights reserved
4
+ // Redistribution or modification prohibited
5
+
6
+ var href_base = '%style_url%'.replace(/(.*\/).*/, '$1'); // inline js is good for something
7
+
8
+ function $(id) {
9
+ if (document.getElementById)
10
+ elem = document.getElementById(id);
11
+ else if ( document.all )
12
+ elem = eval("document.all." + id);
13
+ else
14
+ return false;
15
+ return elem;
16
+ }
17
+
18
+ function toggle(id) {
19
+ elem = $(id);
20
+ elemStyle = elem.style;
21
+ if (elemStyle.display == "block") {
22
+ elemStyle.display = "none"
23
+ } else {
24
+ elemStyle.display = "block"
25
+ }
26
+ return true;
27
+ }
28
+
29
+ function toggleText(id) {
30
+ elem = $(id)
31
+ if (m = elem.innerHTML.match(/(Hide)(.*)/)) {
32
+ elem.innerHTML = "Show" + m[2];
33
+ } else if (m = elem.innerHTML.match(/(Show)(.*)/)) {
34
+ elem.innerHTML = "Hide" + m[2];
35
+ }
36
+ return true;
37
+ }
38
+
39
+ function span(s, klass) {
40
+ return '<span class="' + klass + '">' + s + '</span>';
41
+ }
42
+
43
+ function highlightSymbols() {
44
+ pres = document.getElementsByTagName('pre');
45
+ for(var i = 0; i < pres.length; i++) {
46
+ pre = pres[i];
47
+ spans = pre.getElementsByTagName('span');
48
+ for(var k = 0; k < spans.length; k++) {
49
+ span = spans[k];
50
+ if (span.className.match(/ruby-identifier/)) {
51
+ if (span.innerHTML.match(/^:/)) {
52
+ span.className += " ruby-symbol";
53
+ }
54
+ }
55
+ }
56
+ }
57
+ }
58
+
59
+ function hasClass(obj) {
60
+ var result = false;
61
+ if (obj.getAttributeNode("class") != null) {
62
+ result = obj.getAttributeNode("class").value;
63
+ }
64
+ return result;
65
+ }
66
+
67
+ function stripe() {
68
+ var even = true;
69
+ var color = "#e4ebed";
70
+ var tables = document.getElementsByTagName('table');
71
+ if (tables.length == 0) { return; }
72
+ for (var h = 0; h < tables.length; h++) {
73
+ var trs = tables[h].getElementsByTagName("tr");
74
+ for (var i = 0; i < trs.length; i++) {
75
+ var tds = trs[i].getElementsByTagName("td");
76
+ for (var j = 0; j < tds.length; j++) {
77
+ if (hasClass(tds[j]) != "first") {
78
+ var mytd = tds[j];
79
+ if (even) {
80
+ mytd.style.backgroundColor = color;
81
+ }
82
+ }
83
+ }
84
+ even = ! even;
85
+ }
86
+ }
87
+ }
88
+
89
+ function ajaxGet(url) {
90
+ url = (href_base + url).replace('/./', '/')
91
+ var req = false;
92
+
93
+ if (window.ActiveXObject) {
94
+ try {
95
+ // stupid hack because IE7 disables local Ajax with the native xmlhttprequest object
96
+ // for security purposes. Yet ActiveX still works. Thanks, Microsoft. I hate you. Die.
97
+ req = new ActiveXObject("MSXML2.XMLHTTP.3.0");
98
+ } catch (e) {
99
+ try {
100
+ /* IE 6 and maybe 5, don't know, don't care */
101
+ req = new ActiveXObject("Msxml2.XMLHTTP");
102
+ } catch (e) {
103
+ try {
104
+ req = new ActiveXObject("Microsoft.XMLHTTP");
105
+ } catch (e) {
106
+ req = false;
107
+ }
108
+ }
109
+ }
110
+ }
111
+
112
+ /* real browsers */
113
+ if (!req && window.XMLHttpRequest) {
114
+ try {
115
+ req = new XMLHttpRequest();
116
+ } catch (e) {
117
+ req = false;
118
+ }
119
+ }
120
+
121
+ if (req) {
122
+ req.open('GET', url, false);
123
+ req.send(null);
124
+ return req.responseText;
125
+ } else {
126
+ return "Ajax error";
127
+ }
128
+ }
129
+
130
+
131
+ function addEvent(elm, evType, fn, useCapture) {
132
+ if (elm.addEventListener) {
133
+ elm.addEventListener(evType, fn, useCapture);
134
+ return true;
135
+ } else if (elm.attachEvent) {
136
+ var r = elm.attachEvent('on' + evType, fn);
137
+ return r;
138
+ } else {
139
+ elm['on' + evType] = fn;
140
+ }
141
+ }
142
+
143
+ function insertIndices() {
144
+ pages = ["class", "file", "method"]
145
+ for (x in pages) {
146
+ $(pages[x]).innerHTML += ajaxGet('fr_' + pages[x] + '_index.html').replace(/(href=")/g, '$1' + href_base);
147
+ }
148
+ /* mouseoverify method links */
149
+ links = $('method').getElementsByTagName('a');
150
+ for (var x = 0; x < links.length; x++) {
151
+ if (m = links[x].innerHTML.match(/(.*)\s\((.*)\)/)) {
152
+ links[x].innerHTML = m[1] + '<br>';
153
+ links[x].title = m[2];
154
+ }
155
+ }
156
+ /* this is stupid */
157
+ $('class').style.display = "block";
158
+ $('file').style.display = "block";
159
+
160
+ /* has to be here because IE7 does not guarantee the onLoad callback order */
161
+ abbreviateIndicesInner(["class", "file"], 25, "a");
162
+ /* same, linkTitle() depends on the class link list */
163
+ linkTitle();
164
+ }
165
+
166
+ function abbreviateIndices() {
167
+ var ids = ["defined_in", "child_of", "includes", "requires", "method", "methods"];
168
+ abbreviateIndicesInner(ids, 25, 'a');
169
+ abbreviateIndicesInner(ids, 25, 'span');
170
+ }
171
+
172
+ function abbreviateIndicesInner(indices, amount, tag) {
173
+ for (var x = 0; x < indices.length; x++) {
174
+ var the_index = $(indices[x]);
175
+ if (the_index) {
176
+ links = the_index.getElementsByTagName(tag);
177
+ for (var y = 0; y < links.length; y++) {
178
+ var link = links[y];
179
+ if (link.getElementsByTagName('span').length == 0 && link.getElementsByTagName('a').length == 0) {
180
+ // avoid nesting
181
+ link.innerHTML = link.innerHTML.replace(/<br>|\n/gi, '');
182
+ link.title = link.innerHTML;
183
+ link.innerHTML = abbreviate(link.innerHTML, amount) + '<br>';
184
+ }
185
+ }
186
+ }
187
+ }
188
+ }
189
+
190
+ function linkTitle() {
191
+
192
+ /* grab the correct title element from the index */
193
+ var index_page = ajaxGet('index.html');
194
+ title_text = index_page.match(/<title>(.*)<\/title>/m)[1];
195
+ document.title = title_text + " - " + document.title;
196
+ var p = $('header').getElementsByTagName('p')[0]
197
+ if (p.innerHTML.match(/^\s*$/)) {
198
+ p.innerHTML = title_text;
199
+ } else {
200
+ p.innerHTML = title_text + ": " + p.innerHTML;
201
+ }
202
+
203
+ /* set the link properly */
204
+ title_link = index_page.match(/<a\s+href="(.*?)"/)[1];
205
+ var element = $('title');
206
+ var item_type = "";
207
+ var item_name = "";
208
+ if (m = element.innerHTML.match(/(Class:|Module:|File:)\s*(.*)/)) {
209
+ item_type = m[1];
210
+ item_name = m[2];
211
+ } else {
212
+ item_name = element.innerHTML;
213
+ }
214
+ element.innerHTML = '<a href="' + href_base + title_link + '">' + item_type + " " + abbreviate(item_name, 45) + '</a>';
215
+ element.getElementsByTagName('a')[0].title = item_name
216
+
217
+ /* breadcrumb navigation */
218
+ items = item_name.split("::");
219
+ items_new = item_name.split("::");
220
+ file_links = $('class').getElementsByTagName('a');
221
+ for (var x = 0; x < items.length - 1; x++ ){
222
+ var item = items[x];
223
+ link = ("/classes/" + items.slice(0,x).join("/") + "/" + item + ".html").replace('//', '/');
224
+ regex = new RegExp(RegExp.escape(link) + '$');
225
+ for (var y = 0; y < file_links.length; y++) {
226
+ if (file_links[y].href.match(regex)) {
227
+ items_new[x] = '<a href="' + href_base + link + '">' + item + '</a>';
228
+ break;
229
+ }
230
+ }
231
+ }
232
+ $('item_name').innerHTML = item_type + ' ' + items_new.join(" :: ");
233
+ }
234
+
235
+ function abbreviate(s, size) {
236
+ while (s.length > size) {
237
+ var old_s = s;
238
+ s = s.replace(/\s|\n/mg, '');
239
+ s = s.replace(/([A-Z])[a-z]+/m, '$1');
240
+ if (!s || old_s == s) {
241
+ return "..." + s.substring(s.length - size, s.length);
242
+ }
243
+ }
244
+ return s;
245
+ }
246
+
247
+ function disableSubmit(event) {
248
+ var keyCode = event.keyCode ? event.keyCode : event.which ? event.which : event.charCode;
249
+ if (keyCode == 13) {
250
+ return false;
251
+ } else {
252
+ return true;
253
+ }
254
+ }
255
+
256
+ function filterList(id, s, event) {
257
+
258
+ /* some weak escaping */
259
+ s = s.replace(/[^\w\d\.\_\-\/\:\=\[\]\?\!]/g, '');
260
+ s = RegExp.escape(s);
261
+
262
+ var show_all = false;
263
+ if (s.match(/^\s*$/)) {
264
+ show_all = true;
265
+ }
266
+
267
+ links = $(id).getElementsByTagName('a')
268
+ regex = new RegExp(s, 'i');
269
+
270
+ for (var x = 0; x < links.length; x++) {
271
+ var link = links[x];
272
+ if (show_all) {
273
+ link.style.display = 'inline';
274
+ } else {
275
+ if (link.innerHTML.match(regex)) {
276
+ link.style.display = 'inline';
277
+ } else {
278
+ link.style.display = 'none';
279
+ }
280
+ }
281
+ }
282
+ return true;
283
+ }
284
+
285
+ RegExp.escape = function(text) {
286
+ if (!arguments.callee.sRE) {
287
+ var specials = ['/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\\\'];
288
+ arguments.callee.sRE = new RegExp(
289
+ '(\\\\' + specials.join('|\\\\') + ')', 'g'
290
+ );
291
+ }
292
+ return text.replace(arguments.callee.sRE, '\\\\$1');
293
+ }
294
+
295
+ function hacks() {
296
+ // show the spacer if necessary,
297
+ divs = document.getElementsByTagName('div');
298
+ for(var x = 0; x < divs.length; x++) {
299
+ if (divs[x].className && divs[x].className.match(/top/)) {
300
+ document.getElementById('spacer').style.display = 'block';
301
+ }
302
+ }
303
+ // remove extra colons from tables
304
+ tds = document.getElementsByTagName('td');
305
+ for(var x = 0; x < tds.length; x++) {
306
+ str = tds[x].innerHTML
307
+ if (str.charAt(str.length - 1) == ":") {
308
+ tds[x].innerHTML = str.slice(0, str.length - 1)
309
+ }
310
+ }
311
+ }
312
+
313
+ addEvent(window, 'load', insertIndices, false);
314
+ addEvent(window, 'load', abbreviateIndices, false);
315
+ addEvent(window, 'load', stripe, false);
316
+ addEvent(window, 'load', highlightSymbols, false);
317
+ addEvent(window, 'load', hacks, false);
@@ -0,0 +1,281 @@
1
+
2
+ # RDoc workarounds
3
+ class String
4
+ def if_exists (item = nil)
5
+ unless item
6
+ self unless self =~ /(%(\w+)%)/
7
+ "\nIF:#{$2}\n#{self}\nENDIF:#{$2}\n"
8
+ else
9
+ "\nIF:#{item}\n#{self}\nENDIF:#{item}\n"
10
+ end
11
+ end
12
+ def loop(item)
13
+ "\nSTART:#{item}\n#{self}\nEND:#{item}\n"
14
+ end
15
+ end
16
+
17
+ module RDoc
18
+ module Page
19
+
20
+ puts "Allison 2 template (c) 2007 Cloudburst, LLC"
21
+
22
+ require 'pathname'
23
+ CACHE_DIR = File.expand_path(File.dirname(__FILE__) + "/../cache")
24
+ Dir.mkdir(CACHE_DIR) unless File.exist?(CACHE_DIR)
25
+
26
+ begin
27
+ require 'rubygems'
28
+ gem 'markaby', '>= 0.5'
29
+ require 'markaby'
30
+ require 'base64'
31
+
32
+ # Markaby page says Markaby is better in its own module
33
+ module Allison
34
+
35
+ PROJECT = `pwd`.split("/").reverse.detect {|dir| dir !~ /trunk/ }
36
+
37
+ FONTS = METHOD_LIST = SRC_PAGE = FILE_PAGE = CLASS_PAGE = ""
38
+
39
+ FR_INDEX_BODY = "!INCLUDE!" # Who knows
40
+
41
+ STYLE, JAVASCRIPT = ["css", "js"].map do |extension|
42
+ s = File.open(File.dirname(__FILE__) + "/allison.#{extension}").read
43
+ # Programmatic CSS
44
+ if extension == "css"
45
+ s_lines = s.split("\n")
46
+ meths = []
47
+ s_lines.collect! do |line|
48
+ line = line.squeeze(" ").strip
49
+ if line =~ /(\w+)/ and meths.include? $1
50
+ line = instance_eval line
51
+ # puts "Called method #{$1}"
52
+ elsif line !~ /\*\/|\/\*/ and line =~ /(@.*|^def (\w+).*)/
53
+ # printf "Evalled #{$1}"
54
+ result = instance_eval $1
55
+ # puts " to #{result.inspect}"
56
+ result = (result.is_a?(Fixnum) ? result.to_s + "px" : result.to_s)
57
+ line = (line == $1 ? "" : line.gsub($1, result))
58
+ meths.push $2 if $2
59
+ end
60
+ line !~ /^\s*$|\s*^\/\*.*\*\/\s*$|\{|\}/ ? line + ";" : line
61
+ end
62
+ s = s_lines.join("\n")
63
+ else
64
+ # Do nothing; the Javascript is already fine
65
+ end
66
+ s
67
+ end
68
+
69
+ INDEX = Markaby::Builder.new.xhtml_strict do
70
+ head do
71
+ title '%title%'
72
+ link :rel => 'stylesheet', :type => 'text/css', :href => 'rdoc-style.css', :media => 'screen'
73
+ tag! :meta, 'http-equiv' => 'refresh', 'content' => '0;url=%initial_page%'
74
+ end
75
+ body do
76
+ div.container! do
77
+ 6.times {|n| div('', :class => "curve", :id => "preheader_curve_#{n}") }
78
+ div.header! do
79
+ span.title! do
80
+ p { '&nbsp;' }
81
+ h1 "Ruby Documentation"
82
+ end
83
+ end
84
+ div.clear {}
85
+ div.redirect! do
86
+ a :href => '%initial_page%' do
87
+ h1 "Redirect"
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end.to_s
93
+
94
+ FILE_INDEX = METHOD_INDEX = CLASS_INDEX = Markaby::Builder.new.capture do
95
+ a :href => '%href%' do
96
+ self << '%name%'
97
+ br
98
+ end
99
+ end.loop('entries')
100
+
101
+ BODY = Markaby::Builder.new.xhtml_strict do
102
+ head do
103
+ title "%title%"
104
+ link :rel => 'stylesheet', :type => 'text/css', :href => '%style_url%', :media => 'screen'
105
+ script :type => 'text/javascript' do
106
+ JAVASCRIPT
107
+ end
108
+ end
109
+ body do
110
+ div.container! do
111
+ 6.times {|n| div('', :class => "curve", :id => "preheader_curve_#{n}") }
112
+ div.header! do
113
+ p {'%full_path%'.if_exists}
114
+ span do
115
+ h1.title! '%title%'.if_exists
116
+ end
117
+ self << "!INCLUDE!" # Always empty
118
+ end
119
+ div.clear {}
120
+ div.left! do
121
+ self << (div.navigation.darker.top.child_of! do
122
+ # Ugh
123
+ h3 "Child of"
124
+ self << "<span>\n#{"<a href='%par_url%'>".if_exists}%parent%#{"</a>".if_exists('par_url')}</span>"
125
+ end).if_exists('parent')
126
+
127
+ self << div.navigation.darker.top.defined_in! do
128
+ h3('Defined in')
129
+ self << a('%full_path%', :href => '%full_path_url%').if_exists.loop('infiles')
130
+ end.if_exists('infiles')
131
+
132
+ ['includes', 'requires', 'methods'].each do |item|
133
+ self << div.navigation.top(:id => item) do
134
+ self << h3(item.capitalize)
135
+ self << "#{"<a href='%aref%'>".if_exists}%name%#{br}#{"</a>".if_exists('aref')}".if_exists('name').loop(item)
136
+ end.if_exists(item)
137
+ end
138
+
139
+ div.spacer! ''
140
+
141
+ # For the local AJAX includes
142
+ ['class', 'file', 'method'].each do |item|
143
+ div.navigation.darker.index :id => "#{item}_wrapper" do
144
+ div.list_header do
145
+ h3 'All ' + (item == 'class' ? 'classes' : item + 's')
146
+ end
147
+ div.list_header_link do
148
+ a((item == 'method' ? 'Show...' : 'Hide...'),
149
+ :id => "#{item}_link", :href => "#",
150
+ :onclick=> "toggle('#{item}'); toggleText('#{item}_link'); return false;")
151
+ end
152
+ div.clear {}
153
+ div(:id => item) do
154
+ form do
155
+ label(:for => "filter_#{item}") { 'Filter:' + '&nbsp;' * 2 }
156
+ input '', :type => 'text', :id => "filter_#{item}",
157
+ :onKeyUp => "return filterList('#{item}', this.value, event);",
158
+ :onKeyPress => "return disableSubmit(event);"
159
+ end
160
+ end
161
+ end
162
+ end
163
+ end
164
+
165
+ div.content! do
166
+
167
+ self << capture do
168
+ h1.item_name! '%title%'
169
+ end.if_exists('title')
170
+
171
+ self << capture do
172
+ div.description! do
173
+ '%description%'
174
+ end
175
+ end.if_exists('description')
176
+
177
+ self << capture do
178
+ self << h1 {a '%sectitle%', :name => '%secsequence%'}.if_exists('sectitle')
179
+ self << p {'%seccomment%'}.if_exists
180
+
181
+ self << capture do
182
+ h1 "Child modules and classes"
183
+ p '%classlist%'
184
+ end.if_exists('classlist')
185
+
186
+ ['constants', 'aliases', 'attributes'].each do |item|
187
+ self << capture do
188
+ h1(item.capitalize)
189
+ p do
190
+ table do
191
+ fields = %w[name value old_name new_name rw]
192
+ self << tr do
193
+ # Header row
194
+ if item == 'constants'
195
+ th 'Name'
196
+ th 'Value'
197
+ elsif item == 'aliases'
198
+ th 'Old name'
199
+ th 'New name'
200
+ elsif item == 'attributes'
201
+ th 'Name'
202
+ th 'Read/write?'
203
+ end
204
+ end
205
+ self << tr do
206
+ # Looped item rows
207
+ fields.each do |field|
208
+ if field !~ /desc/
209
+ self << td('%' + field + '%', :class => field =~ /^old|^name/ ? "highlight" : "normal").if_exists
210
+ else
211
+ self << td(('%' + field+ '%').if_exists)
212
+ end
213
+ end
214
+ end.loop(item)
215
+ end
216
+ end
217
+ end.if_exists(item)
218
+ end
219
+
220
+ self << capture do
221
+ h1('%type% %category% Methods')
222
+ self << capture do
223
+ self << a.small(:name => '%aref%') {br}.if_exists
224
+ div.method_block do
225
+ h3 { "<a href='#%aref%'>".if_exists + '%callseq%'.if_exists + '%name%'.if_exists + '%params%'.if_exists + "</a>".if_exists('aref')}
226
+ self << '%m_desc%'.if_exists
227
+
228
+ self << capture do
229
+ p.source_link :id => '%aref%-show-link' do
230
+ a "Show source...", :id => '%aref%-link', :href => "#",
231
+ :onclick=> "toggle('%aref%-source'); toggleText('%aref%-link'); return false;"
232
+ end
233
+ div.source :id => '%aref%-source' do
234
+ pre { '%sourcecode%' }
235
+ end
236
+ end.if_exists('sourcecode')
237
+ end
238
+
239
+ end.loop('methods').if_exists('methods')
240
+ end.loop('method_list').if_exists('method_list')
241
+
242
+ end.loop('sections').if_exists('sections')
243
+
244
+ end
245
+
246
+ div.footer!.clear do
247
+ self << Time.now.strftime("Generated on %b %d, %Y").gsub(' 0', ' ')
248
+ self << " / Allison 2 &copy; 2007 "
249
+ a "Cloudburst, LLC", :href => "http://cloudbur.st"
250
+ end
251
+ end
252
+
253
+ self << '<script src="http://feeds.feedburner.com/~s/snax" type="text/javascript" charset="utf-8"></script>'
254
+
255
+ end
256
+
257
+ end.to_s
258
+ end
259
+
260
+ Allison.constants.each do |c|
261
+ eval "#{c} = Allison::#{c}" # Jump out of the namespace
262
+ begin
263
+ File.open("#{CACHE_DIR}/#{c}", 'w') do |f|
264
+ f.puts eval(c) # Write cache
265
+ end
266
+ rescue Errno::EACCES => e
267
+ end
268
+ end
269
+
270
+ rescue LoadError => e
271
+ # We don't have some dependency
272
+ lib = (e.to_s[/(.*)\(/, 1] or e.to_s).split(" ").last.capitalize
273
+ puts "Using cache (couldn't load '#{lib}')"
274
+ Dir[CACHE_DIR + '/*'].each do |filename|
275
+ eval("#{filename.split("/").last} = File.open(filename) {|s| s.read}")
276
+ end
277
+ end
278
+
279
+ end
280
+
281
+ end