22"""
33Notebook 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
910import os
@@ -42,7 +43,7 @@ def process_notebooks(directory="."):
4243 return success_count
4344
4445def 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"\n Processing { 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