notion2hast
v0.1.3
Published
Notion blocks to hast
Downloads
43
Readme
notion2hast
Notion の blocks を hast へ変換。
実装中。
Installtion
$ npm install --save notion2hast
Security
notion2hast
は信頼できるソースのみを扱う前提で動作します。
第三者からのソースを扱う状況では hast-util-sanitize
の併用を推奨します。
Usage
basic
import { Client as NotionClient } from '@notionhq/client'
import { ClientOptions } from '@notionhq/client/build/src/Client'
import { toHtml as hastToHtml } from 'hast-util-to-html'
import { blockToHast } from 'notion2hast'
import { Client } from 'notion2hast'
class FromNotion extends Client {
private client: NotionClient
constructor(options?: ClientOptions) {
super()
this.client = new NotionClient(options)
}
listBlockChildren(
...args: Parameters<NotionClient['blocks']['children']['list']>
): ReturnType<NotionClient['blocks']['children']['list']> {
return this.client.blocks.children.list(...args)
}
}
const apiKey = process.env.API_KEY
const blockId = process.env.BLOCK_ID
const client = new FromNotion({
auth: apiKey
})
const tree = await blockToHast(client, {
block_id: blockId,
blocktoHastOpts: { defaultClassName: true },
richTexttoHastOpts: { defaultClassName: true }
})
console.log(`${hastToHtml(tree)}`)
<p>最初のパラグラフ。</p>
<h2>文字装飾</h2>
<p><strong>太字</strong></p>
<p><em>italic</em></p>
<p><s>打消し線</s></p>
<p><code>code</code></p>
<h2>リスト</h2>
<ul>
<li>項目1</li>
<li>
項目2
<ul>
<li>
項目2-1
<ul>
<li>項目<span style="color: #0b6e99">2-1-1</span></li>
</ul>
</li>
<li>項目2-2</li>
</ul>
</li>
</ul>
Custom Client
Notions の Client(主に fetch 関連)が利用できない環境では Custom Client を利用可能。
以下、Google Apps Script(clasp) で利用する場合の例。
tohast.ts
import { Client as NotionClient } from '@notionhq/client'
import { ClientOptions } from '@notionhq/client/build/src/Client'
import { toHtml as hastToHtml } from 'hast-util-to-html'
import { blockToHast } from '@hankei6km/notion2hast'
import { Client } from '@hankei6km/notion2hast'
import { listBlockChildren } from './notion'
export namespace NotionToHast {
class FromNotion extends Client {
//private client: NotionClient;
private auth: ClientOptions['auth']
constructor(options?: ClientOptions) {
super()
this.auth = options?.auth
}
async listBlockChildren(
...args: Parameters<NotionClient['blocks']['children']['list']>
): Promise<ReturnType<NotionClient['blocks']['children']['list']>> {
return listBlockChildren(this.auth || '', args[0].block_id) as any
}
}
export async function toHast(apiKey: string, block_id: string) {
const client = new FromNotion({ auth: apiKey })
const tree = await blockToHast(client, {
block_id,
blocktoHastOpts: { defaultClassName: true },
richTexttoHastOpts: { defaultClassName: true }
})
console.log(`${hastToHtml(tree)}`)
}
}
notion.ts
import {
CreatePageParameters,
UpdatePageParameters,
QueryDatabaseParameters,
QueryDatabaseResponse
} from '@notionhq/client/build/src/api-endpoints'
const apiIUrlCreatePage = 'https://api.notion.com/v1/pages'
const apiUrlDabtabaseQuery = (database_id: string) =>
`https://api.notion.com/v1/databases/${database_id}/query`
const apiUrlUpdatePage = (page_id: string) =>
`https://api.notion.com/v1/pages/${page_id}`
const apiUrListBlockChildren = (block_id: string) =>
`https://api.notion.com/v1/blocks/${block_id}/children`
const apiVersion = '2022-02-22'
export function isErrRes(
res: GoogleAppsScript.URL_Fetch.HTTPResponse
): boolean {
const code = Math.trunc(res.getResponseCode() / 100)
if (code === 4 || code === 5) {
return true
}
return false
}
export function listBlockChildren(apiKey: string, block_id: string) {
const url = apiUrListBlockChildren(block_id)
try {
const res = UrlFetchApp.fetch(url, {
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
'Notion-Version': apiVersion
},
muteHttpExceptions: true
})
const code = res.getResponseCode()
if (isErrRes(res)) {
throw res.getContentText()
}
const resQuery = JSON.parse(res.getContentText()) as QueryDatabaseResponse
return resQuery
} catch (e) {
console.log(`${e}`)
throw e
}
}
default class name
各要素にデフォルトの class 名を追加。デフォルトのクラス名は properties map の key が使用される。
const client = new FromNotion({
auth: apiKey,
blocktoHastOpts: { defaultClassName: true },
richTexttoHastOpts: { defaultClassName: true }
})
<p class="paragraph">最初のパラグラフ。</p>
<h2 class="heading-2">文字装飾</h2>
<p class="paragraph"><strong class="text-bold">太字</strong></p>
<p class="paragraph"><em class="text-italic">italic</em></p>
<p class="paragraph"><s class="text-strikethrough">打消し線</s></p>
<p class="paragraph"><code class="text-code">code</code></p>
properties map
指定要素のプロパティを変更。className
を指定した場合、指定された要素にデフォルト class 名は追加されない。
const client = new FromNotion({
auth: apiKey,
blocktoHastOpts: {
defaultClassName: true,
blockToHastBuilderOpts: {
propertiesMap: {
'heading-2': { style: 'border: solid;' },
callout: { className: 'flex' },
'callout-paragraph': { className: 'grow' }
}
}
},
richTexttoHastOpts: { defaultClassName: true }
})
<h2 style="border: solid" class="heading-2">コールアウト</h2>
<div class="flex" style="background-color: #ebeced">
<div class="callout-icon-emoji">💡</div>
<div class="grow">
<p>コールアウトの<strong class="text-bold">テキスト</strong>。</p>
</div>
</div>
対応状況
Block
- [x] paragraph
- [x] heading_1
- [x] heading_2
- [x] heading_3
- [x] bulleted_list_item
- [x] numbered_list_item
- [x] quote
- [ ] to_do - チェックは properties map で表現
- [x] toggle
- [ ] template
- [ ] synced_block
- [ ] child_page
- [ ] child_database
- [ ] equation
- [x] code
- [x] callout
- [x] divider
- [ ] breadcrumb
- [ ] table_of_contents
- [x] column_list
- [x] column
- [ ] link_to_page
- [x] table
- [x] table_row
- [ ] embed
- [ ] bookmark -
a
タグとして変換 - [x] image
- [ ] video
- [ ] file
- [ ] audio
- [ ] link_preview
- [ ] unsupported
rich text
- [x] text
- [x] annotations
- [x] bold
- [x] italic
- [x] strikethrough
- [x] underline
- [x] code
- [x] color
- [x] href
- [x] annotations
- [ ] mention
- [ ] user
- [ ] date
- [ ] link_preview
- [ ] template_mention
- [ ] template_mention_date
- [ ] template_mention_user
- [ ] page
- [ ] database
- [ ] annotations
- [ ] bold
- [ ] italic
- [ ] strikethrough
- [ ] underline
- [ ] code
- [ ] color
- [ ] href
- [ ] equation
- [ ] annotations
- [ ] bold
- [ ] italic
- [ ] strikethrough
- [ ] underline
- [ ] code
- [ ] color
- [ ] href
- [ ] annotations
properties mapping
block
paragraph
heading-1
heading-2
heading-3
code
code-pre
code-code
code-caption
callout
callout-icon-emoji
callout-icon-image
callout-paragraph
divider
column-list
column
bulleted-list
bulleted-list-item
numbered-list
numbered-list-item
quote
todo
todo-checked
todo-not-checked
todo-text
toggle
toggle-summary
table
table-row
table-row-cell
table-row-header
table-row-header-top-left
table-row-header-top
table-row-header-left
bookmark
bookmark-link
bookmark-caption
image
image-img
image-caption
rich text
text-link
text-bold
text-code
text-italic
text-strikethrough
text-underline
color
gray
brown
orange
yellow
green
blue
purple
pink
red
gray_background
brown_background
orange_background
yellow_background
green_background
blue_background
purple_background
pink_background
red_background
ライセンス
MIT License
Copyright (c) 2022 hankei6km