Skip to content

Commit

Permalink
Merge pull request #271 from brief/footnotes locally
Browse files Browse the repository at this point in the history
Add PHP-Markdown style footnotes support

Conflicts:
	test/html_render_test.rb
  • Loading branch information
robin850 committed Jul 21, 2013
2 parents 8ad956d + 40923d2 commit f2ad99f
Show file tree
Hide file tree
Showing 9 changed files with 437 additions and 4 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -20,6 +20,8 @@

* Ensure nested code spans put in emphasis work correctly *Robin Dupret*

* Add optional footnotes support *Ben Dolman, Adam Florin, microjo, brief*

## Version 2.3.0

* Add a `:disable_indented_code_blocks` option *Dmitriy Kiriyenko*
Expand Down
2 changes: 2 additions & 0 deletions README.markdown
Expand Up @@ -101,6 +101,8 @@ would not be a valid header.
* `:highlight`: parse highlights.
`This is ==highlighted==`. It looks like this: `<mark>highlighted</mark>`

* `:footnotes`: parse footnotes, PHP-Markdown style. A footnote works very much like a reference-style link: it consists of a marker next to the text (e.g. `This is a sentence.[^1]`) and a footnote definition on its own line anywhere within the document (e.g. `[^1]: This is a footnote.`).

Example:

~~~~~ ruby
Expand Down
60 changes: 60 additions & 0 deletions ext/redcarpet/html.c
Expand Up @@ -526,6 +526,60 @@ rndr_normal_text(struct buf *ob, const struct buf *text, void *opaque)
escape_html(ob, text->data, text->size);
}

static void
rndr_footnotes(struct buf *ob, const struct buf *text, void *opaque)
{
struct html_renderopt *options = opaque;

if (ob->size) bufputc(ob, '\n');

BUFPUTSL(ob, "<div class=\"footnotes\">\n");
bufputs(ob, USE_XHTML(options) ? "<hr/>\n" : "<hr>\n");
BUFPUTSL(ob, "<ol>\n");

if (text)
bufput(ob, text->data, text->size);

BUFPUTSL(ob, "\n</ol>\n</div>\n");
}

static void
rndr_footnote_def(struct buf *ob, const struct buf *text, unsigned int num, void *opaque)
{
size_t i = 0;
int pfound = 0;

/* insert anchor at the end of first paragraph block */
if (text) {
while ((i+3) < text->size) {
if (text->data[i++] != '<') continue;
if (text->data[i++] != '/') continue;
if (text->data[i++] != 'p' && text->data[i] != 'P') continue;
if (text->data[i] != '>') continue;
i -= 3;
pfound = 1;
break;
}
}

bufprintf(ob, "\n<li id=\"fn%d\">\n", num);
if (pfound) {
bufput(ob, text->data, i);
bufprintf(ob, "&nbsp;<a href=\"#fnref%d\" rev=\"footnote\">&#8617;</a>", num);
bufput(ob, text->data + i, text->size - i);
} else if (text) {
bufput(ob, text->data, text->size);
}
BUFPUTSL(ob, "</li>\n");
}

static int
rndr_footnote_ref(struct buf *ob, unsigned int num, void *opaque)
{
bufprintf(ob, "<sup id=\"fnref%d\"><a href=\"#fn%d\" rel=\"footnote\">%d</a></sup>", num, num, num);
return 1;
}

static void
toc_header(struct buf *ob, const struct buf *text, int level, void *opaque)
{
Expand Down Expand Up @@ -594,6 +648,8 @@ sdhtml_toc_renderer(struct sd_callbacks *callbacks, struct html_renderopt *optio
NULL,
NULL,
NULL,
rndr_footnotes,
rndr_footnote_def,

NULL,
rndr_codespan,
Expand All @@ -608,6 +664,7 @@ sdhtml_toc_renderer(struct sd_callbacks *callbacks, struct html_renderopt *optio
rndr_triple_emphasis,
rndr_strikethrough,
rndr_superscript,
rndr_footnote_ref,

NULL,
NULL,
Expand Down Expand Up @@ -637,6 +694,8 @@ sdhtml_renderer(struct sd_callbacks *callbacks, struct html_renderopt *options,
rndr_table,
rndr_tablerow,
rndr_tablecell,
rndr_footnotes,
rndr_footnote_def,

rndr_autolink,
rndr_codespan,
Expand All @@ -651,6 +710,7 @@ sdhtml_renderer(struct sd_callbacks *callbacks, struct html_renderopt *options,
rndr_triple_emphasis,
rndr_strikethrough,
rndr_superscript,
rndr_footnote_ref,

NULL,
rndr_normal_text,
Expand Down

0 comments on commit f2ad99f

Please sign in to comment.