sdoc 0.2.12.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 (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