Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/nbconvert/filters/highlight.py: 29%

68 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-07-01 06:54 +0000

1""" 

2Module containing filter functions that allow code to be highlighted 

3from within Jinja templates. 

4""" 

5 

6# Copyright (c) IPython Development Team. 

7# Distributed under the terms of the Modified BSD License. 

8 

9# pygments must not be imported at the module level 

10# because errors should be raised at runtime if it's actually needed, 

11# not import time, when it may not be needed. 

12 

13from html import escape 

14from warnings import warn 

15 

16from traitlets import observe 

17from traitlets.config import Dict 

18 

19from nbconvert.utils.base import NbConvertBase 

20 

21MULTILINE_OUTPUTS = ["text", "html", "svg", "latex", "javascript", "json"] 

22 

23__all__ = ["Highlight2HTML", "Highlight2Latex"] 

24 

25 

26class Highlight2HTML(NbConvertBase): 

27 """Convert highlighted code to html.""" 

28 

29 extra_formatter_options = Dict( 

30 {}, 

31 help=""" 

32 Extra set of options to control how code is highlighted. 

33 

34 Passed through to the pygments' HtmlFormatter class. 

35 See available list in https://pygments.org/docs/formatters/#HtmlFormatter 

36 """, 

37 config=True, 

38 ) 

39 

40 def __init__(self, pygments_lexer=None, **kwargs): 

41 """Initialize the converter.""" 

42 self.pygments_lexer = pygments_lexer or "ipython3" 

43 super().__init__(**kwargs) 

44 

45 @observe("default_language") 

46 def _default_language_changed(self, change): 

47 warn( 

48 "Setting default_language in config is deprecated as of 5.0, " 

49 "please use language_info metadata instead.", 

50 stacklevel=2, 

51 ) 

52 self.pygments_lexer = change["new"] 

53 

54 def __call__(self, source, language=None, metadata=None): 

55 """ 

56 Return a syntax-highlighted version of the input source as html output. 

57 

58 Parameters 

59 ---------- 

60 source : str 

61 source of the cell to highlight 

62 language : str 

63 language to highlight the syntax of 

64 metadata : NotebookNode cell metadata 

65 metadata of the cell to highlight 

66 """ 

67 from pygments.formatters import HtmlFormatter 

68 

69 if not language: 

70 language = self.pygments_lexer 

71 

72 return _pygments_highlight( 

73 source if len(source) > 0 else " ", 

74 # needed to help post processors: 

75 HtmlFormatter( 

76 cssclass=escape(f" highlight hl-{language}"), **self.extra_formatter_options 

77 ), 

78 language, 

79 metadata, 

80 ) 

81 

82 

83class Highlight2Latex(NbConvertBase): 

84 """Convert highlighted code to latex.""" 

85 

86 extra_formatter_options = Dict( 

87 {}, 

88 help=""" 

89 Extra set of options to control how code is highlighted. 

90 

91 Passed through to the pygments' LatexFormatter class. 

92 See available list in https://pygments.org/docs/formatters/#LatexFormatter 

93 """, 

94 config=True, 

95 ) 

96 

97 def __init__(self, pygments_lexer=None, **kwargs): 

98 """Initialize the converter.""" 

99 self.pygments_lexer = pygments_lexer or "ipython3" 

100 super().__init__(**kwargs) 

101 

102 @observe("default_language") 

103 def _default_language_changed(self, change): 

104 warn( 

105 "Setting default_language in config is deprecated as of 5.0, " 

106 "please use language_info metadata instead.", 

107 stacklevel=2, 

108 ) 

109 self.pygments_lexer = change["new"] 

110 

111 def __call__(self, source, language=None, metadata=None, strip_verbatim=False): 

112 """ 

113 Return a syntax-highlighted version of the input source as latex output. 

114 

115 Parameters 

116 ---------- 

117 source : str 

118 source of the cell to highlight 

119 language : str 

120 language to highlight the syntax of 

121 metadata : NotebookNode cell metadata 

122 metadata of the cell to highlight 

123 strip_verbatim : bool 

124 remove the Verbatim environment that pygments provides by default 

125 """ 

126 from pygments.formatters import LatexFormatter 

127 

128 if not language: 

129 language = self.pygments_lexer 

130 

131 latex = _pygments_highlight( 

132 source, LatexFormatter(**self.extra_formatter_options), language, metadata 

133 ) 

134 if strip_verbatim: 

135 latex = latex.replace(r"\begin{Verbatim}[commandchars=\\\{\}]" + "\n", "") # noqa 

136 return latex.replace("\n\\end{Verbatim}\n", "") 

137 else: 

138 return latex 

139 

140 

141def _pygments_highlight(source, output_formatter, language="ipython", metadata=None): 

142 """ 

143 Return a syntax-highlighted version of the input source 

144 

145 Parameters 

146 ---------- 

147 source : str 

148 source of the cell to highlight 

149 output_formatter : Pygments formatter 

150 language : str 

151 language to highlight the syntax of 

152 metadata : NotebookNode cell metadata 

153 metadata of the cell to highlight 

154 """ 

155 from pygments import highlight 

156 from pygments.lexers import get_lexer_by_name 

157 from pygments.util import ClassNotFound 

158 

159 # If the cell uses a magic extension language, 

160 # use the magic language instead. 

161 if language.startswith("ipython") and metadata and "magics_language" in metadata: 

162 language = metadata["magics_language"] 

163 

164 lexer = None 

165 if language == "ipython2": 

166 try: 

167 from IPython.lib.lexers import IPythonLexer 

168 except ImportError: 

169 warn("IPython lexer unavailable, falling back on Python", stacklevel=2) 

170 language = "python" 

171 else: 

172 lexer = IPythonLexer() 

173 elif language == "ipython3": 

174 try: 

175 from IPython.lib.lexers import IPython3Lexer 

176 except ImportError: 

177 warn("IPython3 lexer unavailable, falling back on Python 3", stacklevel=2) 

178 language = "python3" 

179 else: 

180 lexer = IPython3Lexer() 

181 

182 if lexer is None: 

183 try: 

184 lexer = get_lexer_by_name(language, stripall=True) 

185 except ClassNotFound: 

186 warn("No lexer found for language %r. Treating as plain text." % language, stacklevel=2) 

187 from pygments.lexers.special import TextLexer 

188 

189 lexer = TextLexer() 

190 

191 return highlight(source, lexer, output_formatter)