NotionのPageをZenn記法のMarkdownに変換するライブラリです。
インストール
npm install notion-to-zenn-md
利用方法
import NotionToZennMarkdown from "notion-to-zenn-md";
// Instantiate with your Notion integration secret
const n2zm = new NotionToZennMarkdown('your_notion_integration_secret');
// Generate markdown from Notion page
const md = await n2zm.generateMd('notion_page_id');
console.log(md);
npm
Github
本ライブラリが指すZenn記法のMarkdownについて
本ライブラリにおいて目指すZenn記法のMarkdownとは次の2つの公式記事の記載されている仕様を指します。
中でも特に以下を簡単に行うことを目指しています。
- 埋め込み要素などZenn独自のMarkdown記法をNotionのページコンテンツから生成すること
- Zenn CLIで記事管理をするために必要なFrontMatterをNotionのページプロパティから生成すること
例えば、
NotionのCalloutというブロックから、
Zenn記法のMarkdownを生成して、
:::message
💡 Callout
:::
Zennのメッセージとして表示させることを目指します。
notion-to-zenn-md
の連携について
Notionの設定方法と 以下の手順で、利用の設定を行います。
- Notionに記事管理用のデータベースを作成
- Notion APIからアクセスするためIntegrationのシークレットを取得
- APIに記事管理用データベースのアクセスを許可
- 取得したシークレットを使い
notion-to-zenn-md
を利用したコードを書いていく
1. Notionに記事管理用のデータベースを作成
Notionを開き、左の一覧より「+」(Add a page)ボタンを押下して新しいページを作成します。
新規ページが開かれたら「Table」を選択して新規テーブルを作成します。
データベースを新規で作成します。
データベースが作成されたらのデータベースのプロパティを編集します。プロパティはFrontMatterの生成に利用します。
以下の様にFrontMatterのキーごとにプロパティを設定する必要があります。
FrontMatterのキー名 | プロパティ名 | プロパティタイプ | 必須 | 備考 |
---|---|---|---|---|
title | Title | Title | Y | |
type | Type | Select | Y | |
topics | Topics | Multi-select | Y | |
published | Published | Checkbox | Y | |
published_at | Published At | Date | N | notion-to-zenn-mdではデフォルトで出力しない設定になっています。 |
emoji | - | - | Y | ページに設定できるアイコンの絵文字を利用します。 |
以下に項目ごとの詳細な設定方法を示します。プロパティタイプに間違いがないように設定してください。
Title
新規でデータベースを作成した場合にデフォルトでTitleタイプのプロパティが作成されます。
プロパティの名前が、初期では Name
となっているので、 Title
に変更します。
Type
記事の種別を示すTypeプロパティを作成します。
プロパティタイプは Select
で、選択肢(Options)は idea
と tech
の2つを用意します。
Topics
Zennのタグのような機能のトピックを編集できるプロパティを設定します。プロパティタイプは Multi-select
です。
Published
公開・非公開を設定するためのプロパティです。プロパティタイプは Checkbox
です。
Published At
公開時間を設定するためのプロパティです。プロパティタイプは Date
です。
データベース一覧はこのようになります。
Emoji
絵文字はページごとの「Add icon」から設定します。
設定するとページタイトルにアイコンがつきます。
記事の作成
データベースにページを作成し以下のように記事を書くことができます。
2. Notion APIからアクセスするためIntegrationのシークレットを取得
Notionのインテグレーションのページから新しいインテグレーションを作成します。
作成するとIntegration Secretが発行されます。これはnotion-to-zenn-mdからNotion APIを叩く際に必要になりますので、コピーしておきます。
3. APIに記事管理用データベースのアクセスを許可
先ほどNotionに作ったデータベースのページに戻り、右上の「・・・」ボタンからメニューを開きます。
Connectionsから先ほど作ったIntegrationを追加します。これで先ほど生成されたシークレットを用いてこのデータベースにアクセスすることができる様になります。
notion-to-zenn-md
を利用したコードを書いていく
4. 取得したシークレットを使い 先ほど取得したシークレットを用いて、以下の様にNotionの特定のページをページID指定でMarkdownに変換することができます。
以下の例では取得したページからMarkdownを生成してファイルに保存しています。
import NotionToZennMarkdown from "notion-to-zenn-md";
import { promises as fs } from 'fs';
async function writeToFile(data: string) {
try {
await fs.writeFile('index.md', data);
console.log('The file has been saved!');
} catch (error) {
console.error('An error occurred:', error);
}
}
async function main() {
const n2zm = new NotionToZennMarkdown('secret_xxxxxxxxx'); // シークレット
const md = await n2zm.generateMd('page_id'); // ページID
await writeToFile(md);
}
main();
このコードを用いて以下のNotionのページを出力してみます。
すると以下のような内容のファイルが出力されます。
---
title: "記事のタイトルです。"
emoji: "🤩"
type: "idea"
topics: ["notion", "markdown"]
published: false
---
# Heading 1
## Heading 2
### Heading 3
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec interdum eros a metus imperdiet maximus. Aenean gravida lacinia ultricies. Duis sit amet justo et lectus pharetra accumsan. Pellentesque urna erat.(text)
補足:FrontMatterの出力に任意の名前のプロパティを用いたい場合
generateMd
メソッドなどの第二引数にFrontMatterの各項目とNotionのページのプロパティ名のマッピングのオブジェクトを渡すことで、任意のプロパティ名を設定したページプロパティからFrontMatterの項目値を取得することができます( emoji
以外)。
例えば、 Topics
の代わりに カテゴリー
というプロパティ名を使いたいとします。
以下の様にコードを変更することで topics
の値を カテゴリー
プロパティから値を取得することが可能です。
const md = await n2zm.generateMd('page_id', {
topics: 'カテゴリー'
});
以下が実際に生成されたFrontMatterの topics
の値です。
---
title: "記事のタイトルです。"
emoji: "🤩"
type: "idea"
topics: ["notion-to-zenn-md"]
published: false
---
Published Atに日付を指定
const md = await n2zm.generateMd('page_id', {
topics: 'カテゴリー',
publishedAt: 'Published At', // ページのプロパティ名を指定
});
---
title: "記事のタイトルです。"
emoji: "🤩"
type: "idea"
topics: ["notion-to-zenn-md"]
published: false
published_at: 2023-10-14 00:00
---
その他の機能
以下にその他の機能を示します。
pageToZennMarkdown(pageId: string): Promise<string>
- NotionのページIDを受け取り、そのページをFrontMatterを含まないZenn記法のマークダウンに変換して返します。
- 引数:
pageId
- NotionのページID - 戻り値: ページのマークダウン表現
getFrontMatter(pageId: string, mappingKeys: FrontMatterNotionPropMapping): Promise<FrontMatter>
- NotionのページIDとマッピングキーを受け取り、Zenn記法のマークダウンのFrontMatterを生成して返します。
- 引数:
pageId
- NotionのページIDmappingKeys
- Zenn Markdown Front Matterキーへのマッピングキー
- 戻り値: FrontMatterオブジェクト
getFrontMatterString(pageId: string, mappingKeys?: Partial<FrontMatterNotionPropMapping>): Promise<string>
- NotionのページIDとオプショナルなマッピングキーを受け取り、FrontMatterの文字列を生成して返します。
- 引数:
pageId
- NotionのページIDmappingKeys
(オプショナル) - Zenn Markdown Front Matterキーへのマッピングキー。デフォルト値はdefaultMapping
です。
- 戻り値: FrontMatterの文字列表現
stringify(mdString: string, fontMatter: FrontMatter): string
- マークダウンの文字列とFrontMatterのオブジェクトを受け取り、マークダウンの文字列を生成して返します。
- 引数:
mdString
- マークダウンの文字列fontMatter
- FrontMatterオブジェクト
- 戻り値: マークダウンの文字列表現
generateMd(pageId: string, mappingKeys?: Partial<FrontMatterNotionPropMapping>): Promise<string>
- NotionのページIDとオプショナルなマッピングキーを受け取り、Zenn記法のマークダウンを生成して返します。
- 引数:
pageId
- NotionのページIDmappingKeys
(オプショナル) - Zenn Markdown Front Matterキーへのマッピングキー。デフォルト値はdefaultMapping
です。
- 戻り値: ページのマークダウン表現
NotionブロックからMarkdownへの変換例
見出し
Notion (Heading 1, Heading 2, Heading 3)
Markdown
# 見出し1
## 見出し2
### 見出し3
#### 見出し4
zenn-markdown-html
見出し1
見出し2
見出し3
見出し4
リスト
Notion (Bulleted List)
Markdown
- Hello!
- Hola!
- Bonjour!
- Hi!
zenn-markdown-html
- Hello!
- Hola!
- Bonjour!
- Hi!
番号付きリスト
Notion (Numbered List)
Markdown
1. First
2. Second
zenn-markdown-html
- First
- Second
テキストリンク
Notion (TextにLink)
Markdown
[アンカーテキスト](https://www.kohsuk.tech/)
zenn-markdown-html
画像
Notion (Image)
Markdown
![image](https://image.example.com)
zenn-markdown-html
画像の横幅を指定する
Notion (Text)
Markdown
![altテキスト](https://kohsuk-blog-assets.s3.ap-northeast-1.amazonaws.com/articles/notion-to-zenn-markdown/1698930064770. =250x)
zenn-markdown-html
キャプションをつける
Notion
NotionのImageのCaptionを利用できます。
Markdown
![キャプション](https://image.example.com)
*キャプション*
zenn-markdown-html
キャプション
画像にリンクを貼る
Notion (Text)
Markdown
[![alt text](https://via.placeholder.com/300x200)](https://www.kohsuk.tech/)
zenn-markdown-html
テーブル
Notion (Table)
Markdown
| Head | Head | Head |
| ---- | ---- | ---- |
| Text | Text | Text |
| Text | Text | Text |
zenn-markdown-html
Head | Head | Head |
---|---|---|
Text | Text | Text |
Text | Text | Text |
コードブロック
Notion (Code)
Markdown
const sayHello = () => { console.log("Hello!"); };
zenn-markdown-html
const sayHello = () => {
console.log("Hello!");
};
ファイル名を表示する
NotionのCodeブロックはキャプションをつけることができます。キャプションにファイル名
を記載することで、 言語:ファイル名
とMarkdownを出力させることができます。
Notion (Code)
Markdown
hello.jsconst sayHello = () => { console.log("Hello!"); };
zenn-markdown-html
const sayHello = () => {
console.log("Hello!");
};
diff のシンタックスハイライト
NotionのCodeブロックにも Diff
がありますが、言語とファイル名を指定する欄はありません。
ですので、ここでもCaptionを利用して言語:ファイル名
と書くことでMarkdownでの出力に対応しています。
Notion (Code)
Markdown
hello.jsconst sayHello = () => { - console.log("Hello!"); + console.log("Hello, world!"); };
zenn-markdown-html
const sayHello = () => {
- console.log("Hello!");
+ console.log("Hello, world!");
};
数式(ブロック)
Notion (Block equation)
Markdown
$$
x^n + y^n = z^n\text{ has no non-zero integer solutions for } x, y, z \text{ when } n > 2.
$$
zenn-markdown-html
数式(インライン)
Notion (Inline equation)
Markdown
$E = mc^2$ の様にインラインで数式を含める
zenn-markdown-html
引用
Notion (Quote)
Markdown
> 引用文
> 引用文
zenn-markdown-html
引用文
引用文
注釈
Notionに対応する記法がないため、テキストブロックに直接記載します。
Notion (Text)
Markdown
注釈は例[^1]の様に書きます。インライン^[注釈の内容2]を書くこともできます。
[^1]: 注釈の内容1
zenn-markdown-html
注釈は例[1]の様に書きます。インライン[2]を書くこともできます。
区切り線
Notion (Divider)
Markdown
---
zenn-markdown-html
インラインスタイル
Notion (Text)
Markdown
_イタリック_
**太字**
~~打ち消し線~~
インラインで `code` を挿入する
zenn-markdown-html
イタリック
太字
打ち消し線
インラインで code
を挿入する
インラインのコメント
Notionに該当するブロックがないため、Textブロックに以下の様に記載することで、出力されたMarkdownにHTMLのコメントを挿入します。
Notion (Text)
Markdown
<!— インラインのコメント —>
zenn-markdown-html
<!— インラインのコメント —>
Zenn 独自の記法
メッセージ
Notion (Callout)
Markdown
:::message
🔥 メッセージです。
:::
zenn-markdown-html
アコーディオン(トグル)
Notion (Text)
Markdown
:::details タイトル
内容です。
:::
zenn-markdown-html
タイトル
内容です。
コンテンツの埋め込み
リンクカード
Notion (Web bookmark)
Markdown
@[card](https://www.kohsuk.tech/tech)
zenn-markdown-html
その他の埋め込み
Notionの Embeds
で用意されているものについては、順次対応していきます。
ダイアグラム
NotionにMermaindのダイアグラムをリアルタイムで見ながらコードブロックを編集する機能を利用できます。出力結果は以下の通り、 mermaid
のコードブロックのMarkdownです。