@@ -76,22 +76,28 @@ def observe(self, callback):
76
76
class YNotebook (YBaseDoc ):
77
77
def __init__ (self , * args , ** kwargs ):
78
78
super ().__init__ (* args , ** kwargs )
79
- self ._ycells = self ._ydoc .get_array ("cells" )
80
79
self ._ymeta = self ._ydoc .get_map ("meta" )
80
+ self ._ycells = self ._ydoc .get_array ("cells" )
81
+ self ._ymetadata = self ._ydoc .get_map ("metadata" )
81
82
82
83
@property
83
84
def source (self ):
84
- cells = self ._ycells .to_json ()
85
85
meta = self ._ymeta .to_json ()
86
- cast_all (cells , float , int )
86
+ cells = self ._ycells .to_json ()
87
+ metadata = self ._ymetadata .to_json ()
87
88
cast_all (meta , float , int )
89
+ cast_all (cells , float , int )
90
+ cast_all (metadata , float , int )
88
91
for cell in cells :
89
92
if "id" in cell and meta ["nbformat" ] == 4 and meta ["nbformat_minor" ] <= 4 :
90
93
# strip cell IDs if we have notebook format 4.0-4.4
91
94
del cell ["id" ]
95
+ if cell ["cell_type" ] in ["raw" , "markdown" ] and not cell ["attachments" ]:
96
+ del cell ["attachments" ]
97
+
92
98
return dict (
93
99
cells = cells ,
94
- metadata = meta [ " metadata" ] ,
100
+ metadata = metadata ,
95
101
nbformat = int (meta ["nbformat" ]),
96
102
nbformat_minor = int (meta ["nbformat_minor" ]),
97
103
)
@@ -113,33 +119,49 @@ def source(self, value):
113
119
]
114
120
with self ._ydoc .begin_transaction () as t :
115
121
# clear document
122
+ # TODO: use clear
116
123
cells_len = len (self ._ycells )
117
- if cells_len :
118
- self ._ycells .delete_range (t , 0 , cells_len )
119
124
for key in self ._ymeta :
120
125
self ._ymeta .pop (t , key )
126
+ if cells_len :
127
+ self ._ycells .delete_range (t , 0 , cells_len )
128
+ for key in self ._ymetadata :
129
+ self ._ymetadata .pop (t , key )
121
130
for key in [k for k in self ._ystate if k != "dirty" ]:
122
131
self ._ystate .pop (t , key )
123
132
124
133
# initialize document
125
134
ycells = []
126
135
for cell in nb ["cells" ]:
127
- cell ["source" ] = Y .YText (cell ["source" ])
128
136
if "id" not in cell :
129
137
cell ["id" ] = str (uuid4 ())
130
- if "outputs" in cell :
131
- cell ["outputs" ] = Y .YArray (cell ["outputs" ])
138
+ cell_type = cell ["cell_type" ]
139
+ cell ["source" ] = Y .YText (cell ["source" ])
140
+ metadata = {}
141
+ if "metadata" in cell :
142
+ metadata = cell ["metadata" ]
143
+ cell ["metadata" ] = Y .YMap (metadata )
144
+ if cell_type in ["raw" , "markdown" ]:
145
+ attachments = {}
146
+ if "attachments" in cell :
147
+ attachments = cell ["attachments" ]
148
+ cell ["attachments" ] = Y .YMap (attachments )
149
+ elif cell_type == "code" :
150
+ outputs = cell .get ("outputs" , [])
151
+ cell ["outputs" ] = Y .YArray (outputs )
132
152
ycell = Y .YMap (cell )
133
153
ycells .append (ycell )
134
154
135
155
if ycells :
136
156
self ._ycells .extend (t , ycells )
137
- self ._ymeta .set (t , "metadata" , nb ["metadata" ])
157
+ for k , v in nb ["metadata" ].items ():
158
+ self ._ymetadata .set (t , k , v )
138
159
self ._ymeta .set (t , "nbformat" , nb ["nbformat" ])
139
160
self ._ymeta .set (t , "nbformat_minor" , nb ["nbformat_minor" ])
140
161
141
162
def observe (self , callback ):
142
163
self .unobserve ()
143
164
self ._subscriptions [self ._ystate ] = self ._ystate .observe (callback )
144
- self ._subscriptions [self ._ycells ] = self ._ycells .observe_deep (callback )
145
165
self ._subscriptions [self ._ymeta ] = self ._ymeta .observe (callback )
166
+ self ._subscriptions [self ._ycells ] = self ._ycells .observe_deep (callback )
167
+ self ._subscriptions [self ._ymetadata ] = self ._ymetadata .observe (callback )
0 commit comments