bitclust-core 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (127) hide show
  1. data/ChangeLog +2907 -0
  2. data/Gemfile +7 -0
  3. data/README +21 -0
  4. data/Rakefile +20 -0
  5. data/bin/bitclust +14 -0
  6. data/bin/refe +36 -0
  7. data/bitclust-dev.gemspec +33 -0
  8. data/bitclust.gemspec +30 -0
  9. data/config.in +23 -0
  10. data/config.ru +48 -0
  11. data/config.ru.sample +31 -0
  12. data/data/bitclust/catalog/ja_JP.EUC-JP +78 -0
  13. data/data/bitclust/catalog/ja_JP.UTF-8 +78 -0
  14. data/data/bitclust/template.lillia/class +98 -0
  15. data/data/bitclust/template.lillia/class-index +28 -0
  16. data/data/bitclust/template.lillia/doc +48 -0
  17. data/data/bitclust/template.lillia/layout +19 -0
  18. data/data/bitclust/template.lillia/library +129 -0
  19. data/data/bitclust/template.lillia/library-index +32 -0
  20. data/data/bitclust/template.lillia/method +20 -0
  21. data/data/bitclust/template.lillia/rd_file +6 -0
  22. data/data/bitclust/template.offline/class +67 -0
  23. data/data/bitclust/template.offline/class-index +28 -0
  24. data/data/bitclust/template.offline/doc +13 -0
  25. data/data/bitclust/template.offline/function +22 -0
  26. data/data/bitclust/template.offline/function-index +24 -0
  27. data/data/bitclust/template.offline/layout +18 -0
  28. data/data/bitclust/template.offline/library +87 -0
  29. data/data/bitclust/template.offline/library-index +32 -0
  30. data/data/bitclust/template.offline/method +21 -0
  31. data/data/bitclust/template.offline/rd_file +6 -0
  32. data/data/bitclust/template/class +133 -0
  33. data/data/bitclust/template/class-index +30 -0
  34. data/data/bitclust/template/doc +14 -0
  35. data/data/bitclust/template/function +21 -0
  36. data/data/bitclust/template/function-index +25 -0
  37. data/data/bitclust/template/layout +19 -0
  38. data/data/bitclust/template/library +89 -0
  39. data/data/bitclust/template/library-index +35 -0
  40. data/data/bitclust/template/method +24 -0
  41. data/data/bitclust/template/opensearchdescription +10 -0
  42. data/data/bitclust/template/search +57 -0
  43. data/lib/bitclust.rb +9 -0
  44. data/lib/bitclust/app.rb +129 -0
  45. data/lib/bitclust/classentry.rb +425 -0
  46. data/lib/bitclust/compat.rb +39 -0
  47. data/lib/bitclust/completion.rb +531 -0
  48. data/lib/bitclust/crossrubyutils.rb +91 -0
  49. data/lib/bitclust/database.rb +181 -0
  50. data/lib/bitclust/docentry.rb +83 -0
  51. data/lib/bitclust/entry.rb +223 -0
  52. data/lib/bitclust/exception.rb +38 -0
  53. data/lib/bitclust/functiondatabase.rb +115 -0
  54. data/lib/bitclust/functionentry.rb +81 -0
  55. data/lib/bitclust/functionreferenceparser.rb +76 -0
  56. data/lib/bitclust/htmlutils.rb +80 -0
  57. data/lib/bitclust/interface.rb +87 -0
  58. data/lib/bitclust/libraryentry.rb +211 -0
  59. data/lib/bitclust/lineinput.rb +165 -0
  60. data/lib/bitclust/messagecatalog.rb +95 -0
  61. data/lib/bitclust/methoddatabase.rb +401 -0
  62. data/lib/bitclust/methodentry.rb +202 -0
  63. data/lib/bitclust/methodid.rb +209 -0
  64. data/lib/bitclust/methodsignature.rb +82 -0
  65. data/lib/bitclust/nameutils.rb +236 -0
  66. data/lib/bitclust/parseutils.rb +60 -0
  67. data/lib/bitclust/preprocessor.rb +273 -0
  68. data/lib/bitclust/rdcompiler.rb +507 -0
  69. data/lib/bitclust/refsdatabase.rb +66 -0
  70. data/lib/bitclust/requesthandler.rb +330 -0
  71. data/lib/bitclust/ridatabase.rb +349 -0
  72. data/lib/bitclust/rrdparser.rb +522 -0
  73. data/lib/bitclust/runner.rb +143 -0
  74. data/lib/bitclust/screen.rb +554 -0
  75. data/lib/bitclust/searcher.rb +518 -0
  76. data/lib/bitclust/server.rb +59 -0
  77. data/lib/bitclust/simplesearcher.rb +84 -0
  78. data/lib/bitclust/subcommand.rb +746 -0
  79. data/lib/bitclust/textutils.rb +51 -0
  80. data/lib/bitclust/version.rb +3 -0
  81. data/packer.rb +224 -0
  82. data/refe2.gemspec +29 -0
  83. data/server.exe +0 -0
  84. data/server.exy +159 -0
  85. data/server.rb +10 -0
  86. data/setup.rb +1596 -0
  87. data/standalone.rb +193 -0
  88. data/test/run_test.rb +15 -0
  89. data/test/test_bitclust.rb +81 -0
  90. data/test/test_entry.rb +39 -0
  91. data/test/test_functiondatabase.rb +55 -0
  92. data/test/test_libraryentry.rb +31 -0
  93. data/test/test_methoddatabase.rb +81 -0
  94. data/test/test_methodsignature.rb +14 -0
  95. data/test/test_nameutils.rb +324 -0
  96. data/test/test_preprocessor.rb +84 -0
  97. data/test/test_rdcompiler.rb +534 -0
  98. data/test/test_refsdatabase.rb +76 -0
  99. data/test/test_rrdparser.rb +26 -0
  100. data/test/test_runner.rb +102 -0
  101. data/test/test_simplesearcher.rb +48 -0
  102. data/theme/default/images/external.png +0 -0
  103. data/theme/default/rurema.png +0 -0
  104. data/theme/default/style.css +288 -0
  105. data/theme/default/test.css +254 -0
  106. data/theme/lillia/rurema.png +0 -0
  107. data/theme/lillia/style.css +331 -0
  108. data/theme/lillia/test.css +254 -0
  109. data/tools/bc-ancestors.rb +153 -0
  110. data/tools/bc-checkparams.rb +246 -0
  111. data/tools/bc-classes.rb +80 -0
  112. data/tools/bc-convert.rb +165 -0
  113. data/tools/bc-list.rb +63 -0
  114. data/tools/bc-methods.rb +171 -0
  115. data/tools/bc-preproc.rb +42 -0
  116. data/tools/bc-rdoc.rb +343 -0
  117. data/tools/bc-tochm.rb +301 -0
  118. data/tools/bc-tohtml.rb +125 -0
  119. data/tools/bc-tohtmlpackage.rb +241 -0
  120. data/tools/check-signature.rb +19 -0
  121. data/tools/forall-ruby.rb +20 -0
  122. data/tools/gencatalog.rb +69 -0
  123. data/tools/statrefm.rb +98 -0
  124. data/tools/stattodo.rb +150 -0
  125. data/tools/update-database.rb +146 -0
  126. data/view.cgi +6 -0
  127. metadata +222 -0
@@ -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