跳转至

mkdocs使用说明

新手注意事项

请务必留意文档中的红色和橙色的提示,这些提示是非常重要的,如果你不理解,可以发到群里求助。

阅读本文档之前你需要了解的...

  1. 本文档使用Markdown语法,如果你不熟悉,请先学习一下Markdown语法
  2. 文档使用git作为版本管理工具,如果不熟悉可以先阅读一下Git教程
  3. 做一下demo-repo的练习

新手初次使用建议

阅读和实践流程:

  1. 先阅读Git教程,了解版本管理和协作
  2. 大致了解Markdown语法
  3. 安装好git,vscode和vscode的office viewer插件
  4. 阅读“如何本地部署文档”部分,按步骤操作,部署文档
  5. 阅读“如何本地运行文档”部分,按步骤操作,在浏览器中成功预览文档
  6. 阅读“如何新建文档”和“如何修改文档和提交”两部分,然后按照 如何修改文档和提交 部分的步骤操作,尝试修改文档并提交

下面有一些涉及命令行的操作,我该怎么做?

如果不知道命令行是什么,建议百度,关键词:什么是命令行

  1. 如果你是windows系统,可以使用git bash,也可以使用powershell(推荐)。
  2. 如果你是linux系统,那你不可能不知道怎么做。

介绍篇(非必读)-------------------

什么是mkdocs?

mkdocs是一个静态网站生成器,它使用Markdown语法编写文档,然后使用mkdocs生成静态网站。

为什么要用这个文档?

文档的重要性————ChatGPT

技术团队的文档对于技术传承和内部接口协调都有着非常重要的作用。首先,技术团队的文档可以记录下技术团队在项目中所使用的技术、工具、流程等信息,方便后来的团队成员快速了解项目的背景和现状,从而更快地适应团队工作。此外,技术团队的文档还可以记录下项目中的问题、解决方案以及经验教训等信息,方便后来的团队成员避免重复犯错,提高工作效率。

另外,技术团队的文档也对内部接口协调有着重要的作用。在一个大型项目中,不同的团队可能会负责不同的技术模块,这些模块之间需要进行协调和交互。如果各个团队之间缺乏有效的沟通和协调,可能会导致模块之间出现不兼容、接口不清晰等问题,从而影响项目的整体进度和质量。而技术团队的文档可以记录下各个模块之间的接口、数据格式、调用方式等信息,方便各个团队之间进行协调和交互,避免出现不必要的问题。

综上所述,技术团队的文档对于技术传承和内部接口协调都有着非常重要的作用。通过记录下项目的技术、工具、流程等信息,方便后来的团队成员快速了解项目的整体情况,避免重复工作和浪费时间。同时,技术团队的文档还可以帮助团队成员更好地理解项目的业务需求和技术实现,提高团队成员的工作效率和质量。

————Generated by ChatGPT

有哪些基本的功能?

如何最快地上手?

最简单的方法就是多尝试。(本文章使用了大部分常用的功能,可以作为参考)

使用篇(必读)-------------------

如何本地部署文档?(初次使用)

什么叫文档部署?

文档部署就是将文档生成静态网页的过程。你本地部署文档后,浏览器打开 http://127.0.0.1:8030 就可以看到预览网页了。

本教程提供三种部署方式,对比如下:

方法 部署便捷度 性能 可开发性 备注
docker ⭐⭐⭐⭐⭐ ⭐⭐ ⭐⭐⭐⭐ 自动安装所有依赖,一键部署,只需要安装docker。缺点是预览网页刷新慢。
原生python ⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐ 需要安装python和相关依赖
anaconda ⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐ 需要安装anaconda、配置环境变量、创建虚拟环境、安装依赖

