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