22
33from  __future__ import  annotations 
44
5+ import  json 
56from  typing  import  TYPE_CHECKING , Any 
67
78if  TYPE_CHECKING :
3738
3839<script> 
3940document.addEventListener('DOMContentLoaded', (event) => { 
40-     setupPyodide('%(id_prefix)s', install=%(install)s, themeLight='%(theme_light)s', themeDark='%(theme_dark)s', session='%(session)s'); 
41+     setupPyodide('%(id_prefix)s', install=%(install)s, themeLight='%(theme_light)s', themeDark='%(theme_dark)s', session='%(session)s', heightConfig=%(height_config)s ); 
4142}); 
4243</script> 
4344""" 
4445
4546_counter  =  0 
4647
4748
49+ def  _calculate_height_config (code : str , extra : dict ) ->  dict :
50+     """Calculate height configuration for the Pyodide editor.""" 
51+     # Get per-block options with defaults 
52+     height  =  extra .pop ("height" , "auto" )
53+     min_height  =  extra .pop ("min_height" , 5 )
54+     max_height  =  extra .pop ("max_height" , 30 )
55+     resize  =  extra .pop ("resize" , True )
56+ 
57+     # Validate and convert types 
58+     if  isinstance (height , str ) and  height  !=  "auto" :
59+         try :
60+             height  =  int (height )
61+         except  ValueError :
62+             height  =  "auto" 
63+ 
64+     if  height  !=  "auto"  and  isinstance (height , int ) and  height  <=  0 :
65+         height  =  "auto" 
66+ 
67+     try :
68+         min_height  =  max (1 , int (min_height ))
69+         max_height  =  max (min_height , int (max_height ))
70+     except  ValueError :
71+         min_height , max_height  =  5 , 30 
72+ 
73+     try :
74+         resize  =  str (resize ).lower () in  ("true" , "1" , "yes" , "on" )
75+     except  (ValueError , AttributeError ):
76+         resize  =  True 
77+ 
78+     # Calculate actual height if "auto" 
79+     if  height  ==  "auto" :
80+         # Count lines in the code, with a reasonable default 
81+         lines  =  len (code .strip ().split ("\n " )) if  code .strip () else  5 
82+         height  =  max (min_height , min (lines , max_height ))
83+ 
84+     return  {
85+         "height" : height ,
86+         "minLines" : min_height ,
87+         "maxLines" : max_height ,
88+         "resize" : resize ,
89+     }
90+ 
91+ 
4892def  _format_pyodide (code : str , md : Markdown , session : str , extra : dict , ** options : Any ) ->  str :  # noqa: ARG001 
4993    global  _counter   # noqa: PLW0603 
5094    _counter  +=  1 
95+ 
96+     # Calculate height configuration for this specific code block 
97+     height_config  =  _calculate_height_config (code , extra )
98+ 
5199    version  =  extra .pop ("version" , "0.26.4" ).lstrip ("v" )
52100    install  =  extra .pop ("install" , "" )
53101    install  =  install .split ("," ) if  install  else  []
@@ -57,6 +105,9 @@ def _format_pyodide(code: str, md: Markdown, session: str, extra: dict, **option
57105        theme  =  f"{ theme } { theme }  
58106    theme_light , theme_dark  =  theme .split ("," )
59107
108+     # Convert height_config to JSON string for JavaScript 
109+     height_config_json  =  json .dumps (height_config )
110+ 
60111    data  =  {
61112        "id_prefix" : f"exec-{ _counter }  ,
62113        "initial_code" : code ,
@@ -66,6 +117,7 @@ def _format_pyodide(code: str, md: Markdown, session: str, extra: dict, **option
66117        "session" : session  or  "default" ,
67118        "play_emoji" : _play_emoji ,
68119        "clear_emoji" : _clear_emoji ,
120+         "height_config" : height_config_json ,
69121    }
70122    rendered  =  _template  %  data 
71123    if  exclude_assets :
0 commit comments