(所有方法都只需部署一次,以后一直用就行)

  1. 基础软件安装和配置

    安装githttps://git-scm.com/downloads 下载。如果你用Windows,下载Standalone Installer: 64-bit Git for Windows Setup.

    github ssh登录配置:必应搜索:github ssh免密登录配置,打开任意一篇教程,按照教程操作即可。

    那个黑色窗口(终端)是怎么打开的

    安装完成git后,右键点击桌面,选择Git Bash Here即可打开终端。

  2. 克隆仓库(执行以下命令,如果让你输入[yes/no],输入yes即可)

    git clone git@github.com:Peiyang-Aeromodelling-Association/documentation.git
    

  3. 配置部署软件

    下载并安装python:https://www.python.org/downloads/

    1. 下载并安装anaconda:https://www.anaconda.com/products/individual
    2. 配置环境变量:

      系统PATH环境变量配置

    3. 如果你是windows环境:用管理员权限打开powershell,输入set-executionpolicy remotesigned

    4. 创建一个虚拟环境:conda create -n docs_env
    5. 激活虚拟环境:conda activate docs_env
    6. 安装pip:conda install pip
  4. 进入到文档文件夹下,进一步配置

    1. 将学长/学姐给你的密钥mkdocs_deploykey放在当前目录下(project root)。
    2. 运行以下命令:
      docker-compose up
      
    1. pip install -r requirements.txt
    2. mkdocs serve
    1. conda activate docs_env
    2. pip install -r requirements.txt
    3. mkdocs serve
  5. 过一会,等文档构建完打开浏览器,输入http://127.0.0.1:8030/,即可看到文档。

原理

运行mkdocs serve后,会在本地启动一个mkdocs服务。打开浏览器访问的http://127.0.0.1:8030/是一个环回地址,即访问本机的8030端口。mkdocs服务会监听8030端口,当访问该端口时,会返回mkdocs生成的静态网页。这个是本地运行的文档,你的修改按Ctrl+S保存后,浏览器会自动刷新,你就可以看到修改后的效果了。

如何新建文档?

Markdown编辑器的选择(初次使用)

常用的编辑器有Typoravscode等,Typora是很受欢迎的一款Markdown编辑器,但由于近期要收费,请自己找一下解决办法。

一个免费的替代是vscode+Office Viewer插件。vscodeOffice Viewer插件能带来类似于Typora的所见即所得的编辑体验。

关于这几个软件/插件的安装方法,请自行百度。

如果你使用的是Typora,我建议你每次新建文档、编辑文档前设置一下默认图片文件夹,使新文档的图片资源文件位置和历史文档保持一致,避免混乱。

Typora图片文件夹设置

  1. docs/目录下新建.md文件
  2. 然后在mkdocs.ymlnav中添加新的文档路径和标题

注意yaml语法

yaml语法中,每一级缩进都必须是 两个空格 ,不要使用tab键!

以下是一个例子:

新建一个名为mkdocs使用说明.md的文档

1.在docs/目录下新建.md文件 2.然后在mkdocs.yml的nav中添加新的文档路径和标题

如何修改文档和提交(基础)

以下是一个从创建有限状态机介绍.md到提交的完整例子:

1.新建分支

一定要执行新建分支这一步!

如果大家都直接都在main分支上提交会导致历史混乱,不方便管理。

如果擅自在main分支上修改还不听劝阻,那我只能收回你的写权限了,你以后就老老实实fork+pull request吧。

git checkout -b lcf_update  # 新建分支lcf_update,-b表示新建。不一定要叫lcf_update,可以自己取名

新建分支

2.新建文档并编辑

新建文档并编辑

3.配置文件中新增一个栏目

配置文件中新增一个栏目

4.提交并推送

git add .  # 添加所有修改
git commit -am "新建了FSM介绍文档"  # 提交到本地仓库
git push origin lcf_update  # 推送到远程仓库的lcf_update分支

提交并推送

5.在github上发起Pull Request,合并PR

PR 步骤1

PR 步骤2

在点击绿色的Merge Pull Request前

先确保github actions的自动检查已经通过了,如果没有通过,说明你的文档有问题,需要修改。

1. checking

workflow check

2. passed

workflow check passed

PR 步骤3

如果出现了冲突...

冲突

你可以放在这里先不管了,联系管理员解决你的冲突。解决完之后跳到第6步即可。

或者如果你足够自信,可以参考如何解决冲突?(进阶)一节,自己解决冲突。

然后基本上就可以了。

成功

6.合并PR后,更新本地文档,并删除本地分支和远程分支

git checkout main  # 切换到main分支
git pull  # 更新本地文档,使其与远程文档main分支同步
git branch -d lcf_update  # 删除本地分支(因为main分支已经更新到最新,而lcf_update分支作用是个人临时编写文档使用的,所以编辑完成了就可以删除)
git push origin --delete lcf_update  # 删除对应的远程分支

收尾

为什么我提交了文档,但并没有出现在文章末尾的作者列表中?

原因在于,本地的git config中设置的是邮箱A,而GitHub上关联的是邮箱B,因此GitHub并不认为你是contributor。

