Skip to content

Commit

Permalink
Provide the header bit in the table_cell callback
Browse files Browse the repository at this point in the history
As the same callback is used to render header and body cells, there
is an extra bit needed to check in which one we are currently
rendering the content.

Fixes #604.
  • Loading branch information
mark-lambley-simpro authored and robin850 committed Feb 28, 2021
1 parent 65511c5 commit 27dfb2a
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 4 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
2 changes: 1 addition & 1 deletion README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
25 changes: 22 additions & 3 deletions ext/redcarpet/rc_render.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand Down
39 changes: 39 additions & 0 deletions test/custom_render_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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)
%(<td>#{content}</td>)
end
end

three = Class.new(Redcarpet::Render::HTML) do
def table_cell(content, alignment, header)
tag = header ? "th" : "td"

%(<#{tag}>#{content}</#{tag}>)
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?("<td>A</td>") }
assert { first_output.include?("<td>B</td>") }

assert { second_output.include?("<th>A</th>") }
assert { second_output.include?("<th>B</th>") }

[first_output, second_output].each do |output|
assert { output.include?("<td>C</td>") }
assert { output.include?("<td>D</td>") }
end
end
end

0 comments on commit 27dfb2a

Please sign in to comment.