Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/nbformat/v2/nbpy.py: 19%

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

109 statements  

1"""Read and write notebooks as regular .py files. 

2 

3Authors: 

4 

5* Brian Granger 

6""" 

7 

8# ----------------------------------------------------------------------------- 

9# Copyright (C) 2008-2011 The IPython Development Team 

10# 

11# Distributed under the terms of the BSD License. The full license is in 

12# the file LICENSE, distributed as part of this software. 

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

14 

15# ----------------------------------------------------------------------------- 

16# Imports 

17# ----------------------------------------------------------------------------- 

18from __future__ import annotations 

19 

20import re 

21 

22from .nbbase import new_code_cell, new_notebook, new_text_cell, new_worksheet 

23from .rwbase import NotebookReader, NotebookWriter 

24 

25# ----------------------------------------------------------------------------- 

26# Code 

27# ----------------------------------------------------------------------------- 

28 

29_encoding_declaration_re = re.compile(r"^#.*coding[:=]\s*([-\w.]+)") 

30 

31 

32class PyReaderError(Exception): 

33 """An error raised by the PyReader.""" 

34 

35 

36class PyReader(NotebookReader): 

37 """A Python notebook reader.""" 

38 

39 def reads(self, s, **kwargs): 

40 """Convert a string to a notebook.""" 

41 return self.to_notebook(s, **kwargs) 

42 

43 def to_notebook(self, s, **kwargs): 

44 """Convert a string to a notebook.""" 

45 lines = s.splitlines() 

46 cells = [] 

47 cell_lines: list[str] = [] 

48 state = "codecell" 

49 for line in lines: 

50 if line.startswith("# <nbformat>") or _encoding_declaration_re.match(line): 

51 pass 

52 elif line.startswith("# <codecell>"): 

53 cell = self.new_cell(state, cell_lines) 

54 if cell is not None: 

55 cells.append(cell) 

56 state = "codecell" 

57 cell_lines = [] 

58 elif line.startswith("# <htmlcell>"): 

59 cell = self.new_cell(state, cell_lines) 

60 if cell is not None: 

61 cells.append(cell) 

62 state = "htmlcell" 

63 cell_lines = [] 

64 elif line.startswith("# <markdowncell>"): 

65 cell = self.new_cell(state, cell_lines) 

66 if cell is not None: 

67 cells.append(cell) 

68 state = "markdowncell" 

69 cell_lines = [] 

70 else: 

71 cell_lines.append(line) 

72 if cell_lines and state == "codecell": 

73 cell = self.new_cell(state, cell_lines) 

74 if cell is not None: 

75 cells.append(cell) 

76 ws = new_worksheet(cells=cells) 

77 return new_notebook(worksheets=[ws]) 

78 

79 def new_cell(self, state, lines): 

80 """Create a new cell.""" 

81 if state == "codecell": 

82 input_ = "\n".join(lines) 

83 input_ = input_.strip("\n") 

84 if input_: 

85 return new_code_cell(input=input_) 

86 elif state == "htmlcell": 

87 text = self._remove_comments(lines) 

88 if text: 

89 return new_text_cell("html", source=text) 

90 elif state == "markdowncell": 

91 text = self._remove_comments(lines) 

92 if text: 

93 return new_text_cell("markdown", source=text) 

94 

95 def _remove_comments(self, lines): 

96 new_lines = [] 

97 for line in lines: 

98 if line.startswith("#"): 

99 new_lines.append(line[2:]) 

100 else: 

101 new_lines.append(line) 

102 text = "\n".join(new_lines) 

103 text = text.strip("\n") 

104 return text # noqa: RET504 

105 

106 def split_lines_into_blocks(self, lines): 

107 """Split lines into code blocks.""" 

108 if len(lines) == 1: 

109 yield lines[0] 

110 raise StopIteration() 

111 import ast 

112 

113 source = "\n".join(lines) 

114 code = ast.parse(source) 

115 starts = [x.lineno - 1 for x in code.body] 

116 for i in range(len(starts) - 1): 

117 yield "\n".join(lines[starts[i] : starts[i + 1]]).strip("\n") 

118 yield "\n".join(lines[starts[-1] :]).strip("\n") 

119 

120 

121class PyWriter(NotebookWriter): 

122 """A Python notebook writer.""" 

123 

124 def writes(self, nb, **kwargs): 

125 """Convert a notebook object to a string.""" 

126 lines = ["# -*- coding: utf-8 -*-"] 

127 lines.extend(["# <nbformat>2</nbformat>", ""]) 

128 for ws in nb.worksheets: 

129 for cell in ws.cells: 

130 if cell.cell_type == "code": 

131 input_ = cell.get("input") 

132 if input_ is not None: 

133 lines.extend(["# <codecell>", ""]) 

134 lines.extend(input_.splitlines()) 

135 lines.append("") 

136 elif cell.cell_type == "html": 

137 input_ = cell.get("source") 

138 if input_ is not None: 

139 lines.extend(["# <htmlcell>", ""]) 

140 lines.extend(["# " + line for line in input_.splitlines()]) 

141 lines.append("") 

142 elif cell.cell_type == "markdown": 

143 input_ = cell.get("source") 

144 if input_ is not None: 

145 lines.extend(["# <markdowncell>", ""]) 

146 lines.extend(["# " + line for line in input_.splitlines()]) 

147 lines.append("") 

148 lines.append("") 

149 return str("\n".join(lines)) 

150 

151 

152_reader = PyReader() 

153_writer = PyWriter() 

154 

155reads = _reader.reads 

156read = _reader.read 

157to_notebook = _reader.to_notebook 

158write = _writer.write 

159writes = _writer.writes