解决方法是:在GitHub上关联邮箱A,或者在本地的git config中设置邮箱B。

添加邮箱到GitHub

如何解决冲突?(进阶)

冲突是什么?何时产生?

当两个人同一时间段修改了同一个文件,就会产生冲突。

以下是一个完整的例子:

比如我和杨昕明在同一时间段先后从main分支上新建了各自的分支,打算同时修改mkdocs使用说明.md文件。过程如下:

我先提交了PR并成功合并进了main分支。

lcf更新后的main分支

杨昕明在我提交PR之后,修改好了mkdocs使用说明.md文件,推送了自己的分支yxm_update后,发起了PR。

杨昕明同学的版本

发起PR

然后发现了冲突。根本原因是:git并不知道到底应该选择我的版本还是杨昕明的版本,所以就会提示冲突。 接下来我们使用GitHub自带的编辑器手动选择保留谁的哪一部分内容。解决流程如下图所示:

step 1

step 2

step 3

step 4

冲突至此就成功化解。后续的操作和之前一样,合并PR,更新本地文档,删除本地分支和远程分支即可。

总结一下,冲突是如何产生的可以这样理解:

冲突是如何产生的

(DEPRECATED)如何更新对外开放的stable分支?(进阶)

DEPRECATED

目前这一部分使用GitHub workflow自动与main分支同步,不需要手动更新了,但基本原理没有改变。因此本节内容废弃,仅作了解。

注意

以下操作如果操作不当可能会造成内部文档的泄露以及git仓库的混乱,所以请按照步骤谨慎操作。(初次操作请先联系会的人看着你操作)

原理

stable分支是对外开放的,只包含public.yml中指定的内容,因此需要使用脚本prune.py将不开放的内容从stable分支中删除。

prune.py核心部分
for root, dirs, files in os.walk("./docs"):
for file in files:
    path = os.path.join(root, file)
    # replace backslashes with forward slashes
    path = path.replace("\\", "/")
    # remove the ./ prefix if it exists
    path = path[2:] if path.startswith("./") else path
    if not is_public(path):  # if the file is not public, delete it
        print(f"rm:{path}")
        os.remove(path)  # delete the file
        with open(path, 'w', encoding='utf-8') as f:  # replace original file with redirection template
            f.write(redirection_template(get_suffix(path)))

由于prune.py脚本会将stable分支中不开放的内容从git索引中删除,这会造成一个问题:进行git merge main操作时,stable分支中曾经删除的内容将会被忽略,不会被合并到stable分支中。这可能会造成stable分支中的内容与main分支中的内容不一致(stable部分文件缺失)。

因此需要将stable分支的内容首先回退到与main分支的最新公共祖先的状态,再进行合并操作。

stable分支已经回退到与main分支的最新公共祖先的状态后,仅仅只需要将main分支的最新内容同步到stable分支上即可,因此使用fast-forward模式进行合并。

关于fast-forward模式的详细介绍可以参考1

操作步骤:

  1. 首先和每个组商量好哪些内容是对外开放的,将这些内容写入main分支的public.yml中。
  2. main分支的内容合并到stable分支上。

    a. 更新stable分支。如果stable分支曾经删除过某些文件(使用过剪枝脚本prune.py),则需要先将stable分支的内容恢复到main分支的状态,再进行下一步操作。

    git checkout stable # 切换到stable分支
    git reset --hard $(git merge-base main stable)  # 将stable分支更新到与main分支的最新公共祖先
    
    b. 将main分支的内容合并到stable分支上。
    git merge --ff-only main # 将main分支合并到stable分支,--ff-only参数表示只允许fast-forward合并(即不允许产生新的commit)
    

  3. 运行剪枝脚本,删除不对外开放的内容。

    python prune.py -c public.yml
    

  4. (可选) 修改mkdocs.ymlnav标签,使网站的导航栏目能按需求显示文章标签。具体方法见上文。
  5. 提交并推送到远程仓库。
    git commit -am "Pruned"
    git push -u origin stable --force
    

番外篇(选修)-------------------

如何开启评论区?

根据有关规定,公开内容禁止开放评论区!

在文档开头的fontmatter中添加comments: false即可。

fontmatter

一些常用功能

公式

内联公式
$a^2+b^2=c^2$

内联公式:\(a^2+b^2=c^2\)

块级公式
$$
    \int_0^1 f(x)dx
