diff --git a/lib/bitclust/rdcompiler.rb b/lib/bitclust/rdcompiler.rb
index 23a070f..0b88930 100644
--- a/lib/bitclust/rdcompiler.rb
+++ b/lib/bitclust/rdcompiler.rb
@@ -500,7 +500,7 @@ def bracket_link(link, label = nil, frag = nil)
when 'c'
protect(link) { class_link(arg, label, frag) }
when 'm'
- protect(link) { method_link(complete_spec(arg), label || arg, frag) }
+ protect(link) { method_link(complete_spec(arg), label || display_spec(arg), frag) }
when 'f'
protect(link) {
case arg
@@ -554,7 +554,9 @@ def reference_link(arg)
when 'c'
title, t, id = name, ClassEntry.type_id.to_s, name
when 'm'
- title, t, id = name, MethodEntry.type_id.to_s, name
+ # 表示側(title)のみ display_spec で畳む。id は refs テーブルの
+ # キーなので記載どおり(bitclust#282)
+ title, t, id = display_spec(name), MethodEntry.type_id.to_s, name
when 'd'
title, t, id = @option[:database].get_doc(name).title, DocEntry.type_id.to_s, name
else
@@ -654,6 +656,19 @@ def complete_spec(spec0)
end
end
+ # bitclust#282: [[m:...]] のデフォルトラベル(参照の記載文字列)は表示
+ # 専用なので、module function の ".#" は DB バージョンが 4.0 以降なら
+ # "?." で表示する(#250/#277 の display_typemark と同じ選択規則。
+ # Markdown ソースの [m:Kernel?.x] も inline 復元時に ".#" へ正規化されて
+ # ここに来るため、どちらの表記で書かれていても見出し表記と一致する)。
+ # spec・URL・アンカーキーは不変。明示ラベル(label 引数)には触れない
+ def display_spec(spec)
+ return spec unless spec.include?('.#')
+ db = @option[:database]
+ version = db ? db.propget('version') : nil
+ spec.sub('.#', NameUtils.display_typemark('.#', version))
+ end
+
def seems_code(text)
# FIXME
escape_html(text)
diff --git a/sig/bitclust/rdcompiler.rbs b/sig/bitclust/rdcompiler.rbs
index fde70e7..45357d7 100644
--- a/sig/bitclust/rdcompiler.rbs
+++ b/sig/bitclust/rdcompiler.rbs
@@ -168,6 +168,8 @@ module BitClust
def complete_spec: (String spec0) -> String
+ def display_spec: (String spec) -> String
+
def seems_code: (String text) -> String
def string: (String str) -> void
diff --git a/test/test_mdcompiler.rb b/test/test_mdcompiler.rb
index c89a6c9..c68ddf5 100644
--- a/test/test_mdcompiler.rb
+++ b/test/test_mdcompiler.rb
@@ -1014,6 +1014,23 @@ def test_no_warning_for_fenced_code_block
err = capture_stderr { @md.compile("```ruby\n x = 1\n```\n") }
assert_equal('', err)
end
+
+ def test_md_ref_module_function_display_typemark
+ # bitclust#282: Markdown ソースの [m:Kernel?.at_exit] は inline 復元時に
+ # ".#" へ正規化される(RRD の MethodSpec 互換)が、表示ラベルは DB
+ # バージョンが 4.0 以降なら "?." に戻す。3.4 以前は ".#" のまま。
+ # どちらの表記で書かれていても、ページの見出し表記と常に一致する
+ src = "### def m(v) -> String\n\n" \
+ "[m:Kernel?.at_exit] と [m:Kernel.#at_exit] を参照。\n"
+ { '3.4' => 'Kernel.#at_exit', '4.0' => 'Kernel?.at_exit' }.each do |version, label|
+ db = BitClust::MethodDatabase.dummy("version" => version)
+ md = BitClust::MDCompiler.new(@u, 1, { :database => db })
+ html = compile_method(md, src)
+ assert_equal(2, html.scan(">#{label}").size,
+ "version=#{version}\n#{html}")
+ end
+ end
+
end
# lang 指定付きコードブロックのハイライト(ruby は Ripper ベースの
diff --git a/test/test_rdcompiler.rb b/test/test_rdcompiler.rb
index ae074c6..17b462f 100644
--- a/test/test_rdcompiler.rb
+++ b/test/test_rdcompiler.rb
@@ -938,6 +938,45 @@ def test_bracket_link(data)
assert_equal(expected, @c.send(:compile_text, target), target)
end
+ # bitclust#282: 参照のデフォルトラベル(記載どおりの spec 文字列)も
+ # 表示専用なので、module function の ".#" は DB バージョンが 4.0 以降
+ # なら "?." で表示する(#250/#277 の display_typemark と同じ選択規則)。
+ # URL・アンカー(識別子)は変えない。
+ data("pre-4.0 keeps .#" => ['3.4', 'Kernel.#at_exit'],
+ "4.0 shows ?." => ['4.0', 'Kernel?.at_exit'],
+ "4.1 shows ?." => ['4.1', 'Kernel?.at_exit'])
+ def test_bracket_link_module_function_display(data)
+ version, label = data
+ db = BitClust::MethodDatabase.dummy("version" => version)
+ c = BitClust::RDCompiler.new(@u, 1, {:database => db})
+ assert_equal(%Q(#{label}),
+ c.send(:compile_text, '[[m:Kernel.#at_exit]]'))
+ end
+
+ def test_reference_link_module_function_title_display
+ # refs テーブルに見出しがある場合の「spec/見出し」ラベルの spec 側も
+ # 4.0 以降は "?." 表示にする(doctree に現時点で用例は無い理論エッジ
+ # だが、デフォルトラベルと同じ選択規則で一貫させる)
+ refs = Object.new
+ def refs.[](type, id, frag) = '深掘り'
+ db = BitClust::MethodDatabase.dummy("version" => "4.0")
+ stub(db).refs { refs }
+ c = BitClust::RDCompiler.new(@u, 1, {:database => db})
+ assert_equal(%Q(Kernel?.at_exit/深掘り),
+ c.send(:compile_text, '[[ref:m:Kernel.#at_exit#frag]]'))
+ end
+
+ def test_bracket_link_other_typemarks_unchanged_at_4_0
+ db = BitClust::MethodDatabase.dummy("version" => "4.0")
+ c = BitClust::RDCompiler.new(@u, 1, {:database => db})
+ assert_equal('String.new',
+ c.send(:compile_text, '[[m:String.new]]'))
+ assert_equal('String#dump',
+ c.send(:compile_text, '[[m:String#dump]]'))
+ assert_equal('$~',
+ c.send(:compile_text, '[[m:$~]]'))
+ end
+
data("library root" => ['[[lib:/]]', 'ライブラリ一覧'],
"builtin library" => ['[[lib:_builtin]]', '組み込みライブラリ'],
"C API root" => ['[[f:/]]', '関数一覧'])