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

Adjust EPUB footnotes with backlink before text #8672

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 14 additions & 31 deletions src/Text/Pandoc/Writers/HTML.hs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ import Text.TeXMath
import Text.XML.Light (elChildren, unode, unqual)
import qualified Text.XML.Light as XML
import Text.XML.Light.Output
import Data.String (fromString)

data WriterState = WriterState
{ stNotes :: [Html] -- ^ List of notes
Expand Down Expand Up @@ -299,7 +298,7 @@ pandocToHtml opts (Pandoc meta blocks) = do
if null (stNotes st)
then return mempty
else do
notes <- footnoteSection EndOfDocument (stEmittedNotes st + 1) (reverse (stNotes st))
notes <- footnoteSection EndOfDocument (reverse (stNotes st))
modify (\st' -> st'{ stNotes = mempty, stEmittedNotes = stEmittedNotes st' + length (stNotes st') })
return notes
st <- get
Expand Down Expand Up @@ -524,8 +523,8 @@ tableOfContents opts sects = do
-- | Convert list of Note blocks to a footnote <div>.
-- Assumes notes are sorted.
footnoteSection ::
PandocMonad m => ReferenceLocation -> Int -> [Html] -> StateT WriterState m Html
footnoteSection refLocation startCounter notes = do
PandocMonad m => ReferenceLocation -> [Html] -> StateT WriterState m Html
footnoteSection refLocation notes = do
html5 <- gets stHtml5
slideVariant <- gets stSlideVariant
let hrtag = if refLocation /= EndOfBlock
Expand Down Expand Up @@ -557,13 +556,7 @@ footnoteSection refLocation startCounter notes = do
container $ do
nl
hrtag
-- Keep the previous output exactly the same if we don't
-- have multiple notes sections
if startCounter == 1
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've assumed that this can be dropped as long as ordered lists are not used anymore, is it really the case?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it can't be dropped. This plays a significant role when you use --reference-location=block (or section), which causes the footnotes to be printed at the end of each block (or section). In that case we need to make sure that the numbering continues appropriately in each new footnote section.

then H.ol $ mconcat notes >> nl
else H.ol ! A.start (fromString (show startCounter)) $
mconcat notes >> nl
nl
mconcat notes >> nl

-- | Parse a mailto link; return Just (name, domain) or Nothing.
parseMailto :: Text -> Maybe (Text, Text)
Expand Down Expand Up @@ -1072,7 +1065,7 @@ blockToHtml opts block = do
then do
notes <- if null (stNotes st)
then return mempty
else footnoteSection (writerReferenceLocation opts) (stEmittedNotes st + 1) (reverse (stNotes st))
else footnoteSection (writerReferenceLocation opts) (reverse (stNotes st))
modify (\st' -> st'{ stNotes = mempty, stEmittedNotes = stEmittedNotes st' + length (stNotes st') })
return (doc <> notes)
else return doc
Expand Down Expand Up @@ -1616,26 +1609,16 @@ blockListToNote opts ref blocks = do
-- If last block is Para or Plain, include the backlink at the end of
-- that block. Otherwise, insert a new Plain block with the backlink.
let kvs = [("role","doc-backlink") | html5]
let backlink = [Link ("",["footnote-back"],kvs)
[Str "↩"] ("#" <> "fnref" <> ref,"")]
let blocks' = if null blocks
then []
else let lastBlock = last blocks
otherBlocks = init blocks
in case lastBlock of
Para [Image (_,cls,_) _ (_,tit)]
| "fig:" `T.isPrefixOf` tit
|| "r-stretch" `elem` cls
-> otherBlocks ++ [lastBlock,
Plain backlink]
Para lst -> otherBlocks ++
[Para (lst ++ backlink)]
Plain lst -> otherBlocks ++
[Plain (lst ++ backlink)]
_ -> otherBlocks ++ [lastBlock,
Plain backlink]
let backlink = [Link ("",["footnote-back"],kvs) [Str (ref <> ".")] ("#" <> "fnref" <> ref,""), Space]
blocks' = case blocks of
[] -> []
(firstBlock:otherBlocks) ->
case firstBlock of
(Para lst) -> Para (backlink ++ lst) : otherBlocks
(Plain lst) -> Plain (backlink ++ lst) : otherBlocks
_ -> Plain backlink : blocks
contents <- blockListToHtml opts blocks'
let noteItem = H.li ! prefixedId opts ("fn" <> ref) $ contents
let noteItem = H.div ! prefixedId opts ("fn" <> ref) $ contents
epubVersion <- gets stEPUBVersion
let noteItem' = case epubVersion of
Just EPUB3 -> noteItem !
Expand Down
31 changes: 13 additions & 18 deletions test/Tests/Writers/HTML.hs
Original file line number Diff line number Diff line change
Expand Up @@ -127,10 +127,9 @@ tests =
, "<p>Some more text.</p>"
, "<div class=\"footnotes footnotes-end-of-document\">"
, "<hr />"
, "<ol>"
, "<li id=\"fn1\"><p>Down here.<a href=\"#fnref1\" class=\"footnote-back\">↩︎</a></p></li>"
, "<li id=\"fn2\"><p>The second note.<a href=\"#fnref2\" class=\"footnote-back\">↩︎</a></p></li>"
, "</ol>"
, ""
, "<div id=\"fn1\"><p><a href=\"#fnref1\" class=\"footnote-back\">1.</a> Down here.</p></div>"
, "<div id=\"fn2\"><p><a href=\"#fnref2\" class=\"footnote-back\">2.</a> The second note.</p></div>"
Comment on lines -130 to +132
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think I like this change. Using ordered lists gives us much better formatting (content of a note is aligned), and it will work well even if the note is, say, a code block.

, "</div>"
]
, test (htmlWithOpts def{writerReferenceLocation=EndOfBlock})
Expand All @@ -141,18 +140,16 @@ tests =
, "<h2>First section</h2>"
, "<p>This is a footnote.<a href=\"#fn1\" class=\"footnote-ref\" id=\"fnref1\"><sup>1</sup></a> And this is a <a href=\"https://www.google.com\">link</a>.</p>"
, "<div class=\"footnotes footnotes-end-of-block\">"
, "<ol>"
, "<li id=\"fn1\"><p>Down here.<a href=\"#fnref1\" class=\"footnote-back\">↩︎</a></p></li>"
, "</ol>"
, ""
, "<div id=\"fn1\"><p><a href=\"#fnref1\" class=\"footnote-back\">1.</a> Down here.</p></div>"
, "</div>"
, "<blockquote>"
, "<p>A note inside a block quote.<a href=\"#fn2\" class=\"footnote-ref\" id=\"fnref2\"><sup>2</sup></a></p>"
, "<p>A second paragraph.</p>"
, "</blockquote>"
, "<div class=\"footnotes footnotes-end-of-block\">"
, "<ol start=\"2\">"
, "<li id=\"fn2\"><p>The second note.<a href=\"#fnref2\" class=\"footnote-back\">↩︎</a></p></li>"
, "</ol>"
, ""
, "<div id=\"fn2\"><p><a href=\"#fnref2\" class=\"footnote-back\">2.</a> The second note.</p></div>"
, "</div>"
, "<h2>Second section</h2>"
, "<p>Some more text.</p>"
Expand All @@ -170,10 +167,9 @@ tests =
, "</blockquote>"
, "<div class=\"footnotes footnotes-end-of-section\">"
, "<hr />"
, "<ol>"
, "<li id=\"fn1\"><p>Down here.<a href=\"#fnref1\" class=\"footnote-back\">↩︎</a></p></li>"
, "<li id=\"fn2\"><p>The second note.<a href=\"#fnref2\" class=\"footnote-back\">↩︎</a></p></li>"
, "</ol>"
, ""
, "<div id=\"fn1\"><p><a href=\"#fnref1\" class=\"footnote-back\">1.</a> Down here.</p></div>"
, "<div id=\"fn2\"><p><a href=\"#fnref2\" class=\"footnote-back\">2.</a> The second note.</p></div>"
, "</div>"
, "<h2>Second section</h2>"
, "<p>Some more text.</p>"
Expand All @@ -196,10 +192,9 @@ tests =
, "</div>"
, "<div class=\"footnotes footnotes-end-of-section\">"
, "<hr />"
, "<ol>"
, "<li id=\"fn1\"><p>Down here.<a href=\"#fnref1\" class=\"footnote-back\">↩︎</a></p></li>"
, "<li id=\"fn2\"><p>The second note.<a href=\"#fnref2\" class=\"footnote-back\">↩︎</a></p></li>"
, "</ol>"
, ""
, "<div id=\"fn1\"><p><a href=\"#fnref1\" class=\"footnote-back\">1.</a> Down here.</p></div>"
, "<div id=\"fn2\"><p><a href=\"#fnref2\" class=\"footnote-back\">2.</a> The second note.</p></div>"
, "</div>"
, "<div class=\"section level2\">"
, "<h2>Second section</h2>"
Expand Down
7 changes: 3 additions & 4 deletions test/command/4235.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@ role="doc-noteref"><sup>1</sup></a></p>
<section id="footnotes" class="footnotes footnotes-end-of-document"
role="doc-endnotes">
<hr />
<ol>
<li id="foofn1"><p>Has a footnote.<a href="#foofnref1"
class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>

