跳转至

博客搭建记录

约 1424 个字 185 行代码 7 张图片 预计阅读时间 7 分钟

Abstract

记录搭个人主页 / 咸鱼肆过程中的思考、问题和解决方案!


为什么使用 mkdocs-material?

因为我的笔记长得更像书一样的东西而不是比较零散的博客;看 OIWiki 之类的东西就一直很心动!!


入门教程

Built with Material for MkDocs

另外,由于 mkdocs 对应的仓库里能看到文档的 md 源码,因此其实可以在这两个文档,或者其他用 mkdocs 做的博客(例如 OI Wiki, CTF Wiki 等)里面看有哪些想用的写法,然后从对应的仓库里直接拿进来!


主题颜色 / 夜间模式

Warning

我并不熟悉 HTML/CSS/JS,因此这里的很多做法可能比较蠢QWQ,如果有好的做法请务必告诉我!

是从 OI Wiki 抄的!

修改主题颜色的界面代码长这样:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
### 日间 / 夜间

<div class="tx-switch">
  <button data-md-color-scheme="default"><code>default</code></button>
  <button data-md-color-scheme="slate"><code>slate</code></button>
</div>

<script>
  var buttons = document.querySelectorAll("button[data-md-color-scheme]")
  buttons.forEach(function(button) {
    button.addEventListener("click", function() {
      var attr = this.getAttribute("data-md-color-scheme")
      document.body.setAttribute("data-md-color-scheme", attr)
      localStorage.setItem("data-md-color-scheme",attr);
      updateScheme();
    })
  })
</script>

### 主色

<div class="tx-switch">
  <button class="button1" data-md-color-primary="red" style="background-color:red">red</button>
  <button class="button1" data-md-color-primary="pink" style="background-color:pink;color:black">pink</button>
  <button class="button1" data-md-color-primary="purple" style="background-color:purple">purple</button>
  <button class="button1" data-md-color-primary="indigo" style="background-color:indigo">indigo</button>
  <button class="button1" data-md-color-primary="blue" style="background-color:blue">blue</button>
  <button class="button1" data-md-color-primary="cyan" style="background-color:cyan;color:black">cyan</button>
  <button class="button1" data-md-color-primary="teal" style="background-color:teal">teal</button>
  <button class="button1" data-md-color-primary="green" style="background-color:green">green</button>
  <button class="button1" data-md-color-primary="lime" style="background-color:lime;color:black">lime</button>
  <button class="button1" data-md-color-primary="orange" style="background-color:orange;color:black">orange</button>
  <button class="button1" data-md-color-primary="brown" style="background-color:brown;border-radius=3px">brown</button>
  <button class="button1" data-md-color-primary="grey" style="background-color:grey">grey</button>
  <button class="button1" data-md-color-primary="black" style="background-color:black">black</button>
  <button class="button1" data-md-color-primary="white" style="background-color:white;color:black">white</button>
</div>

<script>
  var buttons = document.querySelectorAll("button[data-md-color-primary]")
  buttons.forEach(function(button) {
    button.addEventListener("click", function() {
      var attr = this.getAttribute("data-md-color-primary")
      document.body.setAttribute("data-md-color-primary", attr)
      localStorage.setItem("data-md-color-primary",attr);
    })
  })
</script>

两段 script 给这些按钮绑定了响应函数,将对应的颜色存入 localStorage

其中 button1 的 css 我放在了一个文件 extra.css 里:

.button1 {
    color: white;
    padding: 1px 4px;
    text-align: center;
    text-decoration: none;
    display: inline-block;
    font-size: 15px;
    margin: 0px 2px;
    cursor: pointer;
    border-radius: 4px;
}

然后,我们在一个文件 extra.js 里面包含了如下代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
(() => {
    var p = localStorage.getItem("data-md-color-primary");
    if (p) {
        document.body.setAttribute('data-md-color-primary', p);
    }
    var a = localStorage.getItem('data-md-color-scheme');
    if (a == null) {
        a = "slate";
        localStorage.setItem("data-md-color-scheme", a);
    }
    document.body.setAttribute('data-md-color-scheme', a);
})()

这段代码就是从 localStorage 里把存了的那些东西拿出来,然后设置到文档的对应位置里去。

我们在 mkdocs.yml 里增加这样的条目,使得每个页面都会包含这段 js,从而每个页面加载时都会运行上面这段代码,进而维持主题的设置:

