83、【Ubuntu】【Hugo】搭建私人博客:文章目录(二)

【声明】本博客所有内容均为个人业余时间创作,所述技术案例均来自公开开源项目(如Github,Apache基金会),不涉及任何企业机密或未公开技术,如有侵权请联系删除

背景

上篇 blog
【Ubuntu】【Hugo】搭建私人博客:文章目录(一)

分析了文章的目录 TOC 功能,并分析了 PaperMod 主题下的默认 toc.html 模板,其中分析完了【提取标题】,下面继续【<details> 可折叠容器】的分析

搭建私人博客

继续看 【<details> 可折叠容器】

  • {``{if (.Param "TocOpen") }} open{``{ end }}:Hugo 模板语法,作用是如果在文章的标题开头写了 TocOpen = true,比如

    或者在 hugo.toml 配置文件中,加入了这个全局配置项,那么 Hugo 在渲染这里时,会自动加上 open 这个属性,这里就会变成 <details open>,表示页面一打开,目录就展开(本来默认是收起的)
  • accesskey="c":设置一个快捷键 ,在大多数浏览器中,按下 Alt + C(Windows)就能聚焦到这个 <summary> 上
  • titile="...":鼠标悬停在这里时,显示的提示文字,告诉用户这里可以使用快捷键

OK,看第三部分:选择 TOC 的生成方式

如果在文章,或 hugo.toml 的全局配置中,启用了配置项 UseHugoToc = true,就会直接使用 Hugo 内置的 .TableOfContents,更简单,但样式(风格)和 PaperMod 不一定是匹配的,否则就执行下面复杂的手动解析过程(PaperMod 默认方式,样式更统一)

第四部分:手动构建嵌套列表(核心难点)

这部分很复杂,因为 Hugo 模板语言没有循环栈,或者递归函数,只能用模拟栈的方式去处理嵌套层级

这里要区分下 Hugo 模板语言和 Go 语言,虽然 Hugo 是用 Go 语言开发的,但在比如 toc.html 这样模板文件上,写的不是 Go 代码,而是 Hugo 的模板语言(基于 Go 的 text/template 和 html/template)

这个模板语言有如下特点:

  • 支持变量,if 条件判断,range 循环等
  • 不支持函数定义,递归,复杂数据结构的操作(比如栈,队列等)
  • 不能直接把字符串转成整数,所以这里需要用 len (seq "$headerLevel") 这样的技巧

简单来说,Hugo 模板是一个受限,表达能力有限的 DSL(领域特定语言),和完整的 Go 语言有很大区别

OK,继续看这段代码

go 复制代码
 {{- $largest := 6 -}}
 {{- range $headers -}}
 {{- $headerLevel := index (findRE "[1-6]" . 1) 0 -}}
 {{- $headerLevel := len (seq $headerLevel) -}}
 {{- if lt $headerLevel $largest -}}
 {{- $largest = $headerLevel -}}

这段代码的的含义是,找出最小标题级别,比如(h2 是 2,h3 是 3,则最小是 2),这里 $largest 实际上是最小的标题数字(对应最高层级,比如 h2 在标题上比 h3 要大)

这里可能有人会有疑问,如果按这么说的话,那最小的不都是 h1 吗?

答案是不一定,因为有人可能不按常理出牌,他可能会跳过 h1 标题,直接用 h2,甚至 h3 标题开头,就比如

md 复制代码
---
title: "跳过 h1 的文章"
toc: true
---

## 这是 h2 标题
一些内容...

### 这是 h3 子标题
更多内容...

可以看到,这里并没有 h1 标题,所以 PaperMod 的 toc.html 处理中,并不假设必须有 h1 或 h2,而是动态找出所有标题中最小的层级(比如全是 h3/h4,就以 h3 为根),并以这个最小层级作为 TOC 的顶层,所有更深的标题都作为它的子项,相当于把 h3 当做逻辑上的顶级标题来对待,就好像一本书,如果第一章直接从 【1.3 小节】开始(中间没有【1.1 小节】,【1.2 小节】),那就把 【1.3 小节】当成第一章的主标题来列目录,虽然奇怪,但是技术上可行


OK,本篇先到这里,如有疑问,欢迎评论区留言讨论,祝各位功力大涨,技术更上一层楼!!!更多内容见下篇 blog
【Ubuntu】【Hugo】搭建私人博客:文章目录(三)

相关推荐
陈布衣26 分钟前
MySQL(1)_MySQL 5.7.21 Linux 安装笔记
linux·笔记·mysql
分布式存储与RustFS2 小时前
给 RustFS 桶加一层内存缓存:用 Alluxio 让热数据少跑一遍网络
运维·云原生·开源·对象存储·分布式存储·s3·性能基准
Oiiouui2 小时前
linux服务器部署Logto后端与对应前端的实现
linux·服务器·前端·后端
ITKEY_3 小时前
用 Emacs Dired 实现 em:退出文件管理器后,让终端自动切换目录
linux·服务器·emacs
wt95273 小时前
VMware 虚拟机磁盘扩容实战文档(Ubuntu 22.04 + LVM)
linux·后端
就像楞次定律3 小时前
【Linux 学习记之二】C++ 构建体系与底层链接机制的深度透视(2)
linux·后端
Decay__3 小时前
22_MySQL 运维自动化平台 —— 部署编排 + 监控 + 巡检 + 告警 + 工单闭环一体化
运维·数据库·sql·mysql·架构
无足鸟ICT3 小时前
【RHCA+】slabtop命令(查看slab缓存)
linux
且从容.3 小时前
Ubuntu 安装 Docker
linux·ubuntu·docker
青梅味猪大肠4 小时前
【操作系统-60】临近适应算法
java·linux·开发语言·嵌入式硬件·算法·操作系统