<div id="foofn1"><p><a href="#foofnref1" class="footnote-back"
role="doc-backlink">1.</a> Has a footnote.</p></div>
</section>
```
9 changes: 4 additions & 5 deletions test/command/7006.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,12 @@ role="doc-noteref"><sup>1</sup></a></p>
<section id="footnotes" class="footnotes footnotes-end-of-document"
role="doc-endnotes">
<hr />
<ol>
<li id="fn1"><p>Foo:</p>

<div id="fn1"><p><a href="#fnref1" class="footnote-back"
role="doc-backlink">1.</a> Foo:</p>
<figure>
<img src="/image.jpg" alt="Caption." />
<figcaption aria-hidden="true">Caption.</figcaption>
</figure>
<a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></li>
</ol>
</figure></div>
</section>
```
26 changes: 14 additions & 12 deletions test/writer.html4
Original file line number Diff line number Diff line change
Expand Up @@ -731,23 +731,25 @@ id="fnref5"><sup>5</sup></a></li>
<p>This paragraph should not be part of the note, as it is not indented.</p>
<div class="footnotes footnotes-end-of-document">
<hr />
<ol>
<li id="fn1"><p>Here is the footnote. It can go anywhere after the footnote
reference. It need not be placed at the end of the document.<a href="#fnref1"
class="footnote-back">↩︎</a></p></li>
<li id="fn2"><p>Here’s the long note. This one contains multiple blocks.</p>

<div id="fn1"><p><a href="#fnref1" class="footnote-back">1.</a> Here is the
footnote. It can go anywhere after the footnote reference. It need not be placed
at the end of the document.</p></div>
<div id="fn2"><p><a href="#fnref2" class="footnote-back">2.</a> Here’s the long
note. This one contains multiple blocks.</p>
<p>Subsequent blocks are indented to show that they belong to the footnote (as
with list items).</p>
<pre><code> { &lt;code&gt; }</code></pre>
<p>If you want, you can indent every line, but you can also be lazy and just
indent the first line of each block.<a href="#fnref2"
class="footnote-back">↩︎</a></p></li>
<li id="fn3"><p>This is <em>easier</em> to type. Inline notes may contain <a
indent the first line of each block.</p></div>
<div id="fn3"><p><a href="#fnref3" class="footnote-back">3.</a> This is
<em>easier</em> to type. Inline notes may contain <a
href="http://google.com">links</a> and <code>]</code> verbatim characters, as
well as [bracketed text].<a href="#fnref3" class="footnote-back">↩︎</a></p></li>
<li id="fn4"><p>In quote.<a href="#fnref4" class="footnote-back">↩︎</a></p></li>
<li id="fn5"><p>In list.<a href="#fnref5" class="footnote-back">↩︎</a></p></li>
</ol>
well as [bracketed text].</p></div>
<div id="fn4"><p><a href="#fnref4" class="footnote-back">4.</a> In
quote.</p></div>
<div id="fn5"><p><a href="#fnref5" class="footnote-back">5.</a> In
list.</p></div>
</div>
</body>
</html>
32 changes: 16 additions & 16 deletions test/writer.html5
Original file line number Diff line number Diff line change
Expand Up @@ -736,26 +736,26 @@ role="doc-noteref"><sup>5</sup></a></li>
<section id="footnotes" class="footnotes footnotes-end-of-document"
role="doc-endnotes">
<hr />
<ol>
<li id="fn1"><p>Here is the footnote. It can go anywhere after the footnote
reference. It need not be placed at the end of the document.<a href="#fnref1"
class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn2"><p>Here’s the long note. This one contains multiple blocks.</p>

<div id="fn1"><p><a href="#fnref1" class="footnote-back"
role="doc-backlink">1.</a> Here is the footnote. It can go anywhere after the
footnote reference. It need not be placed at the end of the document.</p></div>
<div id="fn2"><p><a href="#fnref2" class="footnote-back"
role="doc-backlink">2.</a> Here’s the long note. This one contains multiple
blocks.</p>
<p>Subsequent blocks are indented to show that they belong to the footnote (as
with list items).</p>
<pre><code> { &lt;code&gt; }</code></pre>
<p>If you want, you can indent every line, but you can also be lazy and just
indent the first line of each block.<a href="#fnref2" class="footnote-back"
role="doc-backlink">↩︎</a></p></li>
<li id="fn3"><p>This is <em>easier</em> to type. Inline notes may contain <a
href="http://google.com">links</a> and <code>]</code> verbatim characters, as
well as [bracketed text].<a href="#fnref3" class="footnote-back"
role="doc-backlink">↩︎</a></p></li>
<li id="fn4"><p>In quote.<a href="#fnref4" class="footnote-back"
role="doc-backlink">↩︎</a></p></li>
<li id="fn5"><p>In list.<a href="#fnref5" class="footnote-back"
role="doc-backlink">↩︎</a></p></li>
</ol>
indent the first line of each block.</p></div>
<div id="fn3"><p><a href="#fnref3" class="footnote-back"
role="doc-backlink">3.</a> This is <em>easier</em> to type. Inline notes may
contain <a href="http://google.com">links</a> and <code>]</code> verbatim
characters, as well as [bracketed text].</p></div>
<div id="fn4"><p><a href="#fnref4" class="footnote-back"
role="doc-backlink">4.</a> In quote.</p></div>
<div id="fn5"><p><a href="#fnref5" class="footnote-back"
role="doc-backlink">5.</a> In list.</p></div>
</section>
</body>
</html>