Autoformat

Apply formatting automatically using shortcodes.

Loading...
Files
components/demo.tsx
'use client';

import React from 'react';

import { Plate } from '@udecode/plate-common/react';

import { editorPlugins } from '@/components/editor/plugins/editor-plugins';
import { useCreateEditor } from '@/components/editor/use-create-editor';
import { Editor, EditorContainer } from '@/components/plate-ui/editor';

import { DEMO_VALUES } from './values/demo-values';

export default function Demo({ id }: { id: string }) {
  const editor = useCreateEditor({
    plugins: [...editorPlugins],
    value: DEMO_VALUES[id],
  });

  return (
    <Plate editor={editor}>
      <EditorContainer variant="demo">
        <Editor />
      </EditorContainer>
    </Plate>
  );
}

功能特点

  • 通过短代码快速格式化内容。
  • 提供类似 markdown 的行内代码,用于实时输入。
  • 通过避免工具栏按钮和快捷键来简化编辑。
  • 自动转换功能(例如,# 到 H1)。
  • 提供预定义的格式化规则。

格式化快捷代码:

  • text* 用于加粗文本。
  • _text_ 用于斜体文本。
  • ~~text~~ 用于删除线文本。
  • ...等等。

安装

npm install @udecode/plate-autoformat

使用

import { AutoformatPlugin } from '@udecode/plate-autoformat/react';
 
const plugins = [
  // ...otherPlugins,
  AutoformatPlugin.configure({
    options: {
      rules: autoformatRules,
      enableUndoOnDelete: true,
    },
  }),
];

示例

autoformatRules

'use client';
 
import type { AutoformatRule } from '@udecode/plate-autoformat';
import type { SlateEditor } from '@udecode/plate-common';
 
import {
  autoformatArrow,
  autoformatLegal,
  autoformatLegalHtml,
  autoformatMath,
  autoformatPunctuation,
  autoformatSmartQuotes,
} from '@udecode/plate-autoformat';
import { AutoformatPlugin } from '@udecode/plate-autoformat/react';
import {
  BoldPlugin,
  CodePlugin,
  ItalicPlugin,
  StrikethroughPlugin,
  SubscriptPlugin,
  SuperscriptPlugin,
  UnderlinePlugin,
} from '@udecode/plate-basic-marks/react';
import { BlockquotePlugin } from '@udecode/plate-block-quote/react';
import { insertEmptyCodeBlock } from '@udecode/plate-code-block';
import {
  CodeBlockPlugin,
  CodeLinePlugin,
} from '@udecode/plate-code-block/react';
import {
  getParentNode,
  insertNodes,
  isElement,
  isType,
  setNodes,
} from '@udecode/plate-common';
import { ParagraphPlugin } from '@udecode/plate-common/react';
import { HEADING_KEYS } from '@udecode/plate-heading';
import { HighlightPlugin } from '@udecode/plate-highlight/react';
import { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';
import {
  INDENT_LIST_KEYS,
  ListStyleType,
  toggleIndentList,
} from '@udecode/plate-indent-list';
import { TogglePlugin, openNextToggles } from '@udecode/plate-toggle/react';
 
export const format = (editor: SlateEditor, customFormatting: any) => {
  if (editor.selection) {
    const parentEntry = getParentNode(editor, editor.selection);
 
    if (!parentEntry) return;
 
    const [node] = parentEntry;
 
    if (
      isElement(node) &&
      !isType(editor, node, CodeBlockPlugin.key) &&
      !isType(editor, node, CodeLinePlugin.key)
    ) {
      customFormatting();
    }
  }
};
 
export const autoformatMarks: AutoformatRule[] = [
  {
    match: '***',
    mode: 'mark',
    type: [BoldPlugin.key, ItalicPlugin.key],
  },
  {
    match: '__*',
    mode: 'mark',
    type: [UnderlinePlugin.key, ItalicPlugin.key],
  },
  {
    match: '__**',
    mode: 'mark',
    type: [UnderlinePlugin.key, BoldPlugin.key],
  },
  {
    match: '___***',
    mode: 'mark',
    type: [UnderlinePlugin.key, BoldPlugin.key, ItalicPlugin.key],
  },
  {
    match: '**',
    mode: 'mark',
    type: BoldPlugin.key,
  },
  {
    match: '__',
    mode: 'mark',
    type: UnderlinePlugin.key,
  },
  {
    match: '*',
    mode: 'mark',
    type: ItalicPlugin.key,
  },
  {
    match: '_',
    mode: 'mark',
    type: ItalicPlugin.key,
  },
  {
    match: '~~',
    mode: 'mark',
    type: StrikethroughPlugin.key,
  },
  {
    match: '^',
    mode: 'mark',
    type: SuperscriptPlugin.key,
  },
  {
    match: '~',
    mode: 'mark',
    type: SubscriptPlugin.key,
  },
  {
    match: '==',
    mode: 'mark',
    type: HighlightPlugin.key,
  },
  {
    match: '≡',
    mode: 'mark',
    type: HighlightPlugin.key,
  },
  {
    match: '`',
    mode: 'mark',
    type: CodePlugin.key,
  },
];
 
export const autoformatBlocks: AutoformatRule[] = [
  {
    match: '# ',
    mode: 'block',
    type: HEADING_KEYS.h1,
  },
  {
    match: '## ',
    mode: 'block',
    type: HEADING_KEYS.h2,
  },
  {
    match: '### ',
    mode: 'block',
    type: HEADING_KEYS.h3,
  },
  {
    match: '#### ',
    mode: 'block',
    type: HEADING_KEYS.h4,
  },
  {
    match: '##### ',
    mode: 'block',
    type: HEADING_KEYS.h5,
  },
  {
    match: '###### ',
    mode: 'block',
    type: HEADING_KEYS.h6,
  },
  {
    match: '> ',
    mode: 'block',
    type: BlockquotePlugin.key,
  },
  {
    format: (editor) => {
      insertEmptyCodeBlock(editor, {
        defaultType: ParagraphPlugin.key,
        insertNodesOptions: { select: true },
      });
    },
    match: '```',
    mode: 'block',
    triggerAtBlockStart: false,
    type: CodeBlockPlugin.key,
  },
  {
    match: '+ ',
    mode: 'block',
    preFormat: openNextToggles,
    type: TogglePlugin.key,
  },
  {
    format: (editor) => {
      setNodes(editor, { type: HorizontalRulePlugin.key });
      insertNodes(editor, {
        children: [{ text: '' }],
        type: ParagraphPlugin.key,
      });
    },
    match: ['---', '—-', '___ '],
    mode: 'block',
    type: HorizontalRulePlugin.key,
  },
];
 
export const autoformatIndentLists: AutoformatRule[] = [
  {
    format: (editor) => {
      toggleIndentList(editor, {
        listStyleType: ListStyleType.Disc,
      });
    },
    match: ['* ', '- '],
    mode: 'block',
    type: 'list',
  },
  {
    format: (editor) =>
      toggleIndentList(editor, {
        listStyleType: ListStyleType.Decimal,
      }),
    match: [String.raw`^\d+\.$ `, String.raw`^\d+\)$ `],
    matchByRegex: true,
    mode: 'block',
    type: 'list',
  },
  {
    format: (editor) => {
      toggleIndentList(editor, {
        listStyleType: INDENT_LIST_KEYS.todo,
      });
      setNodes(editor, {
        checked: false,
        listStyleType: INDENT_LIST_KEYS.todo,
      });
    },
    match: ['[] '],
    mode: 'block',
    type: 'list',
  },
  {
    format: (editor) => {
      toggleIndentList(editor, {
        listStyleType: INDENT_LIST_KEYS.todo,
      });
      setNodes(editor, {
        checked: true,
        listStyleType: INDENT_LIST_KEYS.todo,
      });
    },
    match: ['[x] '],
    mode: 'block',
    type: 'list',
  },
];
 
export const autoformatPlugin = AutoformatPlugin.configure({
  options: {
    enableUndoOnDelete: true,
    rules: [
      ...autoformatBlocks,
      ...autoformatMarks,
      ...autoformatSmartQuotes,
      ...autoformatPunctuation,
      ...autoformatLegal,
      ...autoformatLegalHtml,
      ...autoformatArrow,
      ...autoformatMath,
      ...autoformatIndentLists,
    ],
  },
});

autoformatBlocks

autoformatIndentLists

如果使用 Indent List 插件,您可以使用以下规则:

autoformatLists

如果使用 List 插件,您可以使用以下规则:

autoformatMarks

autoformatUtils

API

AutoformatPlugin

Options

Collapse all

    触发规则列表。

    • 可以是以下之一:AutoformatBlockRuleAutoformatMarkRuleAutoformatTextRule
    • 继承 AutoformatCommonRule

    Enable undo on delete.

Rules

You can import the following rules:

名称描述
autoformatSmartQuotes"text" 转换为 "text"
'text' 转换为 'text'
autoformatPunctuation-- 转换为
... 转换为
>> 转换为 »
<< 转换为 «
autoformatArrow-> 转换为
<- 转换为
=> 转换为
<=≤= 转换为
autoformatLegal(tm)(TM) 转换为
(r)(R) 转换为 ®
(c)(C) 转换为 ©
autoformatLegalHtml&trade; 转换为
&reg; 转换为 ®
&copy; 转换为 ©
&sect; 转换为 §
autoformatComparison!> 转换为 !>
!< 转换为
>= 转换为
<= 转换为
!>= 转换为
!<= 转换为
autoformatEquality!= 转换为
== 转换为
!==≠= 转换为
~= 转换为
!~= 转换为
autoformatFraction1/2 转换为 ½
1/3 转换为
...
7/8 转换为
autoformatDivision// 转换为 ÷
autoformatOperation+- 转换为 ±
%% 转换为
%%%‰% 转换为
autoformatDivision rules.
autoformatSubscriptNumbers~0 转换为
~1 转换为
...
~9 转换为
autoformatSubscriptSymbols~+ 转换为
~- 转换为
autoformatSuperscriptNumbers^0 转换为
^1 转换为 ¹
...
^9 转换为
autoformatSuperscriptSymbols^+ 转换为 °
^- 转换为
autoformatMathautoformatComparison rules
autoformatEquality rules
autoformatOperation rules
autoformatFraction rules
autoformatSubscriptNumbers rules
autoformatSubscriptSymbols rules
autoformatSuperscriptNumbers rules
autoformatSuperscriptSymbols rules

AutoformatCommonRule

自动格式化规则的通用结构接口,不受其模式影响。

Attributes

Collapse all

    当触发器和光标前的文本匹配时应用规则。

    • 对于 mode: 'block':在光标前查找结束匹配。
    • 对于 mode: 'text':在光标前查找结束匹配。如果 format 是数组,还会查找开始匹配。
    • 对于 mode: 'mark':查找开始和结束匹配。
    • 注意:'_*'['_*']{ start: '_*', end: '*_' } 是等效的。
    • MatchRange

    触发自动格式化的字符。

    如果为 true,在自动格式化后插入触发字符。

    • 默认值: false

    允许自动格式化的查询函数。

    • AutoformatQueryOptions 继承 Omit<AutoformatCommonRule, 'query'>

AutoformatBlockRule

块模式自动格式化规则的接口。

Attributes

Collapse all

    • 文本:插入文本。
    • 块:设置块类型或自定义格式。
    • 标记:在匹配之间插入标记。

    匹配自动格式化规则的模式。

    • 对于 mode: 'block':设置块类型。如果定义了 format,则忽略此字段。
    • 对于 mode: 'mark':要添加的标记。

    如果为 true,触发器应该在块开始处才允许自动格式化。

    • 默认值: true

    如果为 true,即使在选定块上方有相同类型的块,也允许自动格式化。

    • 默认值: false

    format 之前调用的函数。通常用于重置选定的块。

    自定义格式化函数。

AutoformatMarkRule

标记模式自动格式化规则的接口。

Attributes

Collapse all

    模式为 'mark'。

    要添加的标记。

    如果为 false,当字符串可以被修剪时不进行格式化。

AutoformatTextRule

文本模式自动格式化规则的接口。

Parameters

Collapse all

    模式为 'text'。

    匹配自动格式化规则的模式。

    匹配的文本被该字符串替换,匹配的文本被这些字符串替换,或在匹配时调用的函数。