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

1"""Citation handling for LaTeX output.""" 

2 

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# ----------------------------------------------------------------------------- 

10 

11# ----------------------------------------------------------------------------- 

12# Imports 

13# ----------------------------------------------------------------------------- 

14from html.parser import HTMLParser 

15 

16# ----------------------------------------------------------------------------- 

17# Functions 

18# ----------------------------------------------------------------------------- 

19 

20__all__ = ["citation2latex"] 

21 

22 

23def citation2latex(s): 

24 """Parse citations in Markdown cells. 

25 

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:: 

29 

30 <cite data-cite="granger">(Granger, 2013)</cite> 

31 

32 Becomes :: 

33 

34 \\cite{granger} 

35 

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 

50 

51 

52# ----------------------------------------------------------------------------- 

53# Classes 

54# ----------------------------------------------------------------------------- 

55class CitationParser(HTMLParser): 

56 """Citation Parser 

57 

58 Replaces html tags with data-cite attribute with respective latex \\cite. 

59 

60 Inherites from HTMLParser, overrides: 

61 - handle_starttag 

62 - handle_endtag 

63 """ 

64 

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 

71 

72 def __init__(self): 

73 """Initialize the parser.""" 

74 self.citelist = [] 

75 self.opentags = 0 

76 HTMLParser.__init__(self) 

77 

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 

86 

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 

97 

98 if tag == self.citetag: 

99 # found an open citation tag but not the starting one 

100 self.opentags += 1 # type:ignore 

101 

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 

110 

111 def feed(self, data): 

112 """Handle a feed.""" 

113 self.data = data 

114 HTMLParser.feed(self, data)