bitclust-core 1.7.0 → 1.8.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/data/bitclust/template/class-index +0 -1
- data/data/bitclust/template.epub/class +5 -5
- data/data/bitclust/template.epub/class-index +0 -1
- data/data/bitclust/template.epub/contents +7 -4
- data/data/bitclust/template.epub/layout +4 -4
- data/data/bitclust/template.offline/class-index +0 -1
- data/lib/bitclust/generators/epub.rb +69 -5
- data/lib/bitclust/irb.rb +14 -8
- data/lib/bitclust/markdown_bridge.rb +11 -6
- data/lib/bitclust/markdown_tree.rb +118 -11
- data/lib/bitclust/methoddatabase.rb +17 -4
- data/lib/bitclust/nameutils.rb +13 -0
- data/lib/bitclust/preprocessor.rb +0 -36
- data/lib/bitclust/remote.rb +405 -0
- data/lib/bitclust/runner.rb +5 -10
- data/lib/bitclust/screen.rb +2 -1
- data/lib/bitclust/searcher.rb +43 -24
- data/lib/bitclust/subcommands/chm_command.rb +1 -1
- data/lib/bitclust/subcommands/epub_command.rb +2 -2
- data/lib/bitclust/subcommands/extract_command.rb +7 -0
- data/lib/bitclust/subcommands/htmlfile_command.rb +7 -0
- data/lib/bitclust/subcommands/methods_command.rb +5 -28
- data/lib/bitclust/subcommands/query_command.rb +1 -0
- data/lib/bitclust/subcommands/server_command.rb +21 -10
- data/lib/bitclust/subcommands/setup_command.rb +28 -10
- data/lib/bitclust/syntax_highlighter.rb +65 -4
- data/lib/bitclust/user_dirs.rb +62 -0
- data/lib/bitclust/version.rb +1 -1
- data/test/test_chm_command.rb +22 -0
- data/test/test_epub_command.rb +60 -0
- data/test/test_epub_generator.rb +330 -0
- data/test/test_extract_command.rb +45 -0
- data/test/test_irb_plugin.rb +100 -6
- data/test/test_markdown_bridge.rb +35 -0
- data/test/test_markdown_tree.rb +144 -0
- data/test/test_mdparser.rb +39 -0
- data/test/test_methods_command.rb +32 -0
- data/test/test_opensearchdescription_screen.rb +39 -0
- data/test/test_query_command.rb +30 -0
- data/test/test_remote.rb +374 -0
- data/test/test_runner.rb +61 -1
- data/test/test_searcher.rb +63 -0
- data/test/test_server_command.rb +41 -0
- data/test/test_setup_command.rb +143 -0
- data/test/test_syntax_highlighter.rb +124 -0
- data/test/test_user_dirs.rb +62 -0
- metadata +37 -2
- data/lib/bitclust/ridatabase.rb +0 -359
data/lib/bitclust/ridatabase.rb
DELETED
|
@@ -1,359 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
require 'rdoc/ri/ri_reader'
|
|
3
|
-
require 'rdoc/ri/ri_cache'
|
|
4
|
-
require 'rdoc/ri/ri_paths'
|
|
5
|
-
|
|
6
|
-
class ApplicationError < StandardError; end
|
|
7
|
-
class RiClassNotFound < ApplicationError; end
|
|
8
|
-
|
|
9
|
-
# Handle RDoc(ri) database for tools/bc-rdoc.rb and
|
|
10
|
-
# `bitclust methods --diff`.
|
|
11
|
-
class RiDatabase
|
|
12
|
-
def RiDatabase.open_system_db
|
|
13
|
-
new(RI::Paths.path(true, false, false, false), RUBY_VERSION)
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def RiDatabase.open(dir, version)
|
|
17
|
-
new(RI::Paths.path(false, false, false, false, dir), version)
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def initialize(ripath, version)
|
|
21
|
-
@ripath = ripath
|
|
22
|
-
@reader = RI::RiReader.new(RI::RiCache.new(@ripath))
|
|
23
|
-
@version = version
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
attr_reader :version
|
|
27
|
-
|
|
28
|
-
def get_method(m)
|
|
29
|
-
@reader.get_method(m)
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def current_class=(name)
|
|
33
|
-
@klass = lookup_class(name)
|
|
34
|
-
@singleton_methods = wrap_entries(@reader.singleton_methods(@klass))
|
|
35
|
-
@instance_methods = wrap_entries(@reader.instance_methods(@klass))
|
|
36
|
-
rescue RiClassNotFound
|
|
37
|
-
@klass = nil
|
|
38
|
-
@singleton_methods = []
|
|
39
|
-
@instance_methods = []
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
attr_reader :class
|
|
43
|
-
attr_reader :singleton_methods
|
|
44
|
-
attr_reader :instance_methods
|
|
45
|
-
|
|
46
|
-
def lookup_class(name)
|
|
47
|
-
ns = @reader.top_level_namespace.first
|
|
48
|
-
name.split('::').each do |const|
|
|
49
|
-
ns = ns.contained_class_named(const) or
|
|
50
|
-
raise RiClassNotFound, "no such class in RDoc database: #{name}"
|
|
51
|
-
end
|
|
52
|
-
ns
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
private
|
|
56
|
-
|
|
57
|
-
def wrap_entries(ents)
|
|
58
|
-
ents.map {|m|
|
|
59
|
-
[RiMethodEntry.new(m.name, m)] +
|
|
60
|
-
m.aliases.map {|a| RiMethodEntry.new(a.name, m) }
|
|
61
|
-
}.flatten.uniq
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
class Ent
|
|
66
|
-
def initialize(name, ent)
|
|
67
|
-
@name = name
|
|
68
|
-
@entry = ent
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
attr_reader :name
|
|
72
|
-
attr_reader :entry
|
|
73
|
-
|
|
74
|
-
def ==(other)
|
|
75
|
-
return false if self.class != other.class
|
|
76
|
-
@name == other.name
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
alias eql? ==
|
|
80
|
-
|
|
81
|
-
def hash
|
|
82
|
-
@name.hash
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
def <=>(other)
|
|
86
|
-
@name <=> other.name
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
class BCMethodEntry < Ent
|
|
91
|
-
def bitclust?
|
|
92
|
-
true
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
def inspect
|
|
96
|
-
"\#<BitClust #{@name} #{@entry.inspect}>"
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
def fullname
|
|
100
|
-
"#{@entry.klass.name}#{@entry.typemark}#{@name}"
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
def id
|
|
104
|
-
if @entry.defined?
|
|
105
|
-
fullname()
|
|
106
|
-
else
|
|
107
|
-
"#{fullname()}.#{@entry.library.name}"
|
|
108
|
-
end
|
|
109
|
-
end
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
class RiMethodEntry < Ent
|
|
113
|
-
def bitclust?
|
|
114
|
-
false
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
def inspect
|
|
118
|
-
"\#<RDoc #{@name} #{@entry.fullname}>"
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
def singleton_method?
|
|
122
|
-
@entry.singleton_method?
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
def fullname
|
|
126
|
-
c, t = @entry.fullname.split(/([\.\#])/, 2)
|
|
127
|
-
"#{c}#{t}#{@name}"
|
|
128
|
-
end
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
module RI
|
|
133
|
-
|
|
134
|
-
class RiReader # reopen
|
|
135
|
-
def singleton_methods(c)
|
|
136
|
-
c.singleton_methods.map {|ent| get_method(ent) }
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
def instance_methods(c)
|
|
140
|
-
c.instance_methods.map {|ent| get_method(ent) }
|
|
141
|
-
end
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
-
class ClassEntry # reopen
|
|
145
|
-
def singleton_methods
|
|
146
|
-
@class_methods
|
|
147
|
-
end
|
|
148
|
-
|
|
149
|
-
attr_reader :instance_methods
|
|
150
|
-
|
|
151
|
-
def method_entries
|
|
152
|
-
@class_methods.sort_by {|m| m.name } +
|
|
153
|
-
@instance_methods.sort_by {|m| m.name }
|
|
154
|
-
end
|
|
155
|
-
end
|
|
156
|
-
|
|
157
|
-
class MethodEntry # reopen
|
|
158
|
-
def fullname
|
|
159
|
-
"#{@in_class.full_name}#{@is_class_method ? '.' : '#'}#{@name}"
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
def singleton_method?
|
|
163
|
-
@is_class_method
|
|
164
|
-
end
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
class MethodDescription # reopen
|
|
168
|
-
def fullname
|
|
169
|
-
name = full_name()
|
|
170
|
-
unless /\#/ =~ name
|
|
171
|
-
components = name.split('::')
|
|
172
|
-
m = components.pop || raise
|
|
173
|
-
components.join('::') + '.' + m
|
|
174
|
-
else
|
|
175
|
-
name
|
|
176
|
-
end
|
|
177
|
-
end
|
|
178
|
-
|
|
179
|
-
def singleton_method?
|
|
180
|
-
@is_class_method ||= false
|
|
181
|
-
@is_class_method
|
|
182
|
-
end
|
|
183
|
-
end
|
|
184
|
-
|
|
185
|
-
end
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
module HTMLUtils
|
|
189
|
-
|
|
190
|
-
ESC = {
|
|
191
|
-
'&' => '&',
|
|
192
|
-
'<' => '<',
|
|
193
|
-
'>' => '>',
|
|
194
|
-
'"' => '"'
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
def escape(str)
|
|
198
|
-
t = ESC
|
|
199
|
-
str.gsub(/[&"<>]/) {|s| t[s] }
|
|
200
|
-
end
|
|
201
|
-
module_function :escape
|
|
202
|
-
|
|
203
|
-
UNESC = ESC.invert
|
|
204
|
-
UNESC[' '] = ' '
|
|
205
|
-
|
|
206
|
-
def unescape(str)
|
|
207
|
-
t = UNESC
|
|
208
|
-
str.gsub(/&\w+;/) {|s| t[s] || s }
|
|
209
|
-
end
|
|
210
|
-
module_function :unescape
|
|
211
|
-
|
|
212
|
-
end
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
class Formatter
|
|
216
|
-
|
|
217
|
-
include HTMLUtils
|
|
218
|
-
|
|
219
|
-
def method_info(m)
|
|
220
|
-
@f = StringIO.new
|
|
221
|
-
describe_method m
|
|
222
|
-
@f.string
|
|
223
|
-
end
|
|
224
|
-
|
|
225
|
-
private
|
|
226
|
-
|
|
227
|
-
def line(s = nil)
|
|
228
|
-
if s
|
|
229
|
-
@f.puts s
|
|
230
|
-
else
|
|
231
|
-
@f.puts
|
|
232
|
-
end
|
|
233
|
-
end
|
|
234
|
-
|
|
235
|
-
def describe_method(m)
|
|
236
|
-
if m.params[0,1] == '('
|
|
237
|
-
line "--- #{m.full_name}#{trim_space(m.params)}"
|
|
238
|
-
else
|
|
239
|
-
m.params.lines.each do |sig|
|
|
240
|
-
line "--- #{trim_sig(sig)}#%todo\n"
|
|
241
|
-
end
|
|
242
|
-
end
|
|
243
|
-
unless m.aliases.empty?
|
|
244
|
-
m.aliases.each do |a|
|
|
245
|
-
line "alias #{a.name}"
|
|
246
|
-
end
|
|
247
|
-
end
|
|
248
|
-
#line "\#@TODO rewrite me"
|
|
249
|
-
line
|
|
250
|
-
@f.puts format_elements(m.comment)
|
|
251
|
-
line
|
|
252
|
-
end
|
|
253
|
-
|
|
254
|
-
def trim_space(s)
|
|
255
|
-
s.sub(/\(\s+/, '(').sub(/\s+\)/, ')').sub(/\(\)/, '')
|
|
256
|
-
end
|
|
257
|
-
|
|
258
|
-
def trim_sig(s)
|
|
259
|
-
s = trim_space(s)
|
|
260
|
-
s.sub!(/\A[a-z]\w+\./, '')
|
|
261
|
-
s.sub!(/=>/, '->')
|
|
262
|
-
# steep:ignore:start
|
|
263
|
-
s.sub!(/(->.*)\bstr(ing)?\b/){ $1 + 'String' }
|
|
264
|
-
s.sub!(/(->.*)\bint(eger)?\b/){ $1 + 'Integer' }
|
|
265
|
-
s.sub!(/(->.*)\b(an_)?obj\b/){ $1 + 'object' }
|
|
266
|
-
s.sub!(/(->.*)\b(a_)?hash\b/){ $1 + 'Hash' }
|
|
267
|
-
s.sub!(/(->.*)\b(an_)?array\b/){ $1 + 'Array' }
|
|
268
|
-
# steep:ignore:end
|
|
269
|
-
s.sub!(/ or /, ' | ')
|
|
270
|
-
s
|
|
271
|
-
end
|
|
272
|
-
|
|
273
|
-
def format_elements(elems)
|
|
274
|
-
return "" unless elems
|
|
275
|
-
return "" if elems.empty?
|
|
276
|
-
elems.map {|elem| format_element(elem) }.join("\n\n")
|
|
277
|
-
end
|
|
278
|
-
|
|
279
|
-
def format_element(e)
|
|
280
|
-
# steep:ignore:start
|
|
281
|
-
case e
|
|
282
|
-
when SM::Flow::P, SM::Flow::LI
|
|
283
|
-
paragraph(e)
|
|
284
|
-
when SM::Flow::LIST
|
|
285
|
-
list(e)
|
|
286
|
-
when SM::Flow::VERB
|
|
287
|
-
verbatim(e)
|
|
288
|
-
when SM::Flow::H
|
|
289
|
-
headline(e)
|
|
290
|
-
when SM::Flow::RULE
|
|
291
|
-
;
|
|
292
|
-
else
|
|
293
|
-
raise "unkwnown markup: #{e.class}"
|
|
294
|
-
end
|
|
295
|
-
# steep:ignore:end
|
|
296
|
-
end
|
|
297
|
-
|
|
298
|
-
def headline(e)
|
|
299
|
-
h = '==' + ('=' * e.level)
|
|
300
|
-
text = unescape(e.text)
|
|
301
|
-
"#{h} #{text}"
|
|
302
|
-
end
|
|
303
|
-
|
|
304
|
-
def paragraph(e)
|
|
305
|
-
wrap(unescape(remove_inline(e.body)))
|
|
306
|
-
end
|
|
307
|
-
|
|
308
|
-
def verbatim(e)
|
|
309
|
-
unescape(e.body.rstrip) #.gsub(/^/, ' ')
|
|
310
|
-
end
|
|
311
|
-
|
|
312
|
-
def list(e)
|
|
313
|
-
# steep:ignore:start
|
|
314
|
-
case e.type
|
|
315
|
-
when SM::ListBase::BULLET
|
|
316
|
-
e.contents.map {|item| "* #{format_element(e)}" }.join("\n")
|
|
317
|
-
when SM::ListBase::NUMBER,
|
|
318
|
-
SM::ListBase::LOWERALPHA,
|
|
319
|
-
SM::ListBase::UPPERALPHA
|
|
320
|
-
num = case e.type
|
|
321
|
-
when SM::ListBase::NUMBER then '1'
|
|
322
|
-
when SM::ListBase::LOWERALPHA then 'a'
|
|
323
|
-
when SM::ListBase::UPPERALPHA then 'A'
|
|
324
|
-
end
|
|
325
|
-
e.contents.map {|item|
|
|
326
|
-
str = "#{num}. #{format_element(e)}"
|
|
327
|
-
num = num.succ
|
|
328
|
-
str
|
|
329
|
-
}.join("\n")
|
|
330
|
-
when SM::ListBase::LABELED
|
|
331
|
-
e.contents.map {|item| "#{item.label} #{format_element(e)}" }.join("\n")
|
|
332
|
-
when SM::ListBase::NOTE
|
|
333
|
-
e.contents.map {|item| "#{item.label}\t#{format_element(e)}" }.join("\n")
|
|
334
|
-
else
|
|
335
|
-
raise "unknown list type: #{e.type.inspect}"
|
|
336
|
-
end
|
|
337
|
-
# steep:ignore:end
|
|
338
|
-
end
|
|
339
|
-
|
|
340
|
-
def remove_inline(str)
|
|
341
|
-
str.gsub(/<\/?\w+>/, '')
|
|
342
|
-
end
|
|
343
|
-
|
|
344
|
-
def wrap(str)
|
|
345
|
-
width = 60
|
|
346
|
-
buf = ''
|
|
347
|
-
line = ''
|
|
348
|
-
str.split.each do |chunk|
|
|
349
|
-
line << chunk << ' '
|
|
350
|
-
if line.size > width
|
|
351
|
-
buf << line.strip << "\n"
|
|
352
|
-
line = ''
|
|
353
|
-
end
|
|
354
|
-
end
|
|
355
|
-
buf << line
|
|
356
|
-
buf.strip
|
|
357
|
-
end
|
|
358
|
-
|
|
359
|
-
end
|