TOCはAstroで生成することにした
作成:

やっぱり自動がいい
前回ObsidianでもTOCを生成できるようにしたと書いた。
ObsidianでもTOCしたい
ObsidianでもVScodeのようなTOCを実現する

結局のところ手間がかかるのは一緒なのでAstroで自動生成するようにした。
以下が參考になりました。
[2023年6月版]Astro.js 小ネタ集 その2 Markdownの表示カスタマイズいろいろ
![[2023年6月版]Astro.js 小ネタ集 その2 Markdownの表示カスタマイズいろいろ](https://res.cloudinary.com/zenn/image/upload/s--8-bSRh0K--/c_fit%2Cg_north_west%2Cl_text:notosansjp-medium.otf_55:%255B2023%25E5%25B9%25B46%25E6%259C%2588%25E7%2589%2588%255DAstro.js%2520%25E5%25B0%258F%25E3%2583%258D%25E3%2582%25BF%25E9%259B%2586%2520%25E3%2581%259D%25E3%2581%25AE2%2520Markdown%25E3%2581%25AE%25E8%25A1%25A8%25E7%25A4%25BA%25E3%2582%25AB%25E3%2582%25B9%25E3%2582%25BF%25E3%2583%259E%25E3%2582%25A4%25E3%2582%25BA%25E3%2581%2584%25E3%2582%258D%25E3%2581%2584%25E3%2582%258D%2Cw_1010%2Cx_90%2Cy_100/g_south_west%2Cl_text:notosansjp-medium.otf_37:%25E3%2581%2582%25E3%2581%259D%25E3%2581%25B4%25E3%2583%2586%25E3%2583%2583%25E3%2582%25AF%2Cx_203%2Cy_121/g_south_west%2Ch_90%2Cl_fetch:aHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL3plbm4tdXNlci11cGxvYWQvYXZhdGFyLzYzYWRiZGU0MDcuanBlZw==%2Cr_max%2Cw_90%2Cx_87%2Cy_95/v1627283836/default/og-base-w1200-v2.png)
Contentの他にheadingsも読み込む
---
// /src/pages/[...slug].astro
// ここでheadingsも読み込む
const { Content, headings } = await entry.render();
---
<!-- 中略 -->
<!-- BlogPostにheadingsを渡す -->
<BlogPost frontmatter={entry.data} headings={headings}>
BlogPost.astroでTOCを生成する
---
// /src/layouts/BlogPost.astro
// 見出しが2つ以上の場合フラグを立てる
const headings_flag = headings.length > 2 ? true : false;
---
<!-- 中略 -->
<!-- フラグが立っていれば目次を作る -->
{
headings_flag && (
<aside class="toc">
<ul class="toc-level-0">
{headings
.filter((h) => h.depth < 6)
.map((h) => {
return (
<li class={`toc-level-${h.depth} toc-item`}>
<a href={`#${h.slug}`}>{h.text}</a>
</li>
);
})}
</ul>
</aside>
)
}
<!-- 見出しレベルに合わせたスタイル指定 -->
<style>
.toc-level-0 {
list-style: none;
}
.toc-level-3 {
margin-left: 2em;
}
.toc-level-4 {
margin-left: 4em;
}
.toc-level-5 {
margin-left: 6em;
}
#webmentions img {
max-height: 1.2em;
margin-right: -1ex;
}
</style>
最後に
ObsidianよりやっぱりVSCodeでMarkdown書いたほうが良い気がしてきた。
Syncthingが同期のときObsidianで編集中のファイルから無数にsync-conflictファイルを生み出したりするので。
iCloudの同期がおかしくなってしまったので同期は上記のとおりSyncthingにしました。