diff --git a/.markdownlint.jsonc b/.markdownlint.jsonc
index 1dda4b77..b8e0a768 100644
--- a/.markdownlint.jsonc
+++ b/.markdownlint.jsonc
@@ -1,25 +1,7 @@
{
- "MD007": {
- // Unordered list indentation
- "indent": 4
- },
- "MD013": false, // Line length
- "MD033": {
- // Inline HTML
- "allowed_elements": [
- "br", // Useful in tables
- "figure",
- "figcaption",
- "s",
- "del" // Python-Markdown parsing issue with CJK
- ]
- },
- "MD046": false, // Use fenced code block style, too many false positives
- "MD051": false, // Link fragments should be valid, false positives
- "MD052": false, // Reference link should be defined and used, false positives with includes/man.md
- "MD010": false, // Some command output contains hard tabs
- "MD024": {
- // Allow multiple headers with the same content, if they are not siblings
- "siblings_only": true
- }
+ "MD046": false, // Always use code blocks for commands and outputs.
+ "MD014": false, // Linux 101 always prepend '$' or '#' to command lines.
+ "MD033": false, // Allow inline HTML, required by some special cases.
+ "MD053": false, // False postive for footnotes.
+ "extends": "node_modules/markdownlint/style/prettier.json",
}
diff --git a/README.md b/README.md
index 6bd6ff50..2dd4a6c2 100644
--- a/README.md
+++ b/README.md
@@ -16,7 +16,7 @@
## 友情链接
-- [Linux 201](https://github.com/ustclug/Linux201-docs)
+- [Linux 201](https://github.com/ustclug/Linux201-docs)
## Star History
diff --git a/docs/Appendix/distribution.md b/docs/Appendix/distribution.md
index ade1b92b..7be3a05f 100644
--- a/docs/Appendix/distribution.md
+++ b/docs/Appendix/distribution.md
@@ -6,9 +6,9 @@
Ubuntu 基于 Debian,并且相比 Debian 而言更加新手友好。而 Debian 的开发周期更慢,它的 Stable 分支也更加稳定。在很多方面来说,它们的区别不大,但是仍然需要注意一些事情:
-- 不同的发行版、不同的分支的软件源不能混用。向 Debian 添加 Ubuntu 或 Ubuntu PPAs 的源可能会导致软件依赖的混乱。
-- Debian 不会预置一些 Ubuntu 特有的特性。从 Snapcraft 商店、Livepatch(在不停机的情况下修复内核漏洞的服务)到 ZSys(由 Ubuntu 开发的 ZFS 管理工具)都不会预置在 Debian 中。
-- 在日常使用中,Debian 也有一些小的区别,例如默认情况下,`/sbin` 不在普通用户的 PATH 中。
+- 不同的发行版、不同的分支的软件源不能混用。向 Debian 添加 Ubuntu 或 Ubuntu PPAs 的源可能会导致软件依赖的混乱。
+- Debian 不会预置一些 Ubuntu 特有的特性。从 Snapcraft 商店、Livepatch(在不停机的情况下修复内核漏洞的服务)到 ZSys(由 Ubuntu 开发的 ZFS 管理工具)都不会预置在 Debian 中。
+- 在日常使用中,Debian 也有一些小的区别,例如默认情况下,`/sbin` 不在普通用户的 PATH 中。
## CentOS 与 Fedora {#centos-and-fedora}
@@ -31,9 +31,9 @@ $ sudo dnf upgrade # 更新系统
SELinux 是由 NSA 编写的开源的 Linux 安全模块,在 CentOS 和 Fedora 上都默认开启。SELinux 解决的问题是,传统的 DAC(自主访问控制, Discretionary Access Control)安全模型(我们在第五章中看到的 `rwx` 就是传统的模型)无法有效应对一些安全风险,如[^1]:
-- 用户可能会把「任何人都可读取」的权限赋予在敏感文件(如 SSH 密钥)上。
-- 用户的进程可以修改文件的安全性属性。例如,邮件程序可以(尽管不应该)将邮件文件设置为「任何人都可读取」。
-- 用户的进程继承用户的权限,如果进程本身有问题或是不安全,那么攻击者可以以该用户的权限作任何事情。例如,如果浏览器被攻击,它可以读取到用户的 SSH 密钥,但浏览器显然不应该做这种事情。
+- 用户可能会把「任何人都可读取」的权限赋予在敏感文件(如 SSH 密钥)上。
+- 用户的进程可以修改文件的安全性属性。例如,邮件程序可以(尽管不应该)将邮件文件设置为「任何人都可读取」。
+- 用户的进程继承用户的权限,如果进程本身有问题或是不安全,那么攻击者可以以该用户的权限作任何事情。例如,如果浏览器被攻击,它可以读取到用户的 SSH 密钥,但浏览器显然不应该做这种事情。
SELinux 添加了额外的「强制访问控制」安全措施:系统中所有的文件、进程和端口等都被贴上了 SELinux 标签,如果访问者(Subject)和被访问对象(Object)的标签不符合规则,访问则会被拒绝。
@@ -172,9 +172,9 @@ NixOS 的整个系统配置都写在 `/etc/nixos/configuration.nix` 文件中。
NixOS 使用哈希值来标识每个包,相同内容的包总是有相同的哈希值。这意味着:
-- 不同版本的软件可以同时存在而不会冲突
-- 系统更新是原子性的,要么完全成功,要么完全失败
-- 可以轻松回滚到任何之前的配置
+- 不同版本的软件可以同时存在而不会冲突
+- 系统更新是原子性的,要么完全成功,要么完全失败
+- 可以轻松回滚到任何之前的配置
### 软件包管理 {#nixos-package-management}
@@ -265,13 +265,13 @@ $ nix-shell # 使用 shell.nix 文件定义开发环境
### 学习资源 {#nixos-resources}
-- [NixOS 官方手册](https://nixos.org/manual/nixos/stable/)
-- [NixOS Wiki](https://nixos.wiki/)
-- [Nix Pills - 深入学习 Nix 概念](https://nixos.org/guides/nix-pills/)
-- [Awesome Nix - Nix 生态系统资源](https://github.com/nix-community/awesome-nix)
-- [NixOS 中文](https://nixos-cn.org/)
-- [NixOS 与 Flakes 一份非官方的新手指南](https://nixos-and-flakes.thiscute.world/zh/)
-- [nix_resources](https://linktr.ee/nix_resources)
-- [wrapper-manager](https://viperml.github.io/wrapper-manager/)
+- [NixOS 官方手册](https://nixos.org/manual/nixos/stable/)
+- [NixOS Wiki](https://nixos.wiki/)
+- [Nix Pills - 深入学习 Nix 概念](https://nixos.org/guides/nix-pills/)
+- [Awesome Nix - Nix 生态系统资源](https://github.com/nix-community/awesome-nix)
+- [NixOS 中文](https://nixos-cn.org/)
+- [NixOS 与 Flakes 一份非官方的新手指南](https://nixos-and-flakes.thiscute.world/zh/)
+- [nix_resources](https://linktr.ee/nix_resources)
+- [wrapper-manager](https://viperml.github.io/wrapper-manager/)
NixOS 的学习曲线相对陡峭,但一旦掌握,它提供了传统发行版无法比拟的系统管理体验。特别适合需要可重现环境、频繁实验或需要强系统一致性的用户。
diff --git a/docs/Appendix/man.md b/docs/Appendix/man.md
index a1601add..7ba0d70e 100644
--- a/docs/Appendix/man.md
+++ b/docs/Appendix/man.md
@@ -46,7 +46,7 @@
## 命令行工具:以 `su` 为例
-```
+```text
SU(1) User Commands SU(1)
(第一行的标题是 User Commands,两边的 SU(1) 代表这篇文档是关于 `su` 的,在文档第一卷。
第一卷与 Shell 命令和程序有关。更多信息可以查看 man man 中 DESCRIPTION 一节的内容。)
@@ -262,7 +262,7 @@ util-linux July 2014 SU(1)
文档第三卷是程序库函数的信息,包括了 C 语言的标准库函数。
-```
+```text
STRCMP(3) Linux Programmer's Manual STRCMP(3)
NAME
@@ -320,7 +320,7 @@ COLOPHON(作者信息、文档来源等信息)
文档第二卷是关于系统调用的信息。当然,很多系统调用都由 C 运行时库包装了一层,否则用起来很麻烦。一个目前还没有被包装的系统调用的例子是 `copy_file_range()`,你需要在你的代码里面使用 `syscall()` 去手动包装它,才能方便地使用。
-```
+```text
KILL(2) Linux Programmer's Manual KILL(2)
NAME
diff --git a/docs/Appendix/markdown.md b/docs/Appendix/markdown.md
index be949cde..b4808a58 100644
--- a/docs/Appendix/markdown.md
+++ b/docs/Appendix/markdown.md
@@ -194,14 +194,14 @@ Markdown 使用一种和链接很相似的语法来标记图片,看起来像
我们推荐使用 [Typora](https://typoraio.cn/) 进行 Markdown 的编写,也可以使用 VSCode 配置 Markdown 插件进行编写。下面是一些推荐的 VSCode 插件:
-- [Markdown All in One](https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one)(`yzhang.markdown-all-in-one`)
-- [Markdown Preview Enhanced](https://marketplace.visualstudio.com/items?itemName=shd101wyy.markdown-preview-enhanced)(`shd101wyy.markdown-preview-enhanced`)
-- [Markdown Preview GitHub Styling](https://marketplace.visualstudio.com/items?itemName=bierner.markdown-preview-github-styles)(`bierner.markdown-preview-github-styles`)
+- [Markdown All in One](https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one)(`yzhang.markdown-all-in-one`)
+- [Markdown Preview Enhanced](https://marketplace.visualstudio.com/items?itemName=shd101wyy.markdown-preview-enhanced)(`shd101wyy.markdown-preview-enhanced`)
+- [Markdown Preview GitHub Styling](https://marketplace.visualstudio.com/items?itemName=bierner.markdown-preview-github-styles)(`bierner.markdown-preview-github-styles`)
你可以根据需要进行安装。
## 参考资料
-- [Markdown 官方教程](https://markdown.com.cn/)
-- [知乎:使用 vscode 开始 Markdown 写作之旅](https://zhuanlan.zhihu.com/p/56943330/)
-- [USTC OSH-2023 课程主页](https://osh-2023.github.io/lab0/markdown/)
+- [Markdown 官方教程](https://markdown.com.cn/)
+- [知乎:使用 vscode 开始 Markdown 写作之旅](https://zhuanlan.zhihu.com/p/56943330/)
+- [USTC OSH-2023 课程主页](https://osh-2023.github.io/lab0/markdown/)
diff --git a/docs/Ch01/index.md b/docs/Ch01/index.md
index c553d5e0..93dd0a3c 100644
--- a/docs/Ch01/index.md
+++ b/docs/Ch01/index.md
@@ -93,14 +93,14 @@ Linux 内核并不是一个完整的操作系统,因为它过于精简,单
Debian 是一个完全由自由软件构成的类 UNIX 操作系统,第一个版本发布于 1993 年 9 月 15 日,迄今仍在维护,是最早的发行版之一。其以坚持自由软件精神和生态环境优良而出名,拥有庞大的用户群体,甚至自己也成为了一个主流的子框架,称为“Debian GNU/Linux”。
-
+
Debian 图标
{: .caption }
Debian GNU/Linux 也派生了很多发行版,其中最为著名的便是 Ubuntu(官方译名“友邦拓”)。Ubuntu 由英国的 Canonical 公司主导创立,是一个主打桌面应用的操作系统。其为一般用户提供了一个时新且稳定的由自由软件构成的操作系统,且拥有庞大的社群力量和资源,十分适合普通用户使用。
-
+
Ubuntu 图标
{: .caption }
@@ -109,14 +109,14 @@ Ubuntu 图标
Red Hat Linux 是美国的 Red Hat 公司发行的一个发行版,第一个版本发布于 1994 年 11 月 3 日,也是一个历史悠久的发行版。它曾经也广为使用,但在 2003 年 Red Hat 公司停止了对它的维护,转而将精力都投身于其企业版 Red Hat Enterprise Linux(简称 RHEL)上,Red Hat Linux 自此完结,而商业市场导向的 RHEL 维护至今。
-
+
Red Hat 公司商标,RHEL 是其旗下产品
{: .caption }
在 Red Hat Linux 在停止官方更新后,由社群启动的 Fedora 项目接管了其源代码并构筑了自己的更新,演变成了如今的 Fedora 发行版。Fedora 是一套功能完备且更新迅速的系统,且本身计划也受到了 Red Hat 公司的赞助,成为了公司测试新技术的平台。
-
+
Fedora 图标
{: .caption }
@@ -125,7 +125,7 @@ Fedora 图标
2020 年 12 月,CentOS 社区在其博客中[宣布未来的重点转向 CentOS Stream](https://www.redhat.com/en/blog/centos-stream-building-innovative-future-enterprise-linux),这是一个全新的滚动发行版。在此之前,RHEL 的上游为 Fedora,而 CentOS 的上游为 RHEL;在推出 CentOS Stream 之后,它就成为了 RHEL 的上游发行版。与此同时,CentOS 8 的支持期限被缩短至 2021 年底,且不再推出新的非 Stream 的 CentOS 版本。不满于该决定的人们也组织了新的社区,推出了诸如 [AlmaLinux](https://almalinux.org/)、[Rocky Linux](https://rockylinux.org/) 等发行版。
-
+
CentOS 图标
{: .caption }
@@ -134,14 +134,14 @@ CentOS 图标
Arch Linux 是一个基于 x86-64 架构的 Linux 发行版,不过因为其内核默认就包含了部分非自由的模块,所以其未受到 GNU 计划的官方支持。即便如此,Arch Linux 也因其“简单、现代、实在、人本、万能”的宗旨赢得了 Linux 中坚用户的广泛青睐。不过,Arch Linux 对这个宗旨的定义和其它发行版有所区别。通常的操作系统为了方便用户快速上手,都是尽可能隐藏底层细节,从而避免用户了解操作系统的运行知识即可直接使用。但是 Arch Linux 则是重在构建优雅、极简的代码结构,这方便了使用者去理解系统,但不可避免地要求使用者自身愿意去了解操作系统的运作方式。某种程度上说,它的“简单”和“人本”注重的是方便用户通过了解而去最大化地利用它,而不是采取屏蔽工作原理的方式来降低使用门槛。因此,本书不建议初学者直接上手 Arch Linux,但十分推荐在读者对 Linux 有进一步了解之后去探索它。
-
+
Arch Linux 图标
{: .caption }
Arch Linux 拥有强大的功能,但因其特殊的理念使得用户不易使用。为了能让一般用户也能用上 Arch Linux 的强大功能,它的变种 Manjaro 发行版于 2011 年问世。Manjaro 发行版基于 Arch Linux,但更注重易用,因而更适合一般用户。
-
+
Manjaro 图标
{: .caption }
@@ -166,7 +166,7 @@ Manjaro 图标
由谷歌公司推出的 Android 叫做 Android 原生系统,而基于该原生系统诞生出来的各类独特的操作系统就是 Android/Linux 系下的子发行版。Android/Linux 下的子发行版很多,如华为公司的 EMUI 操作系统和小米公司的 MIUI 操作系统等。
-
+
Android 10 原生界面
{: .caption }
@@ -179,7 +179,7 @@ Android 10 原生界面
另一类有名的服务器操作系统是微软公司的 Windows Server 系列,不过其流行程度比不上各类 Linux 发行版。
-
+
Windows Server 图标
{: .caption }
@@ -188,7 +188,7 @@ Windows Server 图标
比起十几年前采用传统线路的电视,现在国内很多家庭里的电视都换成了智能数字电视,这些电视通常会配备一个机顶盒来控制电视播放的内容。实际上,电视机顶盒就是一个嵌入式设备,而 Android/Linux 分支下的各类发行版正是主流的嵌入式操作系统,如谷歌公司为数字电视专门推出的 Android TV 操作系统。
-
+
Android TV 图标
{: .caption }
@@ -199,17 +199,17 @@ Android TV 图标
在本机上安装一个 Linux 发行版有很多种选择,如:安装方法可以选择实机安装或虚拟机安装;发行版则可以在诸多选项中任意抉择。然而,对于新手来说,本书**不建议直接采用实机安装 Linux**,因为这样做会面临以下问题:
-- 在安装过程中不理解关键的选项(如:磁盘分区、挂载、交换空间分配等)的意义,很容易做出错误的决定;
-- 错误的配置可能导致自己原先本机上的操作系统和数据遭到不可逆转的损坏;
-- 部分硬件可能对安装的发行版缺少兼容,从而导致意外安装失败。
-- 如果安装的过程中选择下载附加工具,可能会因为默认镜像在国外而导致下载十分缓慢,从而让安装流程变得很漫长。
+- 在安装过程中不理解关键的选项(如:磁盘分区、挂载、交换空间分配等)的意义,很容易做出错误的决定;
+- 错误的配置可能导致自己原先本机上的操作系统和数据遭到不可逆转的损坏;
+- 部分硬件可能对安装的发行版缺少兼容,从而导致意外安装失败。
+- 如果安装的过程中选择下载附加工具,可能会因为默认镜像在国外而导致下载十分缓慢,从而让安装流程变得很漫长。
鉴于以上问题对于新手来说十分常见,本书的编写组为各位读者专门提供了另外一种更为安全高效的方法:在虚拟机上运行 Linux 发行版镜像。虚拟机简单来说可以视作一个安全可靠的沙盒,它受到虚拟机管理软件的管理,而管理软件是直接安装在自己目前常用的操作系统上的。本书**推荐使用虚拟机运行安装完毕的 Linux 镜像**,因为这样会有如下优点:
-- 读者仍然可以安心地使用自己当前的操作系统,因为虚拟机不干涉当前电脑操作系统的配置。
-- 无需考虑底层硬件的兼容性问题,稳定性大幅提升。
-- 系统已经安装完毕,使用虚拟机打开时相当于直接开机,无需经历安装流程。
-- 如果在虚拟机中发生任何错误,可以通过重置、回溯虚拟机镜像的方法无痛修复,而不会伤害到读者计算机上的操作系统和数据。
+- 读者仍然可以安心地使用自己当前的操作系统,因为虚拟机不干涉当前电脑操作系统的配置。
+- 无需考虑底层硬件的兼容性问题,稳定性大幅提升。
+- 系统已经安装完毕,使用虚拟机打开时相当于直接开机,无需经历安装流程。
+- 如果在虚拟机中发生任何错误,可以通过重置、回溯虚拟机镜像的方法无痛修复,而不会伤害到读者计算机上的操作系统和数据。
因此,本书将主要讲解如何为自己搭建一个安全高效的 Linux 虚拟机。如果你有一台远程的 Linux 服务器,可以参考[拓展阅读](./supplement.md#ssh)的内容配置 SSH 连接。
@@ -217,9 +217,9 @@ Android TV 图标
现在在 Windows / macOS 上主流的虚拟机管理软件有:
-- [VMware Workstation Pro](https://support.broadcom.com/group/ecx/productdownloads?subfamily=VMware+Workstation+Pro) 是 VMware 公司(现已被博通收购)推出的一款 Windows 上的虚拟机管理软件,现已免费。
-- [VMware Fusion Pro](https://support.broadcom.com/group/ecx/productdownloads?subfamily=VMware+Fusion) 是 VMware 公司为 macOS 平台推出的虚拟机管理软件,现已免费。
-- [VirtualBox](https://www.virtualbox.org/wiki/Downloads) 是甲骨文公司发行的通用虚拟机管理系统,支持 Windows 和 macOS,且遵循 GPLv2 开源。
+- [VMware Workstation Pro](https://support.broadcom.com/group/ecx/productdownloads?subfamily=VMware+Workstation+Pro) 是 VMware 公司(现已被博通收购)推出的一款 Windows 上的虚拟机管理软件,现已免费。
+- [VMware Fusion Pro](https://support.broadcom.com/group/ecx/productdownloads?subfamily=VMware+Fusion) 是 VMware 公司为 macOS 平台推出的虚拟机管理软件,现已免费。
+- [VirtualBox](https://www.virtualbox.org/wiki/Downloads) 是甲骨文公司发行的通用虚拟机管理系统,支持 Windows 和 macOS,且遵循 GPLv2 开源。
以上软件都是免费的,且支持中文。点击上面对应的链接进入官方下载页面获取安装包,获取完毕后,直接双击打开安装程序,根据安装步骤完成安装即可。
@@ -227,8 +227,8 @@ Android TV 图标
Xubuntu 是 Ubuntu 的一个子发行版,它与 Ubuntu 非常类似,但其体积更小,性能需求更少,因此十分适合各种不同性能的电脑安装使用。本书的编写组已经制作了 Xubuntu 的虚拟机镜像,供读者按需求下载使用。
-- (推荐)Xubuntu 24.04 64 位([VMware](https://ftp.lug.ustc.edu.cn/101/vm/VMware-Xubuntu-24.04-amd64.ova),[VirtualBox](https://ftp.lug.ustc.edu.cn/101/vm/VirtualBox-Xubuntu-24.04-amd64.ova))
-- Xubuntu 22.04 64 位([VMware](https://ftp.lug.ustc.edu.cn/101/vm/VMware-Xubuntu-22.04-amd64.ova),[VirtualBox](https://ftp.lug.ustc.edu.cn/101/vm/VirtualBox-Xubuntu-22.04-amd64.ova))
+- (推荐)Xubuntu 24.04 64 位([VMware](https://ftp.lug.ustc.edu.cn/101/vm/VMware-Xubuntu-24.04-amd64.ova),[VirtualBox](https://ftp.lug.ustc.edu.cn/101/vm/VirtualBox-Xubuntu-24.04-amd64.ova))
+- Xubuntu 22.04 64 位([VMware](https://ftp.lug.ustc.edu.cn/101/vm/VMware-Xubuntu-22.04-amd64.ova),[VirtualBox](https://ftp.lug.ustc.edu.cn/101/vm/VirtualBox-Xubuntu-22.04-amd64.ova))
目前 Ubuntu 已经不再提供 32 位字长的镜像支持,64 位的镜像可以在绝大部分计算机上运行,并且仍然支持运行 32 位的应用。
@@ -261,8 +261,8 @@ Xubuntu 是 Ubuntu 的一个子发行版,它与 Ubuntu 非常类似,但其
如果读者想要自己安装 Ubuntu 操作系统的话,以下两篇博客也可以参考:
-- [在 Windows 下使用 VMware Workstation 安装 Ubuntu](https://ibug.io/p/15-cn)(另有[英文版](https://ibug.io/p/15))
-- [在 macOS 下使用 VMware Fusion 和 VirtualBox 安装 Ubuntu](https://blog.taoky.moe/2019-02-23/installing-os-on-vm.html)
+- [在 Windows 下使用 VMware Workstation 安装 Ubuntu](https://ibug.io/p/15-cn)(另有[英文版](https://ibug.io/p/15))
+- [在 macOS 下使用 VMware Fusion 和 VirtualBox 安装 Ubuntu](https://blog.taoky.moe/2019-02-23/installing-os-on-vm.html)
??? tip "Windows 下使用 VirtualBox"
@@ -283,19 +283,19 @@ Xubuntu 是 Ubuntu 的一个子发行版,它与 Ubuntu 非常类似,但其
若已经安装了上述虚拟机管理软件,则可以直接双击打开虚拟机镜像,管理软件会打开并导入该镜像,导入完毕后可直接点击开始按钮启动。
-
+
VirtualBox 导入设置(需要手动选择镜像)
{: .caption }
-
+
VMware Workstation 启动 Xubuntu 18.04 虚拟机
{: .caption }
如果读者采用了上面列出的虚拟机之一,其默认登录用户名和密码均为 `ustc`,输入密码即可登录虚拟机系统桌面。
-
+
Xubuntu 18.04 虚拟机桌面
{: .caption }
@@ -304,7 +304,7 @@ Xubuntu 18.04 虚拟机桌面
LUG@USTC 是中国科学技术大学主流的开源社群,也是校内最大的学术科技类社团。其现今拥有数百名热爱开源文化的成员,并受益于他们而正在蓬勃发展。LUG@USTC 维护了中国最大的开源镜像站之一 [USTC Mirrors](https://mirrors.ustc.edu.cn/),其作为本土的软件源为国内许多开源软件用户提供了镜像服务,是本社群对社会作出的一项重要贡献。
-
+
LUG@USTC 图标
{: .caption }
@@ -313,7 +313,7 @@ LUG@USTC 图标
你可以从 [LUG@USTC 官方网站](https://lug.ustc.edu.cn/wiki/)中了解我们。官方网站中包括了我们在校内开展的各类流行活动和面向校内外提供的诸多网络服务。
-LUG@USTC 欢迎校内外的朋友加入社群交流。如果你是中国科学技术大学在读学生,你可以通过致邮 {: .img-inline } 附上姓名与学号申请加入本社群;如果你是校外人士,也可以致邮获取进一步的沟通交流方式。
+LUG@USTC 欢迎校内外的朋友加入社群交流。如果你是中国科学技术大学在读学生,你可以通过致邮 {: .img-inline } 附上姓名与学号申请加入本社群;如果你是校外人士,也可以致邮获取进一步的沟通交流方式。
## 思考题 {#questions}
@@ -349,6 +349,9 @@ LUG@USTC 欢迎校内外的朋友加入社群交流。如果你是中国科学
## 引用来源与备注 {#references .no-underline}
[^1]: 数据来自中国互联网信息中心[第 54 次 《中国互联网络发展状况统计报告》(全文)](https://www.cnnic.cn/NMediaFile/2024/0911/MAIN1726017626560DHICKVFSM6.pdf)。
+
[^2]: 信息来自维基百科条目:[操作系统](https://zh.wikipedia.org/wiki/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F)。
+
[^3]: 尽管有许多说法称 Ubuntu LTS 有十年的支持,但是后五年实际上是 Extended Security Maintenance (ESM) 阶段,需要付费的 Ubuntu Advantage 订阅,或者最多 3 台设备的个人免费订阅。ESM 的安全更新仓库与主仓库也是独立的,需要登录后才能访问。
+
[^4]: 数据来自 Ubuntu 介绍:[The Ubuntu lifecycle and release cadence](https://ubuntu.com/about/release-cycle)。
diff --git a/docs/Ch01/supplement.md b/docs/Ch01/supplement.md
index b19e3dd3..65dd082d 100644
--- a/docs/Ch01/supplement.md
+++ b/docs/Ch01/supplement.md
@@ -12,7 +12,7 @@ Android 是 Linux 发行版,但它不是 GNU/Linux,Android 不使用 GNU 的
[AOSP (Android Open Source Project)](https://source.android.google.cn/) 只使用了 GPL 许可证的 Linux Kernel,而在 Kernel 之上的 [ART (Android Runtime)](https://source.android.google.cn/docs/core/runtime)、Bionic C 库、驱动透明化的 [HAL (Hardware Abstraction Layer)](https://source.android.google.cn/docs/core/architecture/hal) 则作为用户态存在,避免 Android 系统框架、Google 移动应用服务框架(GMS)和各厂商的驱动程序被 GPL 感染而开源。
-
+
Android 软件堆栈
{: .caption }
@@ -31,7 +31,7 @@ Android 软件堆栈
读者在使用 Fedora、CentOS、Scientific Linux、RHEL 等系统时,可能会遇到这样的错误:
-- SELinux is preventing XXXX from read access on the file YYYY.
+- SELinux is preventing XXXX from read access on the file YYYY.
这是因为有一个叫做 SELinux 的安全增强组件阻止了一些有潜在风险的操作。
@@ -69,7 +69,7 @@ Max kernel policy version: 31
使用 `setenforce 0` **临时** 改变 SELinux 状态到 `permissive`,这个状态在重启后将恢复为配置文件指定的默认值。
-```
+```console
# setenforce 0
```
@@ -80,7 +80,7 @@ Max kernel policy version: 31
编辑完成后,使用 `sestatus` 可以看到修改效果:
-```
+```console
[...]
Current mode: permissive # <-
Mode from config file: permissive # <- 或 disabled
@@ -95,13 +95,13 @@ Mode from config file: permissive # <- 或 disabled
如果在高分屏(HiDPI)上安装系统,可能会遇到屏幕缩放的问题。可以通过以下方法确认自己是否正在使用高分屏:
-- Windows: 桌面右键,点击「显示设置」,在「缩放与布局」中查看其中的百分比,如果大于 100%,则是高分屏。
-- Mac: 如果你的 Mac 是 Retina 屏幕,那么它就是高分屏。也可以对比「关于本机」->「更多信息」中显示器的分辨率规格与「显示器设置」中实际的分辨率。
+- Windows: 桌面右键,点击「显示设置」,在「缩放与布局」中查看其中的百分比,如果大于 100%,则是高分屏。
+- Mac: 如果你的 Mac 是 Retina 屏幕,那么它就是高分屏。也可以对比「关于本机」->「更多信息」中显示器的分辨率规格与「显示器设置」中实际的分辨率。
因此,虚拟化软件有两种策略。以物理分辨率为 2560x1600,逻辑分辨率为 1440x900,全屏显示为例(缩放比大约为 178%):
-- 向虚拟机汇报实际的物理像素(2560x1600),这样默认情况(不缩放)下虚拟机中的文字和图标会变得非常小。
-- 向虚拟机汇报缩放后的像素(1440x900),这样默认情况下虚拟机中的文字和图标大小是正常的,但是会模糊一些。
+- 向虚拟机汇报实际的物理像素(2560x1600),这样默认情况(不缩放)下虚拟机中的文字和图标会变得非常小。
+- 向虚拟机汇报缩放后的像素(1440x900),这样默认情况下虚拟机中的文字和图标大小是正常的,但是会模糊一些。
如果对显示效果不满意,可以采取以下任一方式调整。
@@ -109,8 +109,8 @@ Mode from config file: permissive # <- 或 disabled
VirtualBox 可以在启动后调整缩放策略。点击菜单栏的「查看」(或「视图」)->「虚拟显示屏 1」(或「虚拟显示器 1」),可以看到缩放比例选项,并且有两种包含了备注的比例:
-- 100%(输出未缩放/unscaled output):代表向虚拟机汇报实际的物理像素。
-- 输出自动缩放/autoscaled output:代表向虚拟机汇报缩放后的像素。
+- 100%(输出未缩放/unscaled output):代表向虚拟机汇报实际的物理像素。
+- 输出自动缩放/autoscaled output:代表向虚拟机汇报缩放后的像素。
默认选择的是 100% 选项,因此可能首次开机会发现界面过小。如果可以接受界面略显模糊,可以选择「输出自动缩放」。
@@ -122,8 +122,8 @@ VMware Workstation (Windows) 中其默认会向虚拟机汇报实际的物理像
Xfce 下有多处与缩放调整有关的设置。调整 Xfce 的缩放有两种方式:
-- 调整显示器缩放设置
-- 调整元素 DPI
+- 调整显示器缩放设置
+- 调整元素 DPI
点击左上角,选择设置管理。在「硬件」->「显示」中可以调整显示器缩放。
@@ -138,9 +138,9 @@ Xfce 下有多处与缩放调整有关的设置。调整 Xfce 的缩放有两种
在「外观」->「字体」中可以调整元素 DPI。默认情况下,Xfce 的 DPI 是 96,将其乘以预期的缩放比并输入。
此时可能会发现 UI 不太协调,以下提供了一些可能需要调整的设置,按类似方式相乘即可:
-- 桌面图标:右键桌面 -> 桌面设置 -> 图标 -> 图标大小
-- 托盘大小:右键面板 -> 面板 -> 面板首选项 -> 「尺寸」下面的「行大小」
-- 鼠标光标:设置 -> 硬件 -> 鼠标和触摸板 -> 主题 -> 光标大小
+- 桌面图标:右键桌面 -> 桌面设置 -> 图标 -> 图标大小
+- 托盘大小:右键面板 -> 面板 -> 面板首选项 -> 「尺寸」下面的「行大小」
+- 鼠标光标:设置 -> 硬件 -> 鼠标和触摸板 -> 主题 -> 光标大小
### 扩大磁盘大小 {#vm-disk-resize}
@@ -168,7 +168,7 @@ I/O 大小(最小/最佳):512 字节 / 512 字节
```
这里可以看到,`/dev/sda2` 这个**分区**被自动扩大了。
-如果没有,那么可以输入以下命令(请勿输入 `$ `,详见[记号约定](../notations.md#command-line)):
+如果没有,那么可以输入以下命令(请勿输入 `$`,详见[记号约定](../notations.md#command-line)):
```console
$ LANGUAGE=C sudo growpart /dev/sda 2
@@ -443,10 +443,10 @@ ustc@ustclug-linux101:~$
如何将 Linux 下的软件与开发生态移植到 Windows 上?在 WSL 出现之前,开发者们进行了各种尝试。这也催生出了一些软件与方案,例如:
-- Cygwin。它包含了一大批 Linux 上的 GNU 和其他的开源工具。它的核心是一个程序库 (`cygwin1.dll`),这个程序库在 Windows 环境下实现了 POSIX API 的功能。Linux 上的软件,可以通过**重新编译**,链接 Cygwin 的方式,在 Windows 上运行。
-- MinGW。它包含了 GCC 和 GNU Binutils 等工具的 Windows 移植。它不支持类似于 `fork()` 这样无法简单用 Windows API 实现的 POSIX API,但是相比于 Cygwin 来说更加轻量,甚至可以在 Linux 上使用 MinGW 交叉编译 Windows 程序。
-- MSYS2。使用 Cygwin 和 MinGW 组建的开发环境,并且使用 Pacman 作为包管理器。
-- Cooperative Linux。这个项目尝试让 Linux 内核和 Windows 内核同时运行在相同的硬件上。Linux 内核经过修改,以能够与 Windows 内核共享硬件资源。这个项目已经长期未活跃了。
+- Cygwin。它包含了一大批 Linux 上的 GNU 和其他的开源工具。它的核心是一个程序库 (`cygwin1.dll`),这个程序库在 Windows 环境下实现了 POSIX API 的功能。Linux 上的软件,可以通过**重新编译**,链接 Cygwin 的方式,在 Windows 上运行。
+- MinGW。它包含了 GCC 和 GNU Binutils 等工具的 Windows 移植。它不支持类似于 `fork()` 这样无法简单用 Windows API 实现的 POSIX API,但是相比于 Cygwin 来说更加轻量,甚至可以在 Linux 上使用 MinGW 交叉编译 Windows 程序。
+- MSYS2。使用 Cygwin 和 MinGW 组建的开发环境,并且使用 Pacman 作为包管理器。
+- Cooperative Linux。这个项目尝试让 Linux 内核和 Windows 内核同时运行在相同的硬件上。Linux 内核经过修改,以能够与 Windows 内核共享硬件资源。这个项目已经长期未活跃了。
当然,我们可以看到,没有一个稳定的方案可以不加修改地直接运行 Linux 程序,直到 WSL 出现。WSL 由微软开发,可以在 64 位的 Windows 10 和 Windows Server 2016 及以上的版本上运行原生(ELF 格式)的 Linux 程序(安装方法详见 WSL 的官方[安装指南](https://learn.microsoft.com/zh-cn/windows/wsl/install))。
@@ -466,9 +466,9 @@ WSL 1 面向 Linux 应用程序提供了一套兼容的内核接口,在 Linux
WSL 2 尝试解决一些 WSL 1 的方式难以解决的问题:
-- 由于其是以翻译系统调用的方式实现 Linux 兼容,WSL 1 无法运行依赖于复杂内核特性的程序(如 Docker),无法运行硬件驱动程序。
-- 没有硬件加速,图形性能差。OpenCL 与 CUDA 也尚未在 WSL 1 中实现。
-- 受到各种因素的影响(如 Windows Defender),WSL 1 的 I/O 性能远低于 Linux 内核的实现。
+- 由于其是以翻译系统调用的方式实现 Linux 兼容,WSL 1 无法运行依赖于复杂内核特性的程序(如 Docker),无法运行硬件驱动程序。
+- 没有硬件加速,图形性能差。OpenCL 与 CUDA 也尚未在 WSL 1 中实现。
+- 受到各种因素的影响(如 Windows Defender),WSL 1 的 I/O 性能远低于 Linux 内核的实现。
WSL2 使用微软的 Hyper-V 虚拟化技术,运行一个轻量的、完整的 Linux 内核。
@@ -498,13 +498,13 @@ WSL2 使用微软的 Hyper-V 虚拟化技术,运行一个轻量的、完整的
可供参考的内容:
-- [The Unofficial Fusion 13 for Apple Silicon Companion Guide](https://communities.vmware.com/t5/VMware-Fusion-Documents/The-Unofficial-Fusion-13-for-Apple-Silicon-Companion-Guide/ta-p/2939907/jump-to/first-unread-message)
+- [The Unofficial Fusion 13 for Apple Silicon Companion Guide](https://communities.vmware.com/t5/VMware-Fusion-Documents/The-Unofficial-Fusion-13-for-Apple-Silicon-Companion-Guide/ta-p/2939907/jump-to/first-unread-message)
如果遇到以上文档中无法解决的问题,可以继续参考下面的两个针对于 VMWare Fusion 22H2 Tech Preview 的文档:
-- [Fusion 22H2 Tech Preview Testing Guide](https://communities.vmware.com/t5/Fusion-22H2-Tech-Preview/Fusion-22H2-Tech-Preview-Testing-Guide/ta-p/2867908)
+- [Fusion 22H2 Tech Preview Testing Guide](https://communities.vmware.com/t5/Fusion-22H2-Tech-Preview/Fusion-22H2-Tech-Preview-Testing-Guide/ta-p/2867908)
-- [Tips and Techniques for the Apple Silicon Tech Preview 22H2](https://communities.vmware.com/t5/Fusion-22H2-Tech-Preview/Tips-and-Techniques-for-the-Apple-Silicon-Tech-Preview-22H2/ta-p/2893986)
+- [Tips and Techniques for the Apple Silicon Tech Preview 22H2](https://communities.vmware.com/t5/Fusion-22H2-Tech-Preview/Tips-and-Techniques-for-the-Apple-Silicon-Tech-Preview-22H2/ta-p/2893986)
#### 下载 VMWare Fusion 13 Player {#download-vmware-fusion}
@@ -514,12 +514,12 @@ WSL2 使用微软的 Hyper-V 虚拟化技术,运行一个轻量的、完整的
首先你需要选择 Ubuntu 发行版。截止到 2023 年 2 月,各个较新的发行版在 VMWare Fusion 上的支持情况为:
-- Ubuntu 20.04.5 LTS (Focal Fossa):可以使用,需要经过改动才能修改图形界面的分辨率。
-- Ubuntu 22.04 LTS (Jammy Jellyfish):从 Ubuntu 22.04.2 LTS 开始可以直接使用。
+- Ubuntu 20.04.5 LTS (Focal Fossa):可以使用,需要经过改动才能修改图形界面的分辨率。
+- Ubuntu 22.04 LTS (Jammy Jellyfish):从 Ubuntu 22.04.2 LTS 开始可以直接使用。
本节选用 Ubuntu 20.04.5 (arm64, server) 作为接下来安装的系统。
-
+
你可以在 [中国科学技术大学开源软件镜像](https://mirrors.ustc.edu.cn/) 获取安装镜像。
{: .caption }
@@ -528,22 +528,22 @@ WSL2 使用微软的 Hyper-V 虚拟化技术,运行一个轻量的、完整的
下载好安装镜像后,打开 VMWare Fusion,导入你下载的镜像:
-
+
点击左上角的加号创建新的虚拟机
{: .caption }
-
+
将你下载好的镜像拖入框中
{: .caption }
-
+
导入完成之后使用默认配置即可,你也可以按照自己的需求对 configuration 进行对应的改动。
{: .caption }
-
+
用键盘对命令行界面进行操作,在配置用户名前的配置一般可以选择默认配置。本页面中你需要配置你的用户名,服务器名称和密码。
{: .caption }
@@ -562,7 +562,7 @@ $ sudo apt-get install ubuntu-desktop
安装好之后需要重新启动虚拟机,这时你应该可以看到你的登陆界面了:
-
+
虚拟机的图形界面
{: .caption }
@@ -601,4 +601,5 @@ $ sudo apt-get install ubuntu-desktop
## 引用来源 {#references .no-underline}
[^1]: [Apple silicon - Wikipedia](https://en.wikipedia.org/wiki/Apple_silicon)
+
[^2]: [Ventoy 中文网站](https://www.ventoy.net/cn/index.html)
diff --git a/docs/Ch02/index.md b/docs/Ch02/index.md
index 934d1e5c..13cd3f1b 100644
--- a/docs/Ch02/index.md
+++ b/docs/Ch02/index.md
@@ -56,14 +56,14 @@ Xfce
我们直接打开 Xfce 中的设置管理器,如图所示。
-
+
图 1. 设置管理器的位置
{: .caption }
这里最常见的设置,都可以找得到。
-
+
图 2. 设置管理器
{: .caption }
@@ -74,7 +74,7 @@ xfdesktop 桌面管理器是 Xfce 中的一个主要模块,它负责在桌面
##### 背景 {#desktop-background}
-
+
图 3. 桌面背景首选项
{: .caption }
@@ -92,7 +92,7 @@ xfdesktop 桌面管理器是 Xfce 中的一个主要模块,它负责在桌面
##### 菜单 {#desktop-menus}
-
+
图 4. 桌面菜单首选项
{: .caption }
@@ -101,21 +101,21 @@ Xfce 允许用户自定义右键菜单和中键菜单的行为。这里可以对
若「在桌面上右击时包含应用程序菜单」选项被选中,则在桌面右键时会显示下面的菜单,用于快速打开应用程序。
-
+
图 5. 桌面应用程序菜单
{: .caption }
若「在桌面上中击时显示窗口列表菜单」选项被选中时,中击桌面可以弹出工作区的菜单,可以显示所有工作区正在运行的应用程序。
-
+
图 6. 桌面工作区菜单
{: .caption }
##### 图标 {#desktop-icons}
-
+
图 7. 桌面图标首选项
{: .caption }
@@ -128,7 +128,7 @@ Xfce 允许用户绘制桌面图标并且设置其外观。
##### 样式 {#appearance-styles}
-
+
图 8. 外观样式首选项
{: .caption }
@@ -141,7 +141,7 @@ Xfce 允许用户绘制桌面图标并且设置其外观。
##### 图标 {#appearance-icons}
-
+
图 9. 外观图标首选项
{: .caption }
@@ -154,7 +154,7 @@ Xfce 允许用户绘制桌面图标并且设置其外观。
##### 字体 {#appearance-fonts}
-
+
图 10. 外观字体首选项
{: .caption }
@@ -171,7 +171,7 @@ xfwm4 窗口管理器也是 Xfce 桌面环境的核心模块。窗口管理器
##### 样式 {#wm-styles}
-
+
图 11. 窗口管理器样式首选项
{: .caption }
@@ -180,7 +180,7 @@ Xfce 允许用户自定义窗口的样式,「样式」对话框是用来控制
##### 键盘 {#wm-keyboard}
-
+
图 12. 窗口管理器键盘首选项
{: .caption }
@@ -191,14 +191,14 @@ Xfce 允许用户自定义窗口的样式,「样式」对话框是用来控制
Xfce-panel 也是 Xfce 的核心模块,具有应用程序启动器,面板菜单,工作区切换器等功能。
-
+
图 13. 默认的顶部面板
{: .caption }
##### 显示 {#panels-display}
-
+
图 14. 面板显示首选项
{: .caption }
@@ -215,7 +215,7 @@ Xfce-panel 也是 Xfce 的核心模块,具有应用程序启动器,面板菜
##### 项目 {#panels-items}
-
+
图 15. 面板项目首选项
{: .caption }
@@ -232,7 +232,7 @@ Thunar 是 Xfce 桌面环境的现代文件管理器。Thunar 从一开始就被
##### 布局 {#file-manager-layout}
-
+
图 16. 文件管理器
{: .caption }
@@ -243,14 +243,14 @@ Thunar 是 Xfce 桌面环境的现代文件管理器。Thunar 从一开始就被
如果不喜欢主界面的图标显示,我们还可以选择「视图」→ 「以详细列表查看来以列表显示」。在列表显示的时候,我们可以通过「视图」→「配置栏」管理列表显示的属性。
-
+
图 17. 文件管理器列表显示
{: .caption }
还有更多可以配置的选项,可以在「编辑」→ 「首选项」中配置。
-
+
图 18. 文件管理器首选项
{: .caption }
@@ -265,14 +265,14 @@ Xfce4-session 是 Xfce 的会话管理器。它的任务是保存桌面的状态
在「设置管理器」的「会话和启动」中可以配置它。
-
+
图 19. 会话与启动
{: .caption }
##### 应用程序自启动 {#autostart}
-
+
图 20. 自启动首选项
{: .caption }
@@ -289,9 +289,9 @@ Xfce4-session 是 Xfce 的会话管理器。它的任务是保存桌面的状态
使用命令行操作可以减少鼠标操作,我们经常可以使用一条命令来代替好几次的鼠标单击。例如如果我们想要移动某一个文件,我们要执行下面步骤:
-- 打开文件所在的文件夹 `/path/to/source/`
-- 打开目标文件夹 `/path/to/dest/`
-- 从 `source` 文件夹拖拽文件 `file.txt` 到 `dest` 文件夹中
+- 打开文件所在的文件夹 `/path/to/source/`
+- 打开目标文件夹 `/path/to/dest/`
+- 从 `source` 文件夹拖拽文件 `file.txt` 到 `dest` 文件夹中
然而使用命令行,我们只需要执行一条指令。
@@ -432,23 +432,23 @@ $ sh run.sh
在图形界面中,我们需要另一个和 shell 交互的程序,叫做终端模拟器,通常它的名称为「终端(Terminal)」。我们可以在「所有程序」找到它。
-
+
图 21. 终端在菜单的位置
{: .caption }
打开后如下图。
-
+
图 22. 终端界面
{: .caption }
### 几条简单的命令 {#shell-commands}
-- `ls`: 列出(**l**i**s**t)目录的内容
-- `cd`: 更改目录(**c**hange **d**irectory)
-- `pwd`: 查看当前所在的目录(**p**rint **w**orking **d**irectory)
+- `ls`: 列出(**l**i**s**t)目录的内容
+- `cd`: 更改目录(**c**hange **d**irectory)
+- `pwd`: 查看当前所在的目录(**p**rint **w**orking **d**irectory)
更多的命令行操作我们将在[第三章](../Ch03/index.md)和[第六章](../Ch06/index.md)详细介绍。
@@ -560,7 +560,7 @@ $ sudo bash wordpress.sh
最后我们打开浏览器并进入 `http://localhost/blog` 来完成最后的配置。
-
+
图 23. WordPress 的初始化配置界面
{: .caption }
@@ -585,7 +585,7 @@ $ jekyll serve
打开浏览器,在浏览器中输入 `localhost:4000` 进入我们搭建的网站。
-{: .img-border }
+{: .img-border }
图 24. Jekyll 的默认网页
{: .caption }
@@ -602,5 +602,5 @@ $ jekyll serve
## 引用来源 {#references .no-underline}
-- [Xfce 文档](https://docs.xfce.org/xfce/start)
-- [Ubuntu 下安装 WordPress](https://ubuntu.com/tutorials/install-and-configure-wordpress)
+- [Xfce 文档](https://docs.xfce.org/xfce/start)
+- [Ubuntu 下安装 WordPress](https://ubuntu.com/tutorials/install-and-configure-wordpress)
diff --git a/docs/Ch02/supplement.md b/docs/Ch02/supplement.md
index 8fe6a107..f89fb402 100644
--- a/docs/Ch02/supplement.md
+++ b/docs/Ch02/supplement.md
@@ -34,7 +34,7 @@ $ sudo reboot
重启后可以看到,GNOME 桌面已经安装完成。我们拥有了图形界面。
-
+
可以看到,通过简单几步,我们的桌面环境就安装成功了。
@@ -68,7 +68,7 @@ $ sudo apt install gnome-tweaks
点击 Download 下载一个压缩包:
-
+
解压后放到 `~/.themes` 文件夹,若不存在该文件夹则创建一个。
@@ -100,7 +100,7 @@ $ gnome-tweaks
#### GNOME 的 Shell 扩展 {#gnome-extensions}
-GNOME 支持很多扩展,并且有一个专门用于扩展的网站。https://extensions.gnome.org/
+GNOME 支持很多扩展,并且有一个专门用于扩展的网站:。
要使用 GNOME 扩展,我们要先安装 `gnome-shell-extensions`。
@@ -112,7 +112,7 @@ $ sudo apt install gnome-shell-extensions
Caffeine: 允许用户停用系统屏幕保护和自动休眠。
-
+
先来查看我们正在使用的 GNOME 版本:
@@ -126,11 +126,11 @@ $ gnome-shell --version
然后将文件夹的名字改为 `metadata.json` 中的 UUID:
-
+
-本例中,UUID 为 "caffeine@patapon.info"
+本例中,UUID 为 `caffeine@patapon.info`
-
+
并将该文件夹放到 `~/.local/share/gnome-shell/extensions/` 中。
@@ -142,7 +142,7 @@ $ gnome-tweaks
在扩展一栏即可启用我们刚刚装的 caffeine。
-
+
!!! tip "提示"
@@ -168,19 +168,19 @@ $ gnome-tweaks
除了系统自带的外观样式和图标外,网络上有更多的主题提供下载。例如在 [Xfce-look](https://www.xfce-look.org/) 上,就有上万个不同类型的主题。安装方法也十分简单。
-
+
我们可以选中任意一款主题。我们以下面这个为例。
-
+
点击 Download 按钮下载它,一般会得到压缩包格式的文件。我们打开设置管理器中的「外观」首选项,把下载好的压缩包文件直接拖拽到样式列表中。
-
+
选中刚刚拖拽进去的主题即可更换。
-
+
!!! tip "提示"
@@ -290,10 +290,10 @@ $ sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/t
下面介绍几个常用的配置文件:
-- `/etc/fstab` 系统磁盘挂载相关配置;
-- `/etc/bash.bashrc` 启动 Bash 时读取的配置脚本;
-- `/etc/sudoers` sudo 权限的配置;
-- `/etc/hosts` 主机名与 IP 映射关系的配置。
+- `/etc/fstab` 系统磁盘挂载相关配置;
+- `/etc/bash.bashrc` 启动 Bash 时读取的配置脚本;
+- `/etc/sudoers` sudo 权限的配置;
+- `/etc/hosts` 主机名与 IP 映射关系的配置。
??? example "示例"
@@ -462,4 +462,4 @@ $ sudo service mysql start
## 引用来源 {#references .no-underline}
-- [How to install themes with GNOME tweak tool? - Ask Ubuntu](https://askubuntu.com/a/1128098/612877)
+- [How to install themes with GNOME tweak tool? - Ask Ubuntu](https://askubuntu.com/a/1128098/612877)
diff --git a/docs/Ch03/index.md b/docs/Ch03/index.md
index 44e6c323..390d950e 100644
--- a/docs/Ch03/index.md
+++ b/docs/Ch03/index.md
@@ -1041,13 +1041,13 @@ https://www.gnu.org/software/tar
可以从输出中快速地了解到:
-- 创建存档文件;
-- 创建压缩的存档文件;
-- 解压一个存档文件;
-- 解压一个存档文件到指定目录;
-- 创建一个存档文件,并通过给定的目标存档文件的后缀名判断希望的压缩算法。在例子中,目标存档文件的后缀名是 `tar.gz` ,即希望创建由 gzip 压缩的存档文件;
-- 给出一个存档文件中的文件列表;
-- 解压一个存档文件,但是只有特定的文件名的文件才会被解压(在例子中,使用了通配符 `*.html` ,即只有以 `.html` 结尾的文件才会被解压)。
+- 创建存档文件;
+- 创建压缩的存档文件;
+- 解压一个存档文件;
+- 解压一个存档文件到指定目录;
+- 创建一个存档文件,并通过给定的目标存档文件的后缀名判断希望的压缩算法。在例子中,目标存档文件的后缀名是 `tar.gz` ,即希望创建由 gzip 压缩的存档文件;
+- 给出一个存档文件中的文件列表;
+- 解压一个存档文件,但是只有特定的文件名的文件才会被解压(在例子中,使用了通配符 `*.html` ,即只有以 `.html` 结尾的文件才会被解压)。
## 思考题 {#questions}
@@ -1102,5 +1102,7 @@ https://www.gnu.org/software/tar
## 引用来源 {#references .no-underline}
[^1]: [软件仓库](http://people.ubuntu.com/~happyaron/udc-cn/lucid-html/ch06s09.html)
+
[^2]: [Ubuntu 源使用帮助](https://mirrors.ustc.edu.cn/help/ubuntu.html)
+
[^3]: [Debian 13 发布说明:已废弃软件包](https://www.debian.org/releases/trixie/release-notes/issues.zh_CN.html#noteworthy-obsolete-packages)
diff --git a/docs/Ch03/supplement.md b/docs/Ch03/supplement.md
index 8a0b4ef0..ff7ea445 100644
--- a/docs/Ch03/supplement.md
+++ b/docs/Ch03/supplement.md
@@ -24,7 +24,7 @@ icon: material/puzzle
在从源代码安装 Nginx 前,需要为它的库安装依赖:
-- PCRE2 - 用于支持正则表达式。
+- PCRE2 - 用于支持正则表达式。
```console
$ wget https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.42/pcre2-10.42.tar.gz
@@ -39,7 +39,7 @@ $ sudo make install
PCRE 有两个大版本,其中最新的 PCRE2 正在持续维护,而发布于 1997 年的旧版的 PCRE 已经停止维护。PCRE2 的源代码包目前托管于 GitHub 上。相关信息可阅读 [PCRE 官网](https://pcre.org/)。
-- zlib - 用于支持 HTTP 头部压缩。
+- zlib - 用于支持 HTTP 头部压缩。
```console
$ wget https://zlib.net/zlib-1.2.13.tar.gz
@@ -50,7 +50,7 @@ $ make
$ sudo make install
```
-- OpenSSL - 用于支持 HTTPS 协议。
+- OpenSSL - 用于支持 HTTPS 协议。
```console
$ wget https://www.openssl.org/source/openssl-1.1.1c.tar.gz
@@ -316,6 +316,9 @@ $ 7z l archive.7z # 浏览压缩包内容
## 引用来源与备注 {#references .no-underline }
[^1]: 本节使用的示例参考自 Nginx 官方说明 [Compiling and Installing from Source](https://docs.nginx.com/nginx/admin-guide/installing-nginx/installing-nginx-open-source/#compiling-and-installing-from-source)。
+
[^2]: 信息来自维基百科条目:[Nginx](https://zh.wikipedia.org/wiki/Nginx)。
+
[^3]: 但是 `unrar` 不是开源软件,因为它的[协议](https://github.com/debian-calibre/unrar-nonfree/blob/master/license.txt)不允许使用其代码制作压缩 RAR 包的工具,这违背了开源软件的定义。
+
[^4]: 参考了 与相关 man 文档编写。
diff --git a/docs/Ch04/index.md b/docs/Ch04/index.md
index 048575e0..6fc88c9d 100644
--- a/docs/Ch04/index.md
+++ b/docs/Ch04/index.md
@@ -114,7 +114,7 @@ $ renice -n 10 -p 12345 # 设置 PID 为 12345 的进程的 nice 值为 10
在实际的 Linux 系统中,进程的状态分类要稍微复杂一些。在 htop 中,按下 H 键到帮助页,可以看到对进程状态的如下描述:
-```
+```text
Status: R: running; S: sleeping; T: traced/stopped; Z: zombie; D: disk sleep
```
@@ -168,7 +168,7 @@ $ # 使用 ps 命令,可以发现 matmul 程序在后台运行,同时我们
而如果需要将前台程序切换到后台,则需要按下 Ctrl + Z 发送 SIGTSTP 使进程挂起,控制权还给 shell,此时屏幕输出如下所示,即(刚才挂起的进程)代号为 2,状态为 stopped,命令为 `ping localhost`。
-{: id=bg width=80% }
+{: id=bg width=80% }
我们可以使用 `jobs` 命令,看到当前 shell 上所有相关的进程了。这里,后台已经有一个进程在运行,所以 `ping localhost` 得到的代号是 2。
@@ -268,7 +268,7 @@ nohup: ignoring input and appending output to '/home/ustc/nohup.out'
### 命令行多终端方案——tmux {#tmux}
-{: width=70% }
+{: width=70% }
!!! info "问题产生了!"
diff --git a/docs/Ch04/supplement.md b/docs/Ch04/supplement.md
index 65f73b8f..d0a955dd 100644
--- a/docs/Ch04/supplement.md
+++ b/docs/Ch04/supplement.md
@@ -141,12 +141,12 @@ NSpgid: 1
一个口诀是 "BUSIER",反过来就是 "REISUB",是一套可以(尽可能在)在操作界面无响应的时候干净地重启系统的按键。按住 Alt + SysRq 后依次按下这六个键即可。
-- R: 从 X 桌面环境夺回键盘的控制权。
-- E: 向除了 init (PID = 1) 以外的进程发送 SIGTERM 信号,要求它们干净地退出。
-- I: 向除了 init 以外的进程发送 SIGKILL 信号,强制退出。
-- S: 从内存同步文件修改到文件系统。
-- U: 重新挂载所有的文件系统为只读状态。
-- B: 立刻重启系统。
+- R: 从 X 桌面环境夺回键盘的控制权。
+- E: 向除了 init (PID = 1) 以外的进程发送 SIGTERM 信号,要求它们干净地退出。
+- I: 向除了 init 以外的进程发送 SIGKILL 信号,强制退出。
+- S: 从内存同步文件修改到文件系统。
+- U: 重新挂载所有的文件系统为只读状态。
+- B: 立刻重启系统。
## 关于 `fork()` {#fork}
diff --git a/docs/Ch05/index.md b/docs/Ch05/index.md
index 791ea434..55896b20 100644
--- a/docs/Ch05/index.md
+++ b/docs/Ch05/index.md
@@ -596,10 +596,12 @@ ncdu 1.18 ~ Use the arrow keys to navigate, press ? for help
## 引用来源 {#references .no-underline}
-- [维基百科上的 Passwd 词条(英语)](https://en.wikipedia.org/wiki/Passwd)
-- [Simple explanation of `sudoers` file](https://askubuntu.com/questions/118204/5958455) - Ask Ubuntu
-- [Sudoers - Community Help Wiki](https://help.ubuntu.com/community/Sudoers) - Ubuntu Documentation
+- [维基百科上的 Passwd 词条(英语)](https://en.wikipedia.org/wiki/Passwd)
+- [Simple explanation of `sudoers` file](https://askubuntu.com/questions/118204/5958455) - Ask Ubuntu
+- [Sudoers - Community Help Wiki](https://help.ubuntu.com/community/Sudoers) - Ubuntu Documentation
[^1]: 这里的哈希,指经过了[密码哈希函数](https://zh.wikipedia.org/wiki/%E5%AF%86%E7%A2%BC%E9%9B%9C%E6%B9%8A%E5%87%BD%E6%95%B8) ([Cryptographic hash function](https://en.wikipedia.org/wiki/Cryptographic_hash_function)) 的处理。密码哈希函数是一种特殊的单向函数,将任意大小的数据映射到一串长度固定的字符串,并且拥有一些优良的性质(如难以找到两个不同的数据,使得映射后的字符串相同),使其破解难度加大。
+
[^3]:
+
[^2]: 然而,对于 Linux 内核来说,系统用户和真实的用户其实没有区别,除了 UID = 0 的用户 (root) 以外。「系统用户」是一个约定俗成而产生的概念。
diff --git a/docs/Ch05/supplement.md b/docs/Ch05/supplement.md
index 01c26c98..db9d14ea 100644
--- a/docs/Ch05/supplement.md
+++ b/docs/Ch05/supplement.md
@@ -10,9 +10,9 @@ icon: material/puzzle
是的。这样的「魔法」,是由文件系统特殊权限位 `setuid` 赋予的。有三个特殊权限位:setuid, setgid 和 sticky。
-- `setuid`: 以文件所属的用户的身份 (UID) 执行此程序。
-- `setgid`: 对文件来说,以文件所属的用户组的身份 (GID) 执行此程序;对目录来说,在这个目录下创建的文件的用户组都与此目录本身的用户组一致,而不是创建者的用户组。
-- `sticky` (restricted deletion flag): 目录中的所有文件只能由文件所有者(除 `root` 以外)删除或者移动。一个典型的例子是临时文件夹 `/tmp`,在此文件夹中你可以创建、修改、重命名、移动、删除自己的文件,但是动不了别人的文件。
+- `setuid`: 以文件所属的用户的身份 (UID) 执行此程序。
+- `setgid`: 对文件来说,以文件所属的用户组的身份 (GID) 执行此程序;对目录来说,在这个目录下创建的文件的用户组都与此目录本身的用户组一致,而不是创建者的用户组。
+- `sticky` (restricted deletion flag): 目录中的所有文件只能由文件所有者(除 `root` 以外)删除或者移动。一个典型的例子是临时文件夹 `/tmp`,在此文件夹中你可以创建、修改、重命名、移动、删除自己的文件,但是动不了别人的文件。
??? tip "setuid 和 sticky 位的历史"
@@ -58,14 +58,14 @@ $ ls -l /usr/bin/sudo
这就涉及到「登录 Shell」和「非登录 Shell」的差别了。「登录 Shell」是属于你的当前会话操作中的第一个进程,一般是在你输入用户名和密码之后打开的 Shell。常见的场景有:
-- `su -` 之后的 Shell。
-- SSH 登录机器后的 Shell
-- Ctrl + Alt + F\[1-7\] 之后 TTY 中的 Shell
+- `su -` 之后的 Shell。
+- SSH 登录机器后的 Shell
+- Ctrl + Alt + F\[1-7\] 之后 TTY 中的 Shell
而「非登录 Shell」的常见场景:
-- `su` 打开的是「非登录 Shell」
-- 在桌面环境中打开的终端(模拟器),启动的也是「非登录 Shell」
+- `su` 打开的是「非登录 Shell」
+- 在桌面环境中打开的终端(模拟器),启动的也是「非登录 Shell」
一般地,「登录 Shell」会额外加载 `profile` 文件(文件名根据你使用的 Shell 的不同而有区别),且它的 `argv[0][0] == '-'`(相信你已经学过 C 语言了)。可以用以下方法验证:
diff --git a/docs/Ch06/index.md b/docs/Ch06/index.md
index e7ea3cc4..42131f3f 100644
--- a/docs/Ch06/index.md
+++ b/docs/Ch06/index.md
@@ -81,15 +81,15 @@ sbin
#### Wget 的特点 {#wget-features}
-- 支持以非交互方式工作,能够在用户注销后在后台进行工作。
+- 支持以非交互方式工作,能够在用户注销后在后台进行工作。
-- 在不稳定的连接中依旧可以正常工作,支持断点续传功能。
+- 在不稳定的连接中依旧可以正常工作,支持断点续传功能。
-- 支持 HTML 页面以及 FTP 站点的递归检索,您可以使用它来获取网站的镜像,或者像爬虫一样遍历网络。
+- 支持 HTML 页面以及 FTP 站点的递归检索,您可以使用它来获取网站的镜像,或者像爬虫一样遍历网络。
-- 在文件获取时可以增加时间标记,因此可以自动识别远程文件自上次检索后是否发生更改,并自动检索新版本。
+- 在文件获取时可以增加时间标记,因此可以自动识别远程文件自上次检索后是否发生更改,并自动检索新版本。
-- 支持代理服务器,以减轻网络负载,加快检索速度。
+- 支持代理服务器,以减轻网络负载,加快检索速度。
#### 使用 Wget {#wget-usage}
@@ -178,11 +178,11 @@ cURL (`curl`) 是一个利用 URL 语法在命令行下工作的文件传输工
在进行文本处理时,我们有一些常见的需求:
-- 获取文本的行数、字数
-- 比较两段文本的不同之处
-- 查看文本的开头几行和最后几行
-- 在文本中查找字符串
-- 在文本中替换字符串
+- 获取文本的行数、字数
+- 比较两段文本的不同之处
+- 查看文本的开头几行和最后几行
+- 在文本中查找字符串
+- 在文本中替换字符串
下面介绍如何在 shell 中做到这些事情。
@@ -244,9 +244,9 @@ $ diff file1 file2
以 head 为例,这里给出共同的用法:
-- 不加参数的时候默认显示前 10 行
-- `-n ` 指定行数,可简化为 `-`
-- `-c ` 指定字节数
+- 不加参数的时候默认显示前 10 行
+- `-n ` 指定行数,可简化为 `-`
+- `-c ` 指定字节数
```console
$ head file # 显示 file 前 10 行
@@ -351,13 +351,13 @@ drwxr-xr-x 2 ustc ustc 4096 11月 17 20:45 模板/
可以使用几种方法运行 Bash 脚本:
-- 在指定的 Shell 下执行,将脚本程序名作为 Shell 的第一个参数:
+- 在指定的 Shell 下执行,将脚本程序名作为 Shell 的第一个参数:
```console
$ bash show.sh [option]
```
-- 将脚本设置为可执行,然后像外部命令一样执行:
+- 将脚本设置为可执行,然后像外部命令一样执行:
```console
$ chmod a+x show.sh
@@ -403,9 +403,9 @@ Bash 也支持在同一个行中安排多个命令:
组命令:
-- 使用 `{ 命令1; 命令2; … }`,组命令在 shell 内执行,不会产生新的进程,注意花括号和命令之间的空格。
+- 使用 `{ 命令1; 命令2; … }`,组命令在 shell 内执行,不会产生新的进程,注意花括号和命令之间的空格。
-- 使用 `(命令1; 命令2; …)`,组命令会建立独立的 shell 子进程来执行组命令,这里的圆括号周围并不需要空格。
+- 使用 `(命令1; 命令2; …)`,组命令会建立独立的 shell 子进程来执行组命令,这里的圆括号周围并不需要空格。
??? example "组命令示例"
@@ -489,17 +489,17 @@ Bash 也支持在同一个行中安排多个命令:
每个用户登录系统后,Linux 都会为其建立一个默认的工作环境,由一组环境变量定义,用户可以通过修改这些环境变量,来定制自己工作环境。在 Bash 中,可用 `env` 命令列出所有已定义的环境变量。通常,用户最关注的几个变量是:
-- `HOME`:用户主目录,一般情况下为 `/home/用户名`。
+- `HOME`:用户主目录,一般情况下为 `/home/用户名`。
-- `LOGNAME`:登录用户名。
+- `LOGNAME`:登录用户名。
-- `PATH`:命令搜索路径,路径以冒号分割。当我们输入命令名时,系统会在 `PATH` 变量中从前往后逐个搜索对应的程序是否在目录中。
+- `PATH`:命令搜索路径,路径以冒号分割。当我们输入命令名时,系统会在 `PATH` 变量中从前往后逐个搜索对应的程序是否在目录中。
-- `PWD`:用户当前工作目录路径。
+- `PWD`:用户当前工作目录路径。
-- `SHELL`:默认 shell 的路径名。
+- `SHELL`:默认 shell 的路径名。
-- `TERM`:使用的终端名。
+- `TERM`:使用的终端名。
可以使用 `export` 命令来定义环境变量。在同一个 shell 中使用 `export` 定义之后,这个环境变量会一直保留,直到这个 shell 退出。
@@ -520,11 +520,11 @@ $ # B=1 的环境变量定义仅对该命令有效
#### 位置变量 {#bash-positional-parameters}
-- Shell 解释用户的命令时,把命令程序名后面的所有字串作为程序的参数。分别对应 `$1`、`$2`、`$3`、……、`$9`,程序名本身对应 `$0`。
+- Shell 解释用户的命令时,把命令程序名后面的所有字串作为程序的参数。分别对应 `$1`、`$2`、`$3`、……、`$9`,程序名本身对应 `$0`。
-- 可用 `shift ` 命令,丢弃开头的 n 个位置变量,改变 `$1`、`$2`、`$3` 等的对应关系。
+- 可用 `shift ` 命令,丢弃开头的 n 个位置变量,改变 `$1`、`$2`、`$3` 等的对应关系。
-- 可用 `set` 命令,重置整个位置变量列表,从而给 `$1`、`$2`、`$3` 等赋值。
+- 可用 `set` 命令,重置整个位置变量列表,从而给 `$1`、`$2`、`$3` 等赋值。
??? example "范例"
@@ -553,18 +553,16 @@ Shell 中还有一组有 shell 定义和设置的特殊变量,用户只能引
#### 特殊字符 {#bash-special-tokens}
-- 反斜杠,消除单个字符的特殊含义。
+- 反斜杠,消除单个字符的特殊含义。
+ - 包含空白字符(空格和制表符)、反斜杠本身、各种引号,以及 `$`、`!` 等。
+ - 与其他语言不同,shell 中反斜杠不会将普通字符转义为其他含义(例如 `\n` 不会被视作换行符)。
- - 包含空白字符(空格和制表符)、反斜杠本身、各种引号,以及 `$`、`!` 等。
- - 与其他语言不同,shell 中反斜杠不会将普通字符转义为其他含义(例如 `\n` 不会被视作换行符)。
+- 使用双引号包裹字符串可以消除空白字符切分参数的特殊含义,但是很多其他特殊字符的特殊含义仍然保留。双引号也被称为「弱引用」。
-- 使用双引号包裹字符串可以消除空白字符切分参数的特殊含义,但是很多其他特殊字符的特殊含义仍然保留。双引号也被称为「弱引用」。
+- 单引号,能消除所有特殊字符的特殊含义,包括反斜杠,因此单引号字符串中不能使用反斜杠转义单引号本身。单引号也被称为「强引用」。
-- 单引号,能消除所有特殊字符的特殊含义,包括反斜杠,因此单引号字符串中不能使用反斜杠转义单引号本身。单引号也被称为「强引用」。
-
-- 反引号(`` ` ``)括起的字符串,被 shell 解释为命令,执行时用命令输出结果代替整个反引号对界限部分。
-
- - 与反引号相同的语法是 `$(command)`,它的好处是界限更明确,且可以嵌套。因此编写新脚本时,更建议使用此语法。
+- 反引号(`` ` ``)括起的字符串,被 shell 解释为命令,执行时用命令输出结果代替整个反引号对界限部分。
+ - 与反引号相同的语法是 `$(command)`,它的好处是界限更明确,且可以嵌套。因此编写新脚本时,更建议使用此语法。
!!! example "特殊字符示例"
@@ -938,11 +936,11 @@ function name {
Bash shell 本身提供了调试方法:
-- 命令行中:`$ bash -x script.sh`。
+- 命令行中:`$ bash -x script.sh`。
-- 脚本开头:`#!/bin/bash -x`。
+- 脚本开头:`#!/bin/bash -x`。
-- 在脚本中用 set 命令调整(`set -x` 启用,`set +x` 禁用)。
+- 在脚本中用 set 命令调整(`set -x` 启用,`set +x` 禁用)。
其中参数选项可以更改,`-n`:读一遍脚本中的命令但不执行,用于检查语法错误;`-v`:一边执行脚本、一边将执行过的脚本命令打印到标准输出;`-x`:提供跟踪执行信息,将执行的每一条命令和结果依次打印出来。注意避免几种调试选项混用。
@@ -1004,8 +1002,8 @@ Bash shell 本身提供了调试方法:
## 引用来源 {#references .no-underline}
-- [catonmat](https://catonmat.net/cookbooks)
-- [vbird](http://cn.linux.vbird.org)
-- [runoob](https://www.runoob.com/linux/linux-shell.html)
-- [linuxde](https://man.linuxde.net)
-- [Bash Quoting](https://www.gnu.org/software/bash/manual/html_node/Quoting.html)
+- [catonmat](https://catonmat.net/cookbooks)
+- [vbird](http://cn.linux.vbird.org)
+- [runoob](https://www.runoob.com/linux/linux-shell.html)
+- [linuxde](https://man.linuxde.net)
+- [Bash Quoting](https://www.gnu.org/software/bash/manual/html_node/Quoting.html)
diff --git a/docs/Ch06/supplement.md b/docs/Ch06/supplement.md
index 0105b157..0c2b9bd6 100644
--- a/docs/Ch06/supplement.md
+++ b/docs/Ch06/supplement.md
@@ -77,9 +77,9 @@ func
fork 炸弹的核心是函数内容:`func | func &`
-- 第一个 func 代表递归执行这个函数。
-- | 代表要将第一个函数的数据结果通过管道传输给后一个函数。
-- & 代表要在后台执行这一条命令,如果其中一个函数被操作系统回收,其调用产生的子函数并不会被回收。
+- 第一个 func 代表递归执行这个函数。
+- | 代表要将第一个函数的数据结果通过管道传输给后一个函数。
+- & 代表要在后台执行这一条命令,如果其中一个函数被操作系统回收,其调用产生的子函数并不会被回收。
于是运行一次这个函数就会创建两个 func 函数的实例,并不断地反复调用。实例的数量会指数爆炸式地增长,最终耗尽系统的资源。
diff --git a/docs/Ch07/index.md b/docs/Ch07/index.md
index e35b4ca2..351ff3f7 100644
--- a/docs/Ch07/index.md
+++ b/docs/Ch07/index.md
@@ -190,9 +190,9 @@ Hello World!
上述方法在源文件较少时是比较方便的,但当我们面对的是数以千计万计的源文件(同样的,在工作或科研中这也是常见状况),我们将面临以下困难:
-- 手动地一一编译实在太麻烦,太浪费精力;
-- 这些源文件的编译有顺序要求,为了满足此依赖关系需要设计一个流程;
-- 编译整个项目需要难以忍受的大量时间,应当考虑到一部分未更改的源文件不需要重新编译。
+- 手动地一一编译实在太麻烦,太浪费精力;
+- 这些源文件的编译有顺序要求,为了满足此依赖关系需要设计一个流程;
+- 编译整个项目需要难以忍受的大量时间,应当考虑到一部分未更改的源文件不需要重新编译。
为了让机器帮助程序员解决这些困难,构建工具应运而生。
同样的,由于需求巨大,构建工具在 Linux 上亦获得了强力支持。
@@ -493,10 +493,10 @@ CPython 中的 C 是指此解释器是用 C 实现。
相应的,Python 还有其他的一些实现:
-- JPython:将 Python 编译到 Java 字节码,由 JVM 来运行;
-- PyPy:相较于 CPython,实现了 JIT(just in time)编译器,性能有极大地提升;
-- Cython:引入了额外的语法和严密的类型系统,性能也有很大提升;
-- Numba:将 Python 编译到机器码,从而直接运行,性能也不错。
+- JPython:将 Python 编译到 Java 字节码,由 JVM 来运行;
+- PyPy:相较于 CPython,实现了 JIT(just in time)编译器,性能有极大地提升;
+- Cython:引入了额外的语法和严密的类型系统,性能也有很大提升;
+- Numba:将 Python 编译到机器码,从而直接运行,性能也不错。
视情况使用不同的 Python 实现能够很大程度地提升性能。
但如果你不确定自己的意向,且性能需求不大,使用官方的 CPython 也是明智之选。
diff --git a/docs/Ch07/supplement.md b/docs/Ch07/supplement.md
index e25a410a..83cf5ec7 100644
--- a/docs/Ch07/supplement.md
+++ b/docs/Ch07/supplement.md
@@ -189,8 +189,8 @@ getaddrinfo.c:(.text+0xd2): warning: Using 'getaddrinfo' in statically linked ap
有时候,我们需要为其他的平台编写程序,例如:
-- 我正在使用的电脑是 x86_64 架构的,但是我现在需要给树莓派编写程序(体系结构不同)。
-- 我正在使用 Linux,但是我现在需要编译出一个 Windows 程序(操作系统不同)。
+- 我正在使用的电脑是 x86_64 架构的,但是我现在需要给树莓派编写程序(体系结构不同)。
+- 我正在使用 Linux,但是我现在需要编译出一个 Windows 程序(操作系统不同)。
怎么办呢?只能用虚拟化程序运行目标架构,然后在上面跑编译了吗?这样会很麻烦、速度可能会很慢,甚至有的时候不可行(例如性能低下的嵌入式设备,可能连编译器都加载不了)。
diff --git a/docs/Ch08/index.md b/docs/Ch08/index.md
index 2174600a..0829175e 100644
--- a/docs/Ch08/index.md
+++ b/docs/Ch08/index.md
@@ -16,10 +16,10 @@ icon: simple/docker
Docker 能够利用 Linux 内核的容器特性,隔离出一个轻便的环境来运行程序。这有什么意义呢?试想以下这些情况:
-- 你运行的 Linux 发行版很老,而你需要运行一个更新版本的 Linux 发行版,或者完全不同的 Linux 发行版设计的程序。基于 Docker 的实现方式,与虚拟机(VM)不同,它们都共用同一个 Linux 内核(虚拟机是完全的虚拟化,包括内核和用户空间)。
-- 你和朋友在设计一个大型的程序,而因为你们配置的环境不同,有时候在某个人的机器上正常运行的程序,在另一台机器上没法正常运行。
-- 你希望在多台服务器上部署一个项目,但是项目需要非常复杂的配置,一个一个配置服务器的成本非常大。
-- …………
+- 你运行的 Linux 发行版很老,而你需要运行一个更新版本的 Linux 发行版,或者完全不同的 Linux 发行版设计的程序。基于 Docker 的实现方式,与虚拟机(VM)不同,它们都共用同一个 Linux 内核(虚拟机是完全的虚拟化,包括内核和用户空间)。
+- 你和朋友在设计一个大型的程序,而因为你们配置的环境不同,有时候在某个人的机器上正常运行的程序,在另一台机器上没法正常运行。
+- 你希望在多台服务器上部署一个项目,但是项目需要非常复杂的配置,一个一个配置服务器的成本非常大。
+- …………
Docker 就可以帮助解决这些问题。它可以快速配置不同的环境(比如说,通过 Docker,你可以在 Ubuntu 发行版上使用 CentOS 发行版的环境),部署应用。
@@ -115,7 +115,7 @@ For more examples and ideas, visit:
### 在 Ubuntu 容器中使用 shell {#use-ubuntu-bash}
-- `docker run -it --rm --name ubuntu-container ubuntu:latest`
+- `docker run -it --rm --name ubuntu-container ubuntu:latest`
这里,`--rm` 代表容器停止运行(退出)之后,会被立刻删除;`--name` 参数代表给容器命名,如果没有加这个参数,那么 docker 会给容器随机起一个格式类似于 gracious_brahmagupta 的名字。
@@ -172,22 +172,22 @@ $ sudo docker rm ubuntu-container
### 在 Python 容器中使用 Python 命令行 {#use-python-repl}
-- `docker run -it --name python3 python`
+- `docker run -it --name python3 python`
与上面的例子类似,执行之后会获得一个 Python 3 最新版本的环境。这里我们通过 `--name` 将创建的容器命名为 `python3`。
### 在 MkDocs 容器中构建本书 {#use-mkdocs-material-build}
-- 从 GitHub 上获取本书源码:`git clone https://github.com/ustclug/Linux101-docs.git`
-- `docker run --rm -v ${PWD}/Linux101-docs:/docs -p 8000:8000 squidfunk/mkdocs-material`
+- 从 GitHub 上获取本书源码:`git clone https://github.com/ustclug/Linux101-docs.git`
+- `docker run --rm -v ${PWD}/Linux101-docs:/docs -p 8000:8000 squidfunk/mkdocs-material`
在执行完成之后,可以使用浏览器访问本地的 8000 端口,以查看构建结果。
这里多出了两个参数:
-- `-v`: 代表将本地的文件(夹)「挂载」(实际是 bind mount)到容器的对应目录中(这里是 `/docs`)。注意这个参数只接受绝对路径,所以这里读取了 `PWD` 这个变量,通过拼接的方式拼出绝对路径。
-- `-p 8000:8000`: 代表将容器的 8000 端口暴露在主机的 8000 端口上,否则容器外部访问不了 8000 端口。
-- 另外,我们不需要在终端中与容器中的进程进行交互,所以没有设置 `-it` 参数。
+- `-v`: 代表将本地的文件(夹)「挂载」(实际是 bind mount)到容器的对应目录中(这里是 `/docs`)。注意这个参数只接受绝对路径,所以这里读取了 `PWD` 这个变量,通过拼接的方式拼出绝对路径。
+- `-p 8000:8000`: 代表将容器的 8000 端口暴露在主机的 8000 端口上,否则容器外部访问不了 8000 端口。
+- 另外,我们不需要在终端中与容器中的进程进行交互,所以没有设置 `-it` 参数。
## 构建自己的 Docker 镜像 {#build-docker-image}
@@ -195,10 +195,10 @@ $ sudo docker rm ubuntu-container
在继续之前,我们来梳理一下 Docker 中的几个关键概念:**容器(container)**、**镜像(image)**、**镜像仓库(registry)**。
-- **镜像仓库**是存储镜像的地方
-- **镜像**是 Docker 容器内文件系统的一份快照
-- **Dockerfile** 包含生成镜像的指令序列,可以理解为构建镜像的脚本
-- **容器**是一个(隔离)的运行环境
+- **镜像仓库**是存储镜像的地方
+- **镜像**是 Docker 容器内文件系统的一份快照
+- **Dockerfile** 包含生成镜像的指令序列,可以理解为构建镜像的脚本
+- **容器**是一个(隔离)的运行环境
它们之间的关系可以用下图表示,其中括号中的命令是查看相应对象列表的命令。
diff --git a/docs/Ch09/index.md b/docs/Ch09/index.md
index 576a5166..b7dd9c4d 100644
--- a/docs/Ch09/index.md
+++ b/docs/Ch09/index.md
@@ -20,10 +20,10 @@ sort 用于文本的行排序。默认排序方式是升序,按每行的字典
一些基本用法:
-- `-r` 降序(从大到小)排序
-- `-u` 去除重复行
-- `-o [file]` 指定输出文件
-- `-n` 用于数值排序,否则“15”会排在“2”前
+- `-r` 降序(从大到小)排序
+- `-u` 去除重复行
+- `-o [file]` 指定输出文件
+- `-n` 用于数值排序,否则“15”会排在“2”前
```console
$ echo -e "snake\nfox\nfish\ncat\nfish\ndog" > animals
@@ -140,25 +140,25 @@ $ sort animals | uniq -c
匹配正整数:
-```
+```text
[1-9][0-9]*
```
匹配仅由 26 个英文字母组成的字符串:
-```
+```text
^[A-Za-z]+$
```
匹配 Chapter 1-99 或 Section 1-99
-```
+```text
^(Chapter|Section) [1-9][0-9]{0,1}$
```
匹配“ter”结尾的单词:
-```
+```text
ter\b
```
@@ -188,9 +188,9 @@ grep 默认使用 BRE,要使用 ERE 可以使用 `grep -E` 或 egrep。
一些用法:
-- `-n`:显示匹配到内容的行号
-- `-v`:显示不被匹配到的行
-- `-i`:忽略字符大小写
+- `-n`:显示匹配到内容的行号
+- `-v`:显示不被匹配到的行
+- `-i`:忽略字符大小写
```console
$ ls /bin | grep -n "^man$" # 搜索内容仅含 man 的行,并且显示行号
@@ -215,11 +215,11 @@ $ sed [OPTIONS] -f scriptfile file(s)
常见 sed 命令:
-- s 替换
-- d 删除
-- c 选定行改成新文本
-- a 当前行下插入文本
-- i 当前行上插入文本
+- s 替换
+- d 删除
+- c 选定行改成新文本
+- a 当前行下插入文本
+- i 当前行上插入文本
```console
$ echo -e "seD\nIS\ngOod" > sed_demo
diff --git a/docs/Ch09/supplement.md b/docs/Ch09/supplement.md
index 2621257a..f6e700a4 100644
--- a/docs/Ch09/supplement.md
+++ b/docs/Ch09/supplement.md
@@ -24,9 +24,9 @@ icon: material/puzzle
组号分配规则:
-- 0 代表整个表达式
-- 从左至右,按左括号的出现顺序分配,第一个为 1,第二个为 2,以此类推
-- 扫描两遍,第一次只分配未命名的组,第二次只分配命名的组。即任意命名组的组号都大于未命名的组号
+- 0 代表整个表达式
+- 从左至右,按左括号的出现顺序分配,第一个为 1,第二个为 2,以此类推
+- 扫描两遍,第一次只分配未命名的组,第二次只分配命名的组。即任意命名组的组号都大于未命名的组号
!!! example "示例"
diff --git a/docs/Ch10/index.md b/docs/Ch10/index.md
index 2e3fbdc3..945f6f32 100644
--- a/docs/Ch10/index.md
+++ b/docs/Ch10/index.md
@@ -20,10 +20,10 @@ wsl --install
这条命令会完成如下几个操作:
-- 启用 WSL 和虚拟化平台
-- 下载并安装 WSL 的 Linux 内核
-- 设定 WSL 2 默认的版本
-- 从微软商店里面下载 Ubuntu 进行安装
+- 启用 WSL 和虚拟化平台
+- 下载并安装 WSL 的 Linux 内核
+- 设定 WSL 2 默认的版本
+- 从微软商店里面下载 Ubuntu 进行安装
安装完毕之后可以直接通过 `ubuntu` 命令启动。
@@ -68,10 +68,10 @@ wsl --set-default-version 2
有的打包为 Appx 的分发方式,也有提供了可执行应用程序来进行安装,在仓库里面提供了安装方式
-- ArchLinux: [ArchWSL](https://github.com/yuk7/ArchWSL)
-- Fedora: [FedoraWSL](https://github.com/yosukes-dev/FedoraWSL)
-- Manjaro: [ManjaroWSL](https://github.com/sileshn/ManjaroWSL)
-- Gentoo: [GentooWSL](https://github.com/imaandrew/GentooWSL)
+- ArchLinux: [ArchWSL](https://github.com/yuk7/ArchWSL)
+- Fedora: [FedoraWSL](https://github.com/yosukes-dev/FedoraWSL)
+- Manjaro: [ManjaroWSL](https://github.com/sileshn/ManjaroWSL)
+- Gentoo: [GentooWSL](https://github.com/imaandrew/GentooWSL)
### 使用 LxRunOffline 进行安装 {#install-lxrunoffline}
@@ -93,9 +93,9 @@ LxRunOffline 是通过 Windows 提供的 API 来进行管理 WSL 的一个命令
./LxRunOffline i -n ArchLinux -d D:/wsl/ArchLinux -f ./archlinux-bootstrap-*.tar.gz
```
-- `-n` WSL 的名称
+- `-n` WSL 的名称
-- `-d` 希望安装的位置,通过这种方法可以不需要将 wsl 安装在 C 盘
+- `-d` 希望安装的位置,通过这种方法可以不需要将 wsl 安装在 C 盘
需要注意的是,这个安装方法不会在开始菜单中添加启动快捷方式,只能够通过命令行的方式启动:
@@ -111,8 +111,8 @@ wsl -d ArchLinux
其中:
-- `ArchLinux` 是 WSL 的名
-- `-v 1000` 是设置登录的用户的 UID
+- `ArchLinux` 是 WSL 的名
+- `-v 1000` 是设置登录的用户的 UID
## 使用 {#usage}
diff --git a/docs/Spec/slide.md b/docs/Spec/slide.md
index d4c19ab1..fb9418f5 100644
--- a/docs/Spec/slide.md
+++ b/docs/Spec/slide.md
@@ -1,16 +1,19 @@
# 演示文稿规格
+
+
+
!!! warning "本文面向编写组提供指导和规范,不面向读者阅读,不属于本书正文。"
## 1. 文件格式
#### (a) 演示文稿的文件格式应属于如下列出的一种或多种:
-- (1) Adobe 可移植文档格式,默认扩展名为 `.pdf`;
+- (1) Adobe 可移植文档格式,默认扩展名为 `.pdf`;
-- (2) Microsoft PowerPoint Open XML 演示文件格式,默认扩展名为 `.pptx`;
+- (2) Microsoft PowerPoint Open XML 演示文件格式,默认扩展名为 `.pptx`;
-- (3) Prezi 文件格式,默认扩展名为 `.pez`。
+- (3) Prezi 文件格式,默认扩展名为 `.pez`。
#### (b) 相同内容的演示文稿可以存在多个文件格式,不过必须包括 §1(a)(1)。
@@ -20,29 +23,29 @@
#### (b) 演示文稿的内容推荐包括的内容有:
-- (1) 本章的标题;
+- (1) 本章的标题;
-- (2) 演示文稿所涉及内容的目录结构;
+- (2) 演示文稿所涉及内容的目录结构;
-- (3) 本章正文中的所有非自主阅读节的核心内容;
+- (3) 本章正文中的所有非自主阅读节的核心内容;
-- (4) 正文中的提示框内容;
+- (4) 正文中的提示框内容;
-- (5) 正文中未出现,但与 §2(b)(2) 相关的背景知识、实例演示等;
+- (5) 正文中未出现,但与 §2(b)(2) 相关的背景知识、实例演示等;
-- (6) 结束页面。
+- (6) 结束页面。
#### (c) §2(b)(1 - 3, 6) 是必需的,其余部分可以按演讲时长、风格等需求考虑添加。
#### (d) 演示文稿的内容不推荐包括:
-- (1) 本章的自主阅读节;
+- (1) 本章的自主阅读节;
-- (2) 本章的拓展阅读;
+- (2) 本章的拓展阅读;
-- (3) 附录,但是特别相关的除外;
+- (3) 附录,但是特别相关的除外;
-- (4) 与正文内容无关的其它内容。
+- (4) 与正文内容无关的其它内容。
#### (e) 演示文稿的内容应当按照本章正文的编写顺序组织,逻辑应当连贯,不过无需面面俱到。
@@ -50,15 +53,15 @@
#### (a) §2(b)(1) 建议使用 1 页,且放在最开头,其中推荐包括的内容为:
-- (1) 本章的标题名、章序号;
+- (1) 本章的标题名、章序号;
-- (2) “中国科学技术大学 LUG” 字样;
+- (2) “中国科学技术大学 LUG” 字样;
-- (3) 演讲的日期;
+- (3) 演讲的日期;
-- (4) 演讲者姓名或昵称;
+- (4) 演讲者姓名或昵称;
-- (5) 名人引言,或者对本章的精要概括。
+- (5) 名人引言,或者对本章的精要概括。
#### (b) §3(a)(1 - 3) 是必需的。
diff --git a/docs/credits.md b/docs/credits.md
index 0e4921c6..61f6750b 100644
--- a/docs/credits.md
+++ b/docs/credits.md
@@ -6,18 +6,18 @@
各章主要作者:
-- 第一章:[RiessarSadyx](https://github.com/RiessarSadyx)
-- 第二章:[LamWS](https://github.com/LamWS)
-- 第三章:[zeyugao](https://github.com/zeyugao)
-- 第四章:[psi-cmd](https://github.com/psi-cmd)
-- 第五章:[taoky](https://github.com/taoky)
-- 第六章:[yuanyiwei](https://github.com/yuanyiwei)
-- 第七章:[myl7](https://github.com/myl7)
-- 第八章:[taoky](https://github.com/taoky)
-- 第九章:[RubyOcelot](https://github.com/RubyOcelot)
+- 第一章:[RiessarSadyx](https://github.com/RiessarSadyx)
+- 第二章:[LamWS](https://github.com/LamWS)
+- 第三章:[zeyugao](https://github.com/zeyugao)
+- 第四章:[psi-cmd](https://github.com/psi-cmd)
+- 第五章:[taoky](https://github.com/taoky)
+- 第六章:[yuanyiwei](https://github.com/yuanyiwei)
+- 第七章:[myl7](https://github.com/myl7)
+- 第八章:[taoky](https://github.com/taoky)
+- 第九章:[RubyOcelot](https://github.com/RubyOcelot)
编排与校对:[iBug](https://github.com/iBug),[taoky](https://github.com/taoky)
## 贡献者 {#contributors}
-[](https://github.com/ustclug/Linux101-docs/graphs/contributors)
+[](https://github.com/ustclug/Linux101-docs/graphs/contributors)
diff --git a/docs/index.md b/docs/index.md
index fdfbd43f..44806083 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -16,13 +16,13 @@ icon: material/hand-wave-outline
本书是一份 Linux 的基础教程,目标是引导不了解 Linux 的读者掌握基础且实用的知识并领略社区开源文化的魅力。若仔细研读完本书,你就能:
-- 了解 Linux 历史和开源社区文化
-- 安装 Linux 发行版并利用内置实用手册
-- 在体验中亲自感受 Linux 的专业能力
-- 自如地操作与配置你的 Linux 系统
-- 理解 Linux 操作系统的思想
-- 使用 Linux 生态高效编程开发
-- 以及灵活运用其它 Linux 生态中十分流行的各类工具等等
+- 了解 Linux 历史和开源社区文化
+- 安装 Linux 发行版并利用内置实用手册
+- 在体验中亲自感受 Linux 的专业能力
+- 自如地操作与配置你的 Linux 系统
+- 理解 Linux 操作系统的思想
+- 使用 Linux 生态高效编程开发
+- 以及灵活运用其它 Linux 生态中十分流行的各类工具等等
对于偏向实用需求的计算机开发或学术研究的读者,通过阅读本书可以快速掌握高效且流行的业界开发和学界研究的工具;对于基于兴趣和探索新事物的目的而前来阅读的读者,本书则能为他们提供一个更广阔的 Linux 世界的面貌和一份快速入门的助力。
@@ -30,15 +30,15 @@ icon: material/hand-wave-outline
本书包括前言、正文及附录。正文共包括 9 章,每章的内容如下:
-- 第 1 章主要讲述了 Linux 的文化和生态,并提供了安装流程。
-- 第 2 章提供了一个自定义 Linux 系统和利用其设立自己专属服务器的体验指南,这一部分应配合课堂分发的工具包和虚拟机使用。
-- 第 3 章简单提供了基本的软件安装和文件操作知识。
-- 第 4 章全面介绍了系统的进程、服务和任务,是一块丰富的核心内容,读者应反复阅读。
-- 第 5 章讲解了用户和用户组、文件权限以及文件系统层次结构等系统管理员必知的文件管理核心知识。
-- 第 6 章提供了网络、文本处理和脚本编程的知识,让读者能利用脚本的力量完成综合任务。
-- 第 7 章简单展示了十分流行的在 Linux 环境下进行 C++ / Python 开发的方法。
-- 第 8 章介绍了近年来业界十分热门的容器隔离技术和 Docker 容器管理软件。
-- 第 9 章为利用脚本编程进行了进阶的说明,包括十分关键的正则表达式。
+- 第 1 章主要讲述了 Linux 的文化和生态,并提供了安装流程。
+- 第 2 章提供了一个自定义 Linux 系统和利用其设立自己专属服务器的体验指南,这一部分应配合课堂分发的工具包和虚拟机使用。
+- 第 3 章简单提供了基本的软件安装和文件操作知识。
+- 第 4 章全面介绍了系统的进程、服务和任务,是一块丰富的核心内容,读者应反复阅读。
+- 第 5 章讲解了用户和用户组、文件权限以及文件系统层次结构等系统管理员必知的文件管理核心知识。
+- 第 6 章提供了网络、文本处理和脚本编程的知识,让读者能利用脚本的力量完成综合任务。
+- 第 7 章简单展示了十分流行的在 Linux 环境下进行 C++ / Python 开发的方法。
+- 第 8 章介绍了近年来业界十分热门的容器隔离技术和 Docker 容器管理软件。
+- 第 9 章为利用脚本编程进行了进阶的说明,包括十分关键的正则表达式。
附录包括用语表和若干追加主题。其中,用语表包含了阅读全书中遇到的专业术语和用语的详细解释;每篇追加主题则包括诸多与本书极为相关的额外知识并已经进行了系统化的组织,提升读者的求知体验。
@@ -54,10 +54,10 @@ icon: material/hand-wave-outline
### 其它资料 {#extras}
-- [记号约定](notations.md)中约定了本书中常用的符号与注记形式。在研读本书的过程中可随时参考。
-- [功劳簿](credits.md)列出了所有为编写本书做出贡献的朋友们。
-- Linux 101 活动于 2020 年的直播记录视频可以在 [LUG FTP](https://ftp.lug.ustc.edu.cn/101/videos) 找到,也可以在 [YouTube](https://www.youtube.com/playlist?list=PLkqsPhn1XtD2h_o5-lY3exDRXtKBiKwkk) 上在线观看。
-- 对于服务器运维等较为深入的应用场景,我们另外启动了《[Linux 201](https://201.ustclug.org/)》项目,作为本书的进阶版,可供感兴趣的读者参考。
+- [记号约定](notations.md)中约定了本书中常用的符号与注记形式。在研读本书的过程中可随时参考。
+- [功劳簿](credits.md)列出了所有为编写本书做出贡献的朋友们。
+- Linux 101 活动于 2020 年的直播记录视频可以在 [LUG FTP](https://ftp.lug.ustc.edu.cn/101/videos) 找到,也可以在 [YouTube](https://www.youtube.com/playlist?list=PLkqsPhn1XtD2h_o5-lY3exDRXtKBiKwkk) 上在线观看。
+- 对于服务器运维等较为深入的应用场景,我们另外启动了《[Linux 201](https://201.ustclug.org/)》项目,作为本书的进阶版,可供感兴趣的读者参考。
## 联系我们 {#contact-us}
diff --git a/docs/notations.md b/docs/notations.md
index ab1f1559..3d1c1a20 100644
--- a/docs/notations.md
+++ b/docs/notations.md
@@ -10,7 +10,6 @@ $ 普通权限执行的命令 1 # 注释 1
# 高级权限执行的命令 2 # 注释 2
命令 2 的输出
-
```
命令开头的 `$` 代表此命令使用普通用户权限运行;命令开头的 `#` 代表执行命令需要使用 root 权限(最高权限),一般等价于 `$ sudo 该命令`。命令行末尾的 `#` 代表此符号与其后的内容都是注释,不参与执行。
diff --git a/package-lock.json b/package-lock.json
index 28c02b3f..486a8539 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,19 +9,802 @@
"version": "0.0.1",
"license": "CC BY-SA 4.0",
"devDependencies": {
- "prettier": "^2.8.8"
+ "markdownlint": "^0.38.0",
+ "prettier": "^3.6.2"
+ }
+ },
+ "node_modules/@types/debug": {
+ "version": "4.1.12",
+ "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz",
+ "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/ms": "*"
+ }
+ },
+ "node_modules/@types/katex": {
+ "version": "0.16.7",
+ "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.7.tgz",
+ "integrity": "sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/ms": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz",
+ "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/unist": {
+ "version": "2.0.11",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz",
+ "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/character-entities": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz",
+ "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/character-entities-legacy": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz",
+ "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/character-reference-invalid": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz",
+ "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/commander": {
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
+ "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 12"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/decode-named-character-reference": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.2.0.tgz",
+ "integrity": "sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "character-entities": "^2.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/dequal": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
+ "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/devlop": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz",
+ "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dequal": "^2.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/is-alphabetical": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz",
+ "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/is-alphanumerical": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz",
+ "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-alphabetical": "^2.0.0",
+ "is-decimal": "^2.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/is-decimal": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz",
+ "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/is-hexadecimal": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz",
+ "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/katex": {
+ "version": "0.16.23",
+ "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.23.tgz",
+ "integrity": "sha512-7VlC1hsEEolL9xNO05v9VjrvWZePkCVBJqj8ruICxYjZfHaHbaU53AlP+PODyFIXEnaEIEWi3wJy7FPZ95JAVg==",
+ "dev": true,
+ "funding": [
+ "https://opencollective.com/katex",
+ "https://github.com/sponsors/katex"
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "commander": "^8.3.0"
+ },
+ "bin": {
+ "katex": "cli.js"
+ }
+ },
+ "node_modules/markdownlint": {
+ "version": "0.38.0",
+ "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.38.0.tgz",
+ "integrity": "sha512-xaSxkaU7wY/0852zGApM8LdlIfGCW8ETZ0Rr62IQtAnUMlMuifsg09vWJcNYeL4f0anvr8Vo4ZQar8jGpV0btQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "micromark": "4.0.2",
+ "micromark-core-commonmark": "2.0.3",
+ "micromark-extension-directive": "4.0.0",
+ "micromark-extension-gfm-autolink-literal": "2.1.0",
+ "micromark-extension-gfm-footnote": "2.1.0",
+ "micromark-extension-gfm-table": "2.1.1",
+ "micromark-extension-math": "3.1.0",
+ "micromark-util-types": "2.0.2"
+ },
+ "engines": {
+ "node": ">=20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/DavidAnson"
+ }
+ },
+ "node_modules/micromark": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz",
+ "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@types/debug": "^4.0.0",
+ "debug": "^4.0.0",
+ "decode-named-character-reference": "^1.0.0",
+ "devlop": "^1.0.0",
+ "micromark-core-commonmark": "^2.0.0",
+ "micromark-factory-space": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-chunked": "^2.0.0",
+ "micromark-util-combine-extensions": "^2.0.0",
+ "micromark-util-decode-numeric-character-reference": "^2.0.0",
+ "micromark-util-encode": "^2.0.0",
+ "micromark-util-normalize-identifier": "^2.0.0",
+ "micromark-util-resolve-all": "^2.0.0",
+ "micromark-util-sanitize-uri": "^2.0.0",
+ "micromark-util-subtokenize": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-core-commonmark": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz",
+ "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "decode-named-character-reference": "^1.0.0",
+ "devlop": "^1.0.0",
+ "micromark-factory-destination": "^2.0.0",
+ "micromark-factory-label": "^2.0.0",
+ "micromark-factory-space": "^2.0.0",
+ "micromark-factory-title": "^2.0.0",
+ "micromark-factory-whitespace": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-chunked": "^2.0.0",
+ "micromark-util-classify-character": "^2.0.0",
+ "micromark-util-html-tag-name": "^2.0.0",
+ "micromark-util-normalize-identifier": "^2.0.0",
+ "micromark-util-resolve-all": "^2.0.0",
+ "micromark-util-subtokenize": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-extension-directive": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-4.0.0.tgz",
+ "integrity": "sha512-/C2nqVmXXmiseSSuCdItCMho7ybwwop6RrrRPk0KbOHW21JKoCldC+8rFOaundDoRBUWBnJJcxeA/Kvi34WQXg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "devlop": "^1.0.0",
+ "micromark-factory-space": "^2.0.0",
+ "micromark-factory-whitespace": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0",
+ "parse-entities": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/micromark-extension-gfm-autolink-literal": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz",
+ "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-sanitize-uri": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/micromark-extension-gfm-footnote": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz",
+ "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "devlop": "^1.0.0",
+ "micromark-core-commonmark": "^2.0.0",
+ "micromark-factory-space": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-normalize-identifier": "^2.0.0",
+ "micromark-util-sanitize-uri": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/micromark-extension-gfm-table": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz",
+ "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "devlop": "^1.0.0",
+ "micromark-factory-space": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/micromark-extension-math": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-extension-math/-/micromark-extension-math-3.1.0.tgz",
+ "integrity": "sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/katex": "^0.16.0",
+ "devlop": "^1.0.0",
+ "katex": "^0.16.0",
+ "micromark-factory-space": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/micromark-factory-destination": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz",
+ "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-factory-label": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz",
+ "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "devlop": "^1.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-factory-space": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz",
+ "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-factory-title": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz",
+ "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-factory-space": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-factory-whitespace": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz",
+ "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-factory-space": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-character": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz",
+ "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-chunked": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz",
+ "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-symbol": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-classify-character": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz",
+ "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-combine-extensions": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz",
+ "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-chunked": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-decode-numeric-character-reference": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz",
+ "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-symbol": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-encode": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz",
+ "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/micromark-util-html-tag-name": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz",
+ "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/micromark-util-normalize-identifier": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz",
+ "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-symbol": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-resolve-all": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz",
+ "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-sanitize-uri": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz",
+ "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-encode": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-subtokenize": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz",
+ "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "devlop": "^1.0.0",
+ "micromark-util-chunked": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-symbol": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
+ "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/micromark-util-types": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz",
+ "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/parse-entities": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz",
+ "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^2.0.0",
+ "character-entities-legacy": "^3.0.0",
+ "character-reference-invalid": "^2.0.0",
+ "decode-named-character-reference": "^1.0.0",
+ "is-alphanumerical": "^2.0.0",
+ "is-decimal": "^2.0.0",
+ "is-hexadecimal": "^2.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/prettier": {
- "version": "2.8.8",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
- "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz",
+ "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==",
"dev": true,
+ "license": "MIT",
"bin": {
- "prettier": "bin-prettier.js"
+ "prettier": "bin/prettier.cjs"
},
"engines": {
- "node": ">=10.13.0"
+ "node": ">=14"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
@@ -29,10 +812,459 @@
}
},
"dependencies": {
+ "@types/debug": {
+ "version": "4.1.12",
+ "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz",
+ "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==",
+ "dev": true,
+ "requires": {
+ "@types/ms": "*"
+ }
+ },
+ "@types/katex": {
+ "version": "0.16.7",
+ "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.7.tgz",
+ "integrity": "sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==",
+ "dev": true
+ },
+ "@types/ms": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz",
+ "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==",
+ "dev": true
+ },
+ "@types/unist": {
+ "version": "2.0.11",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz",
+ "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==",
+ "dev": true
+ },
+ "character-entities": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz",
+ "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==",
+ "dev": true
+ },
+ "character-entities-legacy": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz",
+ "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==",
+ "dev": true
+ },
+ "character-reference-invalid": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz",
+ "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==",
+ "dev": true
+ },
+ "commander": {
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
+ "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
+ "dev": true
+ },
+ "debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.3"
+ }
+ },
+ "decode-named-character-reference": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.2.0.tgz",
+ "integrity": "sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==",
+ "dev": true,
+ "requires": {
+ "character-entities": "^2.0.0"
+ }
+ },
+ "dequal": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
+ "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
+ "dev": true
+ },
+ "devlop": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz",
+ "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==",
+ "dev": true,
+ "requires": {
+ "dequal": "^2.0.0"
+ }
+ },
+ "is-alphabetical": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz",
+ "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==",
+ "dev": true
+ },
+ "is-alphanumerical": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz",
+ "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==",
+ "dev": true,
+ "requires": {
+ "is-alphabetical": "^2.0.0",
+ "is-decimal": "^2.0.0"
+ }
+ },
+ "is-decimal": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz",
+ "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==",
+ "dev": true
+ },
+ "is-hexadecimal": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz",
+ "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==",
+ "dev": true
+ },
+ "katex": {
+ "version": "0.16.23",
+ "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.23.tgz",
+ "integrity": "sha512-7VlC1hsEEolL9xNO05v9VjrvWZePkCVBJqj8ruICxYjZfHaHbaU53AlP+PODyFIXEnaEIEWi3wJy7FPZ95JAVg==",
+ "dev": true,
+ "requires": {
+ "commander": "^8.3.0"
+ }
+ },
+ "markdownlint": {
+ "version": "0.38.0",
+ "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.38.0.tgz",
+ "integrity": "sha512-xaSxkaU7wY/0852zGApM8LdlIfGCW8ETZ0Rr62IQtAnUMlMuifsg09vWJcNYeL4f0anvr8Vo4ZQar8jGpV0btQ==",
+ "dev": true,
+ "requires": {
+ "micromark": "4.0.2",
+ "micromark-core-commonmark": "2.0.3",
+ "micromark-extension-directive": "4.0.0",
+ "micromark-extension-gfm-autolink-literal": "2.1.0",
+ "micromark-extension-gfm-footnote": "2.1.0",
+ "micromark-extension-gfm-table": "2.1.1",
+ "micromark-extension-math": "3.1.0",
+ "micromark-util-types": "2.0.2"
+ }
+ },
+ "micromark": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz",
+ "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==",
+ "dev": true,
+ "requires": {
+ "@types/debug": "^4.0.0",
+ "debug": "^4.0.0",
+ "decode-named-character-reference": "^1.0.0",
+ "devlop": "^1.0.0",
+ "micromark-core-commonmark": "^2.0.0",
+ "micromark-factory-space": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-chunked": "^2.0.0",
+ "micromark-util-combine-extensions": "^2.0.0",
+ "micromark-util-decode-numeric-character-reference": "^2.0.0",
+ "micromark-util-encode": "^2.0.0",
+ "micromark-util-normalize-identifier": "^2.0.0",
+ "micromark-util-resolve-all": "^2.0.0",
+ "micromark-util-sanitize-uri": "^2.0.0",
+ "micromark-util-subtokenize": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "micromark-core-commonmark": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz",
+ "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==",
+ "dev": true,
+ "requires": {
+ "decode-named-character-reference": "^1.0.0",
+ "devlop": "^1.0.0",
+ "micromark-factory-destination": "^2.0.0",
+ "micromark-factory-label": "^2.0.0",
+ "micromark-factory-space": "^2.0.0",
+ "micromark-factory-title": "^2.0.0",
+ "micromark-factory-whitespace": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-chunked": "^2.0.0",
+ "micromark-util-classify-character": "^2.0.0",
+ "micromark-util-html-tag-name": "^2.0.0",
+ "micromark-util-normalize-identifier": "^2.0.0",
+ "micromark-util-resolve-all": "^2.0.0",
+ "micromark-util-subtokenize": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "micromark-extension-directive": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-4.0.0.tgz",
+ "integrity": "sha512-/C2nqVmXXmiseSSuCdItCMho7ybwwop6RrrRPk0KbOHW21JKoCldC+8rFOaundDoRBUWBnJJcxeA/Kvi34WQXg==",
+ "dev": true,
+ "requires": {
+ "devlop": "^1.0.0",
+ "micromark-factory-space": "^2.0.0",
+ "micromark-factory-whitespace": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0",
+ "parse-entities": "^4.0.0"
+ }
+ },
+ "micromark-extension-gfm-autolink-literal": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz",
+ "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==",
+ "dev": true,
+ "requires": {
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-sanitize-uri": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "micromark-extension-gfm-footnote": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz",
+ "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==",
+ "dev": true,
+ "requires": {
+ "devlop": "^1.0.0",
+ "micromark-core-commonmark": "^2.0.0",
+ "micromark-factory-space": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-normalize-identifier": "^2.0.0",
+ "micromark-util-sanitize-uri": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "micromark-extension-gfm-table": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz",
+ "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==",
+ "dev": true,
+ "requires": {
+ "devlop": "^1.0.0",
+ "micromark-factory-space": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "micromark-extension-math": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-extension-math/-/micromark-extension-math-3.1.0.tgz",
+ "integrity": "sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==",
+ "dev": true,
+ "requires": {
+ "@types/katex": "^0.16.0",
+ "devlop": "^1.0.0",
+ "katex": "^0.16.0",
+ "micromark-factory-space": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "micromark-factory-destination": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz",
+ "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==",
+ "dev": true,
+ "requires": {
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "micromark-factory-label": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz",
+ "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==",
+ "dev": true,
+ "requires": {
+ "devlop": "^1.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "micromark-factory-space": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz",
+ "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==",
+ "dev": true,
+ "requires": {
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "micromark-factory-title": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz",
+ "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==",
+ "dev": true,
+ "requires": {
+ "micromark-factory-space": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "micromark-factory-whitespace": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz",
+ "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==",
+ "dev": true,
+ "requires": {
+ "micromark-factory-space": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "micromark-util-character": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz",
+ "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==",
+ "dev": true,
+ "requires": {
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "micromark-util-chunked": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz",
+ "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==",
+ "dev": true,
+ "requires": {
+ "micromark-util-symbol": "^2.0.0"
+ }
+ },
+ "micromark-util-classify-character": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz",
+ "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==",
+ "dev": true,
+ "requires": {
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "micromark-util-combine-extensions": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz",
+ "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==",
+ "dev": true,
+ "requires": {
+ "micromark-util-chunked": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "micromark-util-decode-numeric-character-reference": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz",
+ "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==",
+ "dev": true,
+ "requires": {
+ "micromark-util-symbol": "^2.0.0"
+ }
+ },
+ "micromark-util-encode": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz",
+ "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==",
+ "dev": true
+ },
+ "micromark-util-html-tag-name": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz",
+ "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==",
+ "dev": true
+ },
+ "micromark-util-normalize-identifier": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz",
+ "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==",
+ "dev": true,
+ "requires": {
+ "micromark-util-symbol": "^2.0.0"
+ }
+ },
+ "micromark-util-resolve-all": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz",
+ "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==",
+ "dev": true,
+ "requires": {
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "micromark-util-sanitize-uri": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz",
+ "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==",
+ "dev": true,
+ "requires": {
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-encode": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0"
+ }
+ },
+ "micromark-util-subtokenize": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz",
+ "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==",
+ "dev": true,
+ "requires": {
+ "devlop": "^1.0.0",
+ "micromark-util-chunked": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "micromark-util-symbol": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
+ "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
+ "dev": true
+ },
+ "micromark-util-types": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz",
+ "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==",
+ "dev": true
+ },
+ "ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true
+ },
+ "parse-entities": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz",
+ "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==",
+ "dev": true,
+ "requires": {
+ "@types/unist": "^2.0.0",
+ "character-entities-legacy": "^3.0.0",
+ "character-reference-invalid": "^2.0.0",
+ "decode-named-character-reference": "^1.0.0",
+ "is-alphanumerical": "^2.0.0",
+ "is-decimal": "^2.0.0",
+ "is-hexadecimal": "^2.0.0"
+ }
+ },
"prettier": {
- "version": "2.8.8",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
- "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz",
+ "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==",
"dev": true
}
}
diff --git a/package.json b/package.json
index 2c4f9be3..e9fc4edb 100644
--- a/package.json
+++ b/package.json
@@ -16,6 +16,7 @@
},
"homepage": "https://101.lug.ustc.edu.cn",
"devDependencies": {
- "prettier": "^2.8.8"
+ "markdownlint": "^0.38.0",
+ "prettier": "^3.6.2"
}
}