MkDocs 是一个快速、简单且支持第三方主题的静态站点生成器,用于构建项目文档。文档源文件用 Markdown 编写,并使用单个 YAML 配置文件进行配置。 官网地址:https://www.mkdocs.org/
最近在开发一个基于Django搭建的个人博客系统,找了一些资源和文档,发现MkDocs是一个支持markdown文档发布很强大的静态站点生成器,只需要根据命令创建文档,yaml文件配置文档路径就可以快速的访问HTML静态站点。于是看了一下mkdocs包的源码,其中utils目录下的meta.py文件是通过正则提取markdown文档的meta信息和正文内容的工具包,代码可谓短小精悍。下面对meta.py的代码做一些注释说明,还有引用的使用方法。
demo.md
先粘贴一段markdown文档内容,此篇文章的主要是提取下面文档开头--- 内的key:value信息生成字典,然后将字典和文章剩余的内容返回。
---
title: Hello World
date: 2022-07-14 10:00:00
tags: [markdown, python]
categories: [python, Django]
type: blog
---
## Quick Start
### Create a new project
$ python manage.py startproject blog
### Run server
$ python manage.py runserver
More info: [Deployment](https://docs.djangoproject.com/en/4.0/)
meta.py
粘贴了meta.py的主要代码,然后在代码上添加注释方便观看和理解。当然代码文件开头有版权信息,使用此文件不要删掉版权信息。
这里对下面正则表达式做一些说明:
- 解析:
^-{3} 以—开头[ \t]*\n 匹配\n结尾或\t\n结尾换行符^-{3}[ \t]*\n 以—开头,后边可以有空格,但是以\n结尾的一行数据(.*?\n) 配置^-{3}[ \t]*\n 之后包含\n的数据(?:\.{3}|-{3})[ \t]*\n 匹配…或者—字符串,后边可以有空格,但是以\n结尾的一行数据 - 参考:
* 代表匹配除换行符之外的所有字符.*? 后面多个问号,代表非贪婪模式,也就是说只匹配符合条件的最少字符(?: re) 类似 (…), 但是不表示一个组\s 匹配任意空白字符,等价于 [ \t\n\r\f]。
原文件地址: https://github.com/mkdocs/mkdocs/blob/master/mkdocs/utils/meta.py
import re
import yaml
try:
from yaml import CSafeLoader as SafeLoader
except ImportError:
from yaml import SafeLoader
YAML_RE = re.compile(r'^-{3}[ \t]*\n(.*?\n)(?:\.{3}|-{3})[ \t]*\n', re.UNICODE | re.DOTALL)
META_RE = re.compile(r'^[ ]{0,3}(?P<key>[A-Za-z0-9_-]+):\s*(?P<value>.*)')
META_MORE_RE = re.compile(r'^([ ]{4}|\t)(\s*)(?P<value>.*)')
def get_data(doc):
data = {}
m = YAML_RE.match(doc)
if m:
try:
data = yaml.load(m.group(1), SafeLoader)
if isinstance(data, dict):
doc = doc[m.end():].lstrip('\n')
else:
data = {}
return doc, data
except Exception:
print(str(Exception))
lines = doc.replace('\r\n', '\n').replace('\r', '\n').split('\n')
key = None
while lines:
line = lines.pop(0)
if line.strip() == '':
break
m1 = META_RE.match(line)
if m1:
key = m1.group('key').lower().strip()
value = m1.group('value').strip()
if key in data:
data[key] += f' {value}'
else:
data[key] = value
else:
m2 = META_MORE_RE.match(line)
if m2 and key:
data[key] += ' {}'.format(m2.group('value').strip())
else:
lines.insert(0, line)
break
return '\n'.join(lines).lstrip('\n'), data
调用meta.py文件
在meta.py文件同目录下创建md_utils.py,然后输入下述内容并测试。
import meta
import os
def get_md_info(file_path):
with open(file_path, encoding='utf-8', errors='strict') as f:
source = f.read()
return meta.get_data(source)
if __name__ == '__main__':
base_path = "md_utils\docs"
file_path = os.path.join(base_path, "demo.md")
meta, doc = get_md_info(file_path=file_path)
print("# meta 字典内容:\n", meta)
print("# doc 文本内容:\n", doc)
执行md_utils.py文件,输出内容如下:
{'title': 'Hello World', 'date': datetime.datetime(2022, 7, 14, 10, 0), 'tags': ['markdown', 'python'], 'categories': ['python', 'Django'], 'type': 'blog'}
$ python manage.py startproject blog
$ python manage.py runserver
More info: [Deployment](https://docs.djangoproject.com/en/4.0/)
小结
MkDocs是一个很成熟且轻量化的markdown静态站点生成器,可以快速的部署在github站点实现访问。MkDocs用到了python的markdown 包将文件转成html,同时也写了很好的markdown包扩展类,这个也是后期要学习的地方。后面会进一步完善自己的博客平台,然后分享给大家。感谢阅读!
|