Pagedown: Strange behaviors of block elements in paged-footnotes

Created on 14 Dec 2019  路  4Comments  路  Source: rstudio/pagedown

For example, a footnote with bullet list in html is rendered in the body, and leaves the empty footnote at the bottom of the page.
A footnote with bullet list in markdown is collapsed.

They work fine when paged-footnotes: false.

Source Rmd

````md

output: pagedown::html_paged

paged-footnotes: true

A sentence.[^html]

Another sentence.[^md]

- b

````

Output

image

Most helpful comment

paged-footnotes: true only supports inline footnotes.
The reason comes the W3C CSS Generated Content for Paged Media Module Working Draft. As you can see here, these specifications are only defined for inline elements. There is no support for block elements like lists.

In pagedown, paged-footnotes: true involves this Pandoc filter https://github.com/rstudio/pagedown/blob/master/inst/resources/lua/footnotes.lua which turns block elements into inline elements. The main function used in this filter is pandoc.utils.blocks_to_inlines(). The second part of paged-footnotes: true is this Paged.js handler: https://github.com/rstudio/pagedown/blob/d96b5e210a34b493b0a4d1ea8e02983cb0bee912/inst/resources/js/hooks.js#L208-L321

In the example, the markdown footnote is collapsed because the list (which is a block element) is turned into an inline span (this is the job of the Pandoc filter).

For the HTML footnote, the reason is different. Pandoc parses this markup as raw HTML as you can see in the JSON serialization of the AST:

{"blocks":[{"t":"Para","c":[{"t":"Str","c":"A"},{"t":"Space"},{"t":"Str","c":"sentence."},{"t":"Span","c":[["fn1",["footnote"],[["data-pagedown-footnote-number","1"],["style","white-space: pre-line;"]]],[{"t":"RawInline","c":["html","<ul>"]},{"t":"Str","c":"\n"},{"t":"RawInline","c":["html","<li>"]},{"t":"Str","c":"\na\n"},{"t":"RawInline","c":["html","</li>"]},{"t":"Str","c":"\n"},{"t":"RawInline","c":["html","<li>"]},{"t":"Str","c":"\nb\n"},{"t":"RawInline","c":["html","</li>"]},{"t":"Str","c":"\n"},{"t":"RawInline","c":["html","</ul>"]}]]}]},{"t":"Para","c":[{"t":"Str","c":"Another"},{"t":"Space"},{"t":"Str","c":"sentence."},{"t":"Span","c":[["fn2",["footnote"],[["data-pagedown-footnote-number","2"],["style","white-space: pre-line;"]]],[{"t":"Str","c":"ab"}]]}]}],"pandoc-api-version":[1,17,5,4],"meta":{"newpage_html_class":{"t":"MetaString","c":"page-break-after"},"paged-footnotes":{"t":"MetaBool","c":true},"output":{"t":"MetaMap","c":{"pagedown::html_paged":{"t":"MetaMap","c":{"keep_md":{"t":"MetaBool","c":true}}}}}}}

Pandoc's HTML writer takes this raw HTML asis. So, the generated markup is:

<p>A sentence.<span id="fn1" class="footnote" style="white-space: pre-line;" data-pagedown-footnote-number="1"><ul>
<li>
a
</li>
<li>
b
</li>
</ul></span></p>

Having a block element like <ul></ul> in a <p> element is illegal: this markup is invalid.
Browsers are quite flexible: they add a missing closing </p> tag just before the opening <ul> tag and by consequence a closing </span> tag too. So, the footnote is "reduced" to this void span element:

<span id="fn1" class="footnote" style="white-space: pre-line;" data-pagedown-footnote-number="1"></span>

I think I will add in the documentation that paged-footnotes: true only works for inline footnotes.

All 4 comments

paged-footnotes: true only supports inline footnotes.
The reason comes the W3C CSS Generated Content for Paged Media Module Working Draft. As you can see here, these specifications are only defined for inline elements. There is no support for block elements like lists.

In pagedown, paged-footnotes: true involves this Pandoc filter https://github.com/rstudio/pagedown/blob/master/inst/resources/lua/footnotes.lua which turns block elements into inline elements. The main function used in this filter is pandoc.utils.blocks_to_inlines(). The second part of paged-footnotes: true is this Paged.js handler: https://github.com/rstudio/pagedown/blob/d96b5e210a34b493b0a4d1ea8e02983cb0bee912/inst/resources/js/hooks.js#L208-L321

In the example, the markdown footnote is collapsed because the list (which is a block element) is turned into an inline span (this is the job of the Pandoc filter).

For the HTML footnote, the reason is different. Pandoc parses this markup as raw HTML as you can see in the JSON serialization of the AST:

{"blocks":[{"t":"Para","c":[{"t":"Str","c":"A"},{"t":"Space"},{"t":"Str","c":"sentence."},{"t":"Span","c":[["fn1",["footnote"],[["data-pagedown-footnote-number","1"],["style","white-space: pre-line;"]]],[{"t":"RawInline","c":["html","<ul>"]},{"t":"Str","c":"\n"},{"t":"RawInline","c":["html","<li>"]},{"t":"Str","c":"\na\n"},{"t":"RawInline","c":["html","</li>"]},{"t":"Str","c":"\n"},{"t":"RawInline","c":["html","<li>"]},{"t":"Str","c":"\nb\n"},{"t":"RawInline","c":["html","</li>"]},{"t":"Str","c":"\n"},{"t":"RawInline","c":["html","</ul>"]}]]}]},{"t":"Para","c":[{"t":"Str","c":"Another"},{"t":"Space"},{"t":"Str","c":"sentence."},{"t":"Span","c":[["fn2",["footnote"],[["data-pagedown-footnote-number","2"],["style","white-space: pre-line;"]]],[{"t":"Str","c":"ab"}]]}]}],"pandoc-api-version":[1,17,5,4],"meta":{"newpage_html_class":{"t":"MetaString","c":"page-break-after"},"paged-footnotes":{"t":"MetaBool","c":true},"output":{"t":"MetaMap","c":{"pagedown::html_paged":{"t":"MetaMap","c":{"keep_md":{"t":"MetaBool","c":true}}}}}}}

Pandoc's HTML writer takes this raw HTML asis. So, the generated markup is:

<p>A sentence.<span id="fn1" class="footnote" style="white-space: pre-line;" data-pagedown-footnote-number="1"><ul>
<li>
a
</li>
<li>
b
</li>
</ul></span></p>

Having a block element like <ul></ul> in a <p> element is illegal: this markup is invalid.
Browsers are quite flexible: they add a missing closing </p> tag just before the opening <ul> tag and by consequence a closing </span> tag too. So, the footnote is "reduced" to this void span element:

<span id="fn1" class="footnote" style="white-space: pre-line;" data-pagedown-footnote-number="1"></span>

I think I will add in the documentation that paged-footnotes: true only works for inline footnotes.

Thanks a lot for the explanation, and for the plan to update the documentation!!
It makes sense.

@atusy Thanks a lot for the report! I've updated the documentation in https://github.com/rstudio/pagedown/commit/3f765d9f7c3164bca5d2bddb40a537d087788184.

Great! Thank you!

Was this page helpful?
0 / 5 - 0 ratings