citation.py
72 lines
| 2.1 KiB
| text/x-python
|
PythonLexer
Brian E. Granger
|
r12265 | """Citation handling for LaTeX output.""" | ||
#----------------------------------------------------------------------------- | ||||
# Copyright (c) 2013, the IPython Development Team. | ||||
# | ||||
# Distributed under the terms of the Modified BSD License. | ||||
# | ||||
# The full license is in the file COPYING.txt, distributed with this software. | ||||
#----------------------------------------------------------------------------- | ||||
#----------------------------------------------------------------------------- | ||||
# Code | ||||
#----------------------------------------------------------------------------- | ||||
Brian E. Granger
|
r12299 | __all__ = ['citation2latex'] | ||
Brian E. Granger
|
r12265 | |||
Brian E. Granger
|
r12299 | def citation2latex(s): | ||
Brian E. Granger
|
r12265 | """Parse citations in Markdown cells. | ||
This looks for HTML tags having a data attribute names `data-cite` | ||||
and replaces it by the call to LaTeX cite command. The tranformation | ||||
looks like this: | ||||
`<cite data-cite="granger">(Granger, 2013)</cite>` | ||||
Becomes | ||||
`\\cite{granger}` | ||||
Any HTML tag can be used, which allows the citations to be formatted | ||||
in HTML in any manner. | ||||
""" | ||||
try: | ||||
from lxml import html | ||||
except ImportError: | ||||
return s | ||||
tree = html.fragment_fromstring(s, create_parent='div') | ||||
_process_node_cite(tree) | ||||
Thomas Kluyver
|
r12409 | s = html.tostring(tree, encoding='unicode') | ||
Brian E. Granger
|
r12281 | if s.endswith('</div>'): | ||
s = s[:-6] | ||||
if s.startswith('<div>'): | ||||
s = s[5:] | ||||
Brian E. Granger
|
r12265 | return s | ||
def _process_node_cite(node): | ||||
"""Do the citation replacement as we walk the lxml tree.""" | ||||
def _get(o, name): | ||||
Brian E. Granger
|
r12360 | value = getattr(o, name, None) | ||
Brian E. Granger
|
r12265 | return '' if value is None else value | ||
if 'data-cite' in node.attrib: | ||||
cite = '\cite{%(ref)s}' % {'ref': node.attrib['data-cite']} | ||||
prev = node.getprevious() | ||||
if prev is not None: | ||||
prev.tail = _get(prev, 'tail') + cite + _get(node, 'tail') | ||||
else: | ||||
parent = node.getparent() | ||||
if parent is not None: | ||||
parent.text = _get(parent, 'text') + cite + _get(node, 'tail') | ||||
try: | ||||
node.getparent().remove(node) | ||||
except AttributeError: | ||||
pass | ||||
else: | ||||
for child in node: | ||||
_process_node_cite(child) | ||||