mdslide

mdslide のアイコン

mdslide

Markdown を書くと、報告用の PowerPoint 資料になる。macOS のデスクトップアプリ(Electron)。

mdslide のデモ: 起動画面から資料を開き、書いて、並べ替えて、レイアウトを選び、pptx を書き出すまで

コンセプト

コンセプト図: Markdown を書く → mdslide が体裁を整える → deck.json 経由で python-pptx がマスターに流し込み pptx を出す。AI エージェントと notes/ は Markdown 側に、master.pptx は保管フォルダから

報告資料づくりで手間なのは中身ではなく体裁の手直しでした。並べ替えたら番号を振り直す、本文が溢れたらフォントを縮める、図を貼り直す。mdslide はその部分をツール側に引き取り、人は Markdown を書くことに集中します。

  1. Markdown が唯一の正。左ペインでの並べ替えやレイアウト変更も、すべて Markdown の書き換えとして実装している。GUI とテキストの二重管理をしないので、Git で差分が追えるし、AI が書き換えても壊れない
  2. 書式は PowerPoint に任せる。レイアウト名を Cover / Agenda / Section / Body-Text / Body-2col と付けたマスター pptx を保管フォルダに置き、資料ごとに選ぶ。ツールは書式を持たない
  3. 本文量は縮めずに分ける。表示行モデルでスライドごとの本文量を推定してゲージに出し、溢れたら自動でページを分割する。読めない資料を作らない
  4. 入口は Markdown ファイル、単位はフォルダ。開いた .md と同じフォルダの images/(貼り付けた画像)、notes/(下書き・素材)、out/(生成物)がひとまとまり。フォルダごと渡せる
  5. AI は隣で動く。中央ペイン下のコンソールで Claude Code / Codex CLI / Gemini CLI などをそのフォルダで起動し、「下書き」に書いたメモを渡して整形させたり、マスターの配色に沿った図を生成させたりする。規約を書いた AGENTS.md と、それを読み込む CLAUDE.md(中身は @AGENTS.md の 1 行)がフォルダに自動で置かれる

はじめの 5 分

  1. ターミナルで curl -fsSL https://froggugugugu.github.io/mdslide/install.sh | bash を実行する(Apple silicon 向け)。mdslide が「アプリケーション」に入り、pptx の書き出しに使う python-pptx も専用の環境に入る。dmg から手で入れる方法は下の「インストール」
  2. 起動画面で「新しく作る」を押し、資料のフォルダを選ぶ(ダイアログで新しく作ってもよい)。その中に deck.md が表紙・章・スライド 1 枚だけの空の枠でできる。題はフォルダ名(見本を触りたければ「サンプルを見る」)
  3. 設定(⌘,)の「マスター」で、レイアウト名を規約どおりに付けた pptx を保管フォルダに取り込む(最初の 1 つは既定のマスターになる)。資料ごとに変えるならツールバーのマスター選択で、その選択は Markdown の frontmatter に master: 名前.pptx として書かれる。見本でよければ、同じ画面の「見本を取り込む」で sample-master.pptx(リポジトリの examples/sample-master.pptx と同じもの)が保管フォルダに入る。手持ちのテンプレートから作る手順と AI 用のプロンプトは docs/master-guide.md
  4. 右ペインで書く(既定は Vim キーバインド。設定の「エディタ」で通常のテキスト編集に切り替えられる)。左ペインでドラッグか ⌥↑↓ で並べ替える。番号は自動で振り直される
  5. 「書き出す」で out/deck.pptx ができる。PowerPoint で開いて仕上げる

2 回目からは前回の資料がそのまま開く。別の資料は、ツールバーのファイル名のボタン(Markdown ファイルを開く)から開く。前回のファイルが無ければ起動画面になり、「最近開いたもの」から選べる。使い方は ⌘/ で開く(初回の起動では自動で開く)。

AI エージェントに任せる

  1. 「下書き」(⌘I)に口語でメモを書く。notes/ に自動保存され、ファイルをドロップしても notes/ に入る
  2. コンソール(⌘J)でエージェントを起動し、「整形して deck.md に」を押す。渡す材料はチェックで選べる
  3. 「図を統一テーマで生成」で、![TODO 説明]() の仮置きが theme.json(マスターから抽出した配色)の PNG に置き換わる
  4. 気に入らなければ「前の版に戻す」(.mdslide/history/)

フォルダには規約を書いた AGENTS.md(と、それを @AGENTS.md で読み込む CLAUDE.md)、theme.json、図の生成ヘルパー tools/mdslide_draw.py が自動で置かれる。

動作環境