extra_javascript:
  - 'path/extra.js'

类似地,我们把 extra.css 包含进来:

extra_css:
  - 'path/extra.css'

评论系统

基本的教程参考了 https://squidfunk.github.io/mkdocs-material/setup/adding-a-comment-system/

同时,一个问题是,如何保持评论系统的主题(日间 / 夜间模式)和前面设置的一致呢?在前一节第一段的 md/html 代码的第 15 行有一个 updateScheme();,这个函数也在 extra.js 里,用来在更改主题时通知评论系统同步(其实评论系统的 comment.html 里有 /* Register event handlers after documented loaded */ 的片段,但是响应的和上面抄的 OI Wiki 改的好像并不对应,所以我注释掉了 QWQ):

const updateScheme = e => {
    var giscus = document.querySelector(".giscus-frame");
    var a = localStorage.getItem('data-md-color-scheme');
    var theme = a === "default" ? "light" : "dark";
    alert(a + " -> " + theme);
    giscus.contentWindow.postMessage(
        { giscus: { setConfig: { theme } } },
        "https://giscus.app"
    )
}

同时,我们在评论系统的 comment.html 中,本来也有一段注释了 /* Set palette on initial load */ 的代码,我们也将其改为 updateScheme();


解决公式带纵向滚动条的问题

前置要求

在 mkdocs.yml 里引入一个 css 文件,比如叫 extra.css

extra_css:
- 'path/extra.css'

在 extra.css 里增加这样的东西:

.md-typeset div.arithmatex {
  overflow-y: hidden;
}

显示创建时间和更新时间

在 mkdocs.yml 中增加这样的内容:

plugins:
  - git-revision-date-localized:
      enable_creation_date: true

这个插件需要通过 pip3 install mkdocs-git-revision-date-localized-plugin 来安装。

对应地,如果我们使用 Github Action 之类的 CI 来自动部署博客,我们也需要在其中引入这个插件(见第 18 行高亮处):

.github/workflows/autoBuild.yaml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
name: autoBuild
on:
  push:
    branches:
      - master
      - main
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0
      - uses: actions/setup-python@v2
        with:
          python-version: 3.x
      - run: pip install mkdocs-material
      - run: pip install mkdocs-git-revision-date-localized-plugin
      - run: mkdocs gh-deploy --force

同时,如果使用了 CI 来自动部署博客,需要进一步设置,参见 Note when using build environments;对于 Github Actions,我们需要用上面代码中 11-13 行高亮处的 uses 来代替原先的 - uses: actions/checkout@v2

这里的 enable_creation_date 之类的选项可以在 官方文档 或者 这个插件的文档 里看,我用的是:

plugins:
  - git-revision-date-localized:
      enable_creation_date: true
      type: timeago

效果参见本页最下面))

Tips

如果 mkdocs.yml 里没有

    plugins:
      - search

那要记得加上,因为 MkDocs enables it by default if there is no plugins entry set3.


status 小方块!

效果展示:

blue green red yellow gray

(偷懒,夜间模式下全都弄成白色字体了)

蒋炎岩老师的网站 里偷来了如下 css(里面的部分参数被我改了),放在了 status.css:

