voloko-sdoc 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 ADDED
File without changes
data/bin/sdoc ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rdoc/rdoc'
4
+ require File.dirname(__FILE__) + '/../lib/sdoc' # add extensions
5
+
6
+ begin
7
+ r = RDoc::RDoc.new
8
+ r.document(ARGV)
9
+ rescue RDoc::RDocError => e
10
+ $stderr.puts e.message
11
+ exit(1)
12
+ end
data/lib/sdoc.rb ADDED
@@ -0,0 +1,9 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+ require "sdoc/options"
3
+ require "sdoc/code_objects"
4
+
5
+ module SDoc
6
+ RDoc::RDoc::GENERATORS['shtml'] = RDoc::RDoc::Generator.new("sdoc/generators/shtml_generator.rb",
7
+ "SHTMLGenerator".intern,
8
+ 'shtml')
9
+ end
@@ -0,0 +1,17 @@
1
+ require "rdoc/code_objects"
2
+
3
+ module RDoc
4
+ class TopLevel
5
+ attr_accessor :file_expanded_path
6
+
7
+ def initialize(file_name)
8
+ super()
9
+ @name = "TopLevel"
10
+ @file_relative_name = file_name
11
+ @file_absolute_name = file_name
12
+ @file_expanded_path = File.expand_path(file_name)
13
+ @file_stat = File.stat(file_name)
14
+ @diagram = nil
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,354 @@
1
+ require 'rubygems'
2
+ require 'json'
3
+ require 'fileutils'
4
+ require 'rdoc/generators/html_generator'
5
+
6
+
7
+ module Generators
8
+ # SOURCE_DIR = 'source'
9
+
10
+ module MarkUp
11
+ def snippetize(str)
12
+ if str =~ /^(?>\s*)[^\#]/
13
+ content = str
14
+ else
15
+ content = str.gsub(/^\s*(#+)\s*/, '')
16
+ end
17
+ content.sub(/^(.{0,100}).*$/m, "\\1").gsub(/\r?\n/m, ' ')
18
+ end
19
+ end
20
+
21
+ module CollectMethods
22
+ def collect_methods
23
+ list = @context.method_list
24
+ unless @options.show_all
25
+ list = list.find_all {|m| m.visibility == :public || m.visibility == :protected || m.force_documentation }
26
+ end
27
+ @methods = list.collect {|m| SHtmlMethod.new(m, self, @options) }
28
+ end
29
+ end
30
+
31
+ #####################################################################
32
+
33
+ class SHtmlClass < HtmlClass
34
+ include CollectMethods
35
+
36
+ attr_accessor :children
37
+
38
+ def initialize(context, html_file, prefix, options)
39
+ super(context, html_file, prefix, options)
40
+ @children = []
41
+ end
42
+
43
+ def params
44
+ @context.superclass ? " < #{@context.superclass}" : ''
45
+ end
46
+
47
+ def snippet
48
+ @snippet ||= snippetize(@context.comment)
49
+ end
50
+
51
+ def namespace
52
+ @context.parent ? @context.parent.name : ''
53
+ end
54
+
55
+ def title
56
+ @context.name
57
+ end
58
+
59
+ def content?
60
+ document_self || children.any?{ |c| c.content? }
61
+ end
62
+
63
+ def path_if_available
64
+ document_self ? path : ''
65
+ end
66
+
67
+ def github_url
68
+ @html_file.github_url
69
+ end
70
+ end
71
+
72
+ #####################################################################
73
+
74
+ class SHtmlFile < HtmlFile
75
+ include CollectMethods
76
+
77
+ attr_accessor :github_url
78
+
79
+ def initialize(context, options, file_dir)
80
+ super(context, options, file_dir)
81
+ @github_url = SHTMLGenerator.github_url(@context.file_relative_name, @options) if (@options.github_url)
82
+ end
83
+
84
+ def params
85
+ ''
86
+ end
87
+
88
+ def snippet
89
+ @snippet ||= snippetize(@context.comment)
90
+ end
91
+
92
+ def namespace
93
+ @context.file_absolute_name
94
+ end
95
+
96
+ def title
97
+ File.basename(namespace)
98
+ end
99
+
100
+ def value_hash
101
+ super
102
+ @values["github_url"] = github_url if (@options.github_url)
103
+ @values
104
+ end
105
+
106
+ def absolute_path
107
+ @context.file_expanded_path
108
+ end
109
+
110
+ end
111
+
112
+ #####################################################################
113
+
114
+ class SHtmlMethod < HtmlMethod
115
+ def snippet
116
+ @snippet ||= snippetize(@context.comment)
117
+ end
118
+
119
+ def namespace
120
+ @html_class.name
121
+ end
122
+
123
+ def title
124
+ name
125
+ end
126
+
127
+ def github_url
128
+ if @source_code =~ /File\s(\S+), line (\d+)/
129
+ file = $1
130
+ line = $2.to_i
131
+ end
132
+ url = SHTMLGenerator.github_url(file, @options)
133
+ unless line.nil? || url.nil?
134
+ url + "#L#{line}"
135
+ else
136
+ ''
137
+ end
138
+ end
139
+ end
140
+
141
+ #####################################################################
142
+
143
+ class SHTMLGenerator < HTMLGenerator
144
+
145
+ @@github_url_cache = {}
146
+
147
+ def self.github_url(file_relative_name, options)
148
+ unless @@github_url_cache.has_key? file_relative_name
149
+ file = AllReferences[file_relative_name]
150
+ if file.nil?
151
+ return nil
152
+ end
153
+ path = file.absolute_path
154
+ name = File.basename(file_relative_name)
155
+
156
+ pwd = Dir.pwd
157
+ Dir.chdir(File.dirname(path))
158
+ s = `git log -1 --pretty=format:"commit %H" #{name}`
159
+ Dir.chdir(pwd)
160
+
161
+ m = s.match(/commit\s+(\S+)/)
162
+ if m
163
+ repository_path = path_relative_to_repository(path)
164
+ @@github_url_cache[file_relative_name] = "#{options.github_url}/blob/#{m[1]}#{repository_path}"
165
+ end
166
+ end
167
+ @@github_url_cache[file_relative_name]
168
+ end
169
+
170
+ def self.path_relative_to_repository(path)
171
+ root = find_git_dir(path)
172
+ path[root.size..path.size]
173
+ end
174
+
175
+ def self.find_git_dir(path)
176
+ while !path.empty? && path != '.'
177
+ if (File.exists? File.join(path, '.git'))
178
+ return path
179
+ end
180
+ path = File.dirname(path)
181
+ end
182
+ ''
183
+ end
184
+
185
+
186
+ def SHTMLGenerator.for(options)
187
+ AllReferences::reset
188
+ HtmlMethod::reset
189
+
190
+ SHTMLGenerator.new(options)
191
+ end
192
+
193
+ def load_html_template
194
+ template = @options.template
195
+ unless template =~ %r{/|\\}
196
+ template = File.join("sdoc/generators/template",
197
+ @options.generator.key, template)
198
+ end
199
+ require template
200
+ extend RDoc::Page
201
+ rescue LoadError
202
+ $stderr.puts "Could not find HTML template '#{template}'"
203
+ exit 99
204
+ end
205
+
206
+ def generate_html
207
+ # the individual descriptions for files and classes
208
+ gen_into(@files)
209
+ gen_into(@classes)
210
+ gen_search_index
211
+ gen_tree_index
212
+ gen_main_index
213
+ copy_resources
214
+
215
+ # this method is defined in the template file
216
+ write_extra_pages if defined? write_extra_pages
217
+ end
218
+
219
+ def build_indices
220
+ @toplevels.each do |toplevel|
221
+ @files << SHtmlFile.new(toplevel, @options, FILE_DIR)
222
+ end
223
+ @topclasses = []
224
+ RDoc::TopLevel.all_classes_and_modules.each do |cls|
225
+ @topclasses << build_class_list(cls, @files[0], CLASS_DIR)
226
+ end
227
+ end
228
+
229
+ def build_class_list(from, html_file, class_dir)
230
+ klass = SHtmlClass.new(from, html_file, class_dir, @options)
231
+ @classes << klass
232
+ from.each_classmodule do |mod|
233
+ klass.children << build_class_list(mod, html_file, class_dir)
234
+ end
235
+ klass
236
+ end
237
+
238
+ def copy_resources
239
+ FileUtils.cp_r RDoc::Page::RESOURCES_PATH, '.'
240
+ end
241
+
242
+ def search_string(string)
243
+ string.downcase.gsub(/\s/,'')
244
+ end
245
+
246
+ def gen_tree_index
247
+ tree = gen_tree_level @topclasses
248
+ File.open('tree.yaml', 'w') { |f| f.write(tree.to_yaml) }
249
+ File.open('tree.js', "w") do |f|
250
+ f.write('var tree = '); f.write(tree.to_json)
251
+ end
252
+ end
253
+
254
+ def gen_tree_level(classes)
255
+ tree = []
256
+ classes.select{|c| c.content? }.sort.each do |item|
257
+ item = [item.title, item.namespace, item.path_if_available, item.params, item.snippet, gen_tree_level(item.children)]
258
+ tree << item
259
+ end
260
+ tree
261
+ end
262
+
263
+ def gen_search_index
264
+ entries = HtmlMethod.all_methods.sort
265
+ entries += @classes.sort
266
+ entries += @files.sort
267
+ entries = entries.select { |f| f.document_self }
268
+
269
+ result = {
270
+ :searchIndex => [],
271
+ :longSearchIndex => [],
272
+ :info => []
273
+ }
274
+
275
+ entries.each_with_index do |item, index|
276
+ result[:searchIndex].push( search_string(item.title) )
277
+ result[:longSearchIndex].push( search_string(item.namespace) )
278
+ result[:info].push([item.title, item.namespace, item.path, item.params, item.snippet])
279
+ end
280
+
281
+ File.open('index.js', "w") do |f|
282
+ f.write('var data = '); f.write(result.to_json)
283
+ end
284
+ File.open('index.yaml', 'w') { |f| f.write(result.to_yaml) }
285
+ end
286
+
287
+ end
288
+
289
+ class ContextUser
290
+ def build_method_detail_list(section)
291
+ outer = []
292
+
293
+ methods = @methods.sort
294
+ for singleton in [true, false]
295
+ for vis in [ :public, :protected, :private ]
296
+ res = []
297
+ methods.each do |m|
298
+ if m.section == section and
299
+ m.document_self and
300
+ m.visibility == vis and
301
+ m.singleton == singleton
302
+ row = {}
303
+ if m.call_seq
304
+ row["callseq"] = m.call_seq.gsub(/->/, '&rarr;')
305
+ else
306
+ row["name"] = CGI.escapeHTML(m.name)
307
+ row["params"] = m.params
308
+ end
309
+ desc = m.description.strip
310
+ row["m_desc"] = desc unless desc.empty?
311
+ row["aref"] = m.aref
312
+ row["visibility"] = m.visibility.to_s
313
+
314
+ alias_names = []
315
+ m.aliases.each do |other|
316
+ if other.viewer # won't be if the alias is private
317
+ alias_names << {
318
+ 'name' => other.name,
319
+ 'aref' => other.viewer.as_href(path)
320
+ }
321
+ end
322
+ end
323
+ unless alias_names.empty?
324
+ row["aka"] = alias_names
325
+ end
326
+
327
+ if @options.inline_source
328
+ code = m.source_code
329
+ row["sourcecode"] = code if code
330
+ row["github_url"] = m.github_url
331
+ else
332
+ code = m.src_url
333
+ if code
334
+ row["codeurl"] = code
335
+ row["imgurl"] = m.img_url
336
+ row["github_url"] = m.github_url
337
+ end
338
+ end
339
+ res << row
340
+ end
341
+ end
342
+ if res.size > 0
343
+ outer << {
344
+ "type" => vis.to_s.capitalize,
345
+ "category" => singleton ? "Class" : "Instance",
346
+ "methods" => res
347
+ }
348
+ end
349
+ end
350
+ end
351
+ outer
352
+ end
353
+ end
354
+ end
@@ -0,0 +1,286 @@
1
+ /* Panel (begin) */
2
+ .panel
3
+ {
4
+ position: absolute;
5
+ width: 100%;
6
+ height: 100%;
7
+ top: 0;
8
+ left: 0;
9
+ background: #FFF;
10
+ z-index: 2;
11
+ font-family: "Helvetica Neue", "Arial", sans-serif;
12
+ }
13
+
14
+ .panel_tree .results,
15
+ .panel_results .tree
16
+ {
17
+ display: none;
18
+ }
19
+
20
+ /* Header with search box (begin) */
21
+ .panel .header
22
+ {
23
+ width: 100%;
24
+ height: 29px;
25
+ border-bottom: 1px solid #666;
26
+ position: relative;
27
+ left: 0; top: 0;
28
+ background: #e8e8e8;
29
+ }
30
+
31
+ .panel .header div
32
+ {
33
+ margin: 0 7px;
34
+ }
35
+ .panel .header table
36
+ {
37
+ height: 29px;
38
+ width: 100%;
39
+ }
40
+
41
+ .panel .header table td
42
+ {
43
+ vertical-align: middle;
44
+ text-align: middle;
45
+ }
46
+
47
+ .panel .header label
48
+ {
49
+ position: absolute;
50
+ font-size: 12px;
51
+ line-height: 29px;
52
+ margin-left: 3px;
53
+ color: #999;
54
+ cursor: text;
55
+ }
56
+
57
+ .panel .header table input
58
+ {
59
+ width: 100%;
60
+ box-sizing: border-box;
61
+ -moz-box-sizing: border-box;
62
+ -webkit-box-sizing: border-box;
63
+ display: inline-block;
64
+ -webkit-appearance: searchfield;
65
+ height: 22px;
66
+ //height: auto;
67
+ }
68
+
69
+ /* Header with search box (end) */
70
+
71
+
72
+ /* Results (begin) */
73
+ .panel .result
74
+ {
75
+ position: absolute;
76
+ top: 30px;
77
+ bottom: 0;
78
+ left: 0;
79
+ width: 100%;
80
+ overflow-y: scroll;
81
+ overflow-x: hidden;
82
+ background: #EDF3FE url(../i/results_bg.png);
83
+ z-index: 2;
84
+ }
85
+
86
+ .panel .result ul
87
+ {
88
+ font-size: 0.8em;
89
+ width: 100%;
90
+ background: #EDF3FE url(../i/results_bg.png);
91
+ zoom:1;
92
+ }
93
+
94
+ .panel .result ul li
95
+ {
96
+ height: 46px;
97
+ overflow: hidden;
98
+ padding: 4px 10px 0 10px;
99
+ cursor: default;
100
+ }
101
+
102
+ .panel .result ul li h1
103
+ {
104
+ font-size: 13px;
105
+ font-weight: normal;
106
+ color: #333;
107
+ margin-bottom: 2px;
108
+ white-space: nowrap;
109
+ }
110
+
111
+ .panel .result ul li p
112
+ {
113
+ font-size: 11px;
114
+ color: #333;
115
+ margin-bottom: 2px;
116
+ white-space: nowrap;
117
+ }
118
+
119
+ .panel .result ul li h1 i,
120
+ .panel .result ul li p.snippet
121
+ {
122
+ color: #999;
123
+ }
124
+
125
+ .panel .result ul li b
126
+ {
127
+ color: #000;
128
+ }
129
+
130
+ .panel .result ul li.current
131
+ {
132
+ background: #3875D7;
133
+ }
134
+
135
+ .panel .result ul li.current h1,
136
+ .panel .result ul li.current p
137
+ {
138
+ color: #DDD;
139
+ }
140
+
141
+ .panel .result ul li.current h1 i,
142
+ .panel .result ul li.current p.snippet
143
+ {
144
+ color: #AAA;
145
+ }
146
+
147
+ .panel .result ul li.current b
148
+ {
149
+ color: #FFF;
150
+ }
151
+
152
+
153
+ .panel .result ul li:hover,
154
+ .panel .result ul li.selected
155
+ {
156
+ background: #d0d0d0;
157
+ }
158
+
159
+ .panel .result ul li.current:hover
160
+ {
161
+ background: #2965C0;
162
+ }
163
+ /* Results (end) */
164
+
165
+ /* Tree (begin) */ /**/
166
+ .panel .tree
167
+ {
168
+ position: absolute;
169
+ top: 30px;
170
+ bottom: 0;
171
+ left: 0;
172
+ width: 100%;
173
+ overflow-y: scroll;
174
+ overflow-x: hidden;
175
+ background: #EDF3FE url(../i/tree_bg.png);
176
+ z-index: 3;
177
+ }
178
+
179
+ .panel .tree > ul
180
+ {
181
+ background: #EDF3FE url(../i/tree_bg.png);
182
+ }
183
+
184
+ .panel .tree li .content
185
+ {
186
+ padding-left: 18px;
187
+ padding-top: 5px;
188
+ height: 18px;
189
+ overflow: hidden;
190
+ position: relative;
191
+ }
192
+
193
+ .panel .tree li .icon
194
+ {
195
+ width: 10px;
196
+ height: 9px;
197
+ background: url(../i/arrows.png);
198
+ background-position: 0 -9px;
199
+ position: absolute;
200
+ left: 1px;
201
+ top: 8px;
202
+ }
203
+
204
+ .panel .tree li.closed .icon
205
+ {
206
+ background-position: 0 0;
207
+ }
208
+
209
+ .panel .tree ul li h1
210
+ {
211
+ font-size: 13px;
212
+ font-weight: normal;
213
+ color: #000;
214
+ margin-bottom: 2px;
215
+ white-space: nowrap;
216
+ }
217
+
218
+ .panel .tree ul li p
219
+ {
220
+ font-size: 11px;
221
+ color: #666;
222
+ margin-bottom: 2px;
223
+ white-space: nowrap;
224
+ }
225
+
226
+ .panel .tree ul li h1 i
227
+ {
228
+ color: #999;
229
+ font-style: normal;
230
+ }
231
+
232
+ .panel .tree ul li.empty h1,
233
+ .panel .tree ul li.empty p
234
+ {
235
+ color: #666;
236
+ font-style: italic;
237
+ }
238
+
239
+ .panel .tree ul li.current
240
+ {
241
+ background: #3875D7;
242
+ }
243
+
244
+ .panel .tree ul li.current .icon
245
+ {
246
+ background-position: -10px -9px;
247
+ }
248
+
249
+ .panel .tree ul li.current.closed .icon
250
+ {
251
+ background-position: -10px 0;
252
+ }
253
+
254
+ .panel .tree ul li.current h1
255
+ {
256
+ color: #FFF;
257
+ }
258
+
259
+ .panel .tree ul li.current p
260
+ {
261
+ color: #CCC;
262
+ }
263
+
264
+ .panel .tree ul li.current.empty h1,
265
+ .panel .tree ul li.current.empty p
266
+ {
267
+ color: #999;
268
+ }
269
+
270
+ .panel .tree ul li:hover
271
+ {
272
+ background: #d0d0d0;
273
+ }
274
+
275
+ .panel .tree ul li.current:hover
276
+ {
277
+ background: #2965C0;
278
+ }
279
+
280
+ .panel .tree .stopper
281
+ {
282
+ display: none;
283
+ }
284
+ /* Tree (end) */ /**/
285
+
286
+ /* Panel (end) */