Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Table caption #781

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ end
* list_item(text, list_type)
* paragraph(text)
* table(header, body)
* table_caption(content)
* table_row(content)
* table_cell(content, alignment, header)

Expand Down
18 changes: 16 additions & 2 deletions ext/redcarpet/html.c
Original file line number Diff line number Diff line change
Expand Up @@ -567,10 +567,13 @@ rndr_raw_html(struct buf *ob, const struct buf *text, void *opaque)
}

static void
rndr_table(struct buf *ob, const struct buf *header, const struct buf *body, void *opaque)
rndr_table(struct buf *ob, const struct buf *caption, const struct buf *header, const struct buf *body, void *opaque)
{
if (ob->size) bufputc(ob, '\n');
BUFPUTSL(ob, "<table><thead>\n");
BUFPUTSL(ob, "<table>\n");
if (caption)
bufput(ob, caption->data, caption->size);
BUFPUTSL(ob, "<thead>\n");
if (header)
bufput(ob, header->data, header->size);
BUFPUTSL(ob, "</thead><tbody>\n");
Expand All @@ -579,6 +582,15 @@ rndr_table(struct buf *ob, const struct buf *header, const struct buf *body, voi
BUFPUTSL(ob, "</tbody></table>\n");
}

static void
rndr_tablecaption(struct buf *ob, const struct buf *text, void *opaque)
{
BUFPUTSL(ob, "<caption>\n");
if (text)
bufput(ob, text->data, text->size);
BUFPUTSL(ob, "</caption>\n");
}

static void
rndr_tablerow(struct buf *ob, const struct buf *text, void *opaque)
{
Expand Down Expand Up @@ -774,6 +786,7 @@ sdhtml_toc_renderer(struct sd_callbacks *callbacks, struct html_renderopt *optio
NULL,
NULL,
NULL,
NULL,
rndr_footnotes,
rndr_footnote_def,

Expand Down Expand Up @@ -819,6 +832,7 @@ sdhtml_renderer(struct sd_callbacks *callbacks, struct html_renderopt *options,
rndr_listitem,
rndr_paragraph,
rndr_table,
rndr_tablecaption,
rndr_tablerow,
rndr_tablecell,
rndr_footnotes,
Expand Down
56 changes: 53 additions & 3 deletions ext/redcarpet/markdown.c
Original file line number Diff line number Diff line change
Expand Up @@ -2387,6 +2387,48 @@ parse_table_header(
return under_end + 1;
}

static size_t
parse_table_caption(
struct buf *ob,
struct sd_markdown *rndr,
uint8_t *data,
size_t size)
{
size_t i = 0, caption_start, caption_end;
struct buf *caption_work = 0;

while (i < size && (_isspace(data[i]) || data[i] == '|'))
i++;

if (i == size || data[i] != '#')
return 0;

while (i < size && (_isspace(data[i]) || data[i] == '#'))
i++;

caption_start = i;

while (i < size && data[i] != '\n')
i++;

caption_end = i + 1;

if (i == size)
return 0;

while (i > 0 && (_isspace(data[i - 1]) || data[i - 1] == '|'))
i--;

caption_work = rndr_newbuf(rndr, BUFFER_SPAN);

bufput(caption_work, data + caption_start, i - caption_start);
rndr->cb.table_caption(ob, caption_work, rndr->opaque);

rndr_popbuf(rndr, BUFFER_SPAN);

return caption_end;
}

static size_t
parse_table(
struct buf *ob,
Expand All @@ -2395,18 +2437,25 @@ parse_table(
size_t size)
{
size_t i;
size_t caption_len;

struct buf *caption_work = 0;
struct buf *header_work = 0;
struct buf *body_work = 0;

size_t columns;
int *col_data = NULL;

caption_work = rndr_newbuf(rndr, BUFFER_SPAN);
header_work = rndr_newbuf(rndr, BUFFER_SPAN);
body_work = rndr_newbuf(rndr, BUFFER_BLOCK);

i = parse_table_header(header_work, rndr, data, size, &columns, &col_data);
if (i > 0) {
caption_len = parse_table_caption(caption_work, rndr, data, size);
i = parse_table_header(header_work, rndr, data + caption_len, size - caption_len, &columns, &col_data);

if (i > 0)
{
i += caption_len;

while (i < size) {
size_t row_start;
Expand Down Expand Up @@ -2436,11 +2485,12 @@ parse_table(
}

if (rndr->cb.table)
rndr->cb.table(ob, header_work, body_work, rndr->opaque);
rndr->cb.table(ob, caption_work, header_work, body_work, rndr->opaque);
}

free(col_data);
rndr_popbuf(rndr, BUFFER_SPAN);
rndr_popbuf(rndr, BUFFER_SPAN);
rndr_popbuf(rndr, BUFFER_BLOCK);
return i;
}
Expand Down
3 changes: 2 additions & 1 deletion ext/redcarpet/markdown.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ struct sd_callbacks {
void (*list)(struct buf *ob, const struct buf *text, int flags, void *opaque);
void (*listitem)(struct buf *ob, const struct buf *text, int flags, void *opaque);
void (*paragraph)(struct buf *ob, const struct buf *text, void *opaque);
void (*table)(struct buf *ob, const struct buf *header, const struct buf *body, void *opaque);
void (*table)(struct buf *ob, const struct buf *caption, const struct buf *header, const struct buf *body, void *opaque);
void (*table_caption)(struct buf *ob, const struct buf *text, void *opaque);
void (*table_row)(struct buf *ob, const struct buf *text, void *opaque);
void (*table_cell)(struct buf *ob, const struct buf *text, int flags, void *opaque);
void (*footnotes)(struct buf *ob, const struct buf *text, void *opaque);
Expand Down
15 changes: 11 additions & 4 deletions ext/redcarpet/rc_render.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,15 @@ rndr_paragraph(struct buf *ob, const struct buf *text, void *opaque)
}

static void
rndr_table(struct buf *ob, const struct buf *header, const struct buf *body, void *opaque)
rndr_table(struct buf *ob, const struct buf *caption, const struct buf *header, const struct buf *body, void *opaque)
{
BLOCK_CALLBACK("table", 2, buf2str(header), buf2str(body));
BLOCK_CALLBACK("table", 3, buf2str(caption), buf2str(header), buf2str(body));
}

static void
rndr_tablecaption(struct buf *ob, const struct buf *text, void *opaque)
{
BLOCK_CALLBACK("table_caption", 1, buf2str(text));
}

static void
Expand Down Expand Up @@ -320,6 +326,7 @@ static struct sd_callbacks rb_redcarpet_callbacks = {
rndr_listitem,
rndr_paragraph,
rndr_table,
rndr_tablecaption,
rndr_tablerow,
rndr_tablecell,
rndr_footnotes,
Expand Down Expand Up @@ -358,6 +365,7 @@ static const char *rb_redcarpet_method_names[] = {
"list_item",
"paragraph",
"table",
"table_caption",
"table_row",
"table_cell",
"footnotes",
Expand All @@ -383,8 +391,7 @@ static const char *rb_redcarpet_method_names[] = {
"normal_text",

"doc_header",
"doc_footer"
};
"doc_footer"};

static const size_t rb_redcarpet_method_count = sizeof(rb_redcarpet_method_names)/sizeof(char *);

Expand Down
8 changes: 6 additions & 2 deletions lib/redcarpet/render_strip.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,12 @@ def header(text, header_level)
text + "\n"
end

def table(header, body)
"#{header}#{body}"
def table(caption, header, body)
"#{caption}#{header}#{body}"
end

def table_caption(content)
content + "\n"
end

def table_row(content)
Expand Down
15 changes: 15 additions & 0 deletions test/stripdown_render_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,21 @@ def test_tables
assert_equal expected, output
end

def test_tables_with_caption
markdown = "| # Caption Goes Here |\n" \
"| Left-Aligned | Centre Aligned | Right Aligned |\n" \
"| :------------ |:---------------:| -----:|\n" \
"| col 3 is | some wordy text | $1600 |\n" \
"| col 2 is | centered | $12 |"
expected = "Caption Goes Here\n" \
"Left-Aligned\tCentre Aligned\tRight Aligned\t\n" \
"col 3 is\tsome wordy text\t$1600\t\n" \
"col 2 is\tcentered\t$12\t"
output = render(markdown, with: [:tables])

assert_equal expected, output
end

def test_highlight
markdown = "==Hello world!=="
expected = "Hello world!"
Expand Down