bitclust-core 0.5.0
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.
- 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
|