JupyterLab导出HTML时代码块批量折叠展开方法问询
实现JupyterLab导出HTML时批量默认折叠代码块的方案
方法1:自定义nbconvert HTML模板(推荐)
JupyterLab依赖的nbconvert模板可直接修改,给所有代码块批量加上折叠逻辑,导出时一步到位:
- 复制默认模板
先定位nbconvert的模板目录,执行命令:
jupyter --paths
在输出的data路径下找到nbconvert/templates/html,复制其中的lab/index.html.j2(JupyterLab默认使用的模板)到本地,命名为foldable_code.html.j2。
- 修改模板添加折叠功能
打开自定义模板,找到渲染代码块的循环部分,替换为带折叠逻辑的结构,并在末尾添加样式和交互脚本:
{# 替换原代码单元格渲染逻辑 #} {% for cell in cells %} {% if cell.cell_type == 'code' %} <div class="code-fold-container"> <button class="code-fold-btn">📂 展开代码</button> <div class="code-content" style="display:none;"> {{ cell.source | highlight_code(language=cell.metadata.language or 'python') }} {% if cell.outputs %} {{ cell.outputs | nbconvert_outputs }} {% endif %} </div> </div> {% else %} {{ cell.render() }} {% endif %} {% endfor %} {# 在页脚追加CSS和JS #} {% block footer %} {{ super() }} <style> .code-fold-btn { background: #f5f5f5; border: 1px solid #ccc; padding: 4px 8px; cursor: pointer; border-radius: 4px; margin: 8px 0; } .code-content { margin-left: 16px; } </style> <script> document.querySelectorAll('.code-fold-btn').forEach(btn => { btn.addEventListener('click', () => { const content = btn.nextElementSibling; const isHidden = content.style.display === 'none'; content.style.display = isHidden ? 'block' : 'none'; btn.textContent = isHidden ? '📁 折叠代码' : '📂 展开代码'; }); }); </script> {% endblock footer %}
- 使用自定义模板导出
执行命令导出你的notebook:
jupyter nbconvert --to html --template ./foldable_code.html.j2 your_notebook.ipynb
方法2:批量处理已导出的HTML文件
如果不想修改模板,可通过Python脚本给已导出的HTML批量添加折叠功能:
- 先正常导出HTML
jupyter nbconvert --to html your_notebook.ipynb
- 编写处理脚本
新建add_code_folding.py,内容如下:
from bs4 import BeautifulSoup import os def add_code_folding(html_path): with open(html_path, 'r', encoding='utf-8') as f: soup = BeautifulSoup(f.read(), 'html.parser') # 定位JupyterLab导出的代码单元格容器 code_cells = soup.find_all('div', class_='code_cell') for cell in code_cells: # 创建折叠容器和按钮 fold_container = soup.new_tag('div', class_='code-fold-container') fold_btn = soup.new_tag('button', class_='code-fold-btn') fold_btn.string = '📂 展开代码' # 包装原代码内容 content_div = soup.new_tag('div', class_='code-content') content_div['style'] = 'display:none;' for child in cell.contents: content_div.append(child) # 组装并替换原单元格 fold_container.append(fold_btn) fold_container.append(content_div) cell.replace_with(fold_container) # 添加全局样式和交互逻辑 style_tag = soup.new_tag('style') style_tag.string = """ .code-fold-btn { background: #f5f5f5; border: 1px solid #ccc; padding: 4px 8px; cursor: pointer; border-radius: 4px; margin: 8px 0; } .code-content { margin-left: 16px; } """ script_tag = soup.new_tag('script') script_tag.string = """ document.querySelectorAll('.code-fold-btn').forEach(btn => { btn.addEventListener('click', () => { const content = btn.nextElementSibling; const isHidden = content.style.display === 'none'; content.style.display = isHidden ? 'block' : 'none'; btn.textContent = isHidden ? '📁 折叠代码' : '📂 展开代码'; }); }); """ soup.head.append(style_tag) soup.body.append(script_tag) # 保存处理后的文件 with open(html_path.replace('.html', '_foldable.html'), 'w', encoding='utf-8') as f: f.write(str(soup)) # 批量处理当前目录下所有目标HTML文件 for file in os.listdir('.'): if file.endswith('.html') and not file.endswith('_foldable.html'): add_code_folding(file)
- 运行脚本
python add_code_folding.py
运行后会生成带_foldable.html后缀的文件,其中所有代码块默认折叠,点击按钮即可展开。
注意事项
- 方法1需确认模板路径正确性,不同系统的nbconvert模板位置可能略有差异,用
jupyter --paths可快速定位。 - 方法2中若JupyterLab导出的HTML结构有更新,需调整
find_all的选择器,可通过浏览器开发者工具查看代码块的类名。
内容的提问来源于stack exchange,提问作者Yiffany
相关产品推荐
相关产品推荐