$$
\[ \int_0^1 f(x)dx \]

代码

print("hello world")

表格

表格
| 语法  | 说明     |
|:------|:-------|
| `#`   | 一级标题 |
| `##`  | 二级标题 |
| `###` | 三级标题 |
语法 说明
# 一级标题
## 二级标题
### 三级标题

Admonitions

具体使用请参考这里

注意

!!! note "注意"
    标记出需要读者即使在略读时也要注意的信息。

警告

!!! warning "警告"
    标记出关键信息,读者需要特别注意。

危险

!!! danger "危险"
    标记出可能会导致严重后果的信息。

提示

!!! tip "提示"
    一些常用的小技巧可以在这里提示。

示例

!!! example "示例"
    一些示例可以帮助读者更好地理解。

问题

!!! question "问题"
    适当添加引导性问题并给出答案,可以帮助读者更好地理解。

参考文献

既可以直接指定参考文献,也可以使用bibtex格式的参考文献。

使用bibtex格式的参考文献可以方便地管理参考文献,只需要在bibliography中添加参考文献的bib文件,然后在文档中引用即可。

像LaTeX2一样写Markdown参考文献。

bibtex格式(放在对应的.bib文件中)
@article{gpt3,
    title={Language Models are Few-Shot Learners},
    author={Brown, Tom B and Mann, Benjamin and Ryder, Nick and Subbiah, Melanie and Kaplan, Jared and Dhariwal, Prafulla and Neelakantan, Arvind and Shyam, Pranav and Sastry, Girish and Askell, Amanda and others},
    journal={arXiv preprint arXiv:2005.14165},
    year={2020}
}
引用
GPT[@gpt3]是一个非常厉害的模型。
直接指定参考文献
[^git merge原理]:[git merge原理(递归三路合并算法)](https://www.jianshu.com/p/e8932999fe1f)
引用
参考文献[^git merge原理]是关于git merge原理的。

思维导图

详情参考:https://github.com/markmap/mkdocs-markmap

Draw.io支持

详情见:https://github.com/onixpro/mkdocs-drawio-file/

mkdocs material的详细使用说明(非必读)

参考mkdocs-material

一些Feature请参考这里

开发者幕后(非必读)

开发者幕后

最初是想通过飞书文档来管理内部文档,但飞书文档不支持导出为Markdown,怕万一哪一天突然要收费了,就没法导出了,所以就想着自己部署一个文档。

当时的基本需求是:

  1. 编写文档要足够简单,不需要太多的学习成本。最好是能直接使用Markdown语法。
  2. 支持的内容足够丰富,要能支持公式、代码、表格、图片等。
  3. 功能要足够强大,最好能有搜索功能,能够自动生成目录,能够自动生成导航栏。
  4. 能够方便地多人合作。

初步的想法是使用mkdocs+mkdocs-material+github pages,但是github pages是全部对外开放,有些内部文档不支持访问认证,而Github企业版要收费,所以就想办法进行了一点workaround。

现在采用的方案是mkdocs+mkdocs-material作为基本的文档生成工具,用github actions自动部署到gh-pages分支,然后从云服务器上定时拉取gh-pages分支的内容。

权限管理方面,使用了mike这个工具,它可以将mkdocs生成的文档分成多个版本。我将文档划分为内部使用的dev版本(也就是main分支),以及对外开放的stable版本(也就是stable分支)。注意到访问内部dev版本时,uri中会带有/dev/,所以通过nginx添加一个basic auth,访问/dev/时需要输入用户名和密码,而访问/stable/时则不需要。

当时折腾nginx花费了一些精力。主要是当时的SSL证书不支持通配符,所以我需要配置较为复杂的转发规则才能正常使用文档(将请求都转发到/paa_docs/下)。其中遇到了301重定向的问题、静态资源找不到的问题等等。

后来用了Let's Encrypt的免费证书,直接上通配符证书+二级域名,彻底解决了这个问题。

目前增加了documentation-deploy仓库,方便以submodule的形式将其它API文档一同进行部署。

最后的话

如果还想进一步深入了解幕后的原理,可以参考文档框架设计文档.

希望大家积极参与到文档的编写中来,共同维护好这个文档。文档中留下的是你的足迹,也是你的贡献。

References


  1. git merge原理(递归三路合并算法) 

  2. Leslie Lamport. I1 (\LaTeX)—A Document. Volume 410. pub-AW, 1985.