From 92b6e135f3f8a3b0a6a04d9f3dcabbf962b47acf Mon Sep 17 00:00:00 2001 From: Stan Lo Date: Sun, 4 Jan 2026 13:36:49 +0000 Subject: [PATCH] Fix Markdown strikethrough (`~~text~~`) not rendering in HTML output The Markdown parser correctly parsed `~~text~~` syntax but the AttributeManager did not recognize the resulting formats for HTML conversion: - Single words: `~~word~~` -> `~word~` (not registered as word pair) - Multi-word: `~~words here~~` -> `words here` (tag not registered) Add support for strikethrough formatting: - Register `~` as word pair for `:STRIKE` attribute - Register ``, `` HTML tags for `:STRIKE` - Add `:STRIKE` -> `` tag mapping in `ToHtml` All strikethrough input formats now render as `text` in HTML. --- lib/rdoc/markup/attribute_manager.rb | 3 ++ lib/rdoc/markup/to_html.rb | 7 ++-- test/rdoc/markup/attribute_manager_test.rb | 43 ++++++++++++++++++++-- test/rdoc/rdoc_markdown_test.rb | 28 ++++++++++++++ 4 files changed, 75 insertions(+), 6 deletions(-) diff --git a/lib/rdoc/markup/attribute_manager.rb b/lib/rdoc/markup/attribute_manager.rb index e21560ff08..8de2050670 100644 --- a/lib/rdoc/markup/attribute_manager.rb +++ b/lib/rdoc/markup/attribute_manager.rb @@ -89,12 +89,15 @@ def initialize add_word_pair "*", "*", :BOLD, true add_word_pair "_", "_", :EM, true add_word_pair "+", "+", :TT, true + add_word_pair "~", "~", :STRIKE, true add_html "em", :EM, true add_html "i", :EM, true add_html "b", :BOLD, true add_html "tt", :TT, true add_html "code", :TT, true + add_html "s", :STRIKE, true + add_html "del", :STRIKE, true @word_pair_chars = @matching_word_pairs.keys.join diff --git a/lib/rdoc/markup/to_html.rb b/lib/rdoc/markup/to_html.rb index 22b2236cdd..e496c8c74e 100644 --- a/lib/rdoc/markup/to_html.rb +++ b/lib/rdoc/markup/to_html.rb @@ -419,9 +419,10 @@ def html_list_name(list_type, open_tag) # Maps attributes to HTML tags def init_tags - add_tag :BOLD, "", "" - add_tag :TT, "", "" - add_tag :EM, "", "" + add_tag :BOLD, "", "" + add_tag :TT, "", "" + add_tag :EM, "", "" + add_tag :STRIKE, "", "" end ## diff --git a/test/rdoc/markup/attribute_manager_test.rb b/test/rdoc/markup/attribute_manager_test.rb index 0e267aabf4..a82d500d9d 100644 --- a/test/rdoc/markup/attribute_manager_test.rb +++ b/test/rdoc/markup/attribute_manager_test.rb @@ -17,6 +17,9 @@ def setup @em_on = @am.changed_attribute_by_name([], [:EM]) @em_off = @am.changed_attribute_by_name([:EM], []) + @strike_on = @am.changed_attribute_by_name([], [:STRIKE]) + @strike_off = @am.changed_attribute_by_name([:STRIKE], []) + @bold_em_on = @am.changed_attribute_by_name([], [:BOLD] | [:EM]) @bold_em_off = @am.changed_attribute_by_name([:BOLD] | [:EM], []) @@ -54,7 +57,7 @@ def test_adding def test_add_html_tag @am.add_html("Test", :TEST) tags = @am.html_tags - assert_equal(6, tags.size) + assert_equal(8, tags.size) assert(tags.has_key?("test")) end @@ -164,6 +167,40 @@ def test_bold_html_escaped assert_equal ['cat dog'], @am.flow('cat \dog') end + def test_strike + assert_equal [@strike_on, 'strike', @strike_off], + @am.flow("~strike~") + + assert_equal [@strike_on, 'Strike:', @strike_off], + @am.flow("~Strike:~") + + assert_equal ["cat ", @strike_on, "and", @strike_off, " dog"], + @am.flow("cat ~and~ dog") + end + + def test_strike_html_escaped + assert_equal ['cat dog'], @am.flow('cat \dog') + assert_equal ['cat dog'], @am.flow('cat \dog') + end + + def test_html_like_strike + assert_equal ["cat ", @strike_on, "dog", @strike_off], + @am.flow("cat dog") + end + + def test_html_like_strike_del + assert_equal ["cat ", @strike_on, "dog", @strike_off], + @am.flow("cat dog") + end + + def test_convert_attrs_ignores_strike_inside_code + assert_equal 'foo ~strike~ bar', output('foo ~strike~ bar') + end + + def test_convert_attrs_ignores_strike_inside_tt + assert_equal 'foo ~strike~ bar', output('foo ~strike~ bar') + end + def test_combined assert_equal(["cat ", @em_on, "and", @em_off, " ", @bold_on, "dog", @bold_off], @am.flow("cat _and_ *dog*")) @@ -331,13 +368,13 @@ def test_html_like_teletype_em_bold_SGML def test_initial_html html_tags = @am.html_tags assert html_tags.is_a?(Hash) - assert_equal(5, html_tags.size) + assert_equal(7, html_tags.size) end def test_initial_word_pairs word_pairs = @am.matching_word_pairs assert word_pairs.is_a?(Hash) - assert_equal(3, word_pairs.size) + assert_equal(4, word_pairs.size) end def test_mask_protected_sequence diff --git a/test/rdoc/rdoc_markdown_test.rb b/test/rdoc/rdoc_markdown_test.rb index 82ea9f87e0..6fe07425a5 100644 --- a/test/rdoc/rdoc_markdown_test.rb +++ b/test/rdoc/rdoc_markdown_test.rb @@ -1114,6 +1114,34 @@ def test_parse_strike_tilde_no assert_equal expected, doc end + def test_strike_to_html_single_word + doc = parse "This is ~~strikethrough~~ text.\n" + html = @to_html.convert doc + + assert_match %r{strikethrough}, html + end + + def test_strike_to_html_multiple_words + doc = parse "This is ~~multiple words~~ text.\n" + html = @to_html.convert doc + + assert_match %r{multiple words}, html + end + + def test_strike_to_html_with_s_tag + doc = parse "This has deleted text.\n" + html = @to_html.convert doc + + assert_match %r{deleted}, html + end + + def test_strike_to_html_with_del_tag + doc = parse "This has deleted text.\n" + html = @to_html.convert doc + + assert_match %r{deleted}, html + end + def test_parse_style @parser.css = true