sheldonxxd / obsidian_vault_template_for_researcher

This is an vault template for researchers using obsidian.
GNU General Public License v3.0
1.07k stars 170 forks source link

[建议]:utils.py里关于获取yaml数据的改进 & 动态更新yaml数据 #66

Open JeffeyChou opened 1 year ago

JeffeyChou commented 1 year ago

作者的开箱即用仓库确实很好用,我后面是又复制了一份作为记录生活和学习的仓库。 后面打算把部分知识仓库使用hexo框架通过github page发布到网络上时,md文件模板里front matter 的tags 格式因不是默认的yaml文件格式导致无法识别,随在此建议作者能够改进下该部分代码。

下面是我自己实现的一个读取front matter 数据的代码,在08-Assets/Scripts/utils.py中修改

import yaml
def fetch_front_matter(fp):
    '''提取markdown文件中的 front matter 信息为字典'''
    # 如果对应key为空,类型为str
    with open(fp, 'r', encoding='utf-8') as f:
        front_matter = next(yaml.load_all(f, Loader=yaml.FullLoader))
    return front_matter

对于看到这里的其他读者,如果想格式化自己之前写好的文档里的tags格式,可以参考我下面的代码,对auto_transfer.py修改

# 格式化tags函数
def frontmatter_format(fp):
    linelist = []
    # 原理是先按行读取原文件,在tags一行中替换
    # 同时利用之前读取到的front-matter 文件对tags下的一行添加文字
    # 最后得到修改后的数据,重新打开源文件,从头覆写一遍得到
    match_pattern = re.compile(r'tags')
    info = fetch_front_matter(fp)
    if isinstance(info['tags'], str):
        with open(fp, 'r', encoding='utf-8') as f:
            while 1:
                line = f.readline()
                # 按行读取保存
                if not line:
                    print("read file End")
                    break
                elif match_pattern.search(line):
                    # 读取到tags一行
                    values = line.split(': ')[1].split(' ')
                    o_line = "tags: \n"
                    linelist.append(o_line)
                    for numb in range(0, len(values) - 1):
                        # 割分后最后一个可能是'\n',跳过读取,最后判断
                        if len(values[numb]) != 0:
                            # 这里可能在最后一个标签后多了几个空格,判断读取
                            strline = '- ' + values[numb] + '\n'
                            linelist.append(strline)
                    if values[-1] != '\n':
                        strline = '- ' + values[-1]
                        linelist.append(strline)
                    continue
                linelist.append(line)
        with open(fp, 'w', encoding='utf-8') as f:
            for i in linelist:
                f.write(i)

def main():

    # 获取obsidian 根目录
    vault = Obsidian()
    rootdir = vault.paths['vault']
    # 这里必须是.md文件才有效,我这里出现了其他文件导致files出现了非目标文件
    # rootdir = 'D:\Document\Working'
    this_week = rootdir + '/01-Diary/本周事务'
    files = os.listdir(this_week)
    for file in files:
        if '.md' in file:
            name, ext = os.path.splitext(file)
            fp = os.path.join(this_week, file)
            frontmatter_format(fp)
            先把自己的所有文档都格式化先,不移动它
            if isCompleted(fp):
                # print(fp)
                target = fetch_destination(fp)
                if isShortLink(target):
                    # 如果是符合格式的短码,解析真实相对路径
                    target = shortLinkDecode(rootdir, target)
                if len(target) > 1:
                    # 如果为空也不移动
                    base = os.path.join(rootdir, target)
                    if os.path.exists(base):
                        shutil.move(fp, base)
                        print(f'- [[{name}]]')

根据自己的情况,把 if isCompleted(fp): 后面注释掉,修改 this_week 的位置,移动即可


动态更新yaml数据的话,我用的是插件 Liner ,可以根据文件更新 title, date, updated, 对yaml的keys排序,而且作者原库已知的bug是创建草稿时,默认指定使用 草稿模板,导致一建立时front matter 里的 title 就是 未命名,每次都需要修改特别麻烦,所有我的解决方法去template 设置里取消创建新草稿时默认使用模板,自己选择模板。

这样自己写好标题后再导入模板就没有该问题了。

亦或者在模板文件里删除 title 的字段,使用 Liner 的自动生成title 元数据的方法也可以。