如何为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
相关产品推荐
相关产品推荐

