返回 presentation-ai
presentation-autoformat-kit.tsx
根目录 / src / components / notebook / presentation / editor / plugins / presentation-autoformat-kit.tsx
1 "use client";
2
3 import { BlockquoteRules } from "@platejs/basic-nodes";
4 import { CodeBlockRules } from "@platejs/code-block";
5 import {
6 BulletedListRules,
7 OrderedListRules,
8 TaskListRules,
9 } from "@platejs/list";
10 import { createRuleFactory, KEYS } from "platejs";
11 import { createPlatePlugin } from "platejs/react";
12
13 import {
14 PRESENTATION_TITLE_ELEMENT,
15 type PresentationTitleVariant,
16 } from "../lib";
17
18 function getPresentationTitleVariant(marker: string): PresentationTitleVariant {
19 if (marker === "!!!") return "humongous";
20 if (marker === "!!") return "display";
21 return "title";
22 }
23
24 const presentationTitleRule = createRuleFactory({
25 type: "blockStart",
26 trigger: " ",
27 match: /^!{1,3}$/,
28 apply: ({ editor }, match) => {
29 editor.tf.delete({ at: match.range });
30 editor.tf.setNodes(
31 {
32 type: PRESENTATION_TITLE_ELEMENT,
33 variant: getPresentationTitleVariant(match.text),
34 },
35 { match: (node) => editor.api.isBlock(node) },
36 );
37 return true;
38 },
39 });
40
41 const presentationHeadingRule = createRuleFactory<{
42 level: 1 | 2 | 3 | 4 | 5 | 6;
43 }>(({ level }) => ({
44 type: "blockStart",
45 trigger: " ",
46 match: "#".repeat(level),
47 node: `h${level}`,
48 }));
49
50 const presentationDividerOnSpaceRule = createRuleFactory({
51 type: "blockStart",
52 trigger: " ",
53 match: /^([-*_])\1{2}$/,
54 apply: ({ editor }, match) => {
55 editor.tf.delete({ at: match.range });
56 editor.tf.setNodes({ type: KEYS.hr });
57 editor.tf.insertNodes({
58 children: [{ text: "" }],
59 type: KEYS.p,
60 });
61 return true;
62 },
63 });
64
65 const presentationDividerOnCharacterRule = createRuleFactory<{
66 marker: "-" | "*" | "_";
67 }>(({ marker }) => ({
68 type: "blockStart",
69 trigger: marker,
70 match: `${marker}${marker}`,
71 apply: ({ editor }, match) => {
72 editor.tf.delete({ at: match.range });
73 editor.tf.setNodes({ type: KEYS.hr });
74 editor.tf.insertNodes({
75 children: [{ text: "" }],
76 type: KEYS.p,
77 });
78 return true;
79 },
80 }));
81
82 export const PresentationAutoformatKit = [
83 createPlatePlugin({
84 key: "presentation-autoformat",
85 inputRules: [
86 presentationTitleRule(),
87 presentationHeadingRule({ level: 1 }),
88 presentationHeadingRule({ level: 2 }),
89 presentationHeadingRule({ level: 3 }),
90 presentationHeadingRule({ level: 4 }),
91 presentationHeadingRule({ level: 5 }),
92 presentationHeadingRule({ level: 6 }),
93 BlockquoteRules.markdown(),
94 BulletedListRules.markdown(),
95 BulletedListRules.markdown({ variant: "*" }),
96 OrderedListRules.markdown(),
97 OrderedListRules.markdown({ variant: ")" }),
98 TaskListRules.markdown(),
99 TaskListRules.markdown({ checked: true }),
100 CodeBlockRules.markdown({ on: "match" }),
101 presentationDividerOnCharacterRule({ marker: "-" }),
102 presentationDividerOnCharacterRule({ marker: "*" }),
103 presentationDividerOnCharacterRule({ marker: "_" }),
104 presentationDividerOnSpaceRule(),
105 ],
106 }),
107 ];
108
108 lines Plain Text