You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JupyterLab导出HTML时代码块批量折叠展开方法问询

实现JupyterLab导出HTML时批量默认折叠代码块的方案

方法1:自定义nbconvert HTML模板(推荐)

JupyterLab依赖的nbconvert模板可直接修改,给所有代码块批量加上折叠逻辑,导出时一步到位:

  1. 复制默认模板
    先定位nbconvert的模板目录,执行命令:
jupyter --paths

在输出的data路径下找到nbconvert/templates/html,复制其中的lab/index.html.j2(JupyterLab默认使用的模板)到本地,命名为foldable_code.html.j2。

  1. 修改模板添加折叠功能
    打开自定义模板,找到渲染代码块的循环部分,替换为带折叠逻辑的结构,并在末尾添加样式和交互脚本:
{# 替换原代码单元格渲染逻辑 #}
{% 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 %}
  1. 使用自定义模板导出
    执行命令导出你的notebook:
jupyter nbconvert --to html --template ./foldable_code.html.j2 your_notebook.ipynb

方法2:批量处理已导出的HTML文件

如果不想修改模板,可通过Python脚本给已导出的HTML批量添加折叠功能:

  1. 先正常导出HTML
jupyter nbconvert --to html your_notebook.ipynb
  1. 编写处理脚本
    新建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)
  1. 运行脚本
python add_code_folding.py

运行后会生成带_foldable.html后缀的文件,其中所有代码块默认折叠,点击按钮即可展开。

注意事项

  • 方法1需确认模板路径正确性,不同系统的nbconvert模板位置可能略有差异,用jupyter --paths可快速定位。
  • 方法2中若JupyterLab导出的HTML结构有更新,需调整find_all的选择器,可通过浏览器开发者工具查看代码块的类名。

内容的提问来源于stack exchange,提问作者Yiffany

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 17:25:17