技術書典16でChatGPT本を出します!(ここをクリック)

【Python】Obsidianの指定タグがついたメモをCanvasに一括出力

ぷりんさん「Obsidian Canvas JSONおもすれー」
私「Obsidian Canvasにバーッと出力する方法ない?」
ぷりんさん「できるんじゃね?(適当)」

ということでぷりんさんにたたき台作成・アドバイスをもらいながら作りました。ぷりんさん曰く「書き飛ばしスクリプトだし、公開してもなあ」とのことだったのですが、私からすると「これは新しい技術だし、このプログラムがきっかけにObsidian界隈に新しい風が吹くんじゃ?」と感じたので、我が物顔で公開したいと思います。(許可は取っています)

目次

ソース

長いので折りたたみ
import yaml
from pathlib import Path
from pyjsoncanvas import (
    Canvas,
    FileNode,
)

def extract_header(file_path: Path) -> dict:
    with open(file_path, "r", encoding="utf-8") as f:
        lines = f.readlines()
    is_inside_header = False
    header_lines = []
    for line in lines:
        if line.startswith("---"):
            is_inside_header = not is_inside_header
            if is_inside_header:
                continue
            else:
                break
        if not is_inside_header:
            continue
        header_lines.append(line)
    header_str = "\n".join(header_lines)
    return yaml.safe_load(header_str)


def has_tag(file_path: Path, tag: str) -> bool:
    header = extract_header(file_path)
    if header is not None:
        tags = header.get("tags", [])
        if tag in tags:
            return True
    content = file_path.read_text(encoding="utf-8")
    return f"#{tag}" in content


def main():
    vault_root = Path(r"保管庫のパス")
    vault_path = vault_root / "検索したいフォルダー"
    search_tag = "検索したいタグ(文字列)"
    canvas_path = Path(r"canvasを保管したいパス") / f"summary_{search_tag}.canvas"

    matched_files = [
        file_path
        for file_path in vault_path.glob("*.md")
        if has_tag(file_path, search_tag)
    ]

    canvas = Canvas(nodes=[], edges=[])
    width = 800
    height = 900

    for i, file_path in enumerate(matched_files):
        node = FileNode(
            id=str(i),
            x=0,
            y=0 + i * int(height * 0.5),
            width=width,
            height=height,
            file=str(file_path.relative_to(vault_root).as_posix())
        )

        canvas.add_node(node)

    with open(canvas_path, "w", encoding="utf-8") as f:
        f.write(canvas.to_json())


if __name__ == '__main__':
    main()

出力結果

特定のフォルダー内にある指定タグが付いたメモをCanvasに貼り付けます。

大雑把な流れ

  1. 必要ライブラリーのインストール
  2. 下記のPythonファイルに必要項目を書く
  3. Python実行

詳しい流れ

1.必要ライブラリーのインストール

pipでpyyamlPyJSONCanvasをインストールします。

pip install PyYAML
pip install PyJSONCanvas

2.Pythonファイルに必要項目を書く

mainに下記の項目を記入します。

  • vault_root:保管庫のパス
  • vault_path:検索したいフォルダー
  • search_tag:検索したいタグ(文字列)
  • canvas_path:canvasファイルの保管パス

具体的にはこんな感じです。

vault_root = Path(r"保管庫のパス")
vault_path = vault_root / "検索したいフォルダー"
search_tag = "検索したいタグ(文字列)"
canvas_path = Path(r"canvasファイルの保管パス") / f"summary_{search_tag}.canvas"

書けたら実行しましょう。指定の保存場所にcanvasファイルができたら成功です。

今後やりたいこと

  • 複数フォルダーの検索
  • 子階層検索
  • タグ以外の検索
  • メモの追加・ファイル更新(今は新規作成のみ)
  • TSで書き直してプラグイン化(検索結果から反映したい)

いろいろ応用が利きそうな予感。ありがとうJSONライブラリー、Canvasの可能性が広がった気がする。

参考リンク

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次