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

111 statements  

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

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

18 

19import re 

20from typing import List 

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 pass 

36 

37 

38class PyReader(NotebookReader): 

39 """A Python notebook reader.""" 

40 

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

42 """Convert a string to a notebook.""" 

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

44 

45 def to_notebook(self, s, **kwargs): # noqa 

46 """Convert a string to a notebook.""" 

47 lines = s.splitlines() 

48 cells = [] 

49 cell_lines: List[str] = [] 

50 state = "codecell" 

51 for line in lines: 

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

53 pass 

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

55 cell = self.new_cell(state, cell_lines) 

56 if cell is not None: 

57 cells.append(cell) 

58 state = "codecell" 

59 cell_lines = [] 

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

61 cell = self.new_cell(state, cell_lines) 

62 if cell is not None: 

63 cells.append(cell) 

64 state = "htmlcell" 

65 cell_lines = [] 

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

67 cell = self.new_cell(state, cell_lines) 

68 if cell is not None: 

69 cells.append(cell) 

70 state = "markdowncell" 

71 cell_lines = [] 

72 else: 

73 cell_lines.append(line) 

74 if cell_lines and state == "codecell": 

75 cell = self.new_cell(state, cell_lines) 

76 if cell is not None: 

77 cells.append(cell) 

78 ws = new_worksheet(cells=cells) 

79 nb = new_notebook(worksheets=[ws]) 

80 return nb 

81 

82 def new_cell(self, state, lines): 

83 """Create a new cell.""" 

84 if state == "codecell": 

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

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

87 if input_: 

88 return new_code_cell(input=input_) 

89 elif state == "htmlcell": 

90 text = self._remove_comments(lines) 

91 if text: 

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

93 elif state == "markdowncell": 

94 text = self._remove_comments(lines) 

95 if text: 

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

97 

98 def _remove_comments(self, lines): 

99 new_lines = [] 

100 for line in lines: 

101 if line.startswith("#"): 

102 new_lines.append(line[2:]) 

103 else: 

104 new_lines.append(line) 

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

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

107 return text 

108 

109 def split_lines_into_blocks(self, lines): 

110 """Split lines into code blocks.""" 

111 if len(lines) == 1: 

112 yield lines[0] 

113 raise StopIteration() 

114 import ast 

115 

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

117 code = ast.parse(source) 

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

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

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

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

122 

123 

124class PyWriter(NotebookWriter): 

125 """A Python notebook writer.""" 

126 

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

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

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

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

131 for ws in nb.worksheets: 

132 for cell in ws.cells: 

133 if cell.cell_type == "code": 

134 input_ = cell.get("input") 

135 if input_ is not None: 

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

137 lines.extend(input_.splitlines()) 

138 lines.append("") 

139 elif cell.cell_type == "html": 

140 input_ = cell.get("source") 

141 if input_ is not None: 

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

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

144 lines.append("") 

145 elif cell.cell_type == "markdown": 

146 input_ = cell.get("source") 

147 if input_ is not None: 

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

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

150 lines.append("") 

151 lines.append("") 

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

153 

154 

155_reader = PyReader() 

156_writer = PyWriter() 

157 

158reads = _reader.reads 

159read = _reader.read 

160to_notebook = _reader.to_notebook 

161write = _writer.write 

162writes = _writer.writes