wpdoc 0.2.17

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 (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