wpdoc 0.2.17

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. data/.gitignore +4 -0
  2. data/LICENSE +21 -0
  3. data/README.rdoc +37 -0
  4. data/Rakefile +51 -0
  5. data/VERSION.yml +5 -0
  6. data/bin/wpdoc +11 -0
  7. data/bin/wpdoc-merge +12 -0
  8. data/lib/rdoc/discover.rb +1 -0
  9. data/lib/wpdoc.rb +23 -0
  10. data/lib/wpdoc/c_parser_fix.rb +31 -0
  11. data/lib/wpdoc/generator/shtml.rb +359 -0
  12. data/lib/wpdoc/generator/template/direct/_context.rhtml +180 -0
  13. data/lib/wpdoc/generator/template/direct/class.rhtml +42 -0
  14. data/lib/wpdoc/generator/template/direct/file.rhtml +30 -0
  15. data/lib/wpdoc/generator/template/direct/index.rhtml +14 -0
  16. data/lib/wpdoc/generator/template/direct/resources/apple-touch-icon.png +0 -0
  17. data/lib/wpdoc/generator/template/direct/resources/css/main.css +286 -0
  18. data/lib/wpdoc/generator/template/direct/resources/css/panel.css +383 -0
  19. data/lib/wpdoc/generator/template/direct/resources/css/reset.css +53 -0
  20. data/lib/wpdoc/generator/template/direct/resources/favicon.ico +0 -0
  21. data/lib/wpdoc/generator/template/direct/resources/i/arrows.png +0 -0
  22. data/lib/wpdoc/generator/template/direct/resources/i/results_bg.png +0 -0
  23. data/lib/wpdoc/generator/template/direct/resources/i/tree_bg.png +0 -0
  24. data/lib/wpdoc/generator/template/direct/resources/js/jquery-1.3.2.min.js +19 -0
  25. data/lib/wpdoc/generator/template/direct/resources/js/jquery-effect.js +593 -0
  26. data/lib/wpdoc/generator/template/direct/resources/js/main.js +22 -0
  27. data/lib/wpdoc/generator/template/direct/resources/js/searchdoc.js +620 -0
  28. data/lib/wpdoc/generator/template/direct/resources/panel/index.html +71 -0
  29. data/lib/wpdoc/generator/template/merge/index.rhtml +14 -0
  30. data/lib/wpdoc/github.rb +64 -0
  31. data/lib/wpdoc/helpers.rb +26 -0
  32. data/lib/wpdoc/merge.rb +219 -0
  33. data/lib/wpdoc/templatable.rb +58 -0
  34. metadata +123 -0
@@ -0,0 +1,71 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
3
+ "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
4
+
5
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
6
+ <head>
7
+ <title>layout</title>
8
+ <link rel="stylesheet" href="../css/reset.css" type="text/css" media="screen" charset="utf-8" />
9
+ <link rel="stylesheet" href="../css/panel.css" type="text/css" media="screen" charset="utf-8" />
10
+ <script src="search_index.js" type="text/javascript" charset="utf-8"></script>
11
+ <script src="tree.js" type="text/javascript" charset="utf-8"></script>
12
+ <script src="../js/jquery-1.3.2.min.js" type="text/javascript" charset="utf-8"></script>
13
+ <script src="../js/searchdoc.js" type="text/javascript" charset="utf-8"></script>
14
+ <script type="text/javascript" charset="utf-8">
15
+ //<![CDATA[
16
+ function placeholder() {
17
+ if (jQuery.browser.safari) return;
18
+ $('#search-label').click(function() {
19
+ $('#search').focus();
20
+ $('#search-label').hide();
21
+ });
22
+
23
+ $('#search').focus(function() {
24
+ $('#search-label').hide();
25
+ });
26
+ $('#search').blur(function() {
27
+ this.value == '' && $('#search-label').show()
28
+ });
29
+
30
+ $('#search')[0].value == '' && $('#search-label').show();
31
+ }
32
+ $(function() {
33
+ placeholder();
34
+ var panel = new Searchdoc.Panel($('#panel'), search_data, tree, top.frames[1]);
35
+ $('#search').focus();
36
+
37
+ var s = window.parent.location.search.match(/\?q=([^&]+)/);
38
+ if (s) {
39
+ s = decodeURIComponent(s[1]).replace(/\+/g, ' ');
40
+ if (s.length > 0)
41
+ {
42
+ $('#search').val(s);
43
+ panel.search(s, true);
44
+ }
45
+ }
46
+ })
47
+ //]]>
48
+ </script>
49
+ </head>
50
+ <body>
51
+ <div class="panel panel_tree" id="panel">
52
+ <div class="header">
53
+ <div>
54
+ <label for="search" id="search-label" style="display: none">Search</label>
55
+ <table>
56
+ <tr><td>
57
+ <input type="Search" placeholder="Search" autosave="searchdoc" results="10" id="search" autocomplete="off"/>
58
+ </td></tr>
59
+ </table></div>
60
+ </div>
61
+ <div class="tree">
62
+ <ul>
63
+ </ul>
64
+ </div>
65
+ <div class="result">
66
+ <ul>
67
+ </ul>
68
+ </div>
69
+ </div>
70
+ </body>
71
+ </html>
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html
2
+ PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
3
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
4
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
5
+ <head>
6
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
7
+
8
+ <title><%= @title %></title>
9
+ </head>
10
+ <frameset cols="300,*" frameborder="1" border="1" bordercolor="#666666" framespacing="1">
11
+ <frame src="panel/index.html" title="Search" name="panel" />
12
+ <frame src="<%= index_path %>" name="docwin" />
13
+ </frameset>
14
+ </html>
@@ -0,0 +1,64 @@
1
+ module SDoc::GitHub
2
+ def github_url(path)
3
+ unless @github_url_cache.has_key? path
4
+ @github_url_cache[path] = false
5
+ file = RDoc::TopLevel.find_file_named(path)
6
+ if file
7
+ base_url = repository_url(path)
8
+ if base_url
9
+ sha1 = commit_sha1(path)
10
+ if sha1
11
+ relative_url = path_relative_to_repository(path)
12
+ @github_url_cache[path] = "#{base_url}#{sha1}#{relative_url}"
13
+ end
14
+ end
15
+ end
16
+ end
17
+ @github_url_cache[path]
18
+ end
19
+
20
+ protected
21
+
22
+ def commit_sha1(path)
23
+ name = File.basename(path)
24
+ s = in_dir(File.join(basedir, File.dirname(path))) do
25
+ `git log -1 --pretty=format:"commit %H" #{name}`
26
+ end
27
+ m = s.match(/commit\s+(\S+)/)
28
+ m ? m[1] : false
29
+ end
30
+
31
+ def repository_url(path)
32
+ s = in_dir(File.join(basedir, File.dirname(path))) do
33
+ `git config --get remote.origin.url`
34
+ end
35
+ m = s.match(%r{github.com[/:](.*)\.git$})
36
+ m ? "http://github.com/#{m[1]}/blob/" : false
37
+ end
38
+
39
+ def path_relative_to_repository(path)
40
+ absolute_path = File.join(basedir, path)
41
+ root = path_to_git_dir(File.dirname(absolute_path))
42
+ absolute_path[root.size..absolute_path.size]
43
+ end
44
+
45
+ def path_to_git_dir(path)
46
+ while !path.empty? && path != '.'
47
+ if (File.exists? File.join(path, '.git'))
48
+ return path
49
+ end
50
+ path = File.dirname(path)
51
+ end
52
+ ''
53
+ end
54
+
55
+ def in_dir(dir)
56
+ pwd = Dir.pwd
57
+ Dir.chdir dir
58
+ return yield
59
+ rescue Exception => e
60
+ return ''
61
+ ensure
62
+ Dir.chdir pwd
63
+ end
64
+ end
@@ -0,0 +1,26 @@
1
+ module SDoc::Helpers
2
+ def each_letter_group(methods, &block)
3
+ group = {:name => '', :methods => []}
4
+ methods.sort{ |a, b| a.name <=> b.name }.each do |method|
5
+ gname = group_name method.name
6
+ if gname != group[:name]
7
+ yield group unless group[:methods].size == 0
8
+ group = {
9
+ :name => gname,
10
+ :methods => []
11
+ }
12
+ end
13
+ group[:methods].push(method)
14
+ end
15
+ yield group unless group[:methods].size == 0
16
+ end
17
+
18
+ protected
19
+ def group_name name
20
+ if match = name.match(/^([a-z])/i)
21
+ match[1].upcase
22
+ else
23
+ '#'
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,219 @@
1
+ require 'optparse'
2
+ require 'pathname'
3
+ require 'fileutils'
4
+
5
+ gem 'json_pure', '>= 1.1.3' if defined?(::JRUBY_VERSION)
6
+ require 'json'
7
+
8
+ require 'wpdoc/templatable'
9
+
10
+ class SDoc::Merge
11
+ include SDoc::Templatable
12
+
13
+ FLAG_FILE = "created.rid"
14
+
15
+ def initialize()
16
+ @names = []
17
+ @urls = []
18
+ @op_dir = 'doc'
19
+ @title = ''
20
+ @directories = []
21
+ template_dir = RDoc::Generator::SHtml.template_dir('merge')
22
+ @template_dir = Pathname.new File.expand_path(template_dir)
23
+ end
24
+
25
+ def merge(options)
26
+ parse_options options
27
+
28
+ @outputdir = Pathname.new( @op_dir )
29
+
30
+ check_directories
31
+ setup_output_dir
32
+ setup_names
33
+ copy_files
34
+ copy_docs if @urls.empty?
35
+ merge_search_index
36
+ merge_tree
37
+ generate_index_file
38
+ end
39
+
40
+ def parse_options(options)
41
+ opts = OptionParser.new do |opt|
42
+ opt.banner = "Usage: wpdoc-merge [options] directories"
43
+
44
+ opt.on("-n", "--names [NAMES]", "Names of merged repositories. Comma separated") do |v|
45
+ @names = v.split(',').map{|name| name.strip }
46
+ end
47
+
48
+ opt.on("-o", "--op [DIRECTORY]", "Set the output directory") do |v|
49
+ @op_dir = v
50
+ end
51
+
52
+ opt.on("-t", "--title [TITLE]", "Set the title of merged file") do |v|
53
+ @title = v
54
+ end
55
+
56
+ opt.on("-u", "--urls [URLS]", "Paths to merged docs. If you \n" +
57
+ "set this files and classes won't be actualy copied to merged build") do |v|
58
+ @urls = v.split(' ').map{|name| name.strip }
59
+ end
60
+ end
61
+ opts.parse! options
62
+ @directories = options.dup
63
+ end
64
+
65
+ def merge_tree
66
+ tree = []
67
+ @directories.each_with_index do |dir, i|
68
+ name = @names[i]
69
+ url = @urls.empty? ? name : @urls[i]
70
+ filename = File.join dir, RDoc::Generator::SHtml::TREE_FILE
71
+ data = open(filename).read.sub(/var tree =\s*/, '')
72
+ subtree = JSON.parse data, :max_nesting => 35
73
+ item = [
74
+ name,
75
+ url + '/' + extract_index_path(dir),
76
+ '',
77
+ append_path(subtree, url)
78
+ ]
79
+ tree << item
80
+ end
81
+
82
+ dst = File.join @op_dir, RDoc::Generator::SHtml::TREE_FILE
83
+ FileUtils.mkdir_p File.dirname(dst)
84
+ File.open(dst, "w", 0644) do |f|
85
+ f.write('var tree = '); f.write(tree.to_json)
86
+ end
87
+ end
88
+
89
+ def append_path subtree, path
90
+ subtree.map do |item|
91
+ item[1] = path + '/' + item[1] unless item[1].empty?
92
+ item[3] = append_path item[3], path
93
+ item
94
+ end
95
+ end
96
+
97
+ def merge_search_index
98
+ items = []
99
+ @indexes = {}
100
+ @directories.each_with_index do |dir, i|
101
+ name = @names[i]
102
+ url = @urls.empty? ? name : @urls[i]
103
+ filename = File.join dir, RDoc::Generator::SHtml::SEARCH_INDEX_FILE
104
+ data = open(filename).read.sub(/var search_data =\s*/, '')
105
+ subindex = JSON.parse data, :max_nesting => 35
106
+ @indexes[name] = subindex
107
+
108
+ searchIndex = subindex["index"]["searchIndex"]
109
+ longSearchIndex = subindex["index"]["longSearchIndex"]
110
+ subindex["index"]["info"].each_with_index do |info, j|
111
+ info[2] = url + '/' + info[2]
112
+ info[6] = i
113
+ items << {
114
+ :info => info,
115
+ :searchIndex => searchIndex[j],
116
+ :longSearchIndex => name + ' ' + longSearchIndex[j]
117
+ }
118
+ end
119
+ end
120
+ items.sort! do |a, b|
121
+ # type (class/method/file) or name or doc part or namespace
122
+ [a[:info][5], a[:info][0], a[:info][6], a[:info][1]] <=> [b[:info][5], b[:info][0], b[:info][6], b[:info][1]]
123
+ end
124
+
125
+ index = {
126
+ :searchIndex => items.map{|item| item[:searchIndex]},
127
+ :longSearchIndex => items.map{|item| item[:longSearchIndex]},
128
+ :info => items.map{|item| item[:info]}
129
+ }
130
+ search_data = {
131
+ :index => index,
132
+ :badges => @names
133
+ }
134
+
135
+ dst = File.join @op_dir, RDoc::Generator::SHtml::SEARCH_INDEX_FILE
136
+ FileUtils.mkdir_p File.dirname(dst)
137
+ File.open(dst, "w", 0644) do |f|
138
+ f.write('var search_data = '); f.write(search_data.to_json)
139
+ end
140
+ end
141
+
142
+ def extract_index_path dir
143
+ filename = File.join dir, 'index.html'
144
+ content = File.open(filename) { |f| f.read }
145
+ match = content.match(/<frame\s+src="([^"]+)"\s+name="docwin"/mi)
146
+ if match
147
+ match[1]
148
+ else
149
+ ''
150
+ end
151
+ end
152
+
153
+ def generate_index_file
154
+ templatefile = @template_dir + 'index.rhtml'
155
+ outfile = @outputdir + 'index.html'
156
+ url = @urls.empty? ? @names[0] : @urls[0]
157
+ index_path = url + '/' + extract_index_path(@directories[0])
158
+
159
+ render_template templatefile, binding(), outfile
160
+ end
161
+
162
+ def setup_names
163
+ unless @names.size > 0
164
+ @directories.each do |dir|
165
+ name = File.basename dir
166
+ name = File.basename File.dirname(dir) if name == 'doc'
167
+ @names << name
168
+ end
169
+ end
170
+ end
171
+
172
+ def copy_docs
173
+ @directories.each_with_index do |dir, i|
174
+ name = @names[i]
175
+ index_dir = File.dirname(RDoc::Generator::SHtml::TREE_FILE)
176
+ FileUtils.mkdir_p(File.join(@op_dir, name))
177
+
178
+ Dir.new(dir).each do |item|
179
+ if File.directory?(File.join(dir, item)) && item != '.' && item != '..' && item != index_dir
180
+ FileUtils.cp_r File.join(dir, item), File.join(@op_dir, name, item), :preserve => true
181
+ end
182
+ end
183
+ end
184
+ end
185
+
186
+ def copy_files
187
+ dir = @directories.first
188
+ Dir.new(dir).each do |item|
189
+ if item != '.' && item != '..' && item != RDoc::Generator::SHtml::FILE_DIR && item != RDoc::Generator::SHtml::CLASS_DIR
190
+ FileUtils.cp_r File.join(dir, item), @op_dir, :preserve => true
191
+ end
192
+ end
193
+ end
194
+
195
+ def setup_output_dir
196
+ if File.exists? @op_dir
197
+ error "#{@op_dir} allready exists"
198
+ end
199
+ FileUtils.mkdir_p @op_dir
200
+ end
201
+
202
+ def check_directories
203
+ @directories.each do |dir|
204
+ unless File.exists?(File.join(dir, FLAG_FILE)) &&
205
+ File.exists?(File.join(dir, RDoc::Generator::SHtml::TREE_FILE)) &&
206
+ File.exists?(File.join(dir, RDoc::Generator::SHtml::SEARCH_INDEX_FILE))
207
+ error "#{dir} does not seem to be an wpdoc directory"
208
+ end
209
+ end
210
+ end
211
+
212
+ ##
213
+ # Report an error message and exit
214
+
215
+ def error(msg)
216
+ raise RDoc::Error, msg
217
+ end
218
+
219
+ end
@@ -0,0 +1,58 @@
1
+ require "wpdoc"
2
+
3
+ module SDoc::Templatable
4
+ ### Load and render the erb template in the given +templatefile+ within the
5
+ ### specified +context+ (a Binding object) and return output
6
+ ### Both +templatefile+ and +outfile+ should be Pathname-like objects.
7
+ def eval_template(templatefile, context)
8
+ template_src = templatefile.read
9
+ template = ERB.new( template_src, nil, '<>' )
10
+ template.filename = templatefile.to_s
11
+
12
+ begin
13
+ template.result( context )
14
+ rescue NoMethodError => err
15
+ raise RDoc::Error, "Error while evaluating %s: %s (at %p)" % [
16
+ templatefile.to_s,
17
+ err.message,
18
+ eval( "_erbout[-50,50]", context )
19
+ ], err.backtrace
20
+ end
21
+ end
22
+
23
+ ### Load and render the erb template with the given +template_name+ within
24
+ ### current context. Adds all +local_assigns+ to context
25
+ def include_template(template_name, local_assigns = {})
26
+ source = local_assigns.keys.map { |key| "#{key} = local_assigns[:#{key}];" }.join
27
+ eval("#{source};templatefile = @template_dir + template_name;eval_template(templatefile, binding)")
28
+ end
29
+
30
+ ### Load and render the erb template in the given +templatefile+ within the
31
+ ### specified +context+ (a Binding object) and write it out to +outfile+.
32
+ ### Both +templatefile+ and +outfile+ should be Pathname-like objects.
33
+ def render_template( templatefile, context, outfile )
34
+ output = eval_template(templatefile, context)
35
+
36
+ # TODO delete this dirty hack when documentation for example for GeneratorMethods will not be cutted off by <script> tag
37
+ begin
38
+ if output.respond_to? :force_encoding
39
+ encoding = output.encoding
40
+ output = output.force_encoding('ASCII-8BIT').gsub('<script>', '&lt;script;&gt;').force_encoding(encoding)
41
+ else
42
+ output = output.gsub('<script>', '&lt;script&gt;')
43
+ end
44
+ rescue Exception => e
45
+
46
+ end
47
+
48
+ unless $dryrun
49
+ outfile.dirname.mkpath
50
+ outfile.open( 'w', 0644 ) do |file|
51
+ file.print( output )
52
+ end
53
+ else
54
+ debug_msg " would have written %d bytes to %s" %
55
+ [ output.length, outfile ]
56
+ end
57
+ end
58
+ end