Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/nbconvert/preprocessors/csshtmlheader.py: 44%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

41 statements  

1"""Module that pre-processes the notebook for export to HTML.""" 

2 

3# Copyright (c) Jupyter Development Team. 

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

5 

6import hashlib 

7import os 

8 

9from jupyterlab_pygments import JupyterStyle # type:ignore[import-untyped] 

10from pygments.style import Style 

11from traitlets import Type, Unicode, Union 

12 

13from .base import Preprocessor 

14 

15try: 

16 from notebook import DEFAULT_STATIC_FILES_PATH # type:ignore[import-not-found] 

17except ImportError: 

18 DEFAULT_STATIC_FILES_PATH = None 

19 

20 

21class CSSHTMLHeaderPreprocessor(Preprocessor): 

22 """ 

23 Preprocessor used to pre-process notebook for HTML output. Adds IPython notebook 

24 front-end CSS and Pygments CSS to HTML output. 

25 """ 

26 

27 highlight_class = Unicode(".highlight", help="CSS highlight class identifier").tag(config=True) 

28 

29 style = Union( 

30 [Unicode("default"), Type(klass=Style)], 

31 help="Name of the pygments style to use", 

32 default_value=JupyterStyle, 

33 ).tag(config=True) 

34 

35 def __init__(self, *pargs, **kwargs): 

36 """Initialize the preprocessor.""" 

37 Preprocessor.__init__(self, *pargs, **kwargs) 

38 self._default_css_hash = None 

39 

40 def preprocess(self, nb, resources): 

41 """Fetch and add CSS to the resource dictionary 

42 

43 Fetch CSS from IPython and Pygments to add at the beginning 

44 of the html files. Add this css in resources in the 

45 "inlining.css" key 

46 

47 Parameters 

48 ---------- 

49 nb : NotebookNode 

50 Notebook being converted 

51 resources : dictionary 

52 Additional resources used in the conversion process. Allows 

53 preprocessors to pass variables into the Jinja engine. 

54 """ 

55 resources["inlining"] = {} 

56 resources["inlining"]["css"] = self._generate_header(resources) 

57 return nb, resources 

58 

59 def _generate_header(self, resources): 

60 """ 

61 Fills self.header with lines of CSS extracted from IPython 

62 and Pygments. 

63 """ 

64 from pygments.formatters import HtmlFormatter 

65 

66 header = [] 

67 

68 formatter = HtmlFormatter(style=self.style) 

69 pygments_css = formatter.get_style_defs(self.highlight_class) 

70 header.append(pygments_css) 

71 

72 # Load the user's custom CSS and IPython's default custom CSS. If they 

73 # differ, assume the user has made modifications to his/her custom CSS 

74 # and that we should inline it in the nbconvert output. 

75 config_dir = resources["config_dir"] 

76 custom_css_filename = os.path.join(config_dir, "custom", "custom.css") 

77 if os.path.isfile(custom_css_filename): 

78 if DEFAULT_STATIC_FILES_PATH and self._default_css_hash is None: 

79 self._default_css_hash = self._hash( 

80 os.path.join(DEFAULT_STATIC_FILES_PATH, "custom", "custom.css") 

81 ) 

82 if self._hash(custom_css_filename) != self._default_css_hash: 

83 with open(custom_css_filename, encoding="utf-8") as f: 

84 header.append(f.read()) 

85 return header 

86 

87 def _hash(self, filename): 

88 """Compute the hash of a file.""" 

89 md5 = hashlib.md5() # noqa: S324 

90 with open(filename, "rb") as f: 

91 md5.update(f.read()) 

92 return md5.digest()