項目 要件
OS macOS(Electron)。配布版(Releases の dmg / zip とインストール用コマンド)は Apple silicon 向けで、Intel の Mac はソースから動かす。Linux / Windows は未検証
Node.js 24.15 以上(ソースから動かす場合。.node-version / .nvmrc を置いてあるので fnm / nvm / asdf はそのまま切り替わる)
Python pptx の書き出しに Python 3.9 以上と python-pptx。図の生成を AI に任せるなら 3.12 と requirements.txt
AI エージェント 任意。設定の「ツール」で選んだコマンドをコンソールのシェルで実行する。プリセットは claude codex gemini aider copilot cursor-agent opencode(既定は claude を自動起動)で、自分のコマンドも足せる。コマンドは PATH に入れておく

ブラウザ版(npm run dev:web)は開発と E2E テストのためのもの。Chromium 限定で、pptx 生成とコンソールは使えない。

インストール

ターミナルで次を実行する(Apple silicon 向け)。

curl -fsSL https://froggugugugu.github.io/mdslide/install.sh | bash

scripts/install.sh が次を行う。オプションはスクリプト冒頭のコメントにある。

curl でダウンロードしたファイルには、ブラウザと違って隔離属性(com.apple.quarantine)が付かない。Apple の公証を受けていない配布版でも、このコマンドで入れればそのまま開ける。

ブラウザで dmg をダウンロードして入れる場合は、開く前に隔離属性を外す。外さずに開くと、macOS は「“mdslide”は壊れているため開けません」と表示する(アプリは壊れていない。「ゴミ箱に入れる」は押さずに閉じる)。

  1. Releases の dmg を開き、mdslide を「アプリケーション」にドラッグする
  2. ターミナルで次を実行する

    xattr -dr com.apple.quarantine /Applications/mdslide.app
    
  3. 「アプリケーション」から mdslide を開く

この場合、python-pptx は自分で入れる。アプリは起動時に確認し、見つからなければ案内を出す。

python3 -m venv ~/.config/mdslide/venv
~/.config/mdslide/venv/bin/python -m pip install python-pptx==1.0.2

Python 自体が無ければ、先に xcode-select --install を実行する(Command Line Tools に Python 3 が入っている)。Python の場所は設定の「書き出し」で指定することもできる。

ソースから動かす場合。Node は 24.15 以上(.npmrcengine-strict により、古い Node では npm ci が最初に止まる)。node-pty のビルドに Xcode Command Line Tools(xcode-select --install)が要る。Python は 3.12(requirements.txt の matplotlib と pillow は、Command Line Tools の Python 3.9 には入らない)。Intel の Mac はこの方法で動かす。

npm ci                                                 # Electron と node-pty の再ビルドを含む
python3.12 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt                        # 開発する場合は requirements-dev.txt
npm run dev

配布用のビルドは npm run dist:mac(アドホック署名の dmg / zip を release/ に出す)。GUI を使わずに出力だけ行うこともできる。

python3 tools/export_pptx.py deck.json --master master.pptx -o out.pptx --assets .

Markdown の書き方

---
title: 資料タイトル
subtitle: 副題
agenda: once            # once | per-section | none
numbering: chapter      # chapter (1, 1.1) | flat | none
master: corporate.pptx  # 保管フォルダのマスター。省略時はフォルダの master.pptx、無ければ設定の既定。none で使わない
---

# 章タイトル                      → 中表紙。アジェンダの項目にもなる
## 本文スライド
- 箇条書き(2 スペースで階層)
- **太字**`コード`

## 構成図 {img=3/4 side=left}      → 画像 3/4 幅・左。残りが本文
![構成図](images/arch.png)

## 比較 {layout=2col}             → 最初の空行で左右に分かれる
左の内容

右の内容

## 表とノート
| 指標 | 目標 |
| --- | --- |
| 稼働率 | 99.9% |

> note: スピーカーノート
記法 意味
# 見出し 章(中表紙)。# より前の ## は通し番号になる
## 見出し {属性} 本文スライド。属性は Pandoc 形式
{img=1/1 \| 3/4 \| 1/2} {side=left \| right} 画像スライド。画像はアスペクト比を保って枠に内接
{layout=2col} 2 カラム。Body-2col レイアウトに流し込む
{size=16} そのスライドの本文フォントサイズ(pt)
![TODO 説明]() 画像の仮置き。この行で貼り付けると置き換わる
> note: スピーカーノート
--- 本文内の明示的なページ分割

詳細は docs/markdown-spec.md

ワークスペースの構成

