notebook

都内でWEB系エンジニアやってます。

Obsidian dataviewでテーブルの中に他ページから取得したTaskListとListをそのまま表示させる

DataviewではJavaScriptでコードを書くことで特定のタグやページの情報を取得してまとめてテーブル形式にして表示できる

今回は、DailyNoteの項目の中から特定の項目のリストを取得してインデントなども保持したままテーブルのセルに表示させたい

使い始めたときはできないと思って自前でリストを取得してインデントさせるなど工夫してたが、しっかりドキュメント読んだらさくっと関数を組み合わせるだけで実現できた

Codeblock Reference - Dataview

blacksmithgu.github.io

サンプル

const tasks = dv.pages("#markdown_sample").sort(p => p.file.name, 'asc')
  .flatMap(p => {
    return p.file.lists.where(item => item.section.subpath === "Task" && item.position.start.col === 0)
      .map(item => {
        return [p.file.link, dv.markdownTaskList([item])];
      });
  });


dv.table(['file', 'task'], tasks)
  • markdown_sample1
## Task
- [ ] hoge
    - [ ] Nested 1
    - [ ] Nested 2
- [ ] fuga
- [ ] piyo

#markdown_sample
  • markdown_sample2
## Task
- List Item1
- List Item2
    - Nested Item2-1
    - Nested Item2-2
- List Item3

#markdown_sample

以下はサンプルの説明

特定Header以下のリストを取得する

p.file.listsでタスクリスト含むリストを取得できる

返ってくるのはDataviewのDataArrayなので普通の配列以外の操作演算子を使える、今回はその中のwhereで条件を指定して絞り込む

item.section.subpath === "Tast"

リストの各Itemにはsectionというプロパティが存在していて、これを元に絞り込みできる

サンプルはTaskというHeader以下のリストという条件

リストアイテムのスタート位置

item.position.start.col === 0

でリストのスタート位置がデータとして取れる

インデントしている場合は0以上の数字となるためトップレベルのリストアイテムの場合は0

item.children以下にネストしたリストのデータも入っているので、そのままitemdv.markdownTaskListに渡せばいい感じに出力してくれる

テーブルの中にList表示のMarkdownを含める

dv.taskListだと単純にTaskListをレンダリングするところまで行う

dv.tableもレンダリングを行う関数なので役割が被ってしまうため一緒に使うことは不可能

dv.markdownTaskListだとMarkdownの文字列を返すところまでが仕事

組み合わせることで、タスクリストと普通のリスト両方インデントを維持したままテーブルのセルの中に含めることが可能となる

最初リストに関してはdv.markdownListでやるものかとばかり思っていたがこちらは新たに単純な配列などを渡してリスト化するという方が用途としては近そう

中身見た感じDataviewのオブジェクトに対応してネストさせるような処理はできなそうだった

dv.markdownTaskListであれば、チェックボックスがついていない単純なリストでもインデントを保持したままMarkdownをレンダリングしてくれる(Dataviewのオブジェクトを見てよしなにフォーマットしてくれる)

おわり

これは求めていたもの感がある

今までも結構ドキュメント読んでいたつもりだったが、読めば読むほど気付きがある

というか今まで書いてたスクリプトが結構冗長な書き方だったことにもきづいたので徐々にリプレイスしている…