跳转至

在mkdocs中的代码块添加展开/折叠功能

约 494 个字 • 127 行代码

在查看pymdown-extensions的文档时,发现在Details页面的底部的两个代码块可以展开和折叠(折叠时只展示几行代码),

而mkdoc-material官方对于将代码块收缩这样的功能给出的解决方案是使用Collapsible blocks

参考mkdocs-material官方的讨论区中的一个讨论

Focussable & Collapsible code blocks. · squidfunk/mkdocs-material · Discussion #3944

但是这种方法会将代码块全部的代码都折叠起来,而我更想要pymdown-extensions文档中那样的可以显示开头几行代码的功能。

于是去查看对应的markdown文件中的源码

details.md

//// collapse-code
```css
...
```
////

发现可能是使用了collapse-code这个东西,于是去查看mkdocs.yml中相关的设置

mkdocs.yml

  - tools.collapse_code:
      expand_text: ''
      collapse_text: ''

然后注意到仓库中有一个tools文件夹,里面刚好有collapse_code.py这个文件,

于是我就把tools这个文件夹复制到了我的仓库中,并在mkdocs.yml添加了相同的设置,

尝试mkdocs serve,但报错

ERROR   -  Config value 'markdown_extensions': Failed to load extension 'tools.collapse_code'.
           ModuleNotFoundError: No module named 'tools'

Aborted with a configuration error!

然后在pymdown-extensions仓库中的issues里找到了这个issue

作者的回答提到了正确的方式是运行

python -m mkdocs serve

用这个命令运行就不会出现ModuleNotFoundError了。

但是我尝试在markdown文件中使用//// collapse-code,而预览的页面中,代码块并没有出现可折叠的效果,于是我怀疑可能是需要添加css属性的设置,就把pymdown-extensions仓库中存放css和js的文件夹复制到了我的仓库中,并仿照在mkdocs.yml中进行添加,预览界面中就出现了这个效果。

经过排查,发现是css中标有.collapse-code的属性以及设置按钮svg属性是相关的。最后为了适配我使用的主题,调整了相关的颜色

css设置
:root>* {
    --highlight-svg-arrow-expand: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10 21v-2H6.41l4.5-4.5-1.41-1.41-4.5 4.5V14H3v7zm4.5-10.09 4.5-4.5V10h2V3h-7v2h3.59l-4.5 4.5z"/></svg>');
    --highlight-svg-arrow-collapse: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19.5 3.09 15 7.59V4h-2v7h7V9h-3.59l4.5-4.5zM4 13v2h3.59l-4.5 4.5 1.41 1.41 4.5-4.5V20h2v-7z"/></svg>')
}

.md-typeset .collapse-code {
    position: relative;
    margin-top: 1em;
    margin-bottom: 1em
}

.md-typeset .collapse-code pre {
    margin-top: 0;
    margin-bottom: 0
}

.md-typeset .collapse-code input {
    display: none
}

.md-typeset .collapse-code input~.code-footer {
    width: 100%;
    margin: 0;
    padding: .25em .5em .25em 0em
}

.md-typeset .collapse-code input~.code-footer label {
    position: relative;
    margin: .05em;
    padding: .15em .8em;
    color: var(--md-primary-bg-color);
    font-size: 90%;
    background-color: var(--md-primary-bg-color);
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-size: contain;
    mask-size: contain;
    border-radius: .1rem;
    cursor: pointer;
    content: ""
}

.md-typeset .collapse-code input~.code-footer label:hover {
    background-color: var(--md-default-fg-color--light)
}

.md-typeset .collapse-code input~.code-footer label::before {
    position: absolute;
    top: .15em;
    left: .15em;
    display: block;
    box-sizing: border-box;
    width: 1.25em;
    height: 1.25em;
    background-color: var(--md-primary-fg-color);
    background-size: 1.25em;
    content: ""
}

.md-typeset .collapse-code input~.code-footer label.expand {
    display: none
}

.md-typeset .collapse-code input~.code-footer label.expand::before {
    -webkit-mask-image: var(--highlight-svg-arrow-expand);
    mask-image: var(--highlight-svg-arrow-expand)
}

.md-typeset .collapse-code input~.code-footer label.collapse::before {
    -webkit-mask-image: var(--highlight-svg-arrow-collapse);
    mask-image: var(--highlight-svg-arrow-collapse)
}

.md-typeset .collapse-code input:checked~.code-footer label.expand {
    display: inline
}

.md-typeset .collapse-code input:checked~.code-footer label.collapse {
    display: none
}

.md-typeset .collapse-code input:checked+div.highlight code {
    max-height: 9.375em;
    overflow: hidden
}

.md-typeset .collapse-code input:checked~.code-footer {
    position: absolute;
    bottom: 0;
    left: 0;
    padding: 2em .5em .5em .8rem;
    background-image: linear-gradient(to bottom, transparent, var(--md-default-bg-color) 80% 100%)
}

.md-typeset .tabbed-alternate.tabbed-set>.tabbed-content>.tabbed-block>.collapse-code:only-child {
    margin-top: 0;
    margin-right: -1.2rem;
    margin-left: -1.2rem;
    padding-right: .6rem;
    padding-left: .6rem
}

.md-typeset .tabbed-alternate.tabbed-set>.tabbed-content>.tabbed-block>.collapse-code:only-child>.code-footer {
    left: .6rem
}

@media screen and (max-width: 44.9375em) {
    .md-typeset>.collapse-code {
        margin-right: -0.8rem;
        margin-left: -0.8rem
    }

    .md-typeset>.collapse-code label.collapse {
        left: .8rem
    }
}

期间还在pymdown-extensions discussions里发了一个提问,但是发完之后自己就一步步解决了😂

How to use collapse-code in tools of this repo? · facelessuser/pymdown-extensions · Discussion #2638


最后更新: 2025-04-03
创建日期: 2025-04-03

评论