bitclust-core 0.8.0 → 0.9.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.
- checksums.yaml +4 -4
- data/ChangeLog +16 -0
- data/Gemfile +1 -7
- data/data/bitclust/template/class +14 -0
- data/data/bitclust/template/doc +1 -1
- data/data/bitclust/template/layout +1 -1
- data/data/bitclust/template.epub/class +101 -0
- data/data/bitclust/template.epub/class-index +28 -0
- data/data/bitclust/template.epub/container.xml +6 -0
- data/data/bitclust/template.epub/contents +23 -0
- data/data/bitclust/template.epub/doc +13 -0
- data/data/bitclust/template.epub/function +22 -0
- data/data/bitclust/template.epub/function-index +24 -0
- data/data/bitclust/template.epub/layout +19 -0
- data/data/bitclust/template.epub/library +75 -0
- data/data/bitclust/template.epub/library-index +47 -0
- data/data/bitclust/template.epub/method +21 -0
- data/data/bitclust/template.epub/mimetype +1 -0
- data/data/bitclust/template.epub/nav.xhtml +6 -0
- data/data/bitclust/template.epub/rd_file +6 -0
- data/data/bitclust/template.lillia/class +17 -0
- data/data/bitclust/template.lillia/doc +1 -1
- data/data/bitclust/template.lillia/layout +1 -1
- data/data/bitclust/template.offline/class +14 -0
- data/data/bitclust/template.offline/doc +1 -1
- data/data/bitclust/template.offline/layout +1 -1
- data/lib/bitclust/classentry.rb +31 -11
- data/lib/bitclust/docentry.rb +2 -2
- data/lib/bitclust/entry.rb +1 -0
- data/lib/bitclust/exception.rb +1 -0
- data/lib/bitclust/functionreferenceparser.rb +4 -3
- data/lib/bitclust/generators/epub.rb +118 -0
- data/lib/bitclust/libraryentry.rb +4 -6
- data/lib/bitclust/methodsignature.rb +1 -1
- data/lib/bitclust/nameutils.rb +12 -1
- data/lib/bitclust/rdcompiler.rb +101 -57
- data/lib/bitclust/rrdparser.rb +20 -6
- data/lib/bitclust/runner.rb +2 -0
- data/lib/bitclust/screen.rb +10 -2
- data/lib/bitclust/searcher.rb +4 -0
- data/lib/bitclust/subcommands/epub_command.rb +68 -0
- data/lib/bitclust/subcommands/methods_command.rb +13 -0
- data/lib/bitclust/subcommands/setup_command.rb +2 -2
- data/lib/bitclust/subcommands/statichtml_command.rb +54 -32
- data/lib/bitclust/version.rb +1 -1
- data/test/run_test.rb +0 -0
- data/test/test_functiondatabase.rb +3 -3
- data/test/test_functionreferenceparser.rb +51 -0
- data/test/test_methoddatabase.rb +33 -0
- data/test/test_nameutils.rb +13 -0
- data/test/test_rdcompiler.rb +176 -13
- data/test/test_refsdatabase.rb +8 -0
- metadata +41 -23
data/lib/bitclust/classentry.rb
CHANGED
@@ -64,7 +64,7 @@ module BitClust
|
|
64
64
|
def realname
|
65
65
|
alias? ? aliasof.name : name
|
66
66
|
end
|
67
|
-
|
67
|
+
|
68
68
|
def name_match?(re)
|
69
69
|
re =~ name()
|
70
70
|
end
|
@@ -81,6 +81,8 @@ module BitClust
|
|
81
81
|
property :superclass, 'ClassEntry'
|
82
82
|
property :included, '[ClassEntry]'
|
83
83
|
property :extended, '[ClassEntry]'
|
84
|
+
property :dynamically_included, '[ClassEntry]'
|
85
|
+
property :dynamically_extended, '[ClassEntry]'
|
84
86
|
property :library, 'LibraryEntry'
|
85
87
|
property :aliases, '[ClassEntry]'
|
86
88
|
property :aliasof, 'ClassEntry'
|
@@ -133,7 +135,7 @@ module BitClust
|
|
133
135
|
ancestors.any?{|k| k.name == 'Exception' }
|
134
136
|
end
|
135
137
|
end
|
136
|
-
|
138
|
+
|
137
139
|
def include(m)
|
138
140
|
included().push m
|
139
141
|
end
|
@@ -142,6 +144,24 @@ module BitClust
|
|
142
144
|
extended().push m
|
143
145
|
end
|
144
146
|
|
147
|
+
# Add a module +m+ to the dynamically included module list.
|
148
|
+
def dynamic_include(m, lib)
|
149
|
+
if m.library != lib
|
150
|
+
message = "dynamically included module #{m.name} should be defined in the module #{lib.name}"
|
151
|
+
raise InvalidLibrary, message
|
152
|
+
end
|
153
|
+
dynamically_included().push m
|
154
|
+
end
|
155
|
+
|
156
|
+
# Add a module +m+ to the dynamically extended module list.
|
157
|
+
def dynamic_extend(m, lib)
|
158
|
+
if m.library != lib
|
159
|
+
message = "dynamically extended module #{m.name} should be defined in the module #{lib.name}"
|
160
|
+
raise InvalidLibrary, message
|
161
|
+
end
|
162
|
+
dynamically_extended().push m
|
163
|
+
end
|
164
|
+
|
145
165
|
# Add a alias +c+ to the alias list.
|
146
166
|
def alias(c)
|
147
167
|
aliases().push c
|
@@ -208,7 +228,7 @@ module BitClust
|
|
208
228
|
.map {|ent| MethodEntry.new(@db, "#{@id}/#{ent}") }
|
209
229
|
ret = @entries
|
210
230
|
ancestors[1..level].each{|c| ret += c.entries }
|
211
|
-
ret
|
231
|
+
ret
|
212
232
|
end
|
213
233
|
|
214
234
|
alias methods entries
|
@@ -260,42 +280,42 @@ module BitClust
|
|
260
280
|
|
261
281
|
def singleton_methods(level = 0)
|
262
282
|
# FIXME: inheritance
|
263
|
-
entries(level).select {|m| m.singleton_method? }.
|
283
|
+
entries(level).select {|m| m.singleton_method? }.sort_by {|entry| entry.sort_key }
|
264
284
|
end
|
265
285
|
|
266
286
|
def public_singleton_methods(level = 0)
|
267
287
|
# FIXME: inheritance
|
268
|
-
entries(level).select {|m| m.public_singleton_method? }.
|
288
|
+
entries(level).select {|m| m.public_singleton_method? }.sort_by {|entry| entry.sort_key }
|
269
289
|
end
|
270
290
|
|
271
291
|
def instance_methods(level = 0)
|
272
292
|
# FIXME: inheritance
|
273
|
-
entries(level).select {|m| m.instance_method? }.
|
293
|
+
entries(level).select {|m| m.instance_method? }.sort_by {|entry| entry.sort_key }
|
274
294
|
end
|
275
295
|
|
276
296
|
def private_singleton_methods(level = 0)
|
277
297
|
# FIXME: inheritance
|
278
|
-
entries(level).select {|m| m.private_singleton_method? }.
|
298
|
+
entries(level).select {|m| m.private_singleton_method? }.sort_by {|entry| entry.sort_key }
|
279
299
|
end
|
280
300
|
|
281
301
|
def public_instance_methods(level = 0)
|
282
302
|
# FIXME: inheritance
|
283
|
-
entries(level).select {|m| m.public_instance_method? }.
|
303
|
+
entries(level).select {|m| m.public_instance_method? }.sort_by {|entry| entry.sort_key }
|
284
304
|
end
|
285
305
|
|
286
306
|
def private_instance_methods(level = 0)
|
287
307
|
# FIXME: inheritance
|
288
|
-
entries(level).select {|m| m.private_instance_method? }.
|
308
|
+
entries(level).select {|m| m.private_instance_method? }.sort_by {|entry| entry.sort_key }
|
289
309
|
end
|
290
310
|
|
291
311
|
alias private_methods private_instance_methods
|
292
312
|
|
293
313
|
def constants(level = 0)
|
294
|
-
entries(level).select {|m| m.constant? }.
|
314
|
+
entries(level).select {|m| m.constant? }.sort_by {|entry| entry.sort_key }
|
295
315
|
end
|
296
316
|
|
297
317
|
def special_variables
|
298
|
-
entries().select {|m| m.special_variable? }.
|
318
|
+
entries().select {|m| m.special_variable? }.sort_by {|entry| entry.sort_key }
|
299
319
|
end
|
300
320
|
|
301
321
|
def singleton_method?(name, inherit = true)
|
data/lib/bitclust/docentry.rb
CHANGED
data/lib/bitclust/entry.rb
CHANGED
data/lib/bitclust/exception.rb
CHANGED
@@ -17,6 +17,7 @@ module BitClust
|
|
17
17
|
class WrongInclude < DocumentError; end
|
18
18
|
class InvalidLink < DocumentError; end
|
19
19
|
class InvalidAncestor < DocumentError; end
|
20
|
+
class InvalidLibrary < DocumentError; end
|
20
21
|
class UserError < Error; end
|
21
22
|
class InvalidDatabase < UserError; end
|
22
23
|
class InvalidKey < UserError; end
|
@@ -28,13 +28,14 @@ module BitClust
|
|
28
28
|
|
29
29
|
def parse_file(path, filename, properties)
|
30
30
|
fopen(path, 'r:UTF-8') {|f|
|
31
|
-
return parse(f, filename)
|
31
|
+
return parse(f, filename, properties)
|
32
32
|
}
|
33
33
|
end
|
34
34
|
|
35
|
-
def parse(f, filename)
|
35
|
+
def parse(f, filename, params = {})
|
36
36
|
@filename = filename
|
37
|
-
|
37
|
+
s = Preprocessor.read(f, params)
|
38
|
+
file_entries LineInput.for_string(s)
|
38
39
|
@db.functions
|
39
40
|
end
|
40
41
|
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'tmpdir'
|
3
|
+
require 'erb'
|
4
|
+
|
5
|
+
require 'bitclust/subcommands/statichtml_command'
|
6
|
+
|
7
|
+
module BitClust
|
8
|
+
module Generators
|
9
|
+
class EPUB
|
10
|
+
def initialize(options = {})
|
11
|
+
@options = options.dup
|
12
|
+
@prefix = options[:prefix]
|
13
|
+
@capi = options[:capi]
|
14
|
+
@outputdir = options[:outputdir]
|
15
|
+
@filename = options[:filename]
|
16
|
+
@templatedir = options[:templatedir]
|
17
|
+
@catalog = options[:catalog]
|
18
|
+
@themedir = options[:themedir]
|
19
|
+
@fs_casesensitive = options[:fs_casesensitive]
|
20
|
+
@keep = options[:keep]
|
21
|
+
@verbose = options[:verbose]
|
22
|
+
end
|
23
|
+
|
24
|
+
CONTENTS_DIR_NAME = 'OEBPS'
|
25
|
+
|
26
|
+
def generate
|
27
|
+
make_epub_directory do |epub_directory|
|
28
|
+
contents_directory = epub_directory + CONTENTS_DIR_NAME
|
29
|
+
copy_static_files(epub_directory)
|
30
|
+
generate_xhtml_files(contents_directory)
|
31
|
+
generate_contents_opf(epub_directory)
|
32
|
+
pack_epub(epub_directory)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def make_epub_directory
|
39
|
+
dir = Dir.mktmpdir("epub-", @outputdir)
|
40
|
+
yield Pathname.new(dir)
|
41
|
+
ensure
|
42
|
+
FileUtils.rm_rf(dir, :secure => true, :verbose => @verbose) unless @keep
|
43
|
+
end
|
44
|
+
|
45
|
+
def copy_static_files(epub_directory)
|
46
|
+
FileUtils.cp(@templatedir + "mimetype", epub_directory, :verbose => @verbose)
|
47
|
+
FileUtils.cp(@templatedir + "nav.xhtml", epub_directory, :verbose => @verbose)
|
48
|
+
meta_inf_directory = epub_directory + "META-INF"
|
49
|
+
FileUtils.mkdir_p(meta_inf_directory, :verbose => @verbose)
|
50
|
+
FileUtils.cp(@templatedir + "container.xml", meta_inf_directory, :verbose => @verbose)
|
51
|
+
end
|
52
|
+
|
53
|
+
def generate_xhtml_files(contents_directory)
|
54
|
+
argv = [
|
55
|
+
"--outputdir=#{contents_directory}",
|
56
|
+
"--templatedir=#{@templatedir}",
|
57
|
+
"--catalog=#{@catalog}",
|
58
|
+
"--themedir=#{@themedir}",
|
59
|
+
"--suffix=.xhtml",
|
60
|
+
]
|
61
|
+
argv << "--fs-casesensitive" if @fs_casesensitive
|
62
|
+
argv << "--quiet" unless @verbose
|
63
|
+
options = {
|
64
|
+
:prefix => @prefix,
|
65
|
+
:capi => @capi,
|
66
|
+
}
|
67
|
+
cmd = BitClust::Subcommands::StatichtmlCommand.new
|
68
|
+
cmd.parse(argv)
|
69
|
+
cmd.exec(argv, options)
|
70
|
+
end
|
71
|
+
|
72
|
+
def generate_contents_opf(epub_directory)
|
73
|
+
items = []
|
74
|
+
glob_relative_path(epub_directory, "#{CONTENTS_DIR_NAME}/class/*.xhtml").each do |path|
|
75
|
+
items << {
|
76
|
+
:id => decodename_package(path.basename(".*").to_s),
|
77
|
+
:path => path
|
78
|
+
}
|
79
|
+
end
|
80
|
+
items.sort_by!{|item| item[:path] }
|
81
|
+
contents = ERB.new(File.read(@templatedir + "contents"), nil, "-").result(binding)
|
82
|
+
File.open(epub_directory + "contents.opf", "w") do |f|
|
83
|
+
f.write contents
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def pack_epub(epub_directory)
|
88
|
+
epub_filename = @outputdir + @filename
|
89
|
+
Dir.chdir(epub_directory.to_s) do
|
90
|
+
system("zip -0 -X #{epub_filename} mimetype")
|
91
|
+
system("zip -r #{epub_filename} ./* -x mimetype")
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def glob_relative_path(path, pattern)
|
96
|
+
relative_paths = []
|
97
|
+
absolute_path_to_search = Pathname.new(path).realpath
|
98
|
+
Dir.glob(absolute_path_to_search + pattern) do |absolute_path|
|
99
|
+
absolute_path = Pathname.new(absolute_path)
|
100
|
+
relative_paths << absolute_path.relative_path_from(absolute_path_to_search)
|
101
|
+
end
|
102
|
+
relative_paths
|
103
|
+
end
|
104
|
+
|
105
|
+
def decodename_package(str)
|
106
|
+
if @fs_casesensitive
|
107
|
+
NameUtils.decodename_url(str)
|
108
|
+
else
|
109
|
+
NameUtils.decodename_fs(str)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def last_modified
|
114
|
+
Time.now.iso8601
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -24,6 +24,7 @@ module BitClust
|
|
24
24
|
def initialize(db, id)
|
25
25
|
super db
|
26
26
|
@id = id
|
27
|
+
@name = libid2name(@id)
|
27
28
|
if saved?
|
28
29
|
@classmap = nil
|
29
30
|
@methodmap = nil
|
@@ -36,7 +37,9 @@ module BitClust
|
|
36
37
|
init_properties
|
37
38
|
end
|
38
39
|
|
39
|
-
attr_reader :id
|
40
|
+
attr_reader :id, :name
|
41
|
+
|
42
|
+
alias label name
|
40
43
|
|
41
44
|
def ==(other)
|
42
45
|
@id == other.id
|
@@ -52,11 +55,6 @@ module BitClust
|
|
52
55
|
@id.casecmp(other.id)
|
53
56
|
end
|
54
57
|
|
55
|
-
def name
|
56
|
-
libid2name(@id)
|
57
|
-
end
|
58
|
-
alias label name
|
59
|
-
|
60
58
|
def labels
|
61
59
|
[label()]
|
62
60
|
end
|
@@ -59,7 +59,7 @@ module BitClust
|
|
59
59
|
when /\A\$/ # gvar
|
60
60
|
@name + (@type ? " -> #{@type}" : "")
|
61
61
|
when "+@", "-@", "~", "!", "!@" # unary operator
|
62
|
-
"#{@name.sub(/@/, '')}
|
62
|
+
"#{@name.sub(/@/, '')} self" + (@type ? " -> #{@type}" : "")
|
63
63
|
when "[]" # aref
|
64
64
|
"self[#{@params}]" + (@type ? " -> #{@type}" : "")
|
65
65
|
when "[]=" # aset
|
data/lib/bitclust/nameutils.rb
CHANGED
@@ -21,7 +21,7 @@ module BitClust
|
|
21
21
|
CONST_PATH_RE = /#{CONST_RE}(?:::#{CONST_RE})*/
|
22
22
|
CLASS_NAME_RE = /(?:#{CONST_RE}(?:::compatible)?|fatal|ARGF.class|main)/
|
23
23
|
CLASS_PATH_RE = /(?:#{CONST_PATH_RE}(?:::compatible)?|fatal|ARGF.class|main)/
|
24
|
-
METHOD_NAME_RE = /\w+[?!=]
|
24
|
+
METHOD_NAME_RE = /\w+[?!=]?|===|==|=~|<=>|<=|>=|!=|!~|!@|!|\[\]=|\[\]|\*\*|>>|<<|\+@|\-@|[~+\-*\/%&|^<>`]/
|
25
25
|
TYPEMARK_RE = /(?:\.|\#|\.\#|::|\$)/
|
26
26
|
METHOD_SPEC_RE = /#{CLASS_PATH_RE}#{TYPEMARK_RE}#{METHOD_NAME_RE}/
|
27
27
|
GVAR_RE = /\$(?:\w+|-.|\S)/
|
@@ -212,6 +212,14 @@ module BitClust
|
|
212
212
|
str.gsub(/=[\da-h]{2}/ni) {|s| s[1,2].hex.chr }
|
213
213
|
end
|
214
214
|
|
215
|
+
# string -> encoded string in a rdoc way
|
216
|
+
def encodename_rdocurl(str)
|
217
|
+
str = str.gsub(/[^A-Za-z0-9_.]/n) {|ch|
|
218
|
+
sprintf('-%02X', ch[0].ord)
|
219
|
+
}
|
220
|
+
str.sub(/\A-/, '')
|
221
|
+
end
|
222
|
+
|
215
223
|
# case-sensitive ID -> encoded string (encode only [A-Z])
|
216
224
|
def encodeid(str)
|
217
225
|
str.gsub(/[A-Z]/n) {|ch| "-#{ch}" }.downcase
|
@@ -234,6 +242,9 @@ module BitClust
|
|
234
242
|
}
|
235
243
|
end
|
236
244
|
|
245
|
+
def html_filename(basename, suffix)
|
246
|
+
"#{basename}#{suffix}"
|
247
|
+
end
|
237
248
|
end
|
238
249
|
|
239
250
|
end
|
data/lib/bitclust/rdcompiler.rb
CHANGED
@@ -38,13 +38,23 @@ module BitClust
|
|
38
38
|
}
|
39
39
|
end
|
40
40
|
|
41
|
+
def compile_function(f, opt = nil)
|
42
|
+
@opt = opt
|
43
|
+
@type = :function
|
44
|
+
setup(f.source) {
|
45
|
+
entry
|
46
|
+
}
|
47
|
+
ensure
|
48
|
+
@opt = nil
|
49
|
+
end
|
50
|
+
|
41
51
|
# FIXME
|
42
52
|
def compile_method(m, opt = nil)
|
43
53
|
@opt = opt
|
44
54
|
@type = :method
|
45
55
|
@method = m
|
46
56
|
setup(m.source) {
|
47
|
-
|
57
|
+
entry
|
48
58
|
}
|
49
59
|
ensure
|
50
60
|
@opt = nil
|
@@ -63,13 +73,13 @@ module BitClust
|
|
63
73
|
while @f.next?
|
64
74
|
case @f.peek
|
65
75
|
when /\A---/
|
66
|
-
|
76
|
+
entry_chunk
|
67
77
|
when /\A=+/
|
68
78
|
headline @f.gets
|
69
|
-
when /\A\s
|
70
|
-
|
71
|
-
|
72
|
-
|
79
|
+
when /\A(\s+)\*\s/, /\A(\s+)\(\d+\)\s/
|
80
|
+
@item_stack = []
|
81
|
+
item_list($1.size)
|
82
|
+
raise "@item_stack should be empty. #{@item_stack.inspect}" unless @item_stack.empty?
|
73
83
|
when %r<\A//emlist\{>
|
74
84
|
emlist
|
75
85
|
when /\A:\s/
|
@@ -86,13 +96,13 @@ module BitClust
|
|
86
96
|
end
|
87
97
|
end
|
88
98
|
|
89
|
-
def
|
99
|
+
def entry
|
90
100
|
while @f.next?
|
91
|
-
|
101
|
+
entry_chunk
|
92
102
|
end
|
93
103
|
end
|
94
104
|
|
95
|
-
def
|
105
|
+
def entry_chunk
|
96
106
|
@out.puts '<dl>' if @option[:force]
|
97
107
|
first = true
|
98
108
|
@f.while_match(/\A---/) do |line|
|
@@ -103,8 +113,8 @@ module BitClust
|
|
103
113
|
@f.while_match(/\A:/) do |line|
|
104
114
|
k, v = line.sub(/\A:/, '').split(':', 2)
|
105
115
|
props[k.strip] = v.strip
|
106
|
-
end
|
107
|
-
@out.puts
|
116
|
+
end if @type == :method
|
117
|
+
@out.puts %Q(<dd class="#{@type.to_s}-description">)
|
108
118
|
while @f.next?
|
109
119
|
case @f.peek
|
110
120
|
when /\A===+/
|
@@ -113,14 +123,14 @@ module BitClust
|
|
113
123
|
if @option[:force]
|
114
124
|
break
|
115
125
|
else
|
116
|
-
raise "
|
126
|
+
raise "#{@type.to_s} entry includes headline: #{@f.peek.inspect}"
|
117
127
|
end
|
118
128
|
when /\A---/
|
119
129
|
break
|
120
|
-
when /\A\s
|
121
|
-
|
122
|
-
|
123
|
-
|
130
|
+
when /\A(\s+)\*\s/, /\A(\s+)\(\d+\)\s/
|
131
|
+
@item_stack = []
|
132
|
+
item_list($1.size)
|
133
|
+
raise "@item_stack should be empty. #{@item_stack.inspect}" unless @item_stack.empty?
|
124
134
|
when /\A:\s/
|
125
135
|
dlist
|
126
136
|
when %r<\A//emlist\{>
|
@@ -132,12 +142,12 @@ module BitClust
|
|
132
142
|
when /@todo/
|
133
143
|
todo
|
134
144
|
when /\A@[a-z]/
|
135
|
-
|
145
|
+
entry_info
|
136
146
|
else
|
137
147
|
if @f.peek.strip.empty?
|
138
148
|
@f.gets
|
139
149
|
else
|
140
|
-
|
150
|
+
entry_paragraph
|
141
151
|
end
|
142
152
|
end
|
143
153
|
end
|
@@ -157,32 +167,45 @@ module BitClust
|
|
157
167
|
"<h#{level} #{name}>#{label}</h#{level}>"
|
158
168
|
end
|
159
169
|
|
160
|
-
def
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
+
def item_list(level = 0, indent = true)
|
171
|
+
open_tag = nil
|
172
|
+
close_tag = nil
|
173
|
+
pattern = nil
|
174
|
+
case @f.peek
|
175
|
+
when /\A(\s+)\*\s/
|
176
|
+
open_tag = "<ul>"
|
177
|
+
close_tag = "</ul>"
|
178
|
+
when /\A(\s+)\(\d+\)\s/
|
179
|
+
open_tag = "<ol>"
|
180
|
+
close_tag = "</ol>"
|
170
181
|
end
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
@
|
176
|
-
|
177
|
-
|
178
|
-
string compile_text(line.sub(/\A\s
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
+
if indent
|
183
|
+
line open_tag
|
184
|
+
@item_stack.push(close_tag)
|
185
|
+
end
|
186
|
+
@f.while_match(/\A(\s+)(?:\*\s|\(\d+\))/) do |line|
|
187
|
+
string "<li>"
|
188
|
+
@item_stack.push("</li>")
|
189
|
+
string compile_text(line.sub(/\A(\s+)(?:\*|\(\d+\))/, '').strip)
|
190
|
+
if /\A(\s+)(?!\*\s|\(\d+\))\S/ =~ @f.peek
|
191
|
+
@f.while_match(/\A\s+(?!\*\s|\(\d+\))\S/) do |cont|
|
192
|
+
nl
|
193
|
+
string compile_text(cont.strip)
|
194
|
+
end
|
195
|
+
line @item_stack.pop # current level li
|
196
|
+
elsif /\A(\s+)(?:\*\s|\(\d+\))/ =~ @f.peek and level < $1.size
|
197
|
+
item_list($1.size)
|
198
|
+
line @item_stack.pop # current level ul or ol
|
199
|
+
elsif /\A(\s+)(?:\*\s|\(\d+\))/ =~ @f.peek and level > $1.size
|
200
|
+
line @item_stack.pop # current level li
|
201
|
+
line @item_stack.pop # current level ul or ol
|
202
|
+
line @item_stack.pop # previous level li
|
203
|
+
item_list($1.size, false)
|
204
|
+
else
|
205
|
+
line @item_stack.pop # current level li
|
182
206
|
end
|
183
|
-
line '</li>'
|
184
207
|
end
|
185
|
-
line
|
208
|
+
line @item_stack.pop unless @item_stack.empty?
|
186
209
|
end
|
187
210
|
|
188
211
|
def dlist
|
@@ -293,7 +316,7 @@ module BitClust
|
|
293
316
|
line '</p>'
|
294
317
|
end
|
295
318
|
|
296
|
-
def
|
319
|
+
def entry_info
|
297
320
|
line '<dl>'
|
298
321
|
while @f.next? and /\A\@(?!see)\w+|\A$/ =~ @f.peek
|
299
322
|
header = @f.gets
|
@@ -303,7 +326,7 @@ module BitClust
|
|
303
326
|
case cmd
|
304
327
|
when '@param', '@arg'
|
305
328
|
name = header.slice!(/\A\s*\w+/) || '?'
|
306
|
-
line "<dt class='
|
329
|
+
line "<dt class='#{@type.to_s}-param'>[PARAM] #{escape_html(name.strip)}:</dt>"
|
307
330
|
when '@raise'
|
308
331
|
ex = header.slice!(/\A\s*[\w:]+/) || '?'
|
309
332
|
line "<dt>[EXCEPTION] #{escape_html(ex.strip)}:</dt>"
|
@@ -318,15 +341,15 @@ module BitClust
|
|
318
341
|
end
|
319
342
|
|
320
343
|
# FIXME: parse @param, @return, ...
|
321
|
-
def
|
344
|
+
def entry_paragraph
|
322
345
|
line '<p>'
|
323
|
-
|
346
|
+
read_entry_paragraph(@f).each do |line|
|
324
347
|
line compile_text(line.strip)
|
325
348
|
end
|
326
349
|
line '</p>'
|
327
350
|
end
|
328
351
|
|
329
|
-
def
|
352
|
+
def read_entry_paragraph(f)
|
330
353
|
f.span(%r<\A(?!---|=|//emlist\{|@[a-z])\S>)
|
331
354
|
end
|
332
355
|
|
@@ -342,6 +365,8 @@ module BitClust
|
|
342
365
|
if first
|
343
366
|
string '<span class="permalink">['
|
344
367
|
string a_href(@urlmapper.method_url(methodid2specstring(@method.id)), "permalink")
|
368
|
+
string ']['
|
369
|
+
string rdoc_link(@method.id, @option[:database].properties["version"])
|
345
370
|
string ']</span>'
|
346
371
|
end
|
347
372
|
if @method and not @method.defined?
|
@@ -370,7 +395,7 @@ module BitClust
|
|
370
395
|
arg = _arg.rstrip
|
371
396
|
case type
|
372
397
|
when 'lib'
|
373
|
-
|
398
|
+
protect(link) {
|
374
399
|
case arg
|
375
400
|
when '/', '_index'
|
376
401
|
label = 'All libraries'
|
@@ -379,20 +404,26 @@ module BitClust
|
|
379
404
|
end
|
380
405
|
library_link(arg, label, frag)
|
381
406
|
}
|
382
|
-
when 'c'
|
383
|
-
|
407
|
+
when 'c'
|
408
|
+
protect(link) { class_link(arg, label, frag) }
|
409
|
+
when 'm'
|
410
|
+
protect(link) { method_link(complete_spec(arg), label || arg, frag) }
|
384
411
|
when 'f'
|
385
|
-
|
412
|
+
protect(link) {
|
386
413
|
case arg
|
387
414
|
when '/', '_index'
|
388
415
|
arg, label = '', 'All C API'
|
389
416
|
end
|
390
417
|
function_link(arg, label || arg, frag)
|
391
418
|
}
|
392
|
-
when 'd'
|
393
|
-
|
394
|
-
when '
|
395
|
-
|
419
|
+
when 'd'
|
420
|
+
protect(link) { document_link(arg, label, frag) }
|
421
|
+
when 'ref'
|
422
|
+
protect(link) { reference_link(arg) }
|
423
|
+
when 'url'
|
424
|
+
direct_url(arg)
|
425
|
+
when 'man'
|
426
|
+
man_link(arg)
|
396
427
|
when 'rfc', 'RFC'
|
397
428
|
rfc_link(arg)
|
398
429
|
when 'ruby-list', 'ruby-dev', 'ruby-ext', 'ruby-talk', 'ruby-core'
|
@@ -462,7 +493,7 @@ module BitClust
|
|
462
493
|
MAN_HEADER_URL = "#{opengroup_url}/basedefs/%s.html"
|
463
494
|
MAN_LINUX_URL = "http://man7.org/linux/man-pages/man%1$s/%2$s.%1$s.html"
|
464
495
|
MAN_FREEBSD_URL = "http://www.freebsd.org/cgi/man.cgi?query=%2$s&sektion=%1$s&manpath=FreeBSD+9.0-RELEASE"
|
465
|
-
|
496
|
+
|
466
497
|
def man_url(section, page)
|
467
498
|
case section
|
468
499
|
when "1"
|
@@ -475,17 +506,30 @@ module BitClust
|
|
475
506
|
sprintf(MAN_LINUX_URL, $1, page)
|
476
507
|
when /\A([1-9])freebsd\Z/
|
477
508
|
sprintf(MAN_FREEBSD_URL, $1, page)
|
478
|
-
else
|
509
|
+
else
|
479
510
|
nil
|
480
511
|
end
|
481
512
|
end
|
482
|
-
|
513
|
+
|
483
514
|
def man_link(spec)
|
484
515
|
m = /([\w\.\/]+)\((\w+)\)/.match(spec) or return escape_html(spec)
|
485
516
|
url = man_url(m[2], escape_html(m[1])) or return escape_html(spec)
|
486
517
|
%Q(<a class="external" href="#{escape_html(url)}">#{escape_html("#{m[1]}(#{m[2]})")}</a>)
|
487
518
|
end
|
488
519
|
|
520
|
+
def rdoc_url(method_id, version)
|
521
|
+
cname, tmark, mname, libname = methodid2specparts(method_id)
|
522
|
+
tchar = typemark2char(tmark) == 'i' ? 'i' : 'c'
|
523
|
+
cname = cname.gsub('::', '/')
|
524
|
+
id = "method-#{tchar}-#{encodename_rdocurl(mname)}"
|
525
|
+
|
526
|
+
"http://docs.ruby-lang.org/en/#{version}/#{cname}.html##{id}"
|
527
|
+
end
|
528
|
+
|
529
|
+
def rdoc_link(method_id, version)
|
530
|
+
a_href(rdoc_url(method_id, version), "rdoc")
|
531
|
+
end
|
532
|
+
|
489
533
|
def complete_spec(spec0)
|
490
534
|
case spec0
|
491
535
|
when /\A\$/
|