1"""Code for converting notebooks to and from the v2 format."""
2
3# Copyright (c) IPython Development Team.
4# Distributed under the terms of the Modified BSD License.
5from __future__ import annotations
6
7from .nbbase import nbformat, nbformat_minor
8
9
10def _unbytes(obj):
11 """There should be no bytes objects in a notebook
12
13 v2 stores png/jpeg as b64 ascii bytes
14 """
15 if isinstance(obj, dict):
16 for k, v in obj.items():
17 obj[k] = _unbytes(v)
18 elif isinstance(obj, list):
19 for i, v in enumerate(obj):
20 obj[i] = _unbytes(v)
21 elif isinstance(obj, bytes):
22 # only valid bytes are b64-encoded ascii
23 obj = obj.decode("ascii")
24 return obj
25
26
27def upgrade(nb, from_version=2, from_minor=0):
28 """Convert a notebook to v3.
29
30 Parameters
31 ----------
32 nb : NotebookNode
33 The Python representation of the notebook to convert.
34 from_version : int
35 The original version of the notebook to convert.
36 from_minor : int
37 The original minor version of the notebook to convert (only relevant for v >= 3).
38 """
39 if from_version == 2:
40 # Mark the original nbformat so consumers know it has been converted.
41 nb.nbformat = nbformat
42 nb.nbformat_minor = nbformat_minor
43
44 nb.orig_nbformat = 2
45 nb = _unbytes(nb)
46 for ws in nb["worksheets"]:
47 for cell in ws["cells"]:
48 cell.setdefault("metadata", {})
49 return nb
50 if from_version == 3:
51 if from_minor != nbformat_minor:
52 nb.orig_nbformat_minor = from_minor
53 nb.nbformat_minor = nbformat_minor
54 return nb
55 msg = (
56 "Cannot convert a notebook directly from v%s to v3. "
57 "Try using the nbformat.convert module." % from_version
58 )
59 raise ValueError(msg)
60
61
62def heading_to_md(cell):
63 """turn heading cell into corresponding markdown"""
64 cell.cell_type = "markdown"
65 level = cell.pop("level", 1)
66 cell.source = "#" * level + " " + cell.source
67
68
69def raw_to_md(cell):
70 """let raw passthrough as markdown"""
71 cell.cell_type = "markdown"
72
73
74def downgrade(nb):
75 """Convert a v3 notebook to v2.
76
77 Parameters
78 ----------
79 nb : NotebookNode
80 The Python representation of the notebook to convert.
81 """
82 if nb.nbformat != 3:
83 return nb
84 nb.nbformat = 2
85 for ws in nb.worksheets:
86 for cell in ws.cells:
87 if cell.cell_type == "heading":
88 heading_to_md(cell)
89 elif cell.cell_type == "raw":
90 raw_to_md(cell)
91 return nb