Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/nbconvert/filters/citation.py: 26%
47 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-07-01 06:54 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2023-07-01 06:54 +0000
1"""Citation handling for LaTeX output."""
3# -----------------------------------------------------------------------------
4# Copyright (c) 2013, the IPython Development Team.
5#
6# Distributed under the terms of the Modified BSD License.
7#
8# The full license is in the file COPYING.txt, distributed with this software.
9# -----------------------------------------------------------------------------
11# -----------------------------------------------------------------------------
12# Imports
13# -----------------------------------------------------------------------------
14from html.parser import HTMLParser
16# -----------------------------------------------------------------------------
17# Functions
18# -----------------------------------------------------------------------------
20__all__ = ["citation2latex"]
23def citation2latex(s):
24 """Parse citations in Markdown cells.
26 This looks for HTML tags having a data attribute names ``data-cite``
27 and replaces it by the call to LaTeX cite command. The transformation
28 looks like this::
30 <cite data-cite="granger">(Granger, 2013)</cite>
32 Becomes ::
34 \\cite{granger}
36 Any HTML tag can be used, which allows the citations to be formatted
37 in HTML in any manner.
38 """
39 parser = CitationParser()
40 parser.feed(s)
41 parser.close()
42 outtext = ""
43 startpos = 0
44 for citation in parser.citelist:
45 outtext += s[startpos : citation[1]]
46 outtext += "\\cite{%s}" % citation[0]
47 startpos = citation[2] if len(citation) == 3 else -1 # noqa
48 outtext += s[startpos:] if startpos != -1 else ""
49 return outtext
52# -----------------------------------------------------------------------------
53# Classes
54# -----------------------------------------------------------------------------
55class CitationParser(HTMLParser):
56 """Citation Parser
58 Replaces html tags with data-cite attribute with respective latex \\cite.
60 Inherites from HTMLParser, overrides:
61 - handle_starttag
62 - handle_endtag
63 """
65 # number of open tags
66 opentags = None
67 # list of found citations
68 citelist = None # type:ignore
69 # active citation tag
70 citetag = None
72 def __init__(self):
73 """Initialize the parser."""
74 self.citelist = []
75 self.opentags = 0
76 HTMLParser.__init__(self)
78 def get_offset(self):
79 """Get the offset position."""
80 # Compute startposition in source
81 lin, offset = self.getpos()
82 pos = 0
83 for _ in range(lin - 1):
84 pos = self.data.find("\n", pos) + 1
85 return pos + offset
87 def handle_starttag(self, tag, attrs):
88 """Handle a start tag."""
89 # for each tag check if attributes are present and if no citation is active
90 if self.opentags == 0 and len(attrs) > 0:
91 for atr, data in attrs:
92 if atr.lower() == "data-cite":
93 self.citetag = tag
94 self.opentags = 1
95 self.citelist.append([data, self.get_offset()])
96 return
98 if tag == self.citetag:
99 # found an open citation tag but not the starting one
100 self.opentags += 1 # type:ignore
102 def handle_endtag(self, tag):
103 """Handle an end tag."""
104 if tag == self.citetag:
105 # found citation tag check if starting one
106 if self.opentags == 1:
107 pos = self.get_offset()
108 self.citelist[-1].append(pos + len(tag) + 3)
109 self.opentags -= 1 # type:ignore
111 def feed(self, data):
112 """Handle a feed."""
113 self.data = data
114 HTMLParser.feed(self, data)