Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
footnote role for Sphinx
# -*- coding: utf-8 -*-
import os
from docutils import nodes
from docutils.parsers.rst import roles
class footnote_defs(nodes.General, nodes.Element):
pass
def footnote_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
"""Role for embed footnotes as inline element."""
fn = footnote_defs()
fn['auto'] = '1'
fn['text'] = text
inliner.document.set_id(fn, fn)
_id = fn['ids'].pop()
inliner.document.set_id(fn, fn)
fn['refid'] = fn['ids'].pop()
fn['ids'].append(_id)
return [fn], []
def on_doctree_read(self, doctree):
for i, fn in enumerate(doctree.traverse(footnote_defs)):
fnref = nodes.footnote_reference()
fnref['auto'] = fn['auto']
fnref['ids'] = fn['ids']
fnref['refid'] = fn['refid']
fnref += nodes.Text(str(i + 1))
footnote = nodes.footnote()
footnote['auto'] = fn['auto']
footnote['backrefs'] = fn['ids']
footnote['ids'] = [fn['refid']]
footnote += nodes.label(text=str(i + 1))
footnote += nodes.paragraph(text=fn['text'])
n = fn
while True:
if isinstance(n.parent, (nodes.document)):
break
n = n.parent
if isinstance(n, (nodes.paragraph)):
break
pos = n.parent.index(n)
try:
while isinstance(n.parent.children[pos + 1], nodes.footnote):
pos += 1
except:
pass
n.parent.insert(pos + 1, footnote)
fn.parent.replace(fn, fnref)
def setup(app):
app.add_role('footnote', footnote_role)
app.connect("doctree-read", on_doctree_read)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment