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:/]]', '関数一覧'])