diff --git a/CHANGELOG.md b/CHANGELOG.md index f551d0cd..19385029 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +* Properly provide a third argument to the `table_cell` callback indicating + whether the current cell is part of the header or not. + + The previous implementation with two parameters is still supported. + + Fixes #604, Refs #605. + + *Mark Lambley* + * Fix anchor generation on titles with ampersands. Fixes #696. diff --git a/README.markdown b/README.markdown index 7775d57e..b9764ba0 100644 --- a/README.markdown +++ b/README.markdown @@ -258,7 +258,7 @@ end * paragraph(text) * table(header, body) * table_row(content) -* table_cell(content, alignment) +* table_cell(content, alignment, header) ### Span-level calls diff --git a/ext/redcarpet/rc_render.c b/ext/redcarpet/rc_render.c index 26568ac7..e527c1c8 100644 --- a/ext/redcarpet/rc_render.c +++ b/ext/redcarpet/rc_render.c @@ -113,9 +113,10 @@ rndr_tablerow(struct buf *ob, const struct buf *text, void *opaque) static void rndr_tablecell(struct buf *ob, const struct buf *text, int align, void *opaque) { - VALUE rb_align; + VALUE rb_align, rb_header; + VALUE rb_callback, rb_callback_arity; - switch (align) { + switch (align & MKD_TABLE_ALIGNMASK) { case MKD_TABLE_ALIGN_L: rb_align = CSTR2SYM("left"); break; @@ -133,7 +134,25 @@ rndr_tablecell(struct buf *ob, const struct buf *text, int align, void *opaque) break; } - BLOCK_CALLBACK("table_cell", 2, buf2str(text), rb_align); + if (align & MKD_TABLE_HEADER) { + rb_header = Qtrue; + } else { + rb_header = Qfalse; + } + + struct redcarpet_renderopt *opt = opaque; + + rb_callback = rb_funcall(opt->self, rb_intern("method"), 1, CSTR2SYM("table_cell")); + + rb_callback_arity = rb_funcall(rb_callback, rb_intern("arity"), 0); + + /* For backward compatibility, let's ensure that the erasure with + only two parameters is still supported. */ + if (FIX2SHORT(rb_callback_arity) == 3) { + BLOCK_CALLBACK("table_cell", 3, buf2str(text), rb_align, rb_header); + } else { + BLOCK_CALLBACK("table_cell", 2, buf2str(text), rb_align); + } } static void diff --git a/test/custom_render_test.rb b/test/custom_render_test.rb index 87c9f07c..d86ed353 100644 --- a/test/custom_render_test.rb +++ b/test/custom_render_test.rb @@ -64,4 +64,43 @@ def test_base_render_without_quote_callback assert_equal "", parser.render(%(a "quote")) end + + def test_table_cell_callback_having_either_two_or_three_args + two = Class.new(Redcarpet::Render::HTML) do + def table_cell(content, alignment) + %(#{content}) + end + end + + three = Class.new(Redcarpet::Render::HTML) do + def table_cell(content, alignment, header) + tag = header ? "th" : "td" + + %(<#{tag}>#{content}) + end + end + + markdown = <<-Md.chomp.strip_heredoc + | A | B | + |---|---| + | C | D | + Md + + first_parser = Redcarpet::Markdown.new(two.new, tables: true) + second_parser = Redcarpet::Markdown.new(three.new, tables: true) + + first_output = first_parser.render(markdown) + second_output = second_parser.render(markdown) + + assert { first_output.include?("A") } + assert { first_output.include?("B") } + + assert { second_output.include?("A") } + assert { second_output.include?("B") } + + [first_output, second_output].each do |output| + assert { output.include?("C") } + assert { output.include?("D") } + end + end end