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
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
require 'pathname'
|
|
2
|
+
require 'optparse'
|
|
3
|
+
|
|
4
|
+
unless Object.const_defined?(:Encoding)
|
|
5
|
+
$KCODE = 'UTF-8'
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def srcdir_root
|
|
9
|
+
Pathname.new(__FILE__).realpath.dirname.parent.cleanpath
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
$LOAD_PATH.unshift srcdir_root() + 'lib'
|
|
13
|
+
|
|
14
|
+
require 'bitclust'
|
|
15
|
+
require 'bitclust/subcommand'
|
|
16
|
+
|
|
17
|
+
module BitClust
|
|
18
|
+
class Runner
|
|
19
|
+
def initialize
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def run(argv)
|
|
23
|
+
Signal.trap(:PIPE, 'IGNORE') rescue nil # Win32 does not have SIGPIPE
|
|
24
|
+
Signal.trap(:INT) { exit 3 }
|
|
25
|
+
prepare
|
|
26
|
+
_run(argv)
|
|
27
|
+
rescue Errno::EPIPE
|
|
28
|
+
exit 0
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def prepare
|
|
32
|
+
@prefix = nil
|
|
33
|
+
@version = nil
|
|
34
|
+
@capi = false
|
|
35
|
+
@parser = OptionParser.new
|
|
36
|
+
@parser.banner = <<-EndBanner
|
|
37
|
+
Usage: #{File.basename($0, '.*')} [global options] <subcommand> [options] [args]
|
|
38
|
+
|
|
39
|
+
Subcommands:
|
|
40
|
+
init Initialize database.
|
|
41
|
+
list List libraries/classes/methods in database.
|
|
42
|
+
lookup Lookup a library/class/method from database.
|
|
43
|
+
search Search classes/methods from database.
|
|
44
|
+
query Dispatch arbitrary query.
|
|
45
|
+
update Update database.
|
|
46
|
+
property Handle database properties.
|
|
47
|
+
setup Initialize and update database with default options.
|
|
48
|
+
|
|
49
|
+
Global Options:
|
|
50
|
+
EndBanner
|
|
51
|
+
@parser.on('-d', '--database=PATH', 'Database prefix.') {|path|
|
|
52
|
+
@prefix = path
|
|
53
|
+
}
|
|
54
|
+
@parser.on('-t', '--targer=VERSION', 'Specify Ruby version.') {|v|
|
|
55
|
+
@version = v
|
|
56
|
+
}
|
|
57
|
+
@parser.on('--capi', 'Process C API database.') {
|
|
58
|
+
@capi = true
|
|
59
|
+
}
|
|
60
|
+
@parser.on('--version', 'Print version and quit.') {
|
|
61
|
+
puts BitClust::VERSION
|
|
62
|
+
exit 0
|
|
63
|
+
}
|
|
64
|
+
@parser.on('--help', 'Prints this message and quit.') {
|
|
65
|
+
puts @parser.help
|
|
66
|
+
exit 0
|
|
67
|
+
}
|
|
68
|
+
@subcommands = {
|
|
69
|
+
'init' => BitClust::InitCommand.new,
|
|
70
|
+
'list' => BitClust::ListCommand.new,
|
|
71
|
+
'lookup' => BitClust::LookupCommand.new,
|
|
72
|
+
'search' => BitClust::Searcher.new,
|
|
73
|
+
'query' => BitClust::QueryCommand.new,
|
|
74
|
+
'update' => BitClust::UpdateCommand.new,
|
|
75
|
+
'property' => BitClust::PropertyCommand.new,
|
|
76
|
+
'setup' => BitClust::SetupCommand.new,
|
|
77
|
+
'server' => BitClust::ServerCommand.new,
|
|
78
|
+
}
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def _run(argv)
|
|
82
|
+
begin
|
|
83
|
+
@parser.order!(argv)
|
|
84
|
+
if argv.empty?
|
|
85
|
+
$stderr.puts 'no sub-command given'
|
|
86
|
+
$stderr.puts parser.help
|
|
87
|
+
exit 1
|
|
88
|
+
end
|
|
89
|
+
name = argv.shift
|
|
90
|
+
cmd = @subcommands[name] or error "no such sub-command: #{name}"
|
|
91
|
+
rescue OptionParser::ParseError => err
|
|
92
|
+
$stderr.puts err.message
|
|
93
|
+
$stderr.puts parser.help
|
|
94
|
+
exit 1
|
|
95
|
+
end
|
|
96
|
+
begin
|
|
97
|
+
cmd.parse(argv)
|
|
98
|
+
rescue OptionParser::ParseError => err
|
|
99
|
+
$stderr.puts err.message
|
|
100
|
+
$stderr.puts cmd.help
|
|
101
|
+
exit 1
|
|
102
|
+
end
|
|
103
|
+
case name
|
|
104
|
+
when "setup", "server"
|
|
105
|
+
db = nil
|
|
106
|
+
else
|
|
107
|
+
config = load_config()
|
|
108
|
+
if config
|
|
109
|
+
@version ||= config[:default_version]
|
|
110
|
+
@prefix ||= "#{config[:database_prefix]}-#{@version}"
|
|
111
|
+
end
|
|
112
|
+
unless @prefix
|
|
113
|
+
$stderr.puts "no database given. Use --database option"
|
|
114
|
+
exit 1
|
|
115
|
+
end
|
|
116
|
+
if @capi
|
|
117
|
+
db = BitClust::FunctionDatabase.new(@prefix)
|
|
118
|
+
else
|
|
119
|
+
db = BitClust::MethodDatabase.new(@prefix)
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
cmd.exec(db, argv)
|
|
123
|
+
rescue BitClust::WriterError => err
|
|
124
|
+
raise if $DEBUG
|
|
125
|
+
error err.message
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def load_config
|
|
129
|
+
home_directory = Pathname(ENV['HOME'])
|
|
130
|
+
config_path = home_directory + ".bitclust/config"
|
|
131
|
+
if config_path.exist?
|
|
132
|
+
YAML.load_file(config_path)
|
|
133
|
+
else
|
|
134
|
+
nil
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def error(message)
|
|
139
|
+
$stderr.puts "#{File.basename($0, '.*')}: error: #{message}"
|
|
140
|
+
exit 1
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
@@ -0,0 +1,554 @@
|
|
|
1
|
+
#
|
|
2
|
+
# bitclust/screen.rb
|
|
3
|
+
#
|
|
4
|
+
# Copyright (C) 2006-2008 Minero Aoki
|
|
5
|
+
#
|
|
6
|
+
# This program is free software.
|
|
7
|
+
# You can distribute/modify this program under the Ruby License.
|
|
8
|
+
#
|
|
9
|
+
|
|
10
|
+
require 'bitclust/rdcompiler'
|
|
11
|
+
require 'bitclust/methodsignature'
|
|
12
|
+
require 'bitclust/htmlutils'
|
|
13
|
+
require 'bitclust/nameutils'
|
|
14
|
+
require 'bitclust/messagecatalog'
|
|
15
|
+
require 'erb'
|
|
16
|
+
require 'stringio'
|
|
17
|
+
|
|
18
|
+
module BitClust
|
|
19
|
+
|
|
20
|
+
class ScreenManager
|
|
21
|
+
def initialize(h)
|
|
22
|
+
h[:urlmapper] ||= URLMapper.new(h)
|
|
23
|
+
tmpldir = h[:templatedir] || "#{h[:datadir]}/template"
|
|
24
|
+
h[:template_repository] ||= TemplateRepository.new(tmpldir)
|
|
25
|
+
h[:message_catalog] ||= default_message_catalog(h)
|
|
26
|
+
@conf = h
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def default_message_catalog(h)
|
|
30
|
+
dir = h[:catalogdir] || "#{h[:datadir]}/catalog"
|
|
31
|
+
loc = MessageCatalog.encoding2locale(h[:encoding] || 'utf-8')
|
|
32
|
+
MessageCatalog.load_with_locales(dir, [loc])
|
|
33
|
+
end
|
|
34
|
+
private :default_message_catalog
|
|
35
|
+
|
|
36
|
+
def entry_screen(entry, opt)
|
|
37
|
+
new_screen(Screen.for_entry(entry), entry, opt)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def library_index_screen(libs, opt)
|
|
41
|
+
new_screen(LibraryIndexScreen, libs, opt)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def library_screen(lib, opt)
|
|
45
|
+
new_screen(LibraryScreen, lib, opt)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def class_index_screen(cs, opt)
|
|
49
|
+
new_screen(ClassIndexScreen, cs, opt)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def class_screen(c, opt)
|
|
53
|
+
new_screen(ClassScreen, c, opt)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def method_screen(ms, opt)
|
|
57
|
+
new_screen(MethodScreen, ms, opt)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def opensearchdescription_screen(request_full_uri, opt)
|
|
61
|
+
new_screen(OpenSearchDescriptionScreen, request_full_uri, opt)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def search_screen(result, opt)
|
|
65
|
+
new_screen(SearchScreen, result, opt)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def doc_screen(d, opt)
|
|
69
|
+
new_screen(DocScreen, d, opt)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def function_screen(f, opt)
|
|
73
|
+
new_screen(FunctionScreen, f, opt)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def function_index_screen(fs, opt)
|
|
77
|
+
new_screen(FunctionIndexScreen, fs, opt)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
private
|
|
81
|
+
|
|
82
|
+
def new_screen(c, *args)
|
|
83
|
+
c.new(@conf, *args)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
class URLMapper
|
|
89
|
+
include NameUtils
|
|
90
|
+
|
|
91
|
+
def initialize(h)
|
|
92
|
+
@base_url = h[:base_url]
|
|
93
|
+
@cgi_url = h[:cgi_url]
|
|
94
|
+
@css_url = h[:css_url]
|
|
95
|
+
@favicon_url = h[:favicon_url]
|
|
96
|
+
@theme = h[:theme] || 'default'
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
attr_reader :base_url
|
|
100
|
+
|
|
101
|
+
def cgi_url
|
|
102
|
+
@cgi_url
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def css_url
|
|
106
|
+
return @css_url if @css_url
|
|
107
|
+
"#{@base_url}/theme/#{@theme}/style.css"
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def custom_css_url(css)
|
|
111
|
+
"#{@base_url}/theme/#{@theme}/#{css}"
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def js_url
|
|
115
|
+
return @js_url if @js_url
|
|
116
|
+
"#{@base_url}/theme/#{@theme}/t.js"
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def custom_js_url(js)
|
|
120
|
+
"#{@base_url}/theme/#{@theme}/#{js}"
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def favicon_url
|
|
124
|
+
return @favicon_url if @favicon_url
|
|
125
|
+
"#{@base_url}/theme/#{@theme}/rurema.png"
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def library_index_url
|
|
129
|
+
"#{@cgi_url}/library/"
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def library_url(name)
|
|
133
|
+
"#{@cgi_url}/library/#{libname2id(name)}"
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def class_url(name)
|
|
137
|
+
"#{@cgi_url}/class/#{classname2id(name)}"
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def method_url(spec)
|
|
141
|
+
cname, tmark, mname = *split_method_spec(spec)
|
|
142
|
+
"#{@cgi_url}/method/#{classname2id(cname)}/#{typemark2char(tmark)}/#{encodename_url(mname)}"
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def function_index_url
|
|
146
|
+
"#{@cgi_url}/function/"
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def function_url(name)
|
|
150
|
+
"#{@cgi_url}/function/#{name}"
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def opensearchdescription_url
|
|
154
|
+
"#{@cgi_url}/opensearchdescription"
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def search_url
|
|
158
|
+
"#{@cgi_url}/search"
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def spec_url(name)
|
|
162
|
+
"#{@cgi_url}/spec/#{name}"
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def document_url(name)
|
|
166
|
+
raise unless %r!\A[-\w/]+\z! =~ name
|
|
167
|
+
"#{@cgi_url}/#{name}"
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
class TemplateRepository
|
|
173
|
+
def initialize(prefix)
|
|
174
|
+
@prefix = prefix
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def load(id)
|
|
178
|
+
preproc(File.read("#{@prefix}/#{id}"))
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
private
|
|
182
|
+
|
|
183
|
+
def preproc(template)
|
|
184
|
+
template.gsub(/^\.include ([\w\-]+)/) { load($1.untaint) }.untaint
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
class Screen
|
|
190
|
+
def Screen.for_entry(entry)
|
|
191
|
+
ent = entry.kind_of?(Array) ? entry.first : entry
|
|
192
|
+
::BitClust.const_get("#{ent.type_id.to_s.capitalize}Screen")
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def status
|
|
196
|
+
nil
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
class ErrorScreen < Screen
|
|
201
|
+
include HTMLUtils
|
|
202
|
+
|
|
203
|
+
def initialize(err)
|
|
204
|
+
@error = err
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def status
|
|
208
|
+
500
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def content_type
|
|
212
|
+
'text/html'
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
def body
|
|
216
|
+
<<-EndHTML
|
|
217
|
+
<html>
|
|
218
|
+
<head><title>Error</title></head>
|
|
219
|
+
<body>
|
|
220
|
+
<h1>Error</h1>
|
|
221
|
+
<pre>#{escape_html(@error.message)} (#{escape_html(@error.class.name)})
|
|
222
|
+
#{@error.backtrace.map {|s| escape_html(s) }.join("\n")}</pre>
|
|
223
|
+
</body>
|
|
224
|
+
</html>
|
|
225
|
+
EndHTML
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
class NotFoundScreen < Screen
|
|
230
|
+
include HTMLUtils
|
|
231
|
+
|
|
232
|
+
def initialize(err)
|
|
233
|
+
@error = err
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
def status
|
|
237
|
+
404
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
def content_type
|
|
241
|
+
'text/html'
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
def body
|
|
245
|
+
<<-EndHTML
|
|
246
|
+
<html>
|
|
247
|
+
<head><title>NotFound</title></head>
|
|
248
|
+
<body>
|
|
249
|
+
<h1>NotFound</h1>
|
|
250
|
+
<pre>#{escape_html(@error.message)} (#{escape_html(@error.class.name)})</pre>
|
|
251
|
+
</body>
|
|
252
|
+
</html>
|
|
253
|
+
EndHTML
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
class TemplateScreen < Screen
|
|
258
|
+
include Translatable
|
|
259
|
+
include HTMLUtils
|
|
260
|
+
|
|
261
|
+
def initialize(h)
|
|
262
|
+
@urlmapper = h[:urlmapper]
|
|
263
|
+
@template_repository = h[:template_repository]
|
|
264
|
+
@default_encoding = h[:default_encoding] || h[:database].propget('encoding')
|
|
265
|
+
@target_version = h[:target_version] || h[:database].propget('version')
|
|
266
|
+
init_message_catalog h[:message_catalog]
|
|
267
|
+
@conf = h
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
def content_type
|
|
271
|
+
"text/html; charset=#{encoding()}"
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
def encoding
|
|
275
|
+
default_encoding()
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
def ruby_version
|
|
279
|
+
@target_version || 'unknown'
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
private
|
|
283
|
+
|
|
284
|
+
def default_encoding
|
|
285
|
+
@default_encoding || 'us-ascii'
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
def run_template(id, layout = true)
|
|
289
|
+
method_name = "#{id}_template".gsub('-', '_')
|
|
290
|
+
unless respond_to? method_name
|
|
291
|
+
erb = ERB.new(@template_repository.load(id))
|
|
292
|
+
erb.def_method(self.class, method_name, id + '.erb')
|
|
293
|
+
end
|
|
294
|
+
body = __send__(method_name)
|
|
295
|
+
if layout
|
|
296
|
+
unless respond_to? :layout
|
|
297
|
+
erb = ERB.new(@template_repository.load('layout'))
|
|
298
|
+
erb.def_method(self.class, 'layout', 'layout.erb')
|
|
299
|
+
end
|
|
300
|
+
layout{ body }
|
|
301
|
+
else
|
|
302
|
+
body
|
|
303
|
+
end
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
def h(str)
|
|
307
|
+
escape_html(str.to_s)
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
def css_url
|
|
311
|
+
@urlmapper.css_url
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
def custom_css_url(css)
|
|
315
|
+
@urlmapper.custom_css_url(css)
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
def js_url
|
|
319
|
+
@urlmapper.js_url
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
def custom_js_url(js)
|
|
323
|
+
@urlmapper.custom_js_url(js)
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
def favicon_url
|
|
327
|
+
@urlmapper.favicon_url
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
def opensearchdescription_url
|
|
331
|
+
@urlmapper.opensearchdescription_url
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
def search_url
|
|
335
|
+
@urlmapper.search_url
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
def library_index_url
|
|
339
|
+
@urlmapper.library_index_url
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
def function_index_url
|
|
343
|
+
@urlmapper.function_index_url
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
def headline_init
|
|
347
|
+
@hlevel = 1
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
def headline_push
|
|
351
|
+
@hlevel += 1
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
def headline_pop
|
|
355
|
+
@hlevel -= 1
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
def headline(str)
|
|
359
|
+
"<h#{@hlevel}>#{escape_html(str)}</h#{@hlevel}>"
|
|
360
|
+
end
|
|
361
|
+
|
|
362
|
+
def headline_noescape(str)
|
|
363
|
+
"<h#{@hlevel}>#{str}</h#{@hlevel}>"
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
def search_form
|
|
367
|
+
if @conf[:tochm_mode]
|
|
368
|
+
""
|
|
369
|
+
else
|
|
370
|
+
<<-EndForm
|
|
371
|
+
<form method="get" action="#{h(search_url())}" name="top_search" id="top_search">
|
|
372
|
+
<input value="" name="q" size="15">
|
|
373
|
+
<input value="#{h(_('Search'))}" type="submit">
|
|
374
|
+
</form>
|
|
375
|
+
EndForm
|
|
376
|
+
end
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
def manual_home_link
|
|
380
|
+
document_link('index', _('Ruby %s Reference Manual', ruby_version()))
|
|
381
|
+
end
|
|
382
|
+
|
|
383
|
+
def friendly_library_link(id)
|
|
384
|
+
library_link(id, friendly_library_name(id))
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
def friendly_library_name(id)
|
|
388
|
+
(id == '_builtin') ? _('Builtin Library') : _('library %s', id)
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
def compile_method(m, opt = nil)
|
|
392
|
+
rdcompiler().compile_method(m, opt)
|
|
393
|
+
end
|
|
394
|
+
|
|
395
|
+
def compile_function(f)
|
|
396
|
+
compile_rd(f.source)
|
|
397
|
+
end
|
|
398
|
+
|
|
399
|
+
def compile_rd(src)
|
|
400
|
+
rdcompiler().compile(src)
|
|
401
|
+
end
|
|
402
|
+
|
|
403
|
+
def rdcompiler
|
|
404
|
+
opt = {:catalog => message_catalog()}.merge(@conf)
|
|
405
|
+
RDCompiler.new(@urlmapper, @hlevel, opt)
|
|
406
|
+
end
|
|
407
|
+
|
|
408
|
+
def foreach_method_chunk(src)
|
|
409
|
+
f = LineInput.for_string(src)
|
|
410
|
+
while f.next?
|
|
411
|
+
sigs = f.span(/\A---/).map {|line| MethodSignature.parse(line.rstrip) }
|
|
412
|
+
body = f.break(/\A---/).join.split(/\n\n/, 2).first || ''
|
|
413
|
+
yield sigs, body
|
|
414
|
+
end
|
|
415
|
+
end
|
|
416
|
+
end
|
|
417
|
+
|
|
418
|
+
class IndexScreen < TemplateScreen
|
|
419
|
+
def initialize(h, entries, opt)
|
|
420
|
+
h = h.dup
|
|
421
|
+
h[:entries] = entries
|
|
422
|
+
h[:database] = opt[:database]
|
|
423
|
+
super h
|
|
424
|
+
@entries = entries
|
|
425
|
+
end
|
|
426
|
+
|
|
427
|
+
def encoding
|
|
428
|
+
return default_encoding() if @entries.empty?
|
|
429
|
+
@entries.first.encoding
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
alias charset encoding
|
|
433
|
+
end
|
|
434
|
+
|
|
435
|
+
class EntryBoundScreen < TemplateScreen
|
|
436
|
+
def initialize(h, entry, opt)
|
|
437
|
+
h = h.dup
|
|
438
|
+
h[:entry] = entry
|
|
439
|
+
h[:database] = opt[:database]
|
|
440
|
+
super h
|
|
441
|
+
@entry = entry
|
|
442
|
+
end
|
|
443
|
+
|
|
444
|
+
def encoding
|
|
445
|
+
@entry.encoding || default_encoding()
|
|
446
|
+
end
|
|
447
|
+
|
|
448
|
+
alias charset encoding
|
|
449
|
+
end
|
|
450
|
+
|
|
451
|
+
class LibraryIndexScreen < IndexScreen
|
|
452
|
+
def body
|
|
453
|
+
run_template('library-index')
|
|
454
|
+
end
|
|
455
|
+
end
|
|
456
|
+
|
|
457
|
+
class LibraryScreen < EntryBoundScreen
|
|
458
|
+
def body
|
|
459
|
+
run_template('library')
|
|
460
|
+
end
|
|
461
|
+
end
|
|
462
|
+
|
|
463
|
+
class ClassIndexScreen < IndexScreen
|
|
464
|
+
def body
|
|
465
|
+
run_template('class-index')
|
|
466
|
+
end
|
|
467
|
+
end
|
|
468
|
+
|
|
469
|
+
class OpenSearchDescriptionScreen < TemplateScreen
|
|
470
|
+
def initialize(h, request_full_uri, opt)
|
|
471
|
+
h = h.dup
|
|
472
|
+
h[:database] = opt[:database]
|
|
473
|
+
super h
|
|
474
|
+
@search_full_url = (request_full_uri + search_url()).to_s
|
|
475
|
+
end
|
|
476
|
+
|
|
477
|
+
attr_reader :search_full_url
|
|
478
|
+
|
|
479
|
+
def body
|
|
480
|
+
run_template('opensearchdescription')
|
|
481
|
+
end
|
|
482
|
+
|
|
483
|
+
def content_type
|
|
484
|
+
"application/opensearchdescription+xml; charset=#{encoding()}"
|
|
485
|
+
end
|
|
486
|
+
end
|
|
487
|
+
|
|
488
|
+
class SearchScreen < IndexScreen
|
|
489
|
+
def initialize(h, entries, opt)
|
|
490
|
+
super h, entries, opt
|
|
491
|
+
@query = opt[:q]
|
|
492
|
+
@elapsed_time = opt[:elapsed_time]
|
|
493
|
+
end
|
|
494
|
+
|
|
495
|
+
def body
|
|
496
|
+
run_template('search')
|
|
497
|
+
end
|
|
498
|
+
end
|
|
499
|
+
|
|
500
|
+
class ClassScreen < EntryBoundScreen
|
|
501
|
+
def initialize(h, entry, opt)
|
|
502
|
+
@alevel = opt[:level] || 0
|
|
503
|
+
super(h, entry, opt)
|
|
504
|
+
end
|
|
505
|
+
|
|
506
|
+
def body
|
|
507
|
+
run_template('class')
|
|
508
|
+
end
|
|
509
|
+
end
|
|
510
|
+
|
|
511
|
+
class MethodScreen < TemplateScreen
|
|
512
|
+
def initialize(h, entries, opt)
|
|
513
|
+
h = h.dup
|
|
514
|
+
h[:database] = opt[:database]
|
|
515
|
+
super h
|
|
516
|
+
@entries = entries
|
|
517
|
+
end
|
|
518
|
+
|
|
519
|
+
def encoding
|
|
520
|
+
ent = @entries.first
|
|
521
|
+
ent ? ent.encoding : default_encoding()
|
|
522
|
+
end
|
|
523
|
+
|
|
524
|
+
alias charset encoding
|
|
525
|
+
|
|
526
|
+
def body
|
|
527
|
+
run_template('method')
|
|
528
|
+
end
|
|
529
|
+
end
|
|
530
|
+
|
|
531
|
+
class FunctionScreen < EntryBoundScreen
|
|
532
|
+
def body
|
|
533
|
+
run_template('function')
|
|
534
|
+
end
|
|
535
|
+
end
|
|
536
|
+
|
|
537
|
+
class FunctionIndexScreen < IndexScreen
|
|
538
|
+
def body
|
|
539
|
+
run_template('function-index')
|
|
540
|
+
end
|
|
541
|
+
end
|
|
542
|
+
|
|
543
|
+
class DocScreen < EntryBoundScreen
|
|
544
|
+
|
|
545
|
+
def body
|
|
546
|
+
run_template('doc')
|
|
547
|
+
end
|
|
548
|
+
|
|
549
|
+
def rdcompiler
|
|
550
|
+
h = {:force => true, :catalog => message_catalog() }.merge(@conf)
|
|
551
|
+
RDCompiler.new(@urlmapper, @hlevel, h)
|
|
552
|
+
end
|
|
553
|
+
end
|
|
554
|
+
end
|