批量处理 Front Matter中的tags
sunshj Lv4

在Markdown文档中可以通过Front Matter中的tags来设置hexo文章中的标签属性,但当想把一个标签改名或者添加新的标签时却很麻烦。所以可以使用下面的方法来批量处理tags。

使用python实现

需要下载python-frontmatter

1
pip install python-frontmatter

一、批量替换 Front Matter中的tags标签值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import os
import frontmatter

def update_front_matter(file):
with open(file, 'r', encoding='utf-8') as f:
post = frontmatter.loads(f.read())
is_write = False
tags = post.get("tags", [])
print('FrontMatter中的tags: ', tags)

# 将'教程'替换为'tutorial','总结'替换为'Summarize'。。。
new_tags = list(map(lambda x: x.replace('教程', 'tutorial').replace('总结', 'summary').replace(
'分享', 'share').replace('网站建设', 'Web-building').replace('大数据', 'bigdata'), tags))
print('替换之后的tags'': ', new_tags)

if post.get("tags", None) != new_tags:
post["tags"] = new_tags
if not is_write:
is_write = True
if is_write:
with open(file, 'w', encoding='utf-8') as f:
f.write(frontmatter.dumps(post))

# 递归获取目录下所有文件
def list_all_files(root_path, ignore_dirs=[]):
files = []
default_dirs = [".git", ".config"]
ignore_dirs.extend(default_dirs)

for parent, dirs, filenames in os.walk(root_path):
dirs[:] = [d for d in dirs if not d in ignore_dirs]
filenames = [f for f in filenames if not f[0] == '.']
for file in filenames:
if file.endswith(".md"):
files.append(os.path.join(parent, file))
return files

if __name__ == "__main__":
files = list_all_files('md/')
print("当前目录: ", os.path.dirname(os.path.abspath(__file__)))
for file in files:
print("---------------------------------------------------------------")
print('当前文件: ', file)
update_front_matter(file)

使用方法:

  • files = list_all_files('md/')指定目录
  • new_tags里设置需要更换的规则

注意:

文章的tag必须是- XX格式的才可进行转换

二、批量添加 Front Matter中的tags标签值

由于很多md文章没有添加创建时间,hexo clean ,hexo g , hexo s一通操作后,文章创建时间被修改为了部署时间。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import os
import re
import time
import frontmatter

# 更新md文件的front matter:1.增加创建时间;2.提取tag
def update_front_matter(file):

with open(file, 'r', encoding='utf-8') as f:
post = frontmatter.loads(f.read())

is_write = False

if not post.metadata.get('modify_date', None):
timeArray = time.localtime((os.path.getmtime(file)))
post['date'] = time.strftime("%Y-%m-%d %H:%M", timeArray)
if not is_write:
is_write = True

# 将代码块内容去掉
temp_content = re.sub(r'```([\s\S]*?)```[\s]?', '', post.content)
# 获取tag列表
tags = re.findall(r'\s#[\u4e00-\u9fa5a-zA-Z]+', temp_content, re.M | re.I)
ret_tags = list(set(map(lambda x: x.strip(), tags)))
print('tags in content: ', ret_tags)
print('tags in front matter: ', post.get("tags", []))
if len(ret_tags) == 0:
pass

elif post.get("tags", []) != set(ret_tags):
post['tags'] = ret_tags
if not is_write:
is_write = True

if is_write:
with open(file, 'w', encoding='utf-8') as f:
f.write(frontmatter.dumps(post))

# 递归获取提供目录下所有文件
def list_all_files(root_path, ignore_dirs=[]):
files = []
default_dirs = [".git", ".obsidian", ".config"]
ignore_dirs.extend(default_dirs)

for parent, dirs, filenames in os.walk(root_path):
dirs[:] = [d for d in dirs if not d in ignore_dirs]
filenames = [f for f in filenames if not f[0] == '.']
for file in filenames:
if file.endswith(".md"):
files.append(os.path.join(parent, file))
return files

if __name__ == "__main__":
ignore_dirs = ["Resource", "Write"]
files = list_all_files('./_posts', ignore_dirs=ignore_dirs)

print("current dir: ", os.path.dirname(os.path.abspath(__file__)))
for file in files:
print("---------------------------------------------------------------")
print('current file: ', file)
update_front_matter(file)
time.sleep(1)

使用方法:

  • files = list_all_files('./_posts')指定目录
 评论