pragdave/earmark — pull request #6 by mattly (2014-08-17 03:35:40+00:00)
Title: Footnotes

Hey Dave,

So this isn't really the ideal or even a complete implementation, but I'm going to be really busy over the next weeks and wanted to at least get something working and up and hopefully open a conversation about it. I'm working on a little static site generator in Elixir over at [mattly/tacosmith](/mattly/tacosmith) and for my own needs would like footnote support in a renderer. I figured hacking on a parser written in a functional language I was relatively new to would be a good way to level up my knowledge of both FP and Elixir, and I was right! :)

I'm basing the syntax and markup implementations on [MultiMarkdown](http://fletcher.github.io/MultiMarkdown-4/footnotes) and [Pandoc](http://johnmacfarlane.net/pandoc/README.html#footnotes); IMO they're not *ideal* but they are as close to a standard as you'll find.

It does:
1. Support multi-line single-paragraph footnote definitions.
2. Output the footnote list at the end of the text.
3. Order the footnotes in the list based on the appearances of the links to them in the body text.
4. Only output footnote definitions whose links appear in the text.

Still missing:
1. it doesn't support: `inline footnotes[^those without a separate definition]`
2. multi-paragraph footnotes
3. Scanning for footnote links in anything block except a Paragraph. Lists and BlockQuotes I think should be included, and possibly other blocks.

None of these I think will be terribly hard, I just haven't done them yet.

I'd like to:
1. Be able to specify a generator for the footnote ids by number, so that "1" could output f.e. "page-foo-fn:1" instead of "fn:1", so that footnotes from multiple texts could appear on the same html page without clashing.
2. For that matter, specify a starting footnote number greater than "1", presuming the rendered text will be combined with other rendered text.
3. Specify alternate templates for the renderer to use different (more semantic) markup for both the footnote links and the footnote list.

But these things are generally without precedent in the markdown renderers I've looked at and also nice-to-haves.

I need to get the order of the footnotes correct in order to render the links with their numbers, this required either a) looking for the links beforehand, b) passing and updating the context around as the renderer and Inline.convert_each do their thing, or c) using placeholder values for the rendered links and updating them later. I went with a, figuring it's the simplest approach. There's room for some optimization here, but it would require passing the Options struct into the Parser, or moving that scanning pass somewhere else, and nowhere seemed obvious.

Anyway, I'd love to hear what you think, if this looks good to you, I can keep going on the other missing items and get started on the documentation as well.