開いた Markdown の親フォルダが作業の単位になる。Markdown を開いたときはその名前のまま使い、フォルダを開いたときと「新しく作る」では deck.md になる。

my-deck/
├── report.md            # 唯一の正(開いた Markdown。名前は自由)
├── images/              # 貼り付けた画像(相対パスで参照)
├── master.pptx          # このフォルダ専用のマスター(任意。通常は保管フォルダから frontmatter で選ぶ)
├── deck.json            # 書き出しの中間形式(契約 v2)
├── out/deck.pptx        # 生成結果
├── notes/               # 下書き・素材
├── theme.json           # マスターから抽出した配色とフォント(アプリが書き直す。手で編集しない)
├── tools/mdslide_draw.py # 図の生成ヘルパー(アプリの版で上書きされる)
├── AGENTS.md            # エージェント向けの規約(無いときだけ生成、編集可)
├── CLAUDE.md            # @AGENTS.md の 1 行。Claude Code は同じ規約を読む
└── .mdslide/history/    # AI に指示を送る直前の Markdown のスナップショット(「前の版に戻す」で戻る)

設定

設定は 1 ファイル ~/.config/mdslide/settings.json(XDG_CONFIG_HOME 準拠、MDSLIDE_CONFIG で場所を変更できる)に置く。手で編集した内容はウィンドウにフォーカスが戻ったときに反映される。マスターの保管フォルダ(masters.dir)、既定のマスター(masters.default)、Vim キーバインド(editor.vim)、エディタ幅(editor.width)、書き出しに使う Python の場所(export.python)もここにある。保管フォルダの既定は設定ファイルと同じフォルダの masters/、アプリが最初に探す Python は同じフォルダの venv/

環境変数 用途
MDSLIDE_CONFIG 設定ファイルのパス
MDSLIDE_WORKSPACE 起動時に開くフォルダか Markdown ファイル(起動引数でも渡せる)
MDSLIDE_PYTHON pptx の書き出しに使う Python。指定するとそれだけを使い、自動では探さない
MDSLIDE_NODE node-pty を読み込めない環境で端末を中継する Node(既定 node)

開発

npm run dev                  # Electron(electron-vite dev)
npm run dev:web              # ブラウザ版 http://localhost:5173
npm run typecheck            # tsc(src+tests / electron)
npm test                     # vitest(単体 + 内部結合)
npm run test:coverage        # 閾値 lines 80% / branches 70%
npm run test:py              # pytest(deck.json → pptx、図生成、インストール用スクリプト)
npm run test:e2e             # Web E2E(headless Chromium)
npm run test:e2e:electron    # Electron E2E(実アプリを起動。要ディスプレイ)
npm run test:all             # typecheck / test:coverage / test:py / test:e2e。PR の条件(Electron E2E は CI の macOS ジョブで回る)
場所 保証すること
単体 tests/unit/ parser / render / fit / geometry / importMaster / workspace / 各コンポーネント
内部結合 tests/integration/ store を通した Markdown → スライド → 保存、フォルダ監視と競合
Python tests/python/ deck.json → pptx(レイアウト解決、画像内接、表、ノート、警告)、図の生成ヘルパー、scripts/install.sh(macOS のみ)
E2E tests/e2e/ ユーザーが実際に行う一連の操作。Web は OPFS、Electron は CDP

リリースは package.jsonversion を上げ、同じ版のタグを push する(タグと version が違えば release.yml が止まる)。release.yml の build ジョブが macOS ランナーで dmg / zip をビルドし、署名、インストール用コマンドでの入れ方、ライセンス表示、Electron fuses を確かめる。publish ジョブが下書きのリリースに添付してから公開する(Immutable releases のため、公開後は添付ファイルもタグも変えられない。ADR-0027)。使い方ページ(GitHub Pages)とインストール用コマンドは、main への push で pages.yml が更新する。

v="v$(node -p "require('./package.json').version")" && git tag "$v" && git push origin "$v"

設計の要点は次のとおり。詳細は CLAUDE.mddocs/adr/

依存関係の固定

サプライチェーン攻撃への備えとして、依存はすべて完全一致で固定し、更新は PR 経由でのみ取り込む。

ドキュメント

クレジット

このプロジェクトは project-blueprints を利用して開発している。Claude Code のルール・スキル・エージェント・品質ゲートといった開発の枠組みはそこから来ており、このリポジトリには mdslide 固有の規約(CLAUDE.md)だけを含めている。

ライセンス

MIT。同梱するサードパーティのソフトウェアと素材のライセンス、商標については THIRD_PARTY_NOTICES.md。脆弱性は公開の Issue ではなく、SECURITY.md の方法で知らせてください。