publicURL | presentationID | defaults | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1K7iPGagmMcZOeZSXmAR-zYf0tKqExvgOqQA9ueC4njg |
|
- https://github.com/k1LoW/deck
- MarkdownからGoogleスライドを作成するツール (k1LoW++)
- 紹介記事
- 継続的なスライド作成
- コンテンツとデザインの分離
- 毎回新たに再生成するアプローチではない
- Googleスライド側を直接いじった以下のような調整も極力維持される
- 画像などの位置の調整
- スライド内に手動で追加したシェイプ
- 一度スライド化してからスライド側で最終調整だと、その後の継続的な更新が億劫になるが、それが解決される
- 発表版と公開版を分けるなどもやりやすい
- Google Slideの版管理も活用できる
- コンテンツはMarkdown
- デザインはGoogleスライドのテーマを使って制御
- CSS的な機能をGoogleスライドのテーマに持たせるということ
基本的には"Markdown"と"Googleスライドのテーマ"を編集することで大体のことが事足りる。
生成されたGoogleスライド自体の直接調整もできるが、あまり必要が無い。画像位置の調整などをするくらい。
- Googleスライドには「テンプレート」という機能もある
- これはテーマとは異なる
- 用語の混同に注意
- テーマ: 事前に設定された色、フォント、背景、レイアウトのグループ。
- 背景: スライドのコンテンツの背後にある画像や色。
- レイアウト: スライド上のテキストと画像の配置。
参考: Google スライドでテンプレートを使用したり、テーマ、背景、レイアウトを変更したりする
- プレーンテキストである
- レビューや差分確認が容易
- 好きなエディタで編集可能
- 文字のスタイルなどもMarkdownで調整できる
- マウス不要
- アドホックなスタイル調整にならずデザインの一貫性も保たれる
- 最近だとAI支援も受けやすい
- Copilotなどがいい感じに補完候補を出してくれる
- AI Agentに作らせても
- プレゼンツールとしてのGoogleスライドを使える
- スピーカーノートやタイマーなどのスピーカーパネル
- 資料の共有もやりやすい
- URLで共有可能
- 資料の事前提出が必要な場合にも助かる
- PDF出力も可能
- URLで共有可能
- 既存のテーマ資産の活用
公式Homebrewでインストール可能 (exoego++)
% brew install deck
# or go install
% go install github.com/k1LoW/deck/cmd/deck@latest
ここが少し面倒だが、一度セットアップしてしまえば、あとは簡単。
- Google Cloud で開発者プロジェクトを作成 (または再利用)
- APIとサービスでGoogle Slides APIとGoogle Drive APIを有効に
- 認証情報 ページ上部の
+ 認証情報を作成
をクリック - OAuthクライアントIDタイプの認証情報を作成
- タイプとして
デスクトップアプリ
を選択- アプリを公開する必要は無いため Google Auth Paltform / Audience から自分のメールアドレスをテストユーザーに追加
- 認証情報ファイルをダウンロード
~/.local/share/deck/credentials.json
に配置
- プロジェクトを共有する場合、人数が多くなる場合はプロジェクトを分けた方が良いかも
- 会社などで利用する場合
deck
はその仕組み上、結構APIを叩く作りになっている- 極力バッチリクエストにはしている
- 参照: 使用制限 | Google Slides
reqs / min | 読み取り | 書き込み |
---|---|---|
プロジェクト全体 | 3000 | 600 |
ユーザー辺り | 600 | 60 |
% deck new deck.md
deck.md
ファイルが無ければ新規作成- FrontmatterにpresentationIDが挿入される
---
presentationID: xxxxxXXXXxxxxxXXXXxxxxxxxxxx
---
# 最初のページ (基本的にタイトルページ)
https://docs.google.com/presentation/d/xxxxxXXXXxxxxxXXXXxxxxxxxxxx/
がGoogleスライドのURLになる。
% deck new --from xxxxxXXXXxxxxxXXXXxxxxxxxxxx deck.md
既存のスライドのテーマを流用したいときに、元のスライドのIDを指定する。
deck
はテーマが重要なのでこのオプションは大切。テーマ自体はURLを持たないのでプレゼンテーションIDを指定して、そのテーマを流用する。
(設定ファイルに設定可能にしても良いかも)
% deck apply deck.md
Markdownの内容をGoogleスライドに適用する
% deck apply --watch deck.md
Markdownファイルの変更を検知し、適用を自動でおこなう。基本的にスライドMarkdownを編集しながらこれを実行しておく運用になる。
- 外部コマンドと連携してコードブロックを画像変換してスライド内に配置
--code-block-to-image-command(-c)
オプションでコマンド指定- Frontmatterや設定ファイルへの
codeBlockImageCommand:
設定も可能
- Frontmatterや設定ファイルへの
- Songmuは
laminate
, 内部で主にsilicon
を使っている
deck apply -c laminate deck.md
deck new deck.md
でMarkdownファイル作成deck apply -c laminate --watch deck.md
を実行しながらMarkdownファイルを編集- たまに、Googleスライドを確認して位置調整など
deck open deck.md
で対象Googleスライドを開ける
deck apply --watch -c laminate deck.md
~/.config/deck/config.yml
に設定ファイルを置ける- profile対応
~/.config/deck/config-{profile}.yml
に個別の設定ファイルを置ける- profileは
--profile {profile}
オプションで各コマンドに指定 - 仕事用と個人用で分けたい時など
ルールを意識せずとも、直感的に配置されるようになっているし、そうしたい。
- Markdownのhr 要素
---
がスライド区切り- 行頭から3つ以上連続するハイフンをスライド区切りとして扱う
- それ以外の hr 要素は、ページ内のコンテンツ区切りとなる
- スライド内の一番レベルの高い見出しがスライドのタイトルになります
- スライド内の一番高いレベルの見出しの次の見出しがスライドのサブタイトルになります
- 複数設定可
- それ以外のコンテンツは本文として扱われます
- 本文の途中にサブタイトル要素が出現した場合、本文が複数に区切られます
- 本文の途中に hr 要素が現れた場合、それが本文区切りとして扱わる
それぞれ対応するスライド内のプレースホルダーに流し込まれます。
次のスライドにレンダリング例
---
## ここがタイトル
### ここがサブタイトル
これ以降が本文
- `Markdown.pl`
- **CommonMark**
- _GitHub Flavored Markdown_
- Vivliostyle Flavored Markdown
---
これ以降が本文
Markdown.pl
- CommonMark
- GitHub Flavored Markdown
- Vivliostyle Flavored Markdown
CommonMarkの基本的な記法に加えてGFMのテーブル記法もサポート
- Bold (
**bold**
), Italic (*italic*
__italic__
) - List (
-
*
), Ordered list (1.
1)
) - Link (
[Link](https://example.com)
) - Angle bracket autolinks (
<https://example.com>
) - Code (
code
) - Image (

) - Block quote (
> block quote
) - Table (GitHub Flavored Markdown tables)
- RAW inline HTML (e.g.,
<mark>
,<small>
,<kbd>
,<cite>
,<q>
,<span>
,<u>
,<s>
,<sub>
,<sup>
,<var>
,<samp>
,<data>
,<dfn>
,<time>
,<abbr>
)
- Markdown内の画像をスライド内に配置してくれる

の形式- リモートファイルもローカルファイルも両対応
- 場所やサイズは自分で調整
apply
され直しても位置は維持される
- 画像プレースホルダーをレイアウトに設定しておけば場所の制御も可能
- コードブロック画像の配置も同様
- 外部コマンドと連携して画像化したコードブロックを配置
```go
package main
func main() {
println("Hello, World!")
}
```
package main
func main() {
println("Hello, World!")
}
HTMLコメットブロックがスピーカーノートとしてスライドに挿入される。スピーカーノート使えるのは嬉しい人も多いのでは。
<!-- ここがスピーカーノートとして扱われる -->
- 「表示 -> テーマ作成ツール」or「スライド -> テーマを編集」
- テーマは複数の「レイアウト」を持てる
- レイアウトの名前を指定してスライドのデザインを制御する
- プレゼンテーション内のテーマのレイアウト名一覧を表示する
- レイアウトの追加や名前の変更は利用者側で自由おこなう
- 以下はあくまで一例
% deck ls-layouts deck.md
title
part
chapter
title-and-body-2col
title-and-2bodies
title-only
section
1col-text
summary
title-subtitle-body
description
large-number
empty
各スライドのHTMLコメントブロック内に記述したJSONがページ設定として扱われる。現状以下の設定がサポートされている。
- layout: レイアウトの指定
- freeze: スライドをfixしてもう変更しない
- ignore: スライドの生成を行わない
- skip: スライドをskipページとして生成する
<!-- {"layout": "section"} -->
"style" という特別な名前のレイアウトがスタイルシート的な役割を果たし、インライン要素の表示スタイルを定義できる。
code
, bold, italic,link
,blockquote
- その他、
cite
やkbd
といったインラインHTML要素の装飾も定義可能
このページが次のページのようになる
## Inline Style
- <s>strikethrough</s>
- <u>unarticulated annotation</u>
C<sub>8</sub>H<sub>10</sub>N<sub>4</sub>O<sub>2</sub>, also known as
"caffeine."
<var>E</var>=<var>m</var><var>c</var><sup>2</sup>.
strikethrough- unarticulated annotation
C8H10N4O2, also known as "caffeine."
E=mc2.
ページ設定を個別に指定するのではなく、デフォルト設定をまとめて指定できる
以下のようなDSLをFrontmatter内に記述する。これはタイトルのヘッディングレベルに応じたレイアウト指定を実現する設定。
defaults:
- if: page == 1
layout: title
- if: topHeadingLevel == 1
layout: part
- if: topHeadingLevel == 2
layout: chapter
- if: topHeadingLevel == 3
layout: section
# タイトル
## サブタイトル
本文
<!-- {"layout": "part"} -->
本文
## H2タイトル
### H3サブタイトル
本文
<!-- {"layout": "chapter"} -->
本文
タイトルのヘッディングと2レベル以上離れていると本文中にレンダリングされる。
## タイトル
#### 本文中のヘッディング
本文
<!-- {"layout": "chapter"} -->
本文
順番に関わらず、一番高いレベルの見出し(この場合h2)がタイトルとして扱われる。ちなみに、タイトルとサブタイトルの順番は前後しても問題ない。それぞれ違うプレースホルダーに配置されるため。
なので対象レイアウトの表示に則した順番で記述すると分かりやすい。
### サブタイトル1 (左肩部分)
## タイトル
### サブタイトル2
本文
<!-- {"layout": "chapter-2subtitles"} -->
本文
## タイトル
### サブタイトル
本文1
### サブタイトル2
本文2
<!-- {"layout": "title-and-body-2col"} -->
本文1
本文2
ページ区切りにならないhr要素を配置することで本文を分割できる
## タイトル
本文1
- - -
本文2
<!-- {"layout": "title-and-2bodies"} -->
本文1
本文2
- 特別なブロック
blockquote
やtable
は、本文中から抜き出され、独立したオブジェクトとしてスライド上に配置される- 前後のテキストは1つの本文として統合される
- オブジェクトの位置は適宜調整して下さい
- サブタイトルや本文が複数ある場合
- レイアウト内に対応するプレースホルダーが足りない場合、そのテキストはレンダリングされません
- 少し非直感的で警告もされないので不親切だとは思っている
- 警告を出すか、表示を調整するか検討中
以下のような方法がある
- その為のレイアウトをテーマに定義する
<! -- {"layout": "about-company"} -->
のように指定する
- 一枚画像にしてしまってスライド全面で表示する

だけ配置したスライドを作るなど
- Markdown本文中に改行があってもスライド上では改行されない
- 標準的なMarkdownの "Soft line break" 仕様に準拠
- 明示的に改行を挿入したい場合
- "Hard line break" 記法 (行末のスペース2つ) を使う
< br>
タグを直に記述する
- Frontmatterか設定ファイルへの
breaks: true
設定- これにより、Markdown本文中の改行がスライド上でも改行されるようになる
- GitHubサイト上のMarkdownの挙動と同様になるのでそっちの方が嬉しい人も多いかも
- ちなみにGithub Flavored Markdown SpecではSoft line breakは改行表示されないことになっている…
- 「改行するオプションを設けても良い」という記述もある
- ちなみにGithub Flavored Markdown SpecではSoft line breakは改行表示されないことになっている…
deck
のコードブロックの画像化は、任意の画像生成器としても機能するので、 qrencode
コマンドなどと組み合わせてQRコードを生成できる。
コマンドの分岐設定は https://github.com/Songmu/laminate が便利。
```qr
https://github.com/k1LoW/deck
```
https://github.com/k1LoW/deck
- Googleドライブの特定のフォルダ内にスライドを作成できる
- フォルダIDをURLから取得
https://drive.google.com/u/{N}/drive/folders/XXXXX
のXXXXX
部分
- フォルダIDをURLから取得
--folder-id
で指定deck new --folder-id XXXXX deck.md
deck apply --folder-id XXXXX deck.md
- apply時は画像などの一時ファイル作成フォルダとして使われる
- 設定ファイルで指定可能可能
- サービスアカウント利用時は必須
- 新規のサービスアカウントは個別のGoogle Drive容量を持たないため
- 個人のGoogleアカウントではなく、サービスアカウントも利用可能
- GitHub Actions上で動かしたい時など
- ニーズは少ないと思うが
- GitHub Actions上で動かしたい時など
- Google Workspaceの共有ドライブ利用と、
--folder-id
指定が必須- 新規のサービスアカウントは個別のGoogle Drive容量を持たないため
- 古いサービスアカウントは容量が割り当てられていることもある
- 共有フォルダではダメ
- 共有フォルダへの新規ファイル書き込みはアカウントの容量を使う為
- 新規のサービスアカウントは個別のGoogle Drive容量を持たないため
- 詳しくは Service Account Setup for deckを参照のこと
- 自由に利用できます
- 可能ならば何らかの形で支援・貢献して下さると嬉しいです
- 支援や貢献にもいろいろな形があります
- 簡単なものから、できる範囲で構いません
- それが、ソフトウェア自体の継続性にもつながります
- PR活動
- コードへの貢献
- スポンサー
- リポジトリ にstarを付ける
- SNS上で「使ってるよー」と発信する
- Blog等で紹介する
- 実際に
deck
を使ってプレゼンをする
これだけでも立派な貢献なのでめっちゃ嬉しいです。
https://github.com/k1LoW/deck への貢献も大歓迎です。
- バグ報告
- バグ修正
- 機能追加
- パフォーマンス向上
- ドキュメント
deck
実行時にエラーで不正終了した場合、エラーファイル .local/share/deck/error.json
が生成されるので、issueにこちらも添付してもらえると助かります。
オリジナル作者の k1LoW さんと Songmu の二人でメンテナンスしています。GitHub Sponsorsを開けてあるので、是非少額のワンショットでも良いので支援を検討して下さい。
(ちなみに、deck
のインテグレーションテストをGitHub Actionsで実行するためのGoogle WorkspaceやGoogle CloudのリソースにSongmu個人の有料契約を使っているため、ほんのちょっとだけお金がかかっています)
このスライドの元のMarkdownは以下から参照できます。
https://gist.github.com/Songmu/52e7ec5f926670eec190bee7d72bc6c0