.box {
    border-radius: 3px; padding: 1px 4px;
    font-family: 'Lato', 'SimHei', 'STHeiti', 'SimHei', 'Serif';
    font-size: 90%;
}
.box-blue,  .badge-primary  { background-color: rgba(66, 139, 202, 0.5); color: #1d4ed8; }
.box-green, .badge-success  { background-color: rgba(92, 184, 92, 0.5);  color: #15803d; }
.box-red,   .badge-danger   { background-color: rgba(217, 83, 79, 0.5);  color: #b91c1c; }
.box-yellow,.badge-warning  { background-color: rgba(240, 173, 78, 0.5); color: #a16207; }
.box-gray   { background-color: #a0a0a0; }

使用方法如:

<span class="box box-blue">blue</span>
<span class="box box-green">green</span>
<span class="box box-red">red</span>
<span class="box box-yellow">yellow</span>
<span class="box box-gray">gray</span>

另外,如果在暗黑模式,上面的 CSS 设置会看不清。于是偷懒,在暗黑模式把字体全都改成白色;

const updateBoxFontColor = e => {
    var a = localStorage.getItem('data-md-color-scheme');
    if (a !== "default") {
        var elements = document.getElementsByClassName('box');
        for (var i in elements) {
            // alert(elements[i].style.color);
            elements[i].style.color = "white";
        }
    }
}

在 extra.js 里把这个函数的调用加到 (()=>{}) 那个函数的最后去,让它每次自动跑。

Update: 在 这个 commit 里,我改用了官方的明暗模式


字数统计

偷了 xg 的字数统计!在这里:https://github.com/TonyCrane/mkdocs-statistics-plugin


粘贴 URL

因为有粘贴出 [dcl.type.general#1](https://timsong-cpp.github.io/cppwp/n4868/dcl.type.general#1) 的需求(即粘贴这个 URL 时,自动粘贴为 md 的链接格式并将名字填充成 URL 的最后一个 path segment),因此找了找办法。

找到了 https://marketplace.visualstudio.com/items?itemName=mkloubert.vs-script-commands 这个插件,可以自定义 commands

在工作区的 .vscode/settings.json 里加了:

{
    "script.commands": {
        "commands": [
            {
                "id": "xuan.pasteUrl",
                "script": ".vscode/paste_url.js"
            }
        ]
    }
}

其中

.vscode/settings.json
exports.execute = async function () {
    const vscode = require('vscode');

    let editor = vscode.window.activeTextEditor;
    let url = await vscode.env.clipboard.readText();
    let title = url.substring(url.lastIndexOf('/') + 1);
    let markdown = `[${title}](${url})`;
    editor.edit(editBuilder => {
        editBuilder.insert(editor.selection.active, markdown);
    });
}

然后在 VSCode 的 Keyboard Shortcuts 里就能看到 xuan.pasteUrl 了,可以设置一下快捷键和 when


段落链接

标题自己就有链接,不过通过锚的方式可以给任意地方加上链接。

这里 可以跳转到 status 小方块的效果展示区。因为我们在那里加了这样一个锚点:

在页面后面添加 #status_boxes 可以找到页面中 idstatus_boxes 的元素。HTML 中的 id 是唯一的。我们加了一个 idstatus_box<a> 之后就可以通过 #status_boxes 访问到它了!当然也不一定需要是 <a>,别的标签也行。


并排放一些东西

CSS:

.grid {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    gap: 6px;
}

例子:



搭建博客


一些零碎问题

容易忘的东西

  • 代码块标题:title=""
  • 代码块高亮:hl_lines="2 5-10"
  • 行内代码给出对应语言高亮:`#!python range()`,效果是 range()
  • 将其他文件内容插入文件:--8<-- "filename.ext" ,参见 Snippets

在代码块里写代码块

总结来说就是用比要包含的 `{n} 更多的 ` 包裹起来

  • 行内代码使用 ``` ` ``
  • 代码块使用 ```
````markdown
```python
print("Hello World")
```
````

效果:

```python
print("Hello World")
```

表格调整列宽

参考 https://stackoverflow.com/questions/36121672/set-table-column-width-via-markdown

即列宽是由每列最长的元素决定的,因此可以通过给一个元素(比如列标题)定义明确的宽度来调整列宽,例如 <div style="width:290px">property</div>。或者显式地添加若干空格 &nbsp; 也可以达到类似的效果。

嵌入 PDF

把下面的 path 改成 PDF 相对页面的路径就好了:

<object data="path" type="application/pdf" width="100%" height="800">
    <embed src="path" type="application/pdf" />
</object>

widthheight 可以按需修改)

图标

这里 可以搜索到能够使用的图标和对应的代码

设置亮 / 暗主题下显示的不同图片

参见 这里

Example:

Image title Image title

![Image title](https://dummyimage.com/600x400/f5f5f5/aaaaaa#only-light)
![Image title](https://dummyimage.com/600x400/21222c/d5d7e2#only-dark)

键盘按键

可以通过 html 标签 <kbd> 来表示键盘按键,例如 <kbd>Ctrl</kbd> + <kbd>C</kbd> 显示为 Ctrl + C


未完待续!


  1. Material for MkDocs repo 

  2. Material for MkDocs 中文文档 repo 

  3. https://github.com/timvink/mkdocs-git-revision-date-localized-plugin#setup 

颜色主题调整

评论区~

有用的话请给我个赞和 star => GitHub stars
快来跟我聊天~