最終確認日

Obsidian の Callouts をブログで表示する(2026年1月)

前身

  • Obsidian でご飯メモを残せるようにする(2025年11月)
  • Obsidianで画像カードリンクを表示したい

うまくいっておらず。

メモ

marked から markdown-it を使うように変更してもいいかも

変更してみた。

  • Calloutsのテストがなぜブログにアップロードされていない?
    • Supabase に来ていない
    • GitHub Actions 上では アップロードできている。
      • この問題は結局わからん。

Calloutsの表示順調に進んでいる。とりあえず <blockquote> で囲うような状態になった。

<blockquote>
<p>[!info] Child Pane がない?
<a href="/images/LicensePlist を Build Tool Plugin で利用する方法(Xcode 26)-1768575042941.webp" target="_blank" rel="noopener noreferrer">
	<img src="/images/LicensePlist を Build Tool Plugin で利用する方法(Xcode 26)-1768575042941.webp" alt="LicensePlist を Build Tool Plugin で利用する方法(Xcode 26)-1768575042941" width="200" loading="lazy" decoding="async">
</a>
アイテムを追加する時の選択肢に <code>Child Pane</code> はないです。
適当なTypeで作成した後に、Child Pane と書き換えると認識されます。(もしくは <code>PSChildPaneSpecifier</code> と書く)</p>
</blockquote>

これは引用ではないので <blockquote> は不適切じゃないか?修正する

フォルダ構成

marked.js から markdown-itへ乗り換え。次のようにファイルを定義

    ├── markdown
    │   ├── markdownEngine.ts
    │   ├── plugins
    │   │   ├── cardCalloutsPlugin.ts
    │   │   └── obsidianCalloutsPlugin.ts
    │   ├── renderer
    │   │   ├── cardCalloutsRenderer.ts
    │   │   ├── obsidianCalloutsRenderer.ts
    │   │   ├── obsidianRenderer.ts
    │   │   └── wikilinksRenderer.ts
    │   └── types.ts

markdownEngine から各プラグインとRendererを利用する。

import MarkdownIt from "npm:markdown-it";
import type { MarkdownIt as MarkdownItType } from "./types.ts";
import { createCardCalloutsPlugin } from "./plugins/cardCalloutsPlugin.ts";
import { createObsidianCalloutsPlugin } from "./plugins/obsidianCalloutsPlugin.ts";
import { registerObsidianRenderer } from "./renderer/obsidianRenderer.ts";
import { registerObsidianCalloutsRenderer } from "./renderer/obsidianCalloutsRenderer.ts";
import { registerCardCalloutsRenderer } from "./renderer/cardCalloutsRenderer.ts";
import { registerWikiLinksRenderer } from "./renderer/wikilinksRenderer.ts";

import { PostCacheEntry } from "../libs/PostCache.ts";

export type MarkdownEngineDeps = {
  postCache: Map<string, PostCacheEntry>;
  options?: {
    imageUrlForPath?: (imagePath: string) => string;
  };
};

export function createMarkdownEngine(deps: MarkdownEngineDeps): MarkdownItType {
  const md = new MarkdownIt({
    html: true,
    linkify: true,
    typographer: true,
  });

  // plugin
  md.use(createObsidianCalloutsPlugin());
  md.use(createCardCalloutsPlugin());

  // renderer
  registerObsidianRenderer(md, deps.options);
  registerWikiLinksRenderer(md, deps.postCache);

  registerObsidianCalloutsRenderer(md);
  registerCardCalloutsRenderer(md);

  return md;
}

いい感じにできたので、あとは style の設定と画像の表示か。

スタイルを設定する

  • Callouts のアイコンはcss側でいいかも
    • でもObsidian も Zenn もアイコンをちゃんと置いているか。
  • 開閉のDOMもちゃんとできてはいる

画像を表示する

表示できるところまでできた。

PostCache という記事のメタ情報のインデックスを作成する時に、本文上から最初の画像を拾ってくる。

とりあえず全部できた

今回の実装でできる書き方をうるおいらんどで使える記法にまとめた。

marked から markdown-it を使うことで上手くいったと思う。
AI に任せまくったコードですまそ。

最終構成

Obsidian 互換の Calloutsを扱うために、markdown-it を用いて次のように構成した。

  • プラグインで構文を解釈(AST/token 変換)
  • レンダラーでHTMLへ変換

という形で分割している。

また、Calloutsを用いた拡張として独自の記法([!card][!card-grid])は、通常Calloutsとは分離して、専用プラグイン+専用レンダラーで処理する。

    ├── markdown
    │   ├── markdownEngine.ts
    │   ├── plugins
    │   │   ├── calloutsUtils.ts
    │   │   ├── cardCalloutsPlugin.ts
    │   │   ├── obsidianCalloutsPlugin.ts
    │   │   └── obsidianWikilinkInline.ts
    │   ├── renderer
    │   │   ├── cardCalloutsRenderer.ts
    │   │   ├── obsidianCalloutsRenderer.ts
    │   │   ├── obsidianRenderer.ts
    │   │   └── wikilinksRenderer.ts
    │   └── types.ts

各ファイルの役割

markdown/markdownEngine.ts

markdown-it の初期化、。

  • markdown-it のインスタンス生成
  • プラグイン登録順序の管理
  • renderer 登録
  • HTML出力の入口

markdown/types.ts

markdown-it / Token / Renderer などの型定義を集約したファイル。

markdown/plugins/calloutsUtils.ts

Callouts周りの共通処理をまとめたユーティリティ。

  • Callout行の解析補助([!info] など)
  • タイトル・折り畳み・メタ抽出の補助
  • card / 通常calloutで共有する判定処理

Calloutsを構成する複数plugin間でロジックが重複しないようにする目的で導入。

markdown/plugins/obsidianCalloutsPlugin.ts

Obsidian 形式の通常 Callouts を解析し、markdown-it token に変換するプラグイン。

https://help.obsidian.md/calloutsにて記載されている形式のものを変換する。

  • Callouts ブロックの検出
  • Callouts 種別 / タイトル / 折りたたみ指定などを token 化
  • 後段の renderer が HTML を生成できる状態に整形する

markdown/plugins/cardCalloutsPlugin.ts

[!card] [!card-grid] 系のカード表示専用を扱うプラグイン。Calloutsを利用した独自の書き方なので通常のCalloutsは分離して処理する。

  • 出力HTMLが通常Calloutと大きく異なる
  • 「記事一覧」「リンクカード」など、本文のMarkdownレンダリングではなく専用HTML生成が必要
  • 画像、説明、リンクなどを追加している

このプラグインは、cardCallout を検出し、必要なメタ情報(タイトル、リンクリストなど)を token/meta に詰める。

markdown/plugins/obsidianWikilinkInline.ts

Obsidian の Wikilink[[...]])を インライン構文として解析するためのプラグイン。

  • [[...]] をリンク token として扱えるようにする
  • ![[...]](埋め込み形式)との区別
  • 通常リンクやmarkdownリンクと衝突しないように処理順を調整する

markdown/renderer/obsidianRenderer.ts

Obsidian 風にするための基礎レンダリング拡張(見出し/リンク/画像/コード/埋め込み)をまとめて登録する。

Callouts以外の部分を調整している。画像表示やリンク表示などが上手くいかない時はここをいじればok。これまでmarkedで書いていたのはこの部分のみ。

markdown/renderer/obsidianCalloutsRenderer.ts

通常Callouts(card系以外)の HTML 出力担当。
SVGアイコンの付与なども行っている。

markdown/renderer/cardCalloutsRenderer.ts

[!card][!card-grid] 専用のレンダラー。
カードのUIとして完成したHTMLを生成する。

markdown/renderer/wikilinksRenderer.ts

WikilinkHTMLリンクに変換するレンダラー。

  • [[note]]/notes/note のような内部リンクに変換
  • [[note|label]] の label 表示対応

全体フロー(ざっくり)

  1. markdownEngine.tsmarkdown-it を生成
  2. plugins/ が markdown構文を解釈して token 化
  3. renderer/ が token を HTML に変換
  4. Next.js 側は生成されたHTMLを表示

新しい基本の Callouts を追加したい時

  • obsidianCalloutsRenderer.ts にアイコンを追加する。
  • Next.js 側のスタイルシートで調整する。

おわり

ok。Calloutsの調整完了です。

サイトアイコン
公開日
更新日