diff --git a/.changeset/pink-starfishes-jog.md b/.changeset/pink-starfishes-jog.md new file mode 100644 index 0000000000..177ec91e70 --- /dev/null +++ b/.changeset/pink-starfishes-jog.md @@ -0,0 +1,6 @@ +--- +'@udecode/slate-utils': minor +'@udecode/plate-autoformat': minor +--- + +feat: Add matchByRegex option diff --git a/apps/www/src/lib/plate/demo/plugins/autoformatIndentLists.ts b/apps/www/src/lib/plate/demo/plugins/autoformatIndentLists.ts index 49407470c2..29f08f1a2c 100644 --- a/apps/www/src/lib/plate/demo/plugins/autoformatIndentLists.ts +++ b/apps/www/src/lib/plate/demo/plugins/autoformatIndentLists.ts @@ -23,7 +23,8 @@ export const autoformatIndentLists: AutoformatRule[] = [ toggleIndentList(editor, { listStyleType: ListStyleType.Decimal, }), - match: ['1. ', '1) '], + match: ['^\\d+\\.$ ', '^\\d+\\)$ '], + matchByRegex: true, mode: 'block', type: 'list', }, diff --git a/apps/www/src/lib/plate/demo/plugins/autoformatLists.ts b/apps/www/src/lib/plate/demo/plugins/autoformatLists.ts index a5fc01b040..26bd325f66 100644 --- a/apps/www/src/lib/plate/demo/plugins/autoformatLists.ts +++ b/apps/www/src/lib/plate/demo/plugins/autoformatLists.ts @@ -21,7 +21,8 @@ export const autoformatLists: AutoformatRule[] = [ }, { format: (editor) => formatList(editor, ELEMENT_OL), - match: ['1. ', '1) '], + match: ['^\\d+\\.$ ', '^\\d+\\)$ '], + matchByRegex: true, mode: 'block', preFormat, type: ELEMENT_LI, diff --git a/packages/autoformat/src/transforms/autoformatBlock.ts b/packages/autoformat/src/transforms/autoformatBlock.ts index 4642d54393..731dccce9b 100644 --- a/packages/autoformat/src/transforms/autoformatBlock.ts +++ b/packages/autoformat/src/transforms/autoformatBlock.ts @@ -30,6 +30,7 @@ export const autoformatBlock = ( allowSameTypeAbove = false, format, match: _match, + matchByRegex = false, preFormat, text, trigger, @@ -62,9 +63,14 @@ export const autoformatBlock = ( const textFromBlockStart = getEditorString(editor, matchRange); - if (end !== textFromBlockStart) continue; + const isMatched = matchByRegex + ? !!textFromBlockStart.match(end) + : end === textFromBlockStart; + + if (!isMatched) continue; } else { matchRange = getRangeBefore(editor, editor.selection as Range, { + matchByRegex, matchString: end, }); diff --git a/packages/autoformat/src/types.ts b/packages/autoformat/src/types.ts index d1933e9597..b9c5308b5f 100644 --- a/packages/autoformat/src/types.ts +++ b/packages/autoformat/src/types.ts @@ -77,6 +77,14 @@ export interface AutoformatBlockRule< */ format?: (editor: E) => void; + /** + * If true, `match` will be interpreted as regex expression(s). Otherwise, it + * will be compared by string equality. + * + * @default false + */ + matchByRegex?: boolean; + /** * Function called just before `format`. Generally used to reset the selected * block. diff --git a/packages/slate-utils/src/queries/getPointBeforeLocation.ts b/packages/slate-utils/src/queries/getPointBeforeLocation.ts index 340d7a2019..384b046583 100644 --- a/packages/slate-utils/src/queries/getPointBeforeLocation.ts +++ b/packages/slate-utils/src/queries/getPointBeforeLocation.ts @@ -32,6 +32,14 @@ export interface PointBeforeOptions extends BeforeOptions { beforeString: string; }) => boolean; + /** + * If true, `matchString` will be interpreted as regex expression(s). + * Otherwise, it will be compared by string equality. + * + * @default false + */ + matchByRegex?: boolean; + /** Lookup before the location for `matchString`. */ matchString?: string | string[]; @@ -61,6 +69,8 @@ export const getPointBeforeLocation = ( ? castArray(options.matchString) : ['']; + const matchByRegex = options.matchByRegex ?? false; + let point: any; matchStrings.some((matchString) => { @@ -105,8 +115,13 @@ export const getPointBeforeLocation = ( beforeStringToMatch = map(stack.slice(0, -1), 'text').join(''); } + + const isMatched = matchByRegex + ? !!matchString.match(beforeStringToMatch) + : beforeStringToMatch === matchString; + if ( - matchString === beforeStringToMatch || + isMatched || options.match?.({ at, beforePoint, beforeString: beforeStringToMatch }) ) { if (options.afterMatch) { diff --git a/templates/plate-playground-template/src/lib/plate/autoformatIndentLists.ts b/templates/plate-playground-template/src/lib/plate/autoformatIndentLists.ts index 9d5aa0676d..9f11c15f55 100644 --- a/templates/plate-playground-template/src/lib/plate/autoformatIndentLists.ts +++ b/templates/plate-playground-template/src/lib/plate/autoformatIndentLists.ts @@ -1,6 +1,10 @@ import { AutoformatRule } from '@udecode/plate-autoformat'; import { ListStyleType, toggleIndentList } from '@udecode/plate-indent-list'; + + + + export const autoformatIndentLists: AutoformatRule[] = [ { mode: 'block', @@ -15,10 +19,11 @@ export const autoformatIndentLists: AutoformatRule[] = [ { mode: 'block', type: 'list', - match: ['1. ', '1) '], + match: ['^\\d+\\.$ ', '^\\d+\\)$ '], + matchByRegex: true, format: (editor) => toggleIndentList(editor, { listStyleType: ListStyleType.Decimal, }), }, -]; +]; \ No newline at end of file diff --git a/templates/plate-playground-template/src/lib/plate/autoformatLists.ts b/templates/plate-playground-template/src/lib/plate/autoformatLists.ts index 82891ba59e..736bf1e318 100644 --- a/templates/plate-playground-template/src/lib/plate/autoformatLists.ts +++ b/templates/plate-playground-template/src/lib/plate/autoformatLists.ts @@ -1,15 +1,15 @@ import { AutoformatRule } from '@udecode/plate-autoformat'; import { isBlock, setNodes } from '@udecode/plate-common'; -import { - ELEMENT_LI, - ELEMENT_OL, - ELEMENT_TODO_LI, - ELEMENT_UL, - TTodoListItemElement, -} from '@udecode/plate-list'; +import { ELEMENT_LI, ELEMENT_OL, ELEMENT_TODO_LI, ELEMENT_UL, TTodoListItemElement } from '@udecode/plate-list'; + + import { formatList, preFormat } from '@/lib/plate/autoformatUtils'; + + + + export const autoformatLists: AutoformatRule[] = [ { mode: 'block', @@ -21,7 +21,8 @@ export const autoformatLists: AutoformatRule[] = [ { mode: 'block', type: ELEMENT_LI, - match: ['1. ', '1) '], + match: ['^\\d+\\.$ ', '^\\d+\\)$ '], + matchByRegex: true, preFormat, format: (editor) => formatList(editor, ELEMENT_OL), }, @@ -43,4 +44,4 @@ export const autoformatLists: AutoformatRule[] = [ } ), }, -]; +]; \ No newline at end of file