bitclust-core 1.6.0 → 1.7.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/Rakefile +1 -0
- data/data/bitclust/catalog/ja_JP.UTF-8 +4 -2
- data/data/bitclust/template/function-index +1 -0
- data/data/bitclust/template/layout +1 -0
- data/data/bitclust/template.offline/function-index +1 -0
- data/data/bitclust/template.offline/layout +3 -0
- data/lib/bitclust/classentry.rb +1 -1
- data/lib/bitclust/docentry.rb +1 -1
- data/lib/bitclust/functionentry.rb +1 -1
- data/lib/bitclust/irb.rb +68 -0
- data/lib/bitclust/markdown_exporter.rb +311 -0
- data/lib/bitclust/mdcompiler.rb +15 -1
- data/lib/bitclust/mdparser.rb +42 -1
- data/lib/bitclust/methoddatabase.rb +4 -0
- data/lib/bitclust/methodentry.rb +24 -0
- data/lib/bitclust/methodsignature.rb +1 -1
- data/lib/bitclust/preprocessor.rb +4 -1
- data/lib/bitclust/rbs_overload_matcher.rb +179 -0
- data/lib/bitclust/rbs_sig_importer.rb +276 -0
- data/lib/bitclust/rbs_signatures.rb +125 -0
- data/lib/bitclust/rdcompiler.rb +12 -1
- data/lib/bitclust/runner.rb +2 -0
- data/lib/bitclust/screen.rb +4 -0
- data/lib/bitclust/search_index_generator.rb +28 -10
- data/lib/bitclust/searcher.rb +12 -2
- data/lib/bitclust/subcommands/rbssig_command.rb +99 -0
- data/lib/bitclust/subcommands/setup_command.rb +4 -1
- data/lib/bitclust/subcommands/statichtml_command.rb +59 -0
- data/lib/bitclust/version.rb +1 -1
- data/lib/bitclust-irb.rb +2 -0
- data/test/test_irb_plugin.rb +118 -0
- data/test/test_link_checker.rb +1 -1
- data/test/test_markdown_exporter.rb +260 -0
- data/test/test_mdcompiler.rb +47 -5
- data/test/test_mdparser.rb +219 -4
- data/test/test_methodentry.rb +111 -0
- data/test/test_methodsignature.rb +3 -1
- data/test/test_preprocessor.rb +26 -0
- data/test/test_rbs_overload_matcher.rb +170 -0
- data/test/test_rbs_sig_importer.rb +237 -0
- data/test/test_rbssig_command.rb +186 -0
- data/test/test_rdcompiler.rb +99 -1
- data/test/test_search_index_generator.rb +81 -0
- data/test/test_setup_command.rb +21 -0
- data/test/test_statichtml_command.rb +137 -0
- data/theme/default/js/run.js +14 -0
- data/theme/default/js/search_init.js +3 -1
- data/theme/default/js/search_page.js +7 -1
- data/theme/default/js/version_switcher.js +147 -0
- data/theme/default/search.css +21 -0
- data/theme/default/style.css +83 -7
- data/theme/lillia/style.css +26 -0
- metadata +35 -1
|
@@ -114,6 +114,9 @@ module BitClust
|
|
|
114
114
|
key = e.values_at(:name, :full_name, :type, :path)
|
|
115
115
|
entry = (merged[key] ||= e.merge(versions: []))
|
|
116
116
|
entry[:versions] << version
|
|
117
|
+
# 説明文は「最新版か、収録されている最終版」のものを採用する。
|
|
118
|
+
# 昇順走査なので後勝ちで上書きすればよい
|
|
119
|
+
entry[:snippet] = e[:snippet] if e[:snippet]
|
|
117
120
|
end
|
|
118
121
|
end
|
|
119
122
|
merged.values
|
|
@@ -126,14 +129,29 @@ module BitClust
|
|
|
126
129
|
|
|
127
130
|
private
|
|
128
131
|
|
|
132
|
+
# 検索結果に添える説明文。meta description と同じ entry.description
|
|
133
|
+
# (最初の説明段落のプレーンテキスト)を使い、空なら nil(キー自体を
|
|
134
|
+
# 持たせない)。プレーンテキストのまま格納し、HTML エスケープは
|
|
135
|
+
# 表示側(search_init.js / search_page.js)で行う
|
|
136
|
+
def entry_snippet(entry)
|
|
137
|
+
desc = entry.description
|
|
138
|
+
desc unless desc.nil? || desc.empty?
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def with_snippet(hash, entry)
|
|
142
|
+
snippet = entry_snippet(entry)
|
|
143
|
+
hash[:snippet] = snippet if snippet
|
|
144
|
+
hash
|
|
145
|
+
end
|
|
146
|
+
|
|
129
147
|
def class_entries(db)
|
|
130
148
|
db.classes.sort.reject(&:dummy?).map do |c|
|
|
131
|
-
{
|
|
149
|
+
with_snippet({
|
|
132
150
|
name: c.name,
|
|
133
151
|
full_name: c.name,
|
|
134
152
|
type: c.type.to_s,
|
|
135
153
|
path: "class/#{encode(c.name)}#{@suffix}",
|
|
136
|
-
}
|
|
154
|
+
}, c)
|
|
137
155
|
end
|
|
138
156
|
end
|
|
139
157
|
|
|
@@ -162,11 +180,11 @@ module BitClust
|
|
|
162
180
|
# sigil is the only thing distinguishing it, so keep it in +name+
|
|
163
181
|
# too (not just +full_name+) or a "$;"-style query can't match it.
|
|
164
182
|
name = full_name = tmark + mname
|
|
165
|
-
result << { name: name, full_name: full_name, type: type, path: path }
|
|
183
|
+
result << with_snippet({ name: name, full_name: full_name, type: type, path: path }, entry)
|
|
166
184
|
else
|
|
167
185
|
name = mname
|
|
168
186
|
full_name = cname + tmark + mname
|
|
169
|
-
item = { name: name, full_name: full_name, type: type, path: path } #: entry
|
|
187
|
+
item = with_snippet({ name: name, full_name: full_name, type: type, path: path }, entry) #: entry
|
|
170
188
|
if tmark.include?('.')
|
|
171
189
|
# bitclust#279: singleton methods (".") and module functions
|
|
172
190
|
# (".#"/"?.") keep a literal "." in full_name for display, but
|
|
@@ -185,12 +203,12 @@ module BitClust
|
|
|
185
203
|
|
|
186
204
|
def library_entries(db)
|
|
187
205
|
db.libraries.sort.map do |lib|
|
|
188
|
-
{
|
|
206
|
+
with_snippet({
|
|
189
207
|
name: lib.name,
|
|
190
208
|
full_name: lib.name,
|
|
191
209
|
type: 'library',
|
|
192
210
|
path: "library/#{encode(lib.name)}#{@suffix}",
|
|
193
|
-
}
|
|
211
|
+
}, lib)
|
|
194
212
|
end
|
|
195
213
|
end
|
|
196
214
|
|
|
@@ -201,12 +219,12 @@ module BitClust
|
|
|
201
219
|
# Prose pages are identified by a Japanese title, so index the title
|
|
202
220
|
# (for human queries) together with the slug (for identifier queries).
|
|
203
221
|
label = (title && !title.empty? && title != slug) ? "#{title} (#{slug})" : slug
|
|
204
|
-
{
|
|
222
|
+
with_snippet({
|
|
205
223
|
name: label,
|
|
206
224
|
full_name: label,
|
|
207
225
|
type: 'document',
|
|
208
226
|
path: "doc/#{encode(slug)}#{@suffix}",
|
|
209
|
-
}
|
|
227
|
+
}, doc)
|
|
210
228
|
end
|
|
211
229
|
end
|
|
212
230
|
|
|
@@ -272,12 +290,12 @@ module BitClust
|
|
|
272
290
|
|
|
273
291
|
def function_entries(fdb)
|
|
274
292
|
fdb.functions.sort.map do |func|
|
|
275
|
-
{
|
|
293
|
+
with_snippet({
|
|
276
294
|
name: func.name,
|
|
277
295
|
full_name: func.name,
|
|
278
296
|
type: 'function',
|
|
279
297
|
path: "function/#{func.name}#{@suffix}",
|
|
280
|
-
}
|
|
298
|
+
}, func)
|
|
281
299
|
end
|
|
282
300
|
end
|
|
283
301
|
|
data/lib/bitclust/searcher.rb
CHANGED
|
@@ -121,6 +121,14 @@ module BitClust
|
|
|
121
121
|
@parser.help
|
|
122
122
|
end
|
|
123
123
|
|
|
124
|
+
# irb プラグインなど組み込み利用向けの入口。argv のパターンを db から
|
|
125
|
+
# 検索し、結果を view(TerminalView)へ出力する。db が nil なら
|
|
126
|
+
# 既定の場所(~/.bitclust/config など)から探す
|
|
127
|
+
def run_query(db, argv, view)
|
|
128
|
+
@view = view
|
|
129
|
+
search_pattern db, argv
|
|
130
|
+
end
|
|
131
|
+
|
|
124
132
|
private
|
|
125
133
|
|
|
126
134
|
def server_mode_check(argv)
|
|
@@ -374,12 +382,14 @@ module BitClust
|
|
|
374
382
|
|
|
375
383
|
class TerminalView
|
|
376
384
|
|
|
377
|
-
|
|
385
|
+
# io を省略すると出力先は呼び出し時点の $stdout(従来挙動)
|
|
386
|
+
def initialize(compiler, opts, io: nil)
|
|
378
387
|
@compiler = compiler
|
|
379
388
|
@describe_all = opts[:describe_all]
|
|
380
389
|
@line = opts[:line]
|
|
381
390
|
@encoding = opts[:encoding]
|
|
382
391
|
@database = nil
|
|
392
|
+
@io = io
|
|
383
393
|
end
|
|
384
394
|
|
|
385
395
|
attr_accessor :database
|
|
@@ -546,7 +556,7 @@ module BitClust
|
|
|
546
556
|
end
|
|
547
557
|
|
|
548
558
|
def puts(*args)
|
|
549
|
-
|
|
559
|
+
(@io || $stdout).puts(*args.collect {|arg| convert(arg)})
|
|
550
560
|
end
|
|
551
561
|
|
|
552
562
|
def convert(string)
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
#
|
|
3
|
+
# bitclust/subcommands/rbssig_command.rb
|
|
4
|
+
#
|
|
5
|
+
# RBS 型シグネチャを DB のメソッドエントリに書き込む(rbs_sig property):
|
|
6
|
+
#
|
|
7
|
+
# bitclust rbssig --sig-root=RBS_CHECKOUT <dbpath>
|
|
8
|
+
# bitclust rbssig --sig-dir=DIR [--sig-dir=DIR ...] <dbpath>
|
|
9
|
+
#
|
|
10
|
+
# DB 構築(update)後・statichtml 前に実行する(methodsince と同じ位置)。
|
|
11
|
+
# --sig-root には対象 Ruby バージョンに同梱される rbs のチェックアウト
|
|
12
|
+
# (core/ と stdlib/ を含む)を渡す。表示は 4.0 以降のドキュメント専用
|
|
13
|
+
# なので、DB の version が 4.0 未満ならエラーにする。
|
|
14
|
+
|
|
15
|
+
require 'bitclust'
|
|
16
|
+
require 'bitclust/subcommand'
|
|
17
|
+
require 'bitclust/rbs_sig_importer'
|
|
18
|
+
require 'tmpdir'
|
|
19
|
+
require 'fileutils'
|
|
20
|
+
|
|
21
|
+
module BitClust
|
|
22
|
+
module Subcommands
|
|
23
|
+
class RbssigCommand < Subcommand
|
|
24
|
+
MINIMUM_VERSION = Gem::Version.new('4.0')
|
|
25
|
+
|
|
26
|
+
def initialize
|
|
27
|
+
super
|
|
28
|
+
@sig_root = nil
|
|
29
|
+
@sig_dirs = []
|
|
30
|
+
@dry_run = false
|
|
31
|
+
@parser.banner = "Usage: #{File.basename($0, '.*')} rbssig [options] <dbpath>"
|
|
32
|
+
@parser.on('--sig-root=PATH', 'ruby/rbs checkout containing core/ and stdlib/.') {|path|
|
|
33
|
+
@sig_root = path
|
|
34
|
+
}
|
|
35
|
+
@parser.on('--sig-dir=PATH', 'Directory of extra .rbs files (repeatable).') {|path|
|
|
36
|
+
@sig_dirs.push path
|
|
37
|
+
}
|
|
38
|
+
@parser.on('--dry-run', 'Compute and print stats without saving.') {
|
|
39
|
+
@dry_run = true
|
|
40
|
+
}
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# DB パスは位置引数で受けるのでグローバル --database は不要
|
|
44
|
+
def needs_database?
|
|
45
|
+
false
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def exec(argv, options)
|
|
49
|
+
error('no --sig-root or --sig-dir given') if @sig_root.nil? && @sig_dirs.empty?
|
|
50
|
+
error("wrong number of arguments (#{argv.size} for 1)") unless argv.size == 1
|
|
51
|
+
path = argv.first
|
|
52
|
+
version = check_version(path)
|
|
53
|
+
|
|
54
|
+
sig_root = @sig_root
|
|
55
|
+
importer = RbsSigImporter.new(
|
|
56
|
+
core_root: sig_root && File.join(sig_root, 'core'),
|
|
57
|
+
repository_root: sig_root && File.join(sig_root, 'stdlib'),
|
|
58
|
+
sig_dirs: @sig_dirs)
|
|
59
|
+
stats =
|
|
60
|
+
if @dry_run
|
|
61
|
+
apply_dry_run(importer, path)
|
|
62
|
+
else
|
|
63
|
+
importer.apply(MethodDatabase.new(path))
|
|
64
|
+
end
|
|
65
|
+
puts "#{File.basename(path)} (version #{version}): " \
|
|
66
|
+
"entries_updated=#{stats[:entries_updated]} sigs_matched=#{stats[:sigs_matched]} " \
|
|
67
|
+
"methods_missed=#{stats[:methods_missed]}"
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
private
|
|
71
|
+
|
|
72
|
+
# RBS シグネチャ表示は 4.0 以降のドキュメント専用。比較は
|
|
73
|
+
# display_typemark(nameutils.rb)と同じく Gem::Version で行う
|
|
74
|
+
# (文字列比較だと "10.0" が "4.0" より小さく見える)
|
|
75
|
+
def check_version(path)
|
|
76
|
+
version = MethodDatabase.new(path).propget('version') or
|
|
77
|
+
error("#{path}: no version property (not a bitclust database?)")
|
|
78
|
+
begin
|
|
79
|
+
if Gem::Version.new(version) < MINIMUM_VERSION
|
|
80
|
+
error("#{path}: version #{version} is before 4.0; RBS signatures are only for 4.0+ databases")
|
|
81
|
+
end
|
|
82
|
+
rescue ArgumentError
|
|
83
|
+
error("#{path}: malformed version property: #{version.inspect}")
|
|
84
|
+
end
|
|
85
|
+
version
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# --dry-run: 実 DB には書き込まず、複製に apply した統計だけを見せる
|
|
89
|
+
# (methodsince の apply_dry_run と同じ手口)
|
|
90
|
+
def apply_dry_run(importer, path)
|
|
91
|
+
Dir.mktmpdir do |tmp|
|
|
92
|
+
copy = File.join(tmp, 'db')
|
|
93
|
+
FileUtils.cp_r(path, copy)
|
|
94
|
+
importer.apply(MethodDatabase.new(copy))
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
@@ -20,7 +20,10 @@ module BitClust
|
|
|
20
20
|
@prepare = nil
|
|
21
21
|
@cleanup = nil
|
|
22
22
|
@purge = nil
|
|
23
|
-
|
|
23
|
+
# teeny は付けない。#%if (version == "V") や #%version V の等値ゲートは
|
|
24
|
+
# 文字列一致なので、teeny 付きの版名で DB を作ると doctree CI・
|
|
25
|
+
# 生成済みドキュメントとゲートの判定がずれる
|
|
26
|
+
@versions = ["3.3", "3.4", "4.0"]
|
|
24
27
|
@update = true
|
|
25
28
|
@parser.banner = "Usage: #{File.basename($0, '.*')} setup [options]"
|
|
26
29
|
@parser.on('--prepare', 'Prepare config file and checkout repository. Do not create database.') {
|
|
@@ -13,6 +13,7 @@ require 'bitclust/subcommand'
|
|
|
13
13
|
require 'bitclust/progress_bar'
|
|
14
14
|
require 'bitclust/silent_progress_bar'
|
|
15
15
|
require 'bitclust/search_index_generator'
|
|
16
|
+
require 'bitclust/markdown_exporter'
|
|
16
17
|
|
|
17
18
|
module BitClust
|
|
18
19
|
module Subcommands
|
|
@@ -125,6 +126,7 @@ module BitClust
|
|
|
125
126
|
@run_ruby_wasm = nil
|
|
126
127
|
@sitemap_baseurl = nil
|
|
127
128
|
@sitemap_paths = []
|
|
129
|
+
@markdown_output = false
|
|
128
130
|
@parser.banner = "Usage: #{File.basename($0, '.*')} statichtml [options]"
|
|
129
131
|
@parser.on('-o', '--outputdir=PATH', 'Output directory') do |path|
|
|
130
132
|
begin
|
|
@@ -170,6 +172,9 @@ module BitClust
|
|
|
170
172
|
@parser.on('--sitemap-baseurl=URL', 'Generate sitemap.xml under the output directory, with <loc> built from this base URL (e.g. https://docs.ruby-lang.org/ja/3.4/). Omit to skip sitemap.xml generation (default)') do |url|
|
|
171
173
|
@sitemap_baseurl = url
|
|
172
174
|
end
|
|
175
|
+
@parser.on('--markdown-output', 'Also write each page as Markdown (.md next to the .html), assembled from the preprocessed Markdown sources. Ignored for databases not created from a Markdown tree') do
|
|
176
|
+
@markdown_output = true
|
|
177
|
+
end
|
|
173
178
|
@parser.on('--no-stop-on-syntax-error', 'Do not stop on syntax error') do |boolean|
|
|
174
179
|
@stop_on_syntax_error = boolean
|
|
175
180
|
end
|
|
@@ -185,8 +190,10 @@ module BitClust
|
|
|
185
190
|
db = MethodDatabase.new(prefix.to_s)
|
|
186
191
|
fdb = FunctionDatabase.new(prefix.to_s)
|
|
187
192
|
manager = ScreenManager.new(@manager_config)
|
|
193
|
+
@markdown_exporter = MarkdownExporter.new(@urlmapper, @suffix) if @markdown_output
|
|
188
194
|
|
|
189
195
|
db.transaction do
|
|
196
|
+
warn_markdown_output_skipped(db, "the method database")
|
|
190
197
|
methods = {} #: Hash[String, Array[MethodEntry]]
|
|
191
198
|
db.methods.each_with_index do |entry, i|
|
|
192
199
|
next if entry.undefined?
|
|
@@ -203,6 +210,7 @@ module BitClust
|
|
|
203
210
|
end
|
|
204
211
|
|
|
205
212
|
fdb.transaction do
|
|
213
|
+
warn_markdown_output_skipped(fdb, "the function database")
|
|
206
214
|
create_html_entries("capi", fdb.functions, manager, fdb)
|
|
207
215
|
end
|
|
208
216
|
|
|
@@ -234,6 +242,7 @@ module BitClust
|
|
|
234
242
|
FileUtils.cp(@manager_config[:themedir] + "script.js",
|
|
235
243
|
@outputdir.to_s, :verbose => @verbose, :preserve => true)
|
|
236
244
|
copy_run_ruby_wasm_script if @run_ruby_wasm
|
|
245
|
+
copy_version_switcher_script
|
|
237
246
|
FileUtils.cp(@manager_config[:themedir] + @manager_config[:favicon_url],
|
|
238
247
|
@outputdir.to_s, :verbose => @verbose, :preserve => true)
|
|
239
248
|
Dir.mktmpdir do |tmpdir|
|
|
@@ -412,6 +421,19 @@ HERE
|
|
|
412
421
|
end
|
|
413
422
|
end
|
|
414
423
|
|
|
424
|
+
# Copy the version-switcher script. A themedir without it is
|
|
425
|
+
# tolerated: warn and skip instead of aborting the whole build.
|
|
426
|
+
def copy_version_switcher_script
|
|
427
|
+
src = @manager_config[:themedir] + "js" + "version_switcher.js"
|
|
428
|
+
unless src.file?
|
|
429
|
+
$stderr.puts "warning: #{src} not found; version switcher script not copied"
|
|
430
|
+
return
|
|
431
|
+
end
|
|
432
|
+
jsdir = @outputdir + "js"
|
|
433
|
+
FileUtils.mkdir_p(jsdir) unless jsdir.directory?
|
|
434
|
+
FileUtils.cp(src.to_s, jsdir.to_s, :verbose => @verbose, :preserve => true)
|
|
435
|
+
end
|
|
436
|
+
|
|
415
437
|
def create_html_file(entry, manager, outputdir, db)
|
|
416
438
|
e = entry.is_a?(Array) ? entry.sort.first : entry
|
|
417
439
|
case e.type_id
|
|
@@ -419,6 +441,7 @@ HERE
|
|
|
419
441
|
@urlmapper.bitclust_html_base = '..'
|
|
420
442
|
path = outputdir + e.type_id.to_s + html_filename(encodename_package(e.name), @suffix)
|
|
421
443
|
create_html_file_p(entry, manager, path, db)
|
|
444
|
+
create_markdown_file_p(e, path, db)
|
|
422
445
|
when :function
|
|
423
446
|
create_html_function_file(entry, manager, outputdir, db)
|
|
424
447
|
else
|
|
@@ -435,6 +458,11 @@ HERE
|
|
|
435
458
|
path = outputdir + e.type_id.to_s + encodename_package(e.klass.name) +
|
|
436
459
|
e.typechar + html_filename(encodename_package(name), @suffix)
|
|
437
460
|
create_html_file_p(entries, manager, path, db)
|
|
461
|
+
if markdown_export?(db)
|
|
462
|
+
create_file(markdown_path(path),
|
|
463
|
+
@markdown_exporter.method_page(method_name, entries.sort),
|
|
464
|
+
:verbose => @verbose)
|
|
465
|
+
end
|
|
438
466
|
end
|
|
439
467
|
|
|
440
468
|
def create_html_function_file(entry, manager, outputdir, db)
|
|
@@ -442,6 +470,7 @@ HERE
|
|
|
442
470
|
@urlmapper.bitclust_html_base = '..'
|
|
443
471
|
path = outputdir + entry.type_id.to_s + html_filename(entry.name, @suffix)
|
|
444
472
|
create_html_file_p(entry, manager, path, db)
|
|
473
|
+
create_markdown_file_p(entry, path, db)
|
|
445
474
|
end
|
|
446
475
|
|
|
447
476
|
def create_html_file_p(entry, manager, path, db)
|
|
@@ -453,6 +482,36 @@ HERE
|
|
|
453
482
|
record_sitemap_path(path)
|
|
454
483
|
end
|
|
455
484
|
|
|
485
|
+
# --markdown-output は Markdown ツリー由来の DB でのみ有効。
|
|
486
|
+
# ソースが md でない(凍結版 RD など)DB では何も出力しない
|
|
487
|
+
def markdown_export?(db)
|
|
488
|
+
@markdown_output && db.properties['source_format'] == 'markdown'
|
|
489
|
+
end
|
|
490
|
+
|
|
491
|
+
def warn_markdown_output_skipped(db, label)
|
|
492
|
+
return if !@markdown_output || db.properties['source_format'] == 'markdown'
|
|
493
|
+
$stderr.puts "warning: --markdown-output is ignored for #{label}: it was not created from a Markdown tree"
|
|
494
|
+
end
|
|
495
|
+
|
|
496
|
+
def create_markdown_file_p(entry, html_path, db)
|
|
497
|
+
return unless markdown_export?(db)
|
|
498
|
+
content =
|
|
499
|
+
case entry.type_id
|
|
500
|
+
when :library then @markdown_exporter.library_page(_ = entry)
|
|
501
|
+
when :class then @markdown_exporter.class_page(_ = entry)
|
|
502
|
+
when :doc then @markdown_exporter.doc_page(_ = entry)
|
|
503
|
+
when :function then @markdown_exporter.function_page(_ = entry)
|
|
504
|
+
else return
|
|
505
|
+
end
|
|
506
|
+
create_file(markdown_path(html_path), content, :verbose => @verbose)
|
|
507
|
+
end
|
|
508
|
+
|
|
509
|
+
def markdown_path(html_path)
|
|
510
|
+
s = html_path.to_s
|
|
511
|
+
s = s.end_with?(@suffix) ? s[0, s.length - @suffix.length].to_s : s
|
|
512
|
+
Pathname.new("#{s}.md")
|
|
513
|
+
end
|
|
514
|
+
|
|
456
515
|
def create_file(path, str, options = {})
|
|
457
516
|
verbose = options[:verbose]
|
|
458
517
|
$stderr.print("creating #{path} ...") if verbose
|
data/lib/bitclust/version.rb
CHANGED
data/lib/bitclust-irb.rb
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require 'test/unit'
|
|
3
|
+
require 'tmpdir'
|
|
4
|
+
require 'fileutils'
|
|
5
|
+
require 'stringio'
|
|
6
|
+
require 'bitclust'
|
|
7
|
+
require 'bitclust/methoddatabase'
|
|
8
|
+
require 'bitclust/searcher'
|
|
9
|
+
|
|
10
|
+
# bitclust-irb gem の irb コマンド(refe)。
|
|
11
|
+
#
|
|
12
|
+
# テストリスト:
|
|
13
|
+
# [x] TerminalView が io: に出力する(既定は従来どおり $stdout)
|
|
14
|
+
# [x] Irb.lookup がメソッドを検索して整形結果を io へ書く
|
|
15
|
+
# [x] Irb.lookup がクラスも引ける
|
|
16
|
+
# [x] 空のパターンは使い方を表示して例外にしない
|
|
17
|
+
# [x] 見つからないパターンはメッセージを io へ書いて例外にしない
|
|
18
|
+
# [x] require で IRB::Command::Base のサブクラスとして登録される
|
|
19
|
+
class TestBitClustIrbPlugin < Test::Unit::TestCase
|
|
20
|
+
FOO_MD = <<~'MD'
|
|
21
|
+
---
|
|
22
|
+
library: foo
|
|
23
|
+
---
|
|
24
|
+
# class Foo < Object
|
|
25
|
+
|
|
26
|
+
クラスの説明。
|
|
27
|
+
|
|
28
|
+
## Instance Methods
|
|
29
|
+
|
|
30
|
+
### def bar -> nil
|
|
31
|
+
|
|
32
|
+
bar の説明。
|
|
33
|
+
MD
|
|
34
|
+
|
|
35
|
+
def build_markdown_db(dir)
|
|
36
|
+
api = File.join(dir, 'manual', 'api')
|
|
37
|
+
FileUtils.mkdir_p(File.join(api, 'foo'))
|
|
38
|
+
File.write(File.join(api, 'foo.md'), "---\ntype: library\n---\nfoo ライブラリ。\n")
|
|
39
|
+
File.write(File.join(api, 'foo', 'Foo.md'), FOO_MD)
|
|
40
|
+
prefix = File.join(dir, 'db')
|
|
41
|
+
db = BitClust::MethodDatabase.new(prefix)
|
|
42
|
+
db.init
|
|
43
|
+
db.transaction do
|
|
44
|
+
db.propset('version', '3.4')
|
|
45
|
+
db.propset('encoding', 'utf-8')
|
|
46
|
+
end
|
|
47
|
+
db.transaction do
|
|
48
|
+
db.update_by_markdowntree(api)
|
|
49
|
+
end
|
|
50
|
+
BitClust::MethodDatabase.new(prefix)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def with_db(&block)
|
|
54
|
+
Dir.mktmpdir do |dir|
|
|
55
|
+
yield build_markdown_db(dir)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def test_terminal_view_writes_to_given_io
|
|
60
|
+
out = StringIO.new
|
|
61
|
+
view = BitClust::TerminalView.new(BitClust::Plain.new, {}, io: out)
|
|
62
|
+
view.send(:puts, 'hello')
|
|
63
|
+
assert_equal("hello\n", out.string)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def test_lookup_method
|
|
67
|
+
require 'bitclust/irb'
|
|
68
|
+
with_db do |db|
|
|
69
|
+
out = StringIO.new
|
|
70
|
+
BitClust::Irb.lookup('Foo#bar', db: db, io: out)
|
|
71
|
+
assert_match(/Foo#bar/, out.string)
|
|
72
|
+
assert_match(/bar の説明。/, out.string)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def test_lookup_class
|
|
77
|
+
require 'bitclust/irb'
|
|
78
|
+
with_db do |db|
|
|
79
|
+
out = StringIO.new
|
|
80
|
+
BitClust::Irb.lookup('Foo', db: db, io: out)
|
|
81
|
+
assert_match(/class Foo < Object/, out.string)
|
|
82
|
+
assert_match(/クラスの説明。/, out.string)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def test_lookup_empty_pattern_shows_usage
|
|
87
|
+
require 'bitclust/irb'
|
|
88
|
+
with_db do |db|
|
|
89
|
+
out = StringIO.new
|
|
90
|
+
assert_nothing_raised do
|
|
91
|
+
BitClust::Irb.lookup('', db: db, io: out)
|
|
92
|
+
end
|
|
93
|
+
assert_match(/refe/, out.string)
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def test_lookup_not_found_reports_instead_of_raising
|
|
98
|
+
require 'bitclust/irb'
|
|
99
|
+
with_db do |db|
|
|
100
|
+
out = StringIO.new
|
|
101
|
+
assert_nothing_raised do
|
|
102
|
+
BitClust::Irb.lookup('NoSuchClass#no_such_method', db: db, io: out)
|
|
103
|
+
end
|
|
104
|
+
assert_match(/no such method/, out.string)
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def test_command_is_registered_for_irb
|
|
109
|
+
begin
|
|
110
|
+
require 'irb/command'
|
|
111
|
+
rescue LoadError
|
|
112
|
+
omit 'irb >= 1.13 is not available'
|
|
113
|
+
end
|
|
114
|
+
require 'bitclust/irb'
|
|
115
|
+
assert(BitClust::Irb::RefeCommand < ::IRB::Command::Base)
|
|
116
|
+
assert_match(/るりま|リファレンス/, BitClust::Irb::RefeCommand.description)
|
|
117
|
+
end
|
|
118
|
+
end
|