Skip to content

Commit d68cd85

Browse files
committed
‘Hide’ jupyter widget metadata
When we round trip jupyter metadata through YAML, it gets pretty badly mutated. Instead, we just encode it and restore it.
1 parent c5e9454 commit d68cd85

File tree

2 files changed

+20
-0
lines changed

2 files changed

+20
-0
lines changed

src/core/jupyter/jupyter.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ import { pathWithForwardSlashes } from "../path.ts";
149149
import { convertToHtmlSpans, hasAnsiEscapeCodes } from "../ansi-colors.ts";
150150
import { ProjectContext } from "../../project/types.ts";
151151
import { mergeConfigs } from "../config.ts";
152+
import { encode as encodeBase64 } from "encoding/base64.ts";
152153

153154
export const kJupyterNotebookExtensions = [
154155
".ipynb",
@@ -687,9 +688,17 @@ export async function jupyterToMarkdown(
687688
if (options.toIpynb) {
688689
const md: string[] = [];
689690
md.push("---\n");
691+
692+
// If widgets are present, base64 encode their metadata to prevent true round
693+
// tripping through YAML, which heavily mutates the metadata
694+
const widgets = nb.metadata.widgets
695+
? encodeBase64(JSON.stringify(nb.metadata.widgets))
696+
: undefined;
697+
690698
const jupyterMetadata = {
691699
jupyter: {
692700
...nb.metadata,
701+
widgets,
693702
},
694703
};
695704
const yamlText = stringify(jupyterMetadata, {

src/format/ipynb/format-ipynb.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import {
2424
import { formatResourcePath } from "../../core/resources.ts";
2525
import { createFormat } from "../formats-shared.ts";
2626

27+
import { decode as base64decode } from "encoding/base64.ts";
2728
export function ipynbFormat(): Format {
2829
return createFormat("ipynb", {
2930
pandoc: {
@@ -69,6 +70,16 @@ export function ipynbFormat(): Format {
6970
// read notebook
7071
const nb = jupyterFromFile(output);
7172

73+
// We 'hide' widget metafrom the YAML by encoding it to
74+
// prevent the YAML representation from mangling it. Restore
75+
// it here if it is so hidden
76+
const widgets = nb.metadata.widgets;
77+
if (widgets && typeof (widgets) === "string") {
78+
nb.metadata.widgets = JSON.parse(
79+
new TextDecoder().decode(base64decode(widgets)),
80+
);
81+
}
82+
7283
// convert raw cell metadata format to raw_mimetype used by jupyter
7384
nb.cells = nb.cells.map((cell) => {
7485
if (cell.cell_type == "raw") {

0 commit comments

Comments
 (0)