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

如何为Sphinx代码块添加换行切换按钮?

如何给Sphinx的code-block添加换行切换按钮?

想要给Sphinx的code-block添加类似sphinx_copybutton的换行切换按钮(效果参考LazyVim插件文档:缩小浏览器宽度并悬停代码块可见按钮),尝试添加JS、CSS文件实现后,出现两个问题:按钮不在代码块内,且点击无反应。以下是原实现代码及修复方案:

原实现代码

index.rst

Welcome to playground's documentation!
======================================

.. toctree::
   :maxdepth: 2
   :caption: Contents:

.. rst-class:: code-block

   .. code-block:: python

      def hello_world():
          print("Hello, world!")

   .. raw:: html

      <button class="toggle-button">toggle line wrap</button>

styles.css

/* styles.css */
.wrap-lines .code-block {
    white-space: pre-wrap;
    overflow-x: hidden;
}

/* styles.css */
.toggle-button {
    background-color: #007bff;
    color: white;
    border: none;
    padding: 5px 10px;
    cursor: pointer;
}

code_wrap_toggle.js

document.addEventListener("DOMContentLoaded", function () {
    const toggleButtons = document.querySelectorAll(".toggle-button");

    toggleButtons.forEach(function (button) {
        button.addEventListener("click", function () {
            const codeBlock = button.parentElement.nextElementSibling;
            codeBlock.classList.toggle("wrap-lines");
        });
    });
});

conf.py

html_static_path = ['_static']
html_js_files = ["code_wrap_toggle.js"]
html_css_files = ["styles.css"]

def my_visit_line_block(self, node):
    self.new_state(indent=0)
    self.lineblocklevel += 1

def setup(app):
    from sphinx.writers.text import TextTranslator
    TextTranslator.visit_line_block = my_visit_line_block

修复方案

1. 调整按钮与代码块的结构关系

Sphinx生成的code-block会被包裹在highlight类的div中,需要把按钮放到这个容器内才能实现嵌入效果。修改index.rst,用raw html将代码块和按钮包裹在同一个容器:

Welcome to playground's documentation!
======================================

.. toctree::
   :maxdepth: 2
   :caption: Contents:

.. raw:: html
   :file: code_block_with_toggle.html

在_static目录下创建code_block_with_toggle.html文件,内容如下:

<div class="code-block-container">
    <div class="highlight">
        <pre><code class="language-python">def hello_world():
    print("Hello, world!")
</code></pre>
    </div>
    <button class="toggle-button">toggle line wrap</button>
</div>

2. 修正CSS样式,实现嵌入与悬停效果

修改styles.css,让按钮定位在代码块右上角,默认隐藏,悬停时显示,同时修正换行样式的作用目标:

/* 代码块容器相对定位,用于按钮的绝对定位 */
.code-block-container {
    position: relative;
    margin: 1em 0;
}

/* 按钮默认隐藏,悬停容器时显示 */
.code-block-container:hover .toggle-button {
    display: block;
}

/* 按钮定位在右上角 */
.toggle-button {
    position: absolute;
    top: 5px;
    right: 5px;
    background-color: #007bff;
    color: white;
    border: none;
    padding: 3px 8px;
    cursor: pointer;
    font-size: 0.8em;
    border-radius: 3px;
    display: none;
}

/* 换行样式:作用于code元素 */
.wrap-lines code {
    white-space: pre-wrap !important;
    overflow-x: auto;
}

3. 修正JS的DOM选择逻辑

修改code_wrap_toggle.js,正确找到对应的代码块元素:

document.addEventListener("DOMContentLoaded", function () {
    const toggleButtons = document.querySelectorAll(".toggle-button");

    toggleButtons.forEach(function (button) {
        button.addEventListener("click", function () {
            // 获取父容器内的highlight元素
            const highlightBlock = button.parentElement.querySelector(".highlight");
            // 切换wrap-lines类
            highlightBlock.classList.toggle("wrap-lines");
        });
    });
});

4. 清理conf.py冗余代码

删除与换行按钮无关的代码,简化为:

html_static_path = ['_static']
html_js_files = ["code_wrap_toggle.js"]
html_css_files = ["styles.css"]

修改完成后,按钮会嵌入到代码块右上角,悬停时显示,点击可切换代码块的换行状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 00:53:22