将html转换为概念块
#javascript #教程 #typescript #notion

如果您需要将HTML导入概念,则可能面临将HTML转换为Intion块格式的挑战。在我最近的项目中,我偶然发现了这个问题,无法找到提供解决方案的任何现有软件包。这就是为什么在这篇文章中,我想分享帮助我正常工作的代码和库。

第一步是将HTML代码解析到JavaScript对象中。为此,我们使用koude1库中的fromHtml函数,该功能以html字符串为输入并返回hast对象:

import { fromHtml } from 'hast-util-from-html';

const html = '<h1>Hello <strong>world!</strong></h1>';
// HTML to HTML AST
const hast = fromHtml(html, { fragment: true });

hast对象将HTML代码表示为抽象语法树(AST),可以操纵并转换为其他格式:

{
  type: 'root',
  children: [
    {
      type: 'element',
      tagName: 'h1',
      properties: {},
      children: [
        {
          type: 'text',
          value: 'Hello ',
          position: {
            start: { line: 1, column: 5, offset: 4 },
            end: { line: 1, column: 11, offset: 10 }
          }
        },
        {
          type: 'element',
          tagName: 'strong',
          properties: {},
          children: [
            {
              type: 'text',
              value: 'world!',
              position: {
                start: { line: 1, column: 19, offset: 18 },
                end: { line: 1, column: 25, offset: 24 }
              }
            }
          ],
          position: {
            start: { line: 1, column: 11, offset: 10 },
            end: { line: 1, column: 34, offset: 33 }
          }
        }
      ],
      position: {
        start: { line: 1, column: 1, offset: 0 },
        end: { line: 1, column: 39, offset: 38 }
      }
    }
  ],
  data: { quirksMode: false },
  position: {
    start: { line: 1, column: 1, offset: 0 },
    end: { line: 1, column: 39, offset: 38 }
  }
}

将HTML代码解析为hast对象后,下一步就是将其转换为Markdown。我们使用koude6库中的toMdast函数,该库将hast对象作为输入并返回mdast对象。

import { fromHtml } from 'hast-util-from-html';
import { toMdast } from 'hast-util-to-mdast';

const html = '<h1>Hello <strong>world!</strong></h1>';
const hast = fromHtml(html, { fragment: true });
// HTML AST to Markdown AST
const mdast = toMdast(hast);

mdast对象将降价代码表示为AST,类似于以前的HTML AST:

{
  type: 'root',
  children: [
    {
      type: 'heading',
      depth: 1,
      children: [
        {
          type: 'text',
          value: 'Hello ',
          position: {
            start: { line: 1, column: 5, offset: 4 },
            end: { line: 1, column: 11, offset: 10 }
          }
        },
        {
          type: 'strong',
          children: [
            {
              type: 'text',
              value: 'world!',
              position: {
                start: { line: 1, column: 19, offset: 18 },
                end: { line: 1, column: 25, offset: 24 }
              }
            }
          ],
          position: {
            start: { line: 1, column: 11, offset: 10 },
            end: { line: 1, column: 34, offset: 33 }
          }
        }
      ],
      position: {
        start: { line: 1, column: 1, offset: 0 },
        end: { line: 1, column: 39, offset: 38 }
      }
    }
  ],
  position: {
    start: { line: 1, column: 1, offset: 0 },
    end: { line: 1, column: 39, offset: 38 }
  }
}

下一步是将标记AST序列化到Markdown String。我们使用koude11库中的toMarkdown函数,该函数以mdast对象为输入并返回markdown字符串:

import { fromHtml } from 'hast-util-from-html';
import { toMdast } from 'hast-util-to-mdast';
import { toMarkdown } from 'mdast-util-to-markdown';

const html = '<h1>Hello <strong>world!</strong></h1>';
const hast = fromHtml(html, { fragment: true });
const mdast = toMdast(hast);
// Markdown AST to Markdown string
const markdown = toMarkdown(mdast);

Markdown字符串具有我们曾经从Dev.to或Github等编辑器中使用的格式:

# Hello **world!**

最后一步是将标记字符串转换为概念块对象,该对象可用于使用概念API创建新块。我们使用koude14库中的markdownToBlocks函数,该函数将Markdown String作为输入并返回BlockObjectRequest对象的数组:

import { fromHtml } from 'hast-util-from-html';
import { toMdast } from 'hast-util-to-mdast';
import { toMarkdown } from 'mdast-util-to-markdown';
import { markdownToBlocks } from '@tryfabric/martian';

const html = '<h1>Hello <strong>world!</strong></h1>';
const hast = fromHtml(html, { fragment: true });
const mdast = toMdast(hast);
const markdown = toMarkdown(mdast);
// Markdown string to Notion Blocks
const blocks = markdownToBlocks(markdown);

每个BlockObjectRequest对象代表一个概念块,并包含必要的信息,以在您的概念页面中创建和格式化块:

[
  {
    object: 'block',
    type: 'heading_1',
    heading_1: {
      rich_text: [
        {
          type: 'text',
          annotations: {
            bold: false,
            strikethrough: false,
            underline: false,
            italic: false,
            code: false,
            color: 'default'
          },
          text: { content: 'Hello ', link: undefined }
        },
        {
          type: 'text',
          annotations: {
            bold: true,
            strikethrough: false,
            underline: false,
            italic: false,
            code: false,
            color: 'default'
          },
          text: { content: 'world!', link: undefined }
        }
      ]
    }
  }
]

这是如何在原始HTML转换的块中创建概念工作空间中新页面的示例。我们使用koude17库,您需要具有有效的概念API键和数据库ID:

import { Client } from '@notionhq/client';

// ...
const blocks = markdownToBlocks(markdown);

const notion = new Client({ auth: process.env.NOTION_API_KEY });

const properties = {
  Name: {
    title: [{ text: { content: 'New Page' } }]
  }
};

const response = await notion.pages.create({
  parent: { database_id: process.env.NOTION_DATABASE_ID },
  properties,
  children: blocks,
});

概念的响应包含新页面及其属性。但是,它不包含块,因为必须单独查询这些块。

{
  object: 'page',
  id: 'c7d50cb4-0518-4ef9-8457-056a53fd53eb',
  created_time: '2023-03-01T10:28:00.000Z',
  last_edited_time: '2023-03-01T10:28:00.000Z',
  created_by: { object: 'user', id: '9d72c6df-be87-4bb5-8edb-1c19461d01bb' },
  last_edited_by: { object: 'user', id: '9d72c6df-be87-4bb5-8edb-1c19461d01bb' },
  cover: null,
  icon: null,
  parent: {
    type: 'database_id',
    database_id: '95970798-23cc-4f7c-a0c5-4870b80fcdee'
  },
  archived: false,
  properties: {
    Name: {
      id: 'title',
      type: 'title',
      title: [
        {
          type: 'text',
          text: { content: 'New Page', link: null },
          annotations: {
            bold: false,
            italic: false,
            strikethrough: false,
            underline: false,
            code: false,
            color: 'default'
          },
          plain_text: 'New Page',
          href: null
        }
      ]
    },
    // ...
  },
  url: 'https://www.notion.so/New-Page-c7d50cb405184ef98457056a53fd53eb'
}

希望您发现这篇文章有帮助。如果您有任何疑问或评论,请随时将它们留在下面。如果您想与我建立联系,可以在LinkedInGitHub上找到我。感谢您的阅读!