sdoc 0.2.12.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/LICENSE +21 -0
  2. data/README.rdoc +38 -0
  3. data/Rakefile +37 -0
  4. data/VERSION.yml +4 -0
  5. data/bin/sdoc +11 -0
  6. data/bin/sdoc-merge +12 -0
  7. data/lib/rdoc/discover.rb +1 -0
  8. data/lib/sdoc.rb +23 -0
  9. data/lib/sdoc/c_parser_fix.rb +31 -0
  10. data/lib/sdoc/generator/shtml.rb +314 -0
  11. data/lib/sdoc/generator/template/direct/_context.rhtml +172 -0
  12. data/lib/sdoc/generator/template/direct/class.rhtml +40 -0
  13. data/lib/sdoc/generator/template/direct/file.rhtml +30 -0
  14. data/lib/sdoc/generator/template/direct/index.rhtml +14 -0
  15. data/lib/sdoc/generator/template/direct/resources/css/main.css +263 -0
  16. data/lib/sdoc/generator/template/direct/resources/css/panel.css +383 -0
  17. data/lib/sdoc/generator/template/direct/resources/css/reset.css +53 -0
  18. data/lib/sdoc/generator/template/direct/resources/i/arrows.png +0 -0
  19. data/lib/sdoc/generator/template/direct/resources/i/results_bg.png +0 -0
  20. data/lib/sdoc/generator/template/direct/resources/i/tree_bg.png +0 -0
  21. data/lib/sdoc/generator/template/direct/resources/js/jquery-1.3.2.min.js +19 -0
  22. data/lib/sdoc/generator/template/direct/resources/js/jquery-effect.js +593 -0
  23. data/lib/sdoc/generator/template/direct/resources/js/main.js +22 -0
  24. data/lib/sdoc/generator/template/direct/resources/js/searchdoc.js +620 -0
  25. data/lib/sdoc/generator/template/direct/resources/panel/index.html +71 -0
  26. data/lib/sdoc/generator/template/merge/index.rhtml +14 -0
  27. data/lib/sdoc/generator/template/shtml/_context.rhtml +164 -0
  28. data/lib/sdoc/generator/template/shtml/class.rhtml +46 -0
  29. data/lib/sdoc/generator/template/shtml/file.rhtml +37 -0
  30. data/lib/sdoc/generator/template/shtml/index.rhtml +14 -0
  31. data/lib/sdoc/generator/template/shtml/resources/css/main.css +191 -0
  32. data/lib/sdoc/generator/template/shtml/resources/css/panel.css +383 -0
  33. data/lib/sdoc/generator/template/shtml/resources/css/reset.css +53 -0
  34. data/lib/sdoc/generator/template/shtml/resources/i/arrows.png +0 -0
  35. data/lib/sdoc/generator/template/shtml/resources/i/results_bg.png +0 -0
  36. data/lib/sdoc/generator/template/shtml/resources/i/tree_bg.png +0 -0
  37. data/lib/sdoc/generator/template/shtml/resources/js/jquery-1.3.2.min.js +19 -0
  38. data/lib/sdoc/generator/template/shtml/resources/js/main.js +34 -0
  39. data/lib/sdoc/generator/template/shtml/resources/js/searchdoc.js +620 -0
  40. data/lib/sdoc/generator/template/shtml/resources/panel/index.html +71 -0
  41. data/lib/sdoc/github.rb +64 -0
  42. data/lib/sdoc/helpers.rb +26 -0
  43. data/lib/sdoc/merge.rb +217 -0
  44. data/lib/sdoc/templatable.rb +58 -0
  45. metadata +117 -0
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2009 Vladimir Kolesnikov
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
@@ -0,0 +1,38 @@
1
+ = SDoc
2
+ == What's in?
3
+ - shtml - RDoc's generator to build searchable documentation
4
+ - <tt>sdoc-merge</tt> - comand line tool to build merge multiple sdoc documentations
5
+ packages into a single one
6
+ - <tt>sdoc</tt> - command line tool to run rdoc with generator=shtml
7
+
8
+ == Getting Started
9
+ gem sources -a http://gems.github.com
10
+ sudo gem install voloko-sdoc
11
+ sdoc -N projectdir
12
+
13
+ == Command line sdoc
14
+ sdoc is simply a wrapper to rdoc command line tool. see <tt>sdoc --help </tt>
15
+ for more details. <tt>--fmt</tt> is set to shtml by default.
16
+ Default template <tt>-T</tt> is shtml. You can also use 'direct' template.
17
+ Example:
18
+ <tt>sdoc -o doc/rails -T direct rails</tt>
19
+
20
+ == Rake
21
+ # Rakefile
22
+ require 'sdoc' # and use your RDoc task the same way you used it before
23
+
24
+ Rake::RDocTask.new do |rdoc|
25
+ rdoc.rdoc_dir = 'doc/rdoc'
26
+ rdoc.options << '--fmt' << 'shtml' # explictly set shtml generator
27
+ rdoc.template = 'direct' # lighter template used on railsapi.com
28
+ ...
29
+ end
30
+
31
+ == sdoc-merge
32
+ Usage: sdoc-merge [options] directories
33
+ -n, --names [NAMES] Names of merged repositories. Comma separated
34
+ -o, --op [DIRECTORY] Set the output directory
35
+ -t, --title [TITLE] Set the title of merged file
36
+
37
+ Example:
38
+ <tt>sdoc-merge --title "Ruby v1.9, Rails v2.3.2.1" --op merged --names "Ruby,Rails" ruby-v1.9 rails-v2.3.2.1</tt>
@@ -0,0 +1,37 @@
1
+ require 'rake/testtask'
2
+ require 'rake/gempackagetask'
3
+
4
+ task :default => :test
5
+
6
+ Rake::TestTask.new("test") do |t|
7
+ t.libs << 'test'
8
+ t.pattern = 'test/**/*_test.rb'
9
+ t.warning = true
10
+ t.verbose = true
11
+ end
12
+
13
+ desc "Generate file list for .gemspec"
14
+ task :gem_file_list do
15
+ f = FileList.new
16
+ f.include('lib/**/**')
17
+ f.include('rdoc/**/**')
18
+ f.exclude('rdoc/test/**/**')
19
+ print "%w(" + f.to_a.select{|file| !File.directory? file }.join(' ') + ")\n"
20
+ end
21
+
22
+ begin
23
+ require 'jeweler'
24
+ Jeweler::Tasks.new do |gem|
25
+ gem.name = "sdoc"
26
+ gem.summary = "rdoc html with javascript search index."
27
+ gem.email = "voloko@gmail.com"
28
+ gem.homepage = "http://github.com/voloko/sdoc"
29
+ gem.authors = ["Volodya Kolesnikov"]
30
+ gem.add_dependency("json", ">= 1.1.3")
31
+ gem.add_dependency("rdoc", ">= 2.4.2")
32
+
33
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
34
+ end
35
+ rescue LoadError
36
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
37
+ end
@@ -0,0 +1,4 @@
1
+ ---
2
+ :minor: 2
3
+ :patch: 12
4
+ :major: 0
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby -KU
2
+
3
+ require File.dirname(__FILE__) + '/../lib/sdoc' # add extensions
4
+
5
+ begin
6
+ r = RDoc::RDoc.new
7
+ r.document(ARGV)
8
+ rescue RDoc::RDocError => e
9
+ $stderr.puts e.message
10
+ exit(1)
11
+ end
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby -KU
2
+
3
+ require File.dirname(__FILE__) + '/../lib/sdoc' # add extensions
4
+ require 'sdoc/merge'
5
+
6
+ begin
7
+ m = SDoc::Merge.new
8
+ m.merge(ARGV)
9
+ rescue RDoc::RDocError => e
10
+ $stderr.puts e.message
11
+ exit(1)
12
+ end
@@ -0,0 +1 @@
1
+ require File.join(File.dirname(__FILE__), '/../sdoc')
@@ -0,0 +1,23 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+ require "rubygems"
3
+ gem "rdoc", ">= 2.4.2"
4
+
5
+ require "rdoc/rdoc"
6
+
7
+ module SDoc
8
+ end
9
+
10
+ require "sdoc/generator/shtml"
11
+ require "sdoc/c_parser_fix"
12
+
13
+ unless defined? SDOC_FIXED_RDOC_OPTIONS
14
+ SDOC_FIXED_RDOC_OPTIONS = 1
15
+ class RDoc::Options
16
+ alias_method :rdoc_initialize, :initialize
17
+
18
+ def initialize
19
+ rdoc_initialize
20
+ @generator = RDoc::Generator::SHtml
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,31 @@
1
+ require "rdoc/parser/c"
2
+
3
+ # New RDoc somehow misses class comemnts.
4
+ # copyied this function from "2.2.2"
5
+ if ['2.4.2', '2.4.3'].include? RDoc::VERSION
6
+
7
+ class RDoc::Parser::C
8
+ def find_class_comment(class_name, class_meth)
9
+ comment = nil
10
+ if @content =~ %r{((?>/\*.*?\*/\s+))
11
+ (static\s+)?void\s+Init_#{class_name}\s*(?:_\(\s*)?\(\s*(?:void\s*)\)}xmi then
12
+ comment = $1
13
+ elsif @content =~ %r{Document-(?:class|module):\s#{class_name}\s*?(?:<\s+[:,\w]+)?\n((?>.*?\*/))}m
14
+ comment = $1
15
+ else
16
+ if @content =~ /rb_define_(class|module)/m then
17
+ class_name = class_name.split("::").last
18
+ comments = []
19
+ @content.split(/(\/\*.*?\*\/)\s*?\n/m).each_with_index do |chunk, index|
20
+ comments[index] = chunk
21
+ if chunk =~ /rb_define_(class|module).*?"(#{class_name})"/m then
22
+ comment = comments[index-1]
23
+ break
24
+ end
25
+ end
26
+ end
27
+ end
28
+ class_meth.comment = mangle_comment(comment) if comment
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,314 @@
1
+ require 'rubygems'
2
+ gem "rdoc", ">= 2.4.2"
3
+ if Gem.available? "json"
4
+ gem "json", ">= 1.1.3"
5
+ else
6
+ gem "json_pure", ">= 1.1.3"
7
+ end
8
+
9
+ require 'iconv'
10
+ require 'json'
11
+ require 'pathname'
12
+ require 'fileutils'
13
+ require 'erb'
14
+
15
+ require 'rdoc/rdoc'
16
+ require 'rdoc/generator'
17
+ require 'rdoc/generator/markup'
18
+
19
+ require 'sdoc/github'
20
+ require 'sdoc/templatable'
21
+ require 'sdoc/helpers'
22
+
23
+ class RDoc::ClassModule
24
+ def document_self_or_methods
25
+ document_self || method_list.any?{ |m| m.document_self }
26
+ end
27
+
28
+ def with_documentation?
29
+ document_self_or_methods || classes_and_modules.any?{ |c| c.with_documentation? }
30
+ end
31
+ end
32
+
33
+ class RDoc::Generator::SHtml
34
+ RDoc::RDoc.add_generator( self )
35
+ include ERB::Util
36
+ include SDoc::GitHub
37
+ include SDoc::Templatable
38
+ include SDoc::Helpers
39
+
40
+ GENERATOR_DIRS = [File.join('sdoc', 'generator'), File.join('rdoc', 'generator')]
41
+
42
+ # Used in js to reduce index sizes
43
+ TYPE_CLASS = 1
44
+ TYPE_METHOD = 2
45
+ TYPE_FILE = 3
46
+
47
+ TREE_FILE = File.join 'panel', 'tree.js'
48
+ SEARCH_INDEX_FILE = File.join 'panel', 'search_index.js'
49
+
50
+ FILE_DIR = 'files'
51
+ CLASS_DIR = 'classes'
52
+
53
+ RESOURCES_DIR = File.join('resources', '.')
54
+
55
+ attr_reader :basedir
56
+
57
+ def self.for(options)
58
+ self.new(options)
59
+ end
60
+
61
+ def self.template_dir template
62
+ $LOAD_PATH.map do |path|
63
+ GENERATOR_DIRS.map do |dir|
64
+ File.join path, dir, 'template', template
65
+ end
66
+ end.flatten.find do |dir|
67
+ File.directory? dir
68
+ end
69
+ end
70
+
71
+ def initialize(options)
72
+ @options = options
73
+ @options.diagram = false
74
+ @github_url_cache = {}
75
+
76
+ template = @options.template || 'direct'
77
+
78
+ templ_dir = self.class.template_dir template
79
+
80
+ raise RDoc::Error, "could not find template #{template.inspect}" unless
81
+ templ_dir
82
+
83
+ @template_dir = Pathname.new File.expand_path(templ_dir)
84
+ @basedir = Pathname.pwd.expand_path
85
+ end
86
+
87
+ def generate( top_levels )
88
+ @outputdir = Pathname.new( @options.op_dir ).expand_path( @basedir )
89
+ @files = top_levels.sort
90
+ @classes = RDoc::TopLevel.all_classes_and_modules.sort
91
+
92
+ # Now actually write the output
93
+ copy_resources
94
+ generate_class_tree
95
+ generate_search_index
96
+ generate_file_files
97
+ generate_class_files
98
+ generate_index_file
99
+ end
100
+
101
+ def class_dir
102
+ CLASS_DIR
103
+ end
104
+
105
+ def file_dir
106
+ FILE_DIR
107
+ end
108
+
109
+
110
+ protected
111
+ ### Output progress information if debugging is enabled
112
+ def debug_msg( *msg )
113
+ return unless $DEBUG_RDOC
114
+ $stderr.puts( *msg )
115
+ end
116
+
117
+ ### Create class tree structure and write it as json
118
+ def generate_class_tree
119
+ debug_msg "Generating class tree"
120
+ topclasses = @classes.select {|klass| !(RDoc::ClassModule === klass.parent) }
121
+ tree = generate_class_tree_level topclasses
122
+ debug_msg " writing class tree to %s" % TREE_FILE
123
+ File.open(TREE_FILE, "w", 0644) do |f|
124
+ f.write('var tree = '); f.write(tree.to_json)
125
+ end unless $dryrun
126
+ end
127
+
128
+ ### Recursivly build class tree structure
129
+ def generate_class_tree_level(classes)
130
+ tree = []
131
+ classes.select{|c| c.with_documentation? }.sort.each do |klass|
132
+ item = [
133
+ klass.name,
134
+ klass.document_self_or_methods ? klass.path : '',
135
+ klass.module? ? '' : (klass.superclass ? " < #{String === klass.superclass ? klass.superclass : klass.superclass.full_name}" : ''),
136
+ generate_class_tree_level(klass.classes_and_modules)
137
+ ]
138
+ tree << item
139
+ end
140
+ tree
141
+ end
142
+
143
+ ### Create search index for all classes, methods and files
144
+ ### Wite it as json
145
+ def generate_search_index
146
+ debug_msg "Generating search index"
147
+
148
+ index = {
149
+ :searchIndex => [],
150
+ :longSearchIndex => [],
151
+ :info => []
152
+ }
153
+
154
+ add_class_search_index(index)
155
+ add_method_search_index(index)
156
+ add_file_search_index(index)
157
+
158
+ debug_msg " writing search index to %s" % SEARCH_INDEX_FILE
159
+ data = {
160
+ :index => index
161
+ }
162
+ File.open(SEARCH_INDEX_FILE, "w", 0644) do |f|
163
+ f.write('var search_data = '); f.write(data.to_json)
164
+ end unless $dryrun
165
+ end
166
+
167
+ ### Add files to search +index+ array
168
+ def add_file_search_index(index)
169
+ debug_msg " generating file search index"
170
+
171
+ @files.select { |file|
172
+ file.document_self
173
+ }.sort.each do |file|
174
+ index[:searchIndex].push( search_string(file.name) )
175
+ index[:longSearchIndex].push( search_string(file.path) )
176
+ index[:info].push([
177
+ file.name,
178
+ file.path,
179
+ file.path,
180
+ '',
181
+ snippet(file.comment),
182
+ TYPE_FILE
183
+ ])
184
+ end
185
+ end
186
+
187
+ ### Add classes to search +index+ array
188
+ def add_class_search_index(index)
189
+ debug_msg " generating class search index"
190
+
191
+ @classes.select { |klass|
192
+ klass.document_self_or_methods
193
+ }.sort.each do |klass|
194
+ index[:searchIndex].push( search_string(klass.name) )
195
+ index[:longSearchIndex].push( search_string(klass.parent.name) )
196
+ index[:info].push([
197
+ klass.name,
198
+ klass.parent.full_name,
199
+ klass.path,
200
+ klass.module? ? '' : (klass.superclass ? " < #{String === klass.superclass ? klass.superclass : klass.superclass.full_name}" : ''),
201
+ snippet(klass.comment),
202
+ TYPE_CLASS
203
+ ])
204
+ end
205
+ end
206
+
207
+ ### Add methods to search +index+ array
208
+ def add_method_search_index(index)
209
+ debug_msg " generating method search index"
210
+
211
+ list = @classes.map { |klass|
212
+ klass.method_list
213
+ }.flatten.sort{ |a, b| a.name == b.name ? a.parent.full_name <=> b.parent.full_name : a.name <=> b.name }.select { |method|
214
+ method.document_self
215
+ }
216
+ unless @options.show_all
217
+ list = list.find_all {|m| m.visibility == :public || m.visibility == :protected || m.force_documentation }
218
+ end
219
+
220
+ list.each do |method|
221
+ index[:searchIndex].push( search_string(method.name) + '()' )
222
+ index[:longSearchIndex].push( search_string(method.parent.name) )
223
+ index[:info].push([
224
+ method.name,
225
+ method.parent.full_name,
226
+ method.path,
227
+ method.params,
228
+ snippet(method.comment),
229
+ TYPE_METHOD
230
+ ])
231
+ end
232
+ end
233
+
234
+ ### Generate a documentation file for each class
235
+ def generate_class_files
236
+ debug_msg "Generating class documentation in #@outputdir"
237
+ templatefile = @template_dir + 'class.rhtml'
238
+
239
+ @classes.each do |klass|
240
+ debug_msg " working on %s (%s)" % [ klass.full_name, klass.path ]
241
+ outfile = @outputdir + klass.path
242
+ rel_prefix = @outputdir.relative_path_from( outfile.dirname )
243
+
244
+ debug_msg " rendering #{outfile}"
245
+ self.render_template( templatefile, binding(), outfile )
246
+ end
247
+ end
248
+
249
+ ### Generate a documentation file for each file
250
+ def generate_file_files
251
+ debug_msg "Generating file documentation in #@outputdir"
252
+ templatefile = @template_dir + 'file.rhtml'
253
+
254
+ @files.each do |file|
255
+ outfile = @outputdir + file.path
256
+ debug_msg " working on %s (%s)" % [ file.full_name, outfile ]
257
+ rel_prefix = @outputdir.relative_path_from( outfile.dirname )
258
+
259
+ debug_msg " rendering #{outfile}"
260
+ self.render_template( templatefile, binding(), outfile )
261
+ end
262
+ end
263
+
264
+ ### Create index.html with frameset
265
+ def generate_index_file
266
+ debug_msg "Generating index file in #@outputdir"
267
+ templatefile = @template_dir + 'index.rhtml'
268
+ outfile = @outputdir + 'index.html'
269
+ if @options.main_page && index_path = @files.find { |f| f.full_name == @options.main_page }
270
+ index_path = index_path.path
271
+ else
272
+ index_path = @files.first.path
273
+ end
274
+
275
+ self.render_template( templatefile, binding(), outfile )
276
+ end
277
+
278
+ ### Strip comments on a space after 100 chars
279
+ def snippet(str)
280
+ str ||= ''
281
+ if str =~ /^(?>\s*)[^\#]/
282
+ content = str
283
+ else
284
+ content = str.gsub(/^\s*(#+)\s*/, '')
285
+ end
286
+
287
+ content = content.sub(/^(.{100,}?)\s.*/m, "\\1").gsub(/\r?\n/m, ' ')
288
+
289
+ begin
290
+ content.to_json
291
+ rescue # might fail on non-unicode string
292
+ begin
293
+ content = Iconv.conv('latin1//ignore', "UTF8", content) # remove all non-unicode chars
294
+ content.to_json
295
+ rescue
296
+ content = '' # something hugely wrong happend
297
+ end
298
+ end
299
+ content
300
+ end
301
+
302
+ ### Build search index key
303
+ def search_string(string)
304
+ string ||= ''
305
+ string.downcase.gsub(/\s/,'')
306
+ end
307
+
308
+ ### Copy all the resource files to output dir
309
+ def copy_resources
310
+ resoureces_path = @template_dir + RESOURCES_DIR
311
+ debug_msg "Copying #{resoureces_path}/** to #{@outputdir}/**"
312
+ FileUtils.cp_r resoureces_path.to_s, @outputdir.to_s, :preserve => true unless $dryrun
313
+ end
314
+ end