hanna 0.1.12 → 1.5.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.
Files changed (36) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG +117 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +63 -0
  5. data/lib/hanna/template_files/class_index.erb +4 -0
  6. data/lib/hanna/template_files/file_index.erb +9 -0
  7. data/lib/hanna/template_files/index.erb +15 -0
  8. data/lib/hanna/template_files/layout.erb +35 -0
  9. data/lib/hanna/template_files/method_index.erb +11 -0
  10. data/lib/hanna/template_files/method_list.erb +58 -0
  11. data/lib/hanna/template_files/method_search.js +41 -59
  12. data/lib/hanna/template_files/page.erb +48 -0
  13. data/lib/hanna/template_files/sections.erb +92 -0
  14. data/lib/hanna/template_files/styles.css +369 -0
  15. data/lib/hanna.rb +311 -1
  16. data/lib/rdoc/discover.rb +1 -0
  17. metadata +98 -90
  18. data/README.markdown +0 -102
  19. data/Rakefile +0 -4
  20. data/bin/hanna +0 -81
  21. data/lib/hanna/hanna.rb +0 -48
  22. data/lib/hanna/rdoctask.rb +0 -42
  23. data/lib/hanna/template_files/class_index.haml +0 -3
  24. data/lib/hanna/template_files/file_index.haml +0 -12
  25. data/lib/hanna/template_files/index.haml +0 -11
  26. data/lib/hanna/template_files/layout.haml +0 -34
  27. data/lib/hanna/template_files/method_index.haml +0 -13
  28. data/lib/hanna/template_files/method_list.haml +0 -37
  29. data/lib/hanna/template_files/page.haml +0 -50
  30. data/lib/hanna/template_files/prototype-1.6.0.3.js +0 -4320
  31. data/lib/hanna/template_files/sections.haml +0 -83
  32. data/lib/hanna/template_files/styles.sass +0 -364
  33. data/lib/hanna/template_helpers.rb +0 -119
  34. data/lib/hanna/template_page_patch.rb +0 -38
  35. data/lib/hanna/version.rb +0 -19
  36. data/lib/rubygems_plugin.rb +0 -28
@@ -0,0 +1,369 @@
1
+ html, body {
2
+ height: 100%; }
3
+
4
+ body {
5
+ font-family: Lucida Grande, Verdana, Arial, Helvetica, sans-serif;
6
+ font-size: 90%;
7
+ margin: 0;
8
+ padding: 0;
9
+ background: white;
10
+ color: black; }
11
+
12
+ #wrapper {
13
+ min-height: 100%;
14
+ height: auto !important;
15
+ height: 100%;
16
+ margin: 0 auto -43px; }
17
+
18
+ #footer-push {
19
+ height: 43px; }
20
+
21
+ div.header, #footer {
22
+ background: #eeeeee; }
23
+
24
+ #footer {
25
+ border-top: 1px solid silver;
26
+ margin-top: 12px;
27
+ padding: 0 2em;
28
+ line-height: 30px;
29
+ text-align: center;
30
+ font-variant: small-caps;
31
+ font-size: 95%; }
32
+
33
+ .clearing:after {
34
+ content: ".";
35
+ visibility: hidden;
36
+ height: 0;
37
+ display: block;
38
+ clear: both; }
39
+ * html .clearing {
40
+ height: 1px; }
41
+ .clearing *:first-child + html {
42
+ overflow: hidden; }
43
+
44
+ h1, h2, h3, h4, h5, h6 {
45
+ margin: 0;
46
+ font-weight: normal; }
47
+
48
+ a {
49
+ color: #0b3e71; }
50
+ a:hover {
51
+ background: #336699;
52
+ text-decoration: none;
53
+ color: #eeeeff; }
54
+
55
+ #diagram img {
56
+ border: 0; }
57
+
58
+ #description a, .method .description a, .header a {
59
+ color: #336699; }
60
+ #description a:hover, .method .description a:hover, .header a:hover {
61
+ color: #eeeeee; }
62
+ #description h1 a, #description h2 a, #description h3 a, #description h4 a, #description h5 a, #description h6 a, .method .description h1 a, .method .description h2 a, .method .description h3 a, .method .description h4 a, .method .description h5 a, .method .description h6 a, .header h1 a, .header h2 a, .header h3 a, .header h4 a, .header h5 a, .header h6 a {
63
+ color: #0b3e71; }
64
+
65
+ ol {
66
+ margin: 0;
67
+ padding: 0;
68
+ list-style: none; }
69
+ ol li {
70
+ margin-left: 0;
71
+ white-space: nowrap; }
72
+ ol li.other {
73
+ display: none; }
74
+
75
+ ol.expanded li.other {
76
+ display: list-item; }
77
+
78
+ table {
79
+ margin-bottom: 1em;
80
+ font-size: 1em;
81
+ border-collapse: collapse; }
82
+ table td, table th {
83
+ padding: 0.4em 0.8em; }
84
+ table thead {
85
+ background-color: #e8e8e8; }
86
+ table thead th {
87
+ font-variant: small-caps;
88
+ color: #666666; }
89
+ table tr {
90
+ border-bottom: 1px solid silver; }
91
+
92
+ #index a.show, div.header a.show {
93
+ text-decoration: underline;
94
+ font-style: italic;
95
+ color: #666666; }
96
+ #index a.show:after, div.header a.show:after {
97
+ content: " ..."; }
98
+ #index a.show:hover, div.header a.show:hover {
99
+ color: black;
100
+ background: #ffffee; }
101
+
102
+ #index {
103
+ font: 85%/1.2 Arial, Helvetica, sans-serif; }
104
+ #index a {
105
+ text-decoration: none; }
106
+ #index h1 {
107
+ padding: 0.2em 0.5em 0.1em;
108
+ background: #cccccc;
109
+ font: small-caps 1.2em Georgia, serif;
110
+ color: #333333;
111
+ border-bottom: 1px solid gray; }
112
+ #index form {
113
+ margin: 0;
114
+ padding: 0; }
115
+ #index form input {
116
+ margin: 0.4em 3px 0 0.4em;
117
+ width: 80%; }
118
+ #index form #search.untouched {
119
+ color: #777777; }
120
+ #index form .clear_button {
121
+ -moz-border-radius: 7px;
122
+ -webkit-border-radius: 7px;
123
+ background: #aaaaaa;
124
+ color: white;
125
+ padding: 0 5px 1px 5px;
126
+ cursor: pointer; }
127
+ #index ol {
128
+ padding: 0.4em 0.5em; }
129
+ #index ol li {
130
+ white-space: nowrap; }
131
+ #index #index-entries li.hide {
132
+ display: none; }
133
+ #index #index-entries.all li.hide {
134
+ display: block; }
135
+ #index #index-entries li a {
136
+ padding: 1px 2px; }
137
+ #index #index-entries.classes {
138
+ font-size: 1.1em; }
139
+ #index #index-entries.classes ol {
140
+ padding: 0; }
141
+ #index #index-entries.classes span.nodoc {
142
+ display: none; }
143
+ #index #index-entries.classes span.nodoc, #index #index-entries.classes a {
144
+ font-weight: bold; }
145
+ #index #index-entries.classes .parent {
146
+ font-weight: normal; }
147
+ #index #index-entries.methods li, #index #search-results.methods li {
148
+ margin-bottom: 0.2em; }
149
+ #index #index-entries.methods li a .method_name, #index #search-results.methods li a .method_name {
150
+ margin-right: 0.25em; }
151
+ #index #index-entries.methods li a .module_name, #index #search-results.methods li a .module_name {
152
+ color: #666666; }
153
+ #index #index-entries.methods li a:hover .module_name, #index #search-results.methods li a:hover .module_name {
154
+ color: #dddddd; }
155
+
156
+ #index div#index-entries.classes details > summary { list-style: none; white-space: nowrap; }
157
+ #index div#index-entries.classes details > summary::marker { content: none; }
158
+ #index div#index-entries.classes details > summary:after { content: " \25B6"; }
159
+ #index div#index-entries.classes details[open] > summary:after { content: " \25BC"; }
160
+ #index div#index-entries.classes span.class-link { display: block; white-space: nowrap; }
161
+
162
+ #attribute-list .context-item-name {
163
+ font-weight: bold; }
164
+
165
+ div.header {
166
+ font-size: 80%;
167
+ padding: 0.5em 1rem;
168
+ font-family: Arial, Helvetica, sans-serif;
169
+ border-bottom: 1px solid silver; }
170
+ div.header .name {
171
+ font-size: 1.6em;
172
+ font-family: Georgia, serif;
173
+ overflow-wrap: break-word; }
174
+ div.header .name .type {
175
+ color: #666666;
176
+ font-size: 80%;
177
+ font-variant: small-caps; }
178
+ div.header h1.name {
179
+ font-size: 2.2em; }
180
+ div.header .paths, div.header .last-update, div.header .parent {
181
+ color: #666666; }
182
+ div.header .last-update .datetime {
183
+ color: #484848; }
184
+ div.header .parent {
185
+ margin-top: 0.3em; }
186
+ div.header .parent strong {
187
+ font-weight: normal;
188
+ color: #484848; }
189
+
190
+ #content {
191
+ padding: 12px 1rem; }
192
+ #content pre, #content .method .synopsis {
193
+ font: 14px Monaco, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace;
194
+ overflow-wrap: break-word; }
195
+ #content pre {
196
+ color: black;
197
+ background: #eeeeee;
198
+ border: 1px solid silver;
199
+ padding: 0.5em 0.8em;
200
+ overflow: auto; }
201
+ #content p code, #content p tt, #content li code, #content li tt, #content dl code, #content dl tt {
202
+ font: 14px Monaco, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace;
203
+ background: #ffffe3;
204
+ padding: 2px 3px;
205
+ overflow-wrap: break-word;
206
+ line-height: 1.4; }
207
+ #content h1 code, #content h1 tt, #content h2 code, #content h2 tt, #content h3 code, #content h3 tt, #content h4 code, #content h4 tt, #content h5 code, #content h5 tt, #content h6 code, #content h6 tt {
208
+ font-size: 1.1em; }
209
+ #content #text {
210
+ position: relative; }
211
+ #content #description p {
212
+ margin-top: 0.5em; }
213
+ #content #description h1, #content #description h2, #content #description h3, #content #description h4, #content #description h5, #content #description h6 {
214
+ font-family: Georgia, serif; }
215
+ #content #description h1 {
216
+ font-size: 2.2em;
217
+ margin-bottom: 0.2em;
218
+ border-bottom: 3px double #d8d8d8;
219
+ padding-bottom: 0.1em; }
220
+ #content #description h2 {
221
+ font-size: 1.8em;
222
+ color: #0e3062;
223
+ margin: 0.8em 0 0.3em 0; }
224
+ #content #description h3 {
225
+ font-size: 1.6em;
226
+ margin: 0.8em 0 0.3em 0;
227
+ color: #666666; }
228
+ #content #description h4 {
229
+ font-size: 1.4em;
230
+ margin: 0.8em 0 0.3em 0; }
231
+ #content #description h5 {
232
+ font-size: 1.2em;
233
+ margin: 0.8em 0 0.3em 0;
234
+ color: #0e3062; }
235
+ #content #description h6 {
236
+ font-size: 1em;
237
+ margin: 0.8em 0 0.3em 0;
238
+ color: #666666; }
239
+ #content #description ul, #content #description ol, #content .method .description ul, #content .method .description ol {
240
+ margin: 0.8em 0;
241
+ padding-left: 1.5em; }
242
+ #content #description ol, #content .method .description ol {
243
+ list-style: decimal; }
244
+ #content #description ol li, #content .method .description ol li {
245
+ white-space: normal; }
246
+ #content table.rdoc-list {
247
+ border-collapse: collapse;
248
+ border-spacing: 0;
249
+ width: 100%;
250
+ overflow: auto;
251
+ display: block; }
252
+ #content table.rdoc-list tr {
253
+ background-color: white; }
254
+ #content table.rdoc-list tr:nth-child(2n) {
255
+ background-color: #f8f8f8; }
256
+ #content table.rdoc-list td.label {
257
+ font-weight: bold; }
258
+ #content table.rdoc-list td {
259
+ border: 1px solid #ddd;
260
+ padding: 6px 13px; }
261
+
262
+ #method-list {
263
+ max-height: 30rem;
264
+ background: #eeeeee;
265
+ border: 1px solid silver;
266
+ padding: 0.4em 1%;
267
+ overflow-y: auto;
268
+ overflow-x: hidden; }
269
+ #method-list h2 {
270
+ font-size: 1.3em; }
271
+ #method-list h3 {
272
+ font-variant: small-caps;
273
+ text-transform: capitalize;
274
+ font-family: Georgia, serif;
275
+ color: #666666;
276
+ font-size: 1.1em; }
277
+ #method-list ol {
278
+ padding: 0 0 0.5em 0.5em; }
279
+
280
+ #context {
281
+ border-top: 1px dashed silver;
282
+ margin-top: 1em;
283
+ margin-bottom: 1em; }
284
+
285
+ #context h2, #section h2 {
286
+ font: small-caps 1.2em Georgia, serif;
287
+ color: #444444;
288
+ margin: 1em 0 0.2em 0; }
289
+
290
+ .name-list, #class-list ol, #context ol {
291
+ overflow: auto; }
292
+
293
+ #methods .method {
294
+ border: 1px solid silver;
295
+ margin-top: 0.5em;
296
+ background: #eeeeee; }
297
+ #methods .method .synopsis {
298
+ color: black;
299
+ background: silver;
300
+ padding: 0.2em 1em; }
301
+ #methods .method .synopsis .name {
302
+ font-weight: bold; }
303
+ #methods .method .synopsis a {
304
+ text-decoration: none; }
305
+ #methods .method .description {
306
+ padding: 0 1em; }
307
+ #methods .method .description pre {
308
+ background: #f8f8f8; }
309
+ #methods .method .source {
310
+ margin: 0.5em 0; }
311
+ #methods .method .source-toggle {
312
+ font-size: 85%;
313
+ margin-left: 1em; }
314
+ #methods .public-class {
315
+ background: #ffffe4; }
316
+ #methods .public-instance .synopsis {
317
+ color: #eeeeee;
318
+ background: #336699; }
319
+
320
+ #content .method .source pre, #content pre.ruby, #methods .method .description pre.ruby {
321
+ background: #262626;
322
+ color: #ffdead;
323
+ padding: 0.5em;
324
+ border: 1px dashed #999999;
325
+ overflow: auto; }
326
+ #content .method .source pre .ruby-constant, #content pre.ruby .ruby-constant, #methods .method .description pre.ruby .ruby-constant {
327
+ color: #7fffd4;
328
+ background: transparent; }
329
+ #content .method .source pre .ruby-keyword, #content pre.ruby .ruby-keyword, #methods .method .description pre.ruby .ruby-keyword {
330
+ color: aqua;
331
+ background: transparent; }
332
+ #content .method .source pre .ruby-ivar, #content pre.ruby .ruby-ivar, #methods .method .description pre.ruby .ruby-ivar {
333
+ color: #eedd82;
334
+ background: transparent; }
335
+ #content .method .source pre .ruby-operator, #content pre.ruby .ruby-operator, #methods .method .description pre.ruby .ruby-operator {
336
+ color: #00ffee;
337
+ background: transparent; }
338
+ #content .method .source pre .ruby-identifier, #content pre.ruby .ruby-identifier, #methods .method .description pre.ruby .ruby-identifier {
339
+ color: #ffdead;
340
+ background: transparent; }
341
+ #content .method .source pre .ruby-string, #content pre.ruby .ruby-string, #methods .method .description pre.ruby .ruby-string {
342
+ color: #faa;
343
+ background: transparent; }
344
+ #content .method .source pre .ruby-node, #content pre.ruby .ruby-node, #methods .method .description pre.ruby .ruby-node {
345
+ color: #ffa07a;
346
+ background: transparent; }
347
+ #content .method .source pre .ruby-comment, #content pre.ruby .ruby-comment, #methods .method .description pre.ruby .ruby-comment {
348
+ color: #fdf;
349
+ font-weight: bold;
350
+ background: transparent; }
351
+ #content .method .source pre .ruby-regexp, #content pre.ruby .ruby-regexp, #methods .method .description pre.ruby .ruby-regexp {
352
+ color: #ffa07a;
353
+ background: transparent; }
354
+ #content .method .source pre .ruby-value, #content pre.ruby .ruby-value, #methods .method .description pre.ruby .ruby-value {
355
+ color: #7fffd4;
356
+ background: transparent; }
357
+
358
+ @media (min-width: 640px) {
359
+ div.class #content {
360
+ position: relative;
361
+ width: 72%; }
362
+
363
+ #method-list {
364
+ position: absolute;
365
+ top: 0px;
366
+ right: -33%;
367
+ width: 28%;
368
+ }
369
+ }
data/lib/hanna.rb CHANGED
@@ -1 +1,311 @@
1
- require 'hanna/hanna'
1
+ # frozen-string-literal: true
2
+
3
+ # = A better RDoc HTML template
4
+
5
+ require 'pathname'
6
+ require 'erb'
7
+ # :nocov:
8
+ require 'rdoc/rdoc' unless defined?(RDoc::Markup::ToHtml)
9
+ # :nocov:
10
+ require 'rdoc/generator'
11
+
12
+ # Hanna version of RDoc::Generator
13
+ class RDoc::Generator::Hanna
14
+ STYLE = 'styles.css'
15
+ LAYOUT = 'layout.erb'
16
+
17
+ INDEX_PAGE = 'index.erb'
18
+ CLASS_PAGE = 'page.erb'
19
+ METHOD_LIST_PAGE = 'method_list.erb'
20
+ FILE_PAGE = CLASS_PAGE
21
+ SECTIONS_PAGE = 'sections.erb'
22
+
23
+ FILE_INDEX = 'file_index.erb'
24
+ CLASS_INDEX = 'class_index.erb'
25
+ METHOD_INDEX = 'method_index.erb'
26
+
27
+ CLASS_DIR = 'classes'
28
+ FILE_DIR = 'files'
29
+
30
+ INDEX_OUT = 'index.html'
31
+ FILE_INDEX_OUT = 'fr_file_index.html'
32
+ CLASS_INDEX_OUT = 'fr_class_index.html'
33
+ METHOD_INDEX_OUT = 'fr_method_index.html'
34
+ STYLE_OUT = File.join('css', 'style.css')
35
+
36
+ METHOD_SEARCH_JS = "method_search.js"
37
+
38
+ DESCRIPTION = 'RDoc generator designed with simplicity, beauty and ease of browsing in mind'
39
+
40
+ RDoc::RDoc.add_generator( self )
41
+
42
+ class << self
43
+ alias for new
44
+
45
+ # :nocov:
46
+ # For RDoc >= 6.13.1
47
+ def setup_options(options)
48
+ options.class_module_path_prefix = CLASS_DIR if options.respond_to?(:class_module_path_prefix)
49
+ options.file_path_prefix = FILE_DIR if options.respond_to?(:file_path_prefix)
50
+ end
51
+ # :nocov:
52
+ end
53
+
54
+ def initialize( store, options )
55
+ @options = options
56
+ @store = store
57
+
58
+ @templatedir = Pathname.new File.expand_path('../hanna/template_files', __FILE__)
59
+
60
+ @files = nil
61
+ @classes = nil
62
+ @methods = nil
63
+ @attributes = nil
64
+
65
+ @basedir = Pathname.pwd.expand_path
66
+ end
67
+
68
+ def generate
69
+ @outputdir = Pathname.new( @options.op_dir ).expand_path( @basedir )
70
+
71
+ @files = @store.all_files.sort
72
+ @classes = @store.all_classes_and_modules.sort
73
+ @methods = @classes.map {|m| m.method_list }.flatten.sort
74
+ @attributes = @classes.map(&:attributes).flatten.sort
75
+
76
+ # Now actually write the output
77
+ write_static_files
78
+ generate_indexes
79
+ generate_class_files
80
+ generate_file_files
81
+ end
82
+
83
+ def write_static_files
84
+ css_dir = outjoin('css')
85
+ FileUtils.mkdir_p css_dir
86
+ File.binwrite(File.join(css_dir, 'style.css'), File.read(templjoin(STYLE)))
87
+ end
88
+
89
+ def generate_indexes
90
+ @main_page_uri = @files.find { |f| f.name == @options.main_page }.path rescue ''
91
+ File.binwrite(outjoin(INDEX_OUT), erb_template(templjoin(INDEX_PAGE)).to_html(binding))
92
+
93
+ generate_index(FILE_INDEX_OUT, FILE_INDEX, 'File', { :files => @files})
94
+ generate_index(CLASS_INDEX_OUT, CLASS_INDEX, 'Class', { :classes => @classes })
95
+ generate_index(METHOD_INDEX_OUT, METHOD_INDEX, 'Method', { :methods => @methods, :attributes => @attributes })
96
+
97
+ File.binwrite(outjoin(METHOD_SEARCH_JS), File.binread(templjoin(METHOD_SEARCH_JS)))
98
+ end
99
+
100
+ def generate_index(outfile, templfile, index_name, values)
101
+ values.merge!({
102
+ :stylesheet => STYLE_OUT,
103
+ :list_title => "#{index_name} Index"
104
+ })
105
+
106
+ index = erb_template(templjoin(templfile))
107
+
108
+ File.binwrite(outjoin(outfile), with_layout(values){index.to_html(binding, values)})
109
+ end
110
+
111
+ def generate_file_files
112
+ file_page = erb_template(templjoin(FILE_PAGE))
113
+ method_list_page = erb_template(templjoin(METHOD_LIST_PAGE))
114
+
115
+ @files.each do |file|
116
+ path = Pathname.new(file.path)
117
+ stylesheet = Pathname.new(STYLE_OUT).relative_path_from(path.dirname)
118
+
119
+ values = {
120
+ :file => file,
121
+ :entry => file,
122
+ :stylesheet => stylesheet,
123
+ :classmod => nil,
124
+ :title => file.base_name,
125
+ :list_title => nil,
126
+ :description => file.description
127
+ }
128
+
129
+ result = with_layout(values) do
130
+ file_page.to_html(binding, :values => values) do
131
+ method_list_page.to_html(binding, values)
132
+ end
133
+ end
134
+
135
+ dir = path.dirname
136
+ FileUtils.mkdir_p dir
137
+ File.binwrite(outjoin(file.path), result)
138
+ end
139
+ end
140
+
141
+ def generate_class_files
142
+ class_page = erb_template(templjoin(CLASS_PAGE))
143
+ method_list_page = erb_template(templjoin(METHOD_LIST_PAGE))
144
+ sections_page = erb_template(templjoin(SECTIONS_PAGE))
145
+
146
+ @classes.each do |klass|
147
+ outfile = classfile(klass)
148
+ stylesheet = Pathname.new(STYLE_OUT).relative_path_from(outfile.dirname)
149
+ sections = {}
150
+ klass.each_section do |section, constants, attributes|
151
+ method_types = []
152
+ alias_types = []
153
+ klass.methods_by_type(section).each do |type, visibilities|
154
+ visibilities.each do |visibility, methods|
155
+ aliases, methods = methods.partition{|x| x.is_alias_for}
156
+ method_types << ["#{visibility.to_s.capitalize} #{type.to_s.capitalize}", methods.sort] unless methods.empty?
157
+ alias_types << ["#{visibility.to_s.capitalize} #{type.to_s.capitalize}", aliases.sort] unless aliases.empty?
158
+ end
159
+ end
160
+ sections[section] = {:constants=>constants, :attributes=>attributes, :method_types=>method_types, :alias_types=>alias_types}
161
+ end
162
+
163
+ values = {
164
+ :file => klass.path,
165
+ :entry => klass,
166
+ :stylesheet => stylesheet,
167
+ :classmod => klass.type,
168
+ :title => klass.full_name,
169
+ :list_title => nil,
170
+ :description => klass.description,
171
+ :sections => sections
172
+ }
173
+
174
+ result = with_layout(values) do
175
+ h = {:values => values}
176
+ class_page.to_html(binding, h) do
177
+ method_list_page.to_html(binding, h) + sections_page.to_html(binding, h)
178
+ end
179
+ end
180
+
181
+ dir = outfile.dirname
182
+ FileUtils.mkdir_p dir
183
+ File.binwrite(outfile, result)
184
+ end
185
+ end
186
+
187
+ def with_layout(values)
188
+ layout = erb_template(templjoin(LAYOUT))
189
+ layout.to_html(binding, :values => values) { yield }
190
+ end
191
+
192
+ def frame_link(content)
193
+ content.gsub(%r!<a[ \n]href="https?://[^>]*>!).each do |tag|
194
+ a_tag, rest = tag.split(' ', 2)
195
+ rest.gsub!(/target="[^"]*"/, '')
196
+ a_tag + ' target="_top" ' + rest
197
+ end
198
+ end
199
+
200
+ # :nocov:
201
+ # For RDoc < 6.13
202
+ def class_dir
203
+ CLASS_DIR
204
+ end
205
+
206
+ def file_dir
207
+ FILE_DIR
208
+ end
209
+ # :nocov:
210
+
211
+ def h(html)
212
+ CGI::escapeHTML(html.to_s)
213
+ end
214
+
215
+ def render_class_tree(entries, prefix=nil, out=String.new)
216
+ namespaces = { }
217
+
218
+ entries.sort.each do |klass|
219
+ full_name = klass.full_name
220
+ next if namespaces[full_name]
221
+
222
+ class_prefix = "#{full_name}::"
223
+ subentries = @classes.select{|c| c.full_name.start_with?(class_prefix)}
224
+ subentries.each { |x| namespaces[x.full_name] = true }
225
+
226
+ text = prefix ? (prefix + klass.name) : klass.name
227
+ link = link_to(text, classfile(klass))
228
+
229
+ if subentries.empty?
230
+ out << "<span class=\"class-link\">" << link << "</span>\n"
231
+ else
232
+ out << '<details'
233
+ out << ' open' if full_name.count(':') == 0
234
+ out << '><summary>' << link << "</summary>\n"
235
+ render_class_tree(subentries, "<span class=\"parent\">#{full_name}::</span>", out)
236
+ out << "</details>"
237
+ end
238
+ end
239
+
240
+ out
241
+ end
242
+
243
+ def link_to(text, url)
244
+ %[<a href="#{url}">#{text}</a>]
245
+ end
246
+
247
+ def link_to_method(entry, url)
248
+ method_name = entry.pretty_name rescue entry.name
249
+ module_name = entry.parent_name rescue entry.name
250
+ link_to %Q(<span class="method_name" value="#{entry.name}">#{h method_name}</span> <span class="module_name">(#{h module_name})</span>), url
251
+ end
252
+
253
+ def classfile(klass)
254
+ Pathname.new(File.join(CLASS_DIR, klass.full_name.split('::')) + '.html')
255
+ end
256
+
257
+ def outjoin(name)
258
+ File.join(@outputdir, name)
259
+ end
260
+
261
+ def templjoin(name)
262
+ File.join(@templatedir, name)
263
+ end
264
+
265
+ class ERB < ::ERB
266
+ def to_html(binding, values = nil, &block)
267
+ local_values = {}
268
+ binding.local_variables.each do |lv|
269
+ local_values[lv] = binding.local_variable_get(lv)
270
+ end
271
+ binding.local_variable_set(:values, values) if values
272
+ binding.local_variable_set(:block, block) if block
273
+ html = result(binding)
274
+ local_values.each do |lv, val|
275
+ binding.local_variable_set(lv, val)
276
+ end
277
+ html
278
+ end
279
+ end
280
+
281
+ def erb_template(file)
282
+ ERB.new(File.read(file))
283
+ end
284
+
285
+ module LabelListTable
286
+ def list_item_start(list_item, list_type)
287
+ case list_type
288
+ when :LABEL, :NOTE
289
+ "<tr><td class='label'>#{Array(list_item.label).map{|label| to_html(label)}.join("<br />")}</td><td>"
290
+ else
291
+ super
292
+ end
293
+ end
294
+
295
+ def list_end_for(list_type)
296
+ case list_type
297
+ when :LABEL, :NOTE then
298
+ "</td></tr>"
299
+ else
300
+ super
301
+ end
302
+ end
303
+ end
304
+ end
305
+
306
+ class RDoc::Markup::ToHtml
307
+ LIST_TYPE_TO_HTML[:LABEL] = ['<table class="rdoc-list label-list"><tbody>', '</tbody></table>']
308
+ LIST_TYPE_TO_HTML[:NOTE] = ['<table class="rdoc-list note-list"><tbody>', '</tbody></table>']
309
+
310
+ prepend RDoc::Generator::Hanna::LabelListTable
311
+ end
@@ -0,0 +1 @@
1
+ require 'hanna'