bitclust-core 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +2907 -0
- data/Gemfile +7 -0
- data/README +21 -0
- data/Rakefile +20 -0
- data/bin/bitclust +14 -0
- data/bin/refe +36 -0
- data/bitclust-dev.gemspec +33 -0
- data/bitclust.gemspec +30 -0
- data/config.in +23 -0
- data/config.ru +48 -0
- data/config.ru.sample +31 -0
- data/data/bitclust/catalog/ja_JP.EUC-JP +78 -0
- data/data/bitclust/catalog/ja_JP.UTF-8 +78 -0
- data/data/bitclust/template.lillia/class +98 -0
- data/data/bitclust/template.lillia/class-index +28 -0
- data/data/bitclust/template.lillia/doc +48 -0
- data/data/bitclust/template.lillia/layout +19 -0
- data/data/bitclust/template.lillia/library +129 -0
- data/data/bitclust/template.lillia/library-index +32 -0
- data/data/bitclust/template.lillia/method +20 -0
- data/data/bitclust/template.lillia/rd_file +6 -0
- data/data/bitclust/template.offline/class +67 -0
- data/data/bitclust/template.offline/class-index +28 -0
- data/data/bitclust/template.offline/doc +13 -0
- data/data/bitclust/template.offline/function +22 -0
- data/data/bitclust/template.offline/function-index +24 -0
- data/data/bitclust/template.offline/layout +18 -0
- data/data/bitclust/template.offline/library +87 -0
- data/data/bitclust/template.offline/library-index +32 -0
- data/data/bitclust/template.offline/method +21 -0
- data/data/bitclust/template.offline/rd_file +6 -0
- data/data/bitclust/template/class +133 -0
- data/data/bitclust/template/class-index +30 -0
- data/data/bitclust/template/doc +14 -0
- data/data/bitclust/template/function +21 -0
- data/data/bitclust/template/function-index +25 -0
- data/data/bitclust/template/layout +19 -0
- data/data/bitclust/template/library +89 -0
- data/data/bitclust/template/library-index +35 -0
- data/data/bitclust/template/method +24 -0
- data/data/bitclust/template/opensearchdescription +10 -0
- data/data/bitclust/template/search +57 -0
- data/lib/bitclust.rb +9 -0
- data/lib/bitclust/app.rb +129 -0
- data/lib/bitclust/classentry.rb +425 -0
- data/lib/bitclust/compat.rb +39 -0
- data/lib/bitclust/completion.rb +531 -0
- data/lib/bitclust/crossrubyutils.rb +91 -0
- data/lib/bitclust/database.rb +181 -0
- data/lib/bitclust/docentry.rb +83 -0
- data/lib/bitclust/entry.rb +223 -0
- data/lib/bitclust/exception.rb +38 -0
- data/lib/bitclust/functiondatabase.rb +115 -0
- data/lib/bitclust/functionentry.rb +81 -0
- data/lib/bitclust/functionreferenceparser.rb +76 -0
- data/lib/bitclust/htmlutils.rb +80 -0
- data/lib/bitclust/interface.rb +87 -0
- data/lib/bitclust/libraryentry.rb +211 -0
- data/lib/bitclust/lineinput.rb +165 -0
- data/lib/bitclust/messagecatalog.rb +95 -0
- data/lib/bitclust/methoddatabase.rb +401 -0
- data/lib/bitclust/methodentry.rb +202 -0
- data/lib/bitclust/methodid.rb +209 -0
- data/lib/bitclust/methodsignature.rb +82 -0
- data/lib/bitclust/nameutils.rb +236 -0
- data/lib/bitclust/parseutils.rb +60 -0
- data/lib/bitclust/preprocessor.rb +273 -0
- data/lib/bitclust/rdcompiler.rb +507 -0
- data/lib/bitclust/refsdatabase.rb +66 -0
- data/lib/bitclust/requesthandler.rb +330 -0
- data/lib/bitclust/ridatabase.rb +349 -0
- data/lib/bitclust/rrdparser.rb +522 -0
- data/lib/bitclust/runner.rb +143 -0
- data/lib/bitclust/screen.rb +554 -0
- data/lib/bitclust/searcher.rb +518 -0
- data/lib/bitclust/server.rb +59 -0
- data/lib/bitclust/simplesearcher.rb +84 -0
- data/lib/bitclust/subcommand.rb +746 -0
- data/lib/bitclust/textutils.rb +51 -0
- data/lib/bitclust/version.rb +3 -0
- data/packer.rb +224 -0
- data/refe2.gemspec +29 -0
- data/server.exe +0 -0
- data/server.exy +159 -0
- data/server.rb +10 -0
- data/setup.rb +1596 -0
- data/standalone.rb +193 -0
- data/test/run_test.rb +15 -0
- data/test/test_bitclust.rb +81 -0
- data/test/test_entry.rb +39 -0
- data/test/test_functiondatabase.rb +55 -0
- data/test/test_libraryentry.rb +31 -0
- data/test/test_methoddatabase.rb +81 -0
- data/test/test_methodsignature.rb +14 -0
- data/test/test_nameutils.rb +324 -0
- data/test/test_preprocessor.rb +84 -0
- data/test/test_rdcompiler.rb +534 -0
- data/test/test_refsdatabase.rb +76 -0
- data/test/test_rrdparser.rb +26 -0
- data/test/test_runner.rb +102 -0
- data/test/test_simplesearcher.rb +48 -0
- data/theme/default/images/external.png +0 -0
- data/theme/default/rurema.png +0 -0
- data/theme/default/style.css +288 -0
- data/theme/default/test.css +254 -0
- data/theme/lillia/rurema.png +0 -0
- data/theme/lillia/style.css +331 -0
- data/theme/lillia/test.css +254 -0
- data/tools/bc-ancestors.rb +153 -0
- data/tools/bc-checkparams.rb +246 -0
- data/tools/bc-classes.rb +80 -0
- data/tools/bc-convert.rb +165 -0
- data/tools/bc-list.rb +63 -0
- data/tools/bc-methods.rb +171 -0
- data/tools/bc-preproc.rb +42 -0
- data/tools/bc-rdoc.rb +343 -0
- data/tools/bc-tochm.rb +301 -0
- data/tools/bc-tohtml.rb +125 -0
- data/tools/bc-tohtmlpackage.rb +241 -0
- data/tools/check-signature.rb +19 -0
- data/tools/forall-ruby.rb +20 -0
- data/tools/gencatalog.rb +69 -0
- data/tools/statrefm.rb +98 -0
- data/tools/stattodo.rb +150 -0
- data/tools/update-database.rb +146 -0
- data/view.cgi +6 -0
- metadata +222 -0
data/tools/bc-preproc.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'pathname'
|
4
|
+
|
5
|
+
bindir = Pathname.new(__FILE__).realpath.dirname
|
6
|
+
$LOAD_PATH.unshift((bindir + '../lib').realpath)
|
7
|
+
|
8
|
+
require 'bitclust/rrdparser'
|
9
|
+
require 'optparse'
|
10
|
+
|
11
|
+
def main
|
12
|
+
params = {"version" => "1.9.0"}
|
13
|
+
parser = OptionParser.new
|
14
|
+
parser.banner = "Usage: #{File.basename($0, '.*')} <file>..."
|
15
|
+
parser.on('--param=KVPAIR', 'Set parameter by key/value pair.') {|kv|
|
16
|
+
k, v = kv.split('=', 2)
|
17
|
+
params[k] = v
|
18
|
+
}
|
19
|
+
parser.on('--help', 'Prints this message and quit.') {
|
20
|
+
puts parser.help
|
21
|
+
exit
|
22
|
+
}
|
23
|
+
begin
|
24
|
+
parser.parse!
|
25
|
+
rescue OptionParser::ParseError => err
|
26
|
+
$stderr.puts err.message
|
27
|
+
exit 1
|
28
|
+
end
|
29
|
+
|
30
|
+
ARGV.each do |path|
|
31
|
+
File.open(path) {|f|
|
32
|
+
BitClust::Preprocessor.wrap(f, params).each do |line|
|
33
|
+
puts line
|
34
|
+
end
|
35
|
+
}
|
36
|
+
end
|
37
|
+
rescue BitClust::WriterError => err
|
38
|
+
$stderr.puts err.message
|
39
|
+
exit 1
|
40
|
+
end
|
41
|
+
|
42
|
+
main
|
data/tools/bc-rdoc.rb
ADDED
@@ -0,0 +1,343 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# bc-rdoc.rb -- handle rdoc (ri) database.
|
4
|
+
#
|
5
|
+
# "bc-rdoc history" code is derived from bc-history.rb, posted in
|
6
|
+
# [ruby-reference-manual:150] by moriq.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
|
11
|
+
srcdir_root = Pathname.new(__FILE__).realpath.dirname.parent.cleanpath
|
12
|
+
$LOAD_PATH.unshift srcdir_root + 'lib'
|
13
|
+
|
14
|
+
require 'bitclust'
|
15
|
+
require 'bitclust/ridatabase'
|
16
|
+
require 'rdoc/ri/ri_reader'
|
17
|
+
require 'rdoc/ri/ri_cache'
|
18
|
+
require 'rdoc/ri/ri_paths'
|
19
|
+
require 'rdoc/markup/simple_markup/fragments'
|
20
|
+
require 'stringio'
|
21
|
+
require 'pp'
|
22
|
+
require 'optparse'
|
23
|
+
|
24
|
+
class ApplicationError < StandardError; end
|
25
|
+
class RiClassNotFound < ApplicationError; end
|
26
|
+
|
27
|
+
def main
|
28
|
+
Signal.trap(:PIPE) { exit 1 } rescue nil # Win32 does not have SIGPIPE
|
29
|
+
Signal.trap(:INT) { exit 1 }
|
30
|
+
|
31
|
+
parser = OptionParser.new
|
32
|
+
parser.banner = <<-EndUsage
|
33
|
+
Usage: #{File.basename($0)} (list|diff|history) [options]
|
34
|
+
|
35
|
+
Subcommands:
|
36
|
+
list List methods stored in ri database.
|
37
|
+
diff Compare between BitClust and ri database.
|
38
|
+
history Show class/method history stored in ri database.
|
39
|
+
|
40
|
+
Global Options:
|
41
|
+
EndUsage
|
42
|
+
parser.on('--help', 'Prints this message and quit.') {
|
43
|
+
puts parser.help
|
44
|
+
exit 0
|
45
|
+
}
|
46
|
+
begin
|
47
|
+
parser.order!
|
48
|
+
rescue OptionParser::ParseError => err
|
49
|
+
$stderr.puts err.message
|
50
|
+
$stderr.puts parser.help
|
51
|
+
exit 1
|
52
|
+
end
|
53
|
+
|
54
|
+
subcommands = {
|
55
|
+
'list' => ListCommand.new,
|
56
|
+
'diff' => DiffCommand.new,
|
57
|
+
'history' => HistoryCommand.new
|
58
|
+
}
|
59
|
+
subcommands['hist'] = subcommands['history']
|
60
|
+
unless ARGV[0]
|
61
|
+
$stderr.puts 'no subcommand given'
|
62
|
+
$stderr.puts parser.help
|
63
|
+
exit 1
|
64
|
+
end
|
65
|
+
unless subcommands.key?(ARGV[0])
|
66
|
+
$stderr.puts "unknown subcommand: #{ARGV[0].inspect}"
|
67
|
+
$stderr.puts parser.help
|
68
|
+
exit 1
|
69
|
+
end
|
70
|
+
sub = subcommands[ARGV.shift]
|
71
|
+
begin
|
72
|
+
sub.parse ARGV
|
73
|
+
rescue OptionParser::ParseError => err
|
74
|
+
$stderr.puts err.message
|
75
|
+
$stderr.puts sub.parser.help
|
76
|
+
exit 1
|
77
|
+
end
|
78
|
+
sub.exec
|
79
|
+
rescue Errno::EPIPE
|
80
|
+
exit 1
|
81
|
+
rescue ApplicationError, BitClust::UserError => err
|
82
|
+
$stderr.puts err.message
|
83
|
+
exit 1
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
class Subcommand
|
88
|
+
|
89
|
+
def open_ri_database(prefix)
|
90
|
+
if prefix
|
91
|
+
RiDatabase.open(prefix, nil)
|
92
|
+
else
|
93
|
+
RiDatabase.open_system_db
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
class ListCommand < Subcommand
|
101
|
+
|
102
|
+
def initialize
|
103
|
+
@prefix = nil
|
104
|
+
@type = :name
|
105
|
+
@parser = OptionParser.new
|
106
|
+
@parser.banner = "Usage: #{File.basename($0, '.*')} list"
|
107
|
+
@parser.on('--ri-database=PREFIX', 'Ri database prefix') {|path|
|
108
|
+
@prefix = path
|
109
|
+
}
|
110
|
+
@parser.on('-c', '--content', 'Prints method description') {
|
111
|
+
@type = :content
|
112
|
+
}
|
113
|
+
@parser.on('--help', 'Prints this message and quit.') {
|
114
|
+
puts @parser.help
|
115
|
+
exit 0
|
116
|
+
}
|
117
|
+
end
|
118
|
+
|
119
|
+
attr_reader :parser
|
120
|
+
|
121
|
+
def parse(argv)
|
122
|
+
@parser.parse! argv
|
123
|
+
unless argv.size == 1
|
124
|
+
$stderr.puts "class name not given"
|
125
|
+
exit 1
|
126
|
+
end
|
127
|
+
@classname = argv[0]
|
128
|
+
@ri = open_ri_database(@prefix)
|
129
|
+
end
|
130
|
+
|
131
|
+
def exec
|
132
|
+
c = @ri.lookup_class(@classname)
|
133
|
+
case @type
|
134
|
+
when :name
|
135
|
+
c.method_entries.each do |m|
|
136
|
+
puts m.fullname
|
137
|
+
end
|
138
|
+
when :content
|
139
|
+
fmt = Formatter.new
|
140
|
+
c.method_entries.each do |m|
|
141
|
+
puts fmt.method_info(@ri.get_method(m))
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
147
|
+
|
148
|
+
|
149
|
+
class DiffCommand < Subcommand
|
150
|
+
|
151
|
+
def initialize
|
152
|
+
@bcprefix = nil
|
153
|
+
@riprefix = nil
|
154
|
+
@type = :name
|
155
|
+
@parser = OptionParser.new
|
156
|
+
@parser.banner = "Usage: #{File.basename($0, '.*')} diff --bc=PATH --ri=PATH <classname>"
|
157
|
+
@parser.on('--bc-database=PREFIX', 'BitClust database prefix') {|path|
|
158
|
+
@bcprefix = path
|
159
|
+
}
|
160
|
+
@parser.on('--ri-database=PREFIX', 'Ri database prefix') {|path|
|
161
|
+
@riprefix = path
|
162
|
+
}
|
163
|
+
@parser.on('-c', '--content', 'Prints method description') {
|
164
|
+
@type = :content
|
165
|
+
}
|
166
|
+
@parser.on('--help', 'Prints this message and quit.') {
|
167
|
+
puts @parser.help
|
168
|
+
exit 0
|
169
|
+
}
|
170
|
+
end
|
171
|
+
|
172
|
+
attr_reader :parser
|
173
|
+
|
174
|
+
def parse(argv)
|
175
|
+
@parser.parse! argv
|
176
|
+
unless @bcprefix
|
177
|
+
$stderr.puts 'missing BitClust database prefix. Use --bc option'
|
178
|
+
exit 1
|
179
|
+
end
|
180
|
+
@bc = BitClust::MethodDatabase.new(@bcprefix)
|
181
|
+
@ri = open_ri_database(@riprefix)
|
182
|
+
unless argv.size == 1
|
183
|
+
$stderr.puts "wrong number of arguments (#{argv.size} for 1)"
|
184
|
+
$stderr.puts @parser.help
|
185
|
+
exit 1
|
186
|
+
end
|
187
|
+
@classname = argv[0]
|
188
|
+
end
|
189
|
+
|
190
|
+
def exec
|
191
|
+
@ri.current_class = @classname
|
192
|
+
win, lose = *diff_class(bc_lookup_class(@classname), @ri)
|
193
|
+
case @type
|
194
|
+
when :name
|
195
|
+
win.each do |m|
|
196
|
+
puts "+ #{m.id}"
|
197
|
+
end
|
198
|
+
lose.each do |m|
|
199
|
+
puts "- #{m.fullname}"
|
200
|
+
end
|
201
|
+
when :content
|
202
|
+
fmt = Formatter.new
|
203
|
+
lose.each do |m|
|
204
|
+
# puts "\#@\# bc-rdoc: detected missing name: #{m.name}"
|
205
|
+
puts fmt.method_info(m.entry)
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
def bc_lookup_class(classname)
|
211
|
+
@bc.fetch_class(classname)
|
212
|
+
rescue BitClust::ClassNotFound
|
213
|
+
$stderr.puts "warning: class #{classname} not exist in BitClust database"
|
214
|
+
@bc.get_class(classname)
|
215
|
+
end
|
216
|
+
|
217
|
+
def diff_class(bc, ri)
|
218
|
+
unzip(diff_entries(bc, bc_wrap(bc.singleton_methods), ri.singleton_methods),
|
219
|
+
diff_entries(bc, bc_wrap(bc.instance_methods), ri.instance_methods))\
|
220
|
+
.map {|list| list.flatten }
|
221
|
+
end
|
222
|
+
|
223
|
+
def bc_wrap(ents)
|
224
|
+
ents.map {|m|
|
225
|
+
m.names.map {|name| BCMethodEntry.new(name, m) }
|
226
|
+
}.flatten.uniq
|
227
|
+
end
|
228
|
+
|
229
|
+
def unzip(*tuples)
|
230
|
+
[tuples.map {|s, i| s }, tuples.map {|s, i| i }]
|
231
|
+
end
|
232
|
+
|
233
|
+
def diff_entries(bc_class, bc, ri)
|
234
|
+
bc = bc.sort
|
235
|
+
ri = ri.sort
|
236
|
+
[bc - ri, (ri - bc).reject {|m| true_exist?(bc_class, m) }]
|
237
|
+
end
|
238
|
+
|
239
|
+
def true_exist?(c, m)
|
240
|
+
if m.singleton_method?
|
241
|
+
c.singleton_method?(m.name, true)
|
242
|
+
else
|
243
|
+
c.instance_method?(m.name, true)
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
end
|
248
|
+
|
249
|
+
|
250
|
+
class HistoryCommand < Subcommand
|
251
|
+
|
252
|
+
def initialize
|
253
|
+
@riprefix = nil
|
254
|
+
@parser = OptionParser.new
|
255
|
+
@parser.banner = "Usage: #{File.basename($0, '.*')} history --ri=PATH <classname>"
|
256
|
+
@parser.on('--ri-database=PREFIX', 'Ri database prefix') {|path|
|
257
|
+
@riprefix = path
|
258
|
+
}
|
259
|
+
@parser.on('--help', 'Prints this message and quit.') {
|
260
|
+
puts @parser.help
|
261
|
+
exit 0
|
262
|
+
}
|
263
|
+
end
|
264
|
+
|
265
|
+
attr_reader :parser
|
266
|
+
|
267
|
+
def parse(argv)
|
268
|
+
@parser.parse! argv
|
269
|
+
unless @riprefix
|
270
|
+
$stderr.puts 'ri database not given; use --ri option'
|
271
|
+
exit 1
|
272
|
+
end
|
273
|
+
@ris = Dir.glob("#{@riprefix}/1.*").map {|dir|
|
274
|
+
RiDatabase.open(dir, File.basename(dir))
|
275
|
+
}
|
276
|
+
if @ris.empty?
|
277
|
+
$stderr.puts 'wrong ri database directory; directories like <path>/1.8.3/, <path>/1.8.4/, ... must exist'
|
278
|
+
exit 1
|
279
|
+
end
|
280
|
+
unless argv.size == 1
|
281
|
+
$stderr.puts "wrong number of arguments (#{argv.size} for 1)"
|
282
|
+
$stderr.puts @parser.help
|
283
|
+
exit 1
|
284
|
+
end
|
285
|
+
@classname = argv[0]
|
286
|
+
end
|
287
|
+
|
288
|
+
def exec
|
289
|
+
@ris.each do |ri|
|
290
|
+
ri.current_class = @classname
|
291
|
+
end
|
292
|
+
s = {}
|
293
|
+
i = {}
|
294
|
+
@ris.each do |ri|
|
295
|
+
ri.singleton_methods.each do |m|
|
296
|
+
(s[m] ||= []).push ri.version
|
297
|
+
end
|
298
|
+
ri.instance_methods.each do |m|
|
299
|
+
(i[m] ||= []).push ri.version
|
300
|
+
end
|
301
|
+
end
|
302
|
+
namecols = calculate_n_namecols(s.keys + i.keys)
|
303
|
+
versions = @ris.map {|ri| ri.version }
|
304
|
+
print_header namecols, versions
|
305
|
+
print_records namecols, versions, (s.to_a + i.to_a)
|
306
|
+
end
|
307
|
+
|
308
|
+
def calculate_n_namecols(ms)
|
309
|
+
tabstop = 8
|
310
|
+
maxnamelen = ms.map {|m| m.fullname.size }.max
|
311
|
+
(maxnamelen / tabstop + 1) * tabstop
|
312
|
+
end
|
313
|
+
|
314
|
+
def print_header(namecols, versions)
|
315
|
+
print ' ' * namecols
|
316
|
+
versions.each do |ver|
|
317
|
+
printf '%4s', ver.tr('.', '')
|
318
|
+
end
|
319
|
+
puts
|
320
|
+
end
|
321
|
+
|
322
|
+
def print_records(namecols, versions, records)
|
323
|
+
veridx = {}
|
324
|
+
versions.each_with_index do |ver, idx|
|
325
|
+
veridx[ver] = idx
|
326
|
+
end
|
327
|
+
records.sort_by {|m, vers| m.fullname }.each do |m, vers|
|
328
|
+
printf "%-#{namecols}s", m.fullname
|
329
|
+
|
330
|
+
fmt = '%4s' * versions.size
|
331
|
+
cols = ['-'] * versions.size
|
332
|
+
vers.each do |ver|
|
333
|
+
cols[veridx[ver]] = 'o'
|
334
|
+
end
|
335
|
+
printf fmt, *cols
|
336
|
+
puts
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
end
|
341
|
+
|
342
|
+
|
343
|
+
main
|
data/tools/bc-tochm.rb
ADDED
@@ -0,0 +1,301 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
require 'pathname'
|
4
|
+
def srcdir_root
|
5
|
+
(Pathname.new(__FILE__).realpath.dirname + '..').cleanpath
|
6
|
+
end
|
7
|
+
|
8
|
+
$LOAD_PATH.unshift srcdir_root() + 'lib'
|
9
|
+
|
10
|
+
#def srcdir_root
|
11
|
+
# #Pathname.new(__FILE__).realpath.dirname.parent.cleanpath
|
12
|
+
# Pathname.new(__FILE__).dirname.parent.cleanpath
|
13
|
+
#end
|
14
|
+
#$LOAD_PATH.unshift srcdir_root + 'lib'
|
15
|
+
|
16
|
+
require 'bitclust'
|
17
|
+
require 'erb'
|
18
|
+
require 'fileutils'
|
19
|
+
require 'kconv'
|
20
|
+
require 'optparse'
|
21
|
+
begin
|
22
|
+
require 'progressbar'
|
23
|
+
rescue LoadError
|
24
|
+
class ProgressBar
|
25
|
+
def initialize(title, total, out = STDERR)
|
26
|
+
@title, @total, @out = title, total, out
|
27
|
+
end
|
28
|
+
attr_reader :title
|
29
|
+
|
30
|
+
def inc(step = 1)
|
31
|
+
end
|
32
|
+
|
33
|
+
def finish
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
HHP_SKEL = <<EOS
|
39
|
+
[OPTIONS]
|
40
|
+
Compatibility=1.1 or later
|
41
|
+
Compiled file=refm.chm
|
42
|
+
Contents file=refm.hhc
|
43
|
+
Default Window=titlewindow
|
44
|
+
Default topic=doc/index.html
|
45
|
+
Display compile progress=No
|
46
|
+
Error log file=refm.log
|
47
|
+
Full-text search=Yes
|
48
|
+
Index file=refm.hhk
|
49
|
+
Language=0x411 日本語 (日本)
|
50
|
+
Title=Rubyリファレンスマニュアル
|
51
|
+
|
52
|
+
[WINDOWS]
|
53
|
+
titlewindow="Rubyリファレンスマニュアル","refm.hhc","refm.hhk","doc/index.html","doc/index.html",,,,,0x21420,,0x387e,,,,,,,,0
|
54
|
+
|
55
|
+
[FILES]
|
56
|
+
<%= @html_files.join("\n") %>
|
57
|
+
EOS
|
58
|
+
|
59
|
+
HHC_SKEL = <<EOS
|
60
|
+
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
|
61
|
+
<HTML>
|
62
|
+
<HEAD>
|
63
|
+
</HEAD>
|
64
|
+
<BODY>
|
65
|
+
<UL><% [:library].each do |k| %>
|
66
|
+
<%= @sitemap[k].to_html %>
|
67
|
+
<% end %></UL>
|
68
|
+
</BODY>
|
69
|
+
</HTML>
|
70
|
+
EOS
|
71
|
+
|
72
|
+
HHK_SKEL = <<EOS
|
73
|
+
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
|
74
|
+
<HTML>
|
75
|
+
<HEAD>
|
76
|
+
</HEAD>
|
77
|
+
<BODY>
|
78
|
+
<UL><% @index_contents.sort.each do |content| %>
|
79
|
+
<%= content.to_html %>
|
80
|
+
<% end %></UL>
|
81
|
+
</BODY>
|
82
|
+
</HTML>
|
83
|
+
EOS
|
84
|
+
|
85
|
+
class Sitemap
|
86
|
+
def initialize(name, local = nil)
|
87
|
+
@name = name
|
88
|
+
@contents = Content.new(name, local)
|
89
|
+
end
|
90
|
+
|
91
|
+
def method_missing(name, *args, &block)
|
92
|
+
@contents.send(name, *args, &block)
|
93
|
+
end
|
94
|
+
|
95
|
+
class Content
|
96
|
+
include Enumerable
|
97
|
+
include ERB::Util
|
98
|
+
|
99
|
+
def initialize(name, local = nil)
|
100
|
+
@name = name
|
101
|
+
@local = local
|
102
|
+
@contents = []
|
103
|
+
end
|
104
|
+
attr_reader :name, :local, :contents
|
105
|
+
|
106
|
+
def [](index)
|
107
|
+
@contents[index]
|
108
|
+
end
|
109
|
+
|
110
|
+
def <<(content)
|
111
|
+
@contents << content
|
112
|
+
end
|
113
|
+
|
114
|
+
def <=>(other)
|
115
|
+
@name <=> other.name
|
116
|
+
end
|
117
|
+
|
118
|
+
def each
|
119
|
+
@contents.each do |content|
|
120
|
+
yield content
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def to_html
|
125
|
+
str = "<LI> <OBJECT type=\"text/sitemap\">\n"
|
126
|
+
str << " <param name=\"Name\" value=\"<%=h @name%>\">\n"
|
127
|
+
if @local
|
128
|
+
str << " <param name=\"Local\" value=\"<%=@local%>\">\n"
|
129
|
+
end
|
130
|
+
str << " </OBJECT>\n"
|
131
|
+
unless contents.empty?
|
132
|
+
str << "<UL>\n"
|
133
|
+
@contents.each do |content|
|
134
|
+
str << content.to_html
|
135
|
+
end
|
136
|
+
str << "</UL>\n"
|
137
|
+
end
|
138
|
+
ERB.new(str).result(binding)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
module BitClust
|
144
|
+
|
145
|
+
class URLMapperEx < URLMapper
|
146
|
+
def library_url(name)
|
147
|
+
if name == '/'
|
148
|
+
"/library/index.html"
|
149
|
+
else
|
150
|
+
"/library/#{encodename_fs(name)}.html"
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def class_url(name)
|
155
|
+
"/class/#{encodename_fs(name)}.html"
|
156
|
+
end
|
157
|
+
|
158
|
+
def method_url(spec)
|
159
|
+
cname, tmark, mname = *split_method_spec(spec)
|
160
|
+
"/method/#{encodename_fs(cname)}/#{typemark2char(tmark)}/#{encodename_fs(mname)}.html"
|
161
|
+
end
|
162
|
+
|
163
|
+
def document_url(name)
|
164
|
+
"/doc/#{encodename_fs(name)}.html"
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def main
|
170
|
+
@sitemap = {
|
171
|
+
:library => Sitemap.new('ライブラリ', 'library/index.html'),
|
172
|
+
}
|
173
|
+
@sitemap[:library] << Sitemap::Content.new('標準ライブラリ', 'library/_builtin.html')
|
174
|
+
@sitemap[:library] << Sitemap::Content.new('添付ライブラリ')
|
175
|
+
@stdlibs = {}
|
176
|
+
@index_contents = []
|
177
|
+
prefix = Pathname.new('./db')
|
178
|
+
outputdir = Pathname.new('./chm')
|
179
|
+
manager_config = {
|
180
|
+
:baseurl => 'http://example.com/',
|
181
|
+
:suffix => '.html',
|
182
|
+
:templatedir => srcdir_root + 'data'+ 'bitclust' + 'template',
|
183
|
+
:themedir => srcdir_root + 'theme' + 'default',
|
184
|
+
:css_url => 'style.css',
|
185
|
+
:cgi_url => '',
|
186
|
+
:tochm_mode => true
|
187
|
+
}
|
188
|
+
manager_config[:urlmapper] = BitClust::URLMapperEx.new(manager_config)
|
189
|
+
|
190
|
+
parser = OptionParser.new
|
191
|
+
parser.on('-d', '--database=PATH', 'Database prefix') do |path|
|
192
|
+
prefix = Pathname.new(path).realpath
|
193
|
+
end
|
194
|
+
parser.on('-o', '--outputdir=PATH', 'Output directory') do |path|
|
195
|
+
begin
|
196
|
+
outputdir = Pathname.new(path).realpath
|
197
|
+
rescue Errno::ENOENT
|
198
|
+
FileUtils.mkdir_p(path, :verbose => true)
|
199
|
+
retry
|
200
|
+
end
|
201
|
+
end
|
202
|
+
parser.on('--help', 'Prints this message and quit') do
|
203
|
+
puts(parser.help)
|
204
|
+
exit(0)
|
205
|
+
end
|
206
|
+
begin
|
207
|
+
parser.parse!
|
208
|
+
rescue OptionParser::ParseError => err
|
209
|
+
STDERR.puts(err.message)
|
210
|
+
STDERR.puts(parser.help)
|
211
|
+
exit(1)
|
212
|
+
end
|
213
|
+
|
214
|
+
db = BitClust::MethodDatabase.new(prefix.to_s)
|
215
|
+
manager = BitClust::ScreenManager.new(manager_config)
|
216
|
+
@html_files = []
|
217
|
+
db.transaction do
|
218
|
+
methods = {}
|
219
|
+
pb = ProgressBar.new('method', db.methods.size)
|
220
|
+
db.methods.each_with_index do |entry, i|
|
221
|
+
method_name = entry.klass.name + entry.typemark + entry.name
|
222
|
+
(methods[method_name] ||= []) << entry
|
223
|
+
pb.inc
|
224
|
+
end
|
225
|
+
pb.finish
|
226
|
+
entries = db.docs + db.libraries.sort + db.classes.sort + methods.values.sort
|
227
|
+
pb = ProgressBar.new('entry', entries.size)
|
228
|
+
entries.each_with_index do |c, i|
|
229
|
+
filename = create_html_file(c, manager, outputdir, db)
|
230
|
+
@html_files << filename
|
231
|
+
e = c.is_a?(Array) ? c.sort.first : c
|
232
|
+
case e.type_id
|
233
|
+
when :library
|
234
|
+
content = Sitemap::Content.new(e.name.to_s, filename)
|
235
|
+
if e.name.to_s != '_builtin'
|
236
|
+
@sitemap[:library][1] << content
|
237
|
+
@stdlibs[e.name.to_s] = content
|
238
|
+
end
|
239
|
+
@index_contents << Sitemap::Content.new(e.name.to_s, filename)
|
240
|
+
when :class
|
241
|
+
content = Sitemap::Content.new(e.name.to_s, filename)
|
242
|
+
if e.library.name.to_s == '_builtin'
|
243
|
+
@sitemap[:library][0] << content
|
244
|
+
else
|
245
|
+
@stdlibs[e.library.name.to_s] << content
|
246
|
+
end
|
247
|
+
@index_contents << Sitemap::Content.new("#{e.name} (#{e.library.name})", filename)
|
248
|
+
when :method
|
249
|
+
e.names.each do |e_name|
|
250
|
+
name = e.typename == :special_variable ? "$#{e_name}" : e_name
|
251
|
+
@index_contents <<
|
252
|
+
Sitemap::Content.new("#{name} (#{e.library.name} - #{e.klass.name})", filename)
|
253
|
+
@index_contents <<
|
254
|
+
Sitemap::Content.new("#{e.klass.name}#{e.typemark}#{name} (#{e.library.name})", filename)
|
255
|
+
end
|
256
|
+
end
|
257
|
+
pb.title.replace(e.name)
|
258
|
+
pb.inc
|
259
|
+
end
|
260
|
+
pb.finish
|
261
|
+
end
|
262
|
+
@html_files.sort!
|
263
|
+
create_file(outputdir + 'refm.hhp', HHP_SKEL, true)
|
264
|
+
create_file(outputdir + 'refm.hhc', HHC_SKEL, true)
|
265
|
+
create_file(outputdir + 'refm.hhk', HHK_SKEL, true)
|
266
|
+
create_file(outputdir + 'library/index.html', manager.library_index_screen(db.libraries.sort, {:database => db}).body)
|
267
|
+
create_file(outputdir + 'class/index.html', manager.class_index_screen(db.classes.sort, {:database => db}).body)
|
268
|
+
FileUtils.cp(manager_config[:themedir] + manager_config[:css_url],
|
269
|
+
outputdir.to_s, {:verbose => true, :preserve => true})
|
270
|
+
end
|
271
|
+
|
272
|
+
def create_html_file(entry, manager, outputdir, db)
|
273
|
+
html = manager.entry_screen(entry, {:database => db}).body
|
274
|
+
e = entry.is_a?(Array) ? entry.sort.first : entry
|
275
|
+
path = case e.type_id
|
276
|
+
when :library, :class, :doc
|
277
|
+
outputdir + e.type_id.to_s + (BitClust::NameUtils.encodename_fs(e.name) + '.html')
|
278
|
+
when :method
|
279
|
+
outputdir + e.type_id.to_s + BitClust::NameUtils.encodename_fs(e.klass.name) +
|
280
|
+
e.typechar + (BitClust::NameUtils.encodename_fs(e.name) + '.html')
|
281
|
+
else
|
282
|
+
raise
|
283
|
+
end
|
284
|
+
FileUtils.mkdir_p(path.dirname) unless path.dirname.directory?
|
285
|
+
path.open('w') do |f|
|
286
|
+
f.write(html)
|
287
|
+
end
|
288
|
+
path.relative_path_from(outputdir).to_s
|
289
|
+
end
|
290
|
+
|
291
|
+
def create_file(path, skel, sjis_flag = false)
|
292
|
+
STDERR.print("creating #{path} ...")
|
293
|
+
str = ERB.new(skel).result(binding)
|
294
|
+
str = str.tosjis if sjis_flag
|
295
|
+
path.open('w') do |f|
|
296
|
+
f.write(str)
|
297
|
+
end
|
298
|
+
STDERR.puts(" done.")
|
299
|
+
end
|
300
|
+
|
301
|
+
main
|