Skip to content

Commit 9746c48

Browse files
authored
Enhance notebook converter for GitHub compatibility
1 parent 730db06 commit 9746c48

1 file changed

Lines changed: 25 additions & 23 deletions

File tree

.github/workflows/convert_notebooks.py

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
"""
33
Notebook to GitHub-Compatible Format Converter
44
5-
This script renders XML-format notebooks to standard Jupyter JSON format
6-
with the required widget state metadata for GitHub rendering.
5+
This script fixes Jupyter notebooks for GitHub rendering by:
6+
1. Converting XML-format notebooks to standard Jupyter JSON format
7+
2. Cleaning widget metadata that can cause GitHub rendering issues
78
"""
89

910
import os
@@ -42,7 +43,7 @@ def process_notebooks(directory="."):
4243
return success_count
4344

4445
def convert_notebook(filepath):
45-
"""Convert a XML notebook to standard Jupyter JSON format"""
46+
"""Convert a notebook to GitHub-compatible format by cleaning widget metadata"""
4647
print(f"\nProcessing {filepath}")
4748

4849
try:
@@ -99,6 +100,7 @@ def convert_notebook(filepath):
99100
"pygments_lexer": "ipython3",
100101
"version": "3.8.10"
101102
},
103+
# Add empty widget state to prevent GitHub rendering issues
102104
"widgets": {
103105
"application/vnd.jupyter.widget-state+json": {
104106
"state": {},
@@ -117,34 +119,34 @@ def convert_notebook(filepath):
117119
return True
118120

119121
else:
120-
# It's already in JSON format, check if it has widget state
122+
# It's already in JSON format, clean widget metadata
121123
try:
122-
nb_dict = json.loads(content)
124+
notebook = json.loads(content)
125+
print(f" Cleaning widget metadata...")
123126

124-
# Check if we need to add widget state metadata
125-
if "widgets" not in nb_dict.get("metadata", {}):
126-
print(f" Adding widget state metadata to JSON notebook...")
127-
nb = nbformat.reads(content, as_version=4)
128-
if "metadata" not in nb:
129-
nb.metadata = {}
130-
nb.metadata["widgets"] = {
127+
# Remove potentially problematic widget state but keep proper structure
128+
if 'metadata' in notebook:
129+
# Replace with clean widget state
130+
notebook['metadata']['widgets'] = {
131131
"application/vnd.jupyter.widget-state+json": {
132132
"state": {},
133133
"version_major": 2,
134134
"version_minor": 0
135135
}
136136
}
137-
138-
# Validate and write the notebook
139-
validate(nb)
140-
with open(filepath, 'w', encoding='utf-8') as f:
141-
nbformat.write(nb, f)
142-
143-
print(f" Successfully added widget state to {filepath}")
144-
return True
145-
else:
146-
print(f" Notebook already in correct format for GitHub, no changes needed")
147-
return True
137+
138+
# Clean widget metadata from cells as well
139+
for cell in notebook.get('cells', []):
140+
if 'metadata' in cell and 'widgets' in cell['metadata']:
141+
del cell['metadata']['widgets']
142+
143+
# Write the cleaned notebook
144+
with open(filepath, 'w', encoding='utf-8') as f:
145+
json.dump(notebook, f, indent=2)
146+
147+
print(f" Successfully cleaned {filepath} for GitHub compatibility")
148+
return True
149+
148150
except json.JSONDecodeError:
149151
print(f" ERROR: {filepath} is not in valid JSON format or XML format")
150152
return False

0 commit comments

Comments
 (0)