@prosekit/extensions 0.14.0 → 0.14.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{drop-indicator-B_oMfeVP.js → drop-indicator-DJq8pF92.js} +1 -1
- package/dist/{drop-indicator-B_oMfeVP.js.map → drop-indicator-DJq8pF92.js.map} +1 -1
- package/dist/{file-iLVR0eM0.js → file-upload-I9m1EJAM.js} +1 -1
- package/dist/file-upload-I9m1EJAM.js.map +1 -0
- package/dist/{index-cp1u4e0e.d.ts → file-upload-dr3IXUty.d.ts} +1 -1
- package/dist/file-upload-dr3IXUty.d.ts.map +1 -0
- package/dist/{paste-rule-BaDghcaU.js → mark-paste-rule-n_2Ehmb5.js} +1 -1
- package/dist/mark-paste-rule-n_2Ehmb5.js.map +1 -0
- package/dist/{mark-rule-CYe8zk4q.js → mark-rule-CUnXwBuy.js} +1 -1
- package/dist/{mark-rule-CYe8zk4q.js.map → mark-rule-CUnXwBuy.js.map} +1 -1
- package/dist/prosekit-extensions-blockquote.js +1 -1
- package/dist/prosekit-extensions-bold.js +1 -1
- package/dist/prosekit-extensions-code-block.d.ts +1 -1
- package/dist/prosekit-extensions-code-block.js +2 -2
- package/dist/prosekit-extensions-code.js +1 -1
- package/dist/prosekit-extensions-drop-indicator.js +1 -1
- package/dist/prosekit-extensions-enter-rule.d.ts +6 -78
- package/dist/prosekit-extensions-enter-rule.d.ts.map +1 -1
- package/dist/prosekit-extensions-enter-rule.js +37 -2
- package/dist/prosekit-extensions-enter-rule.js.map +1 -0
- package/dist/prosekit-extensions-file.d.ts +2 -2
- package/dist/prosekit-extensions-file.js +1 -1
- package/dist/prosekit-extensions-heading.js +1 -1
- package/dist/prosekit-extensions-horizontal-rule.js +1 -1
- package/dist/prosekit-extensions-image.d.ts +2 -1
- package/dist/prosekit-extensions-image.d.ts.map +1 -1
- package/dist/prosekit-extensions-image.js +1 -1
- package/dist/prosekit-extensions-input-rule.js +89 -2
- package/dist/prosekit-extensions-input-rule.js.map +1 -0
- package/dist/prosekit-extensions-italic.js +1 -1
- package/dist/prosekit-extensions-link.js +4 -4
- package/dist/prosekit-extensions-list.js +2 -2
- package/dist/prosekit-extensions-mark-rule.js +1 -1
- package/dist/prosekit-extensions-math.d.ts +154 -0
- package/dist/prosekit-extensions-math.d.ts.map +1 -0
- package/dist/prosekit-extensions-math.js +104 -0
- package/dist/prosekit-extensions-math.js.map +1 -0
- package/dist/prosekit-extensions-paste-rule.js +1 -1
- package/dist/prosekit-extensions-placeholder.js +1 -1
- package/dist/prosekit-extensions-strike.js +1 -1
- package/dist/prosekit-extensions-table.js +1 -1
- package/dist/prosekit-extensions-yjs.d.ts.map +1 -1
- package/dist/shiki-highlighter-chunk.d.ts +19 -2
- package/dist/shiki-highlighter-chunk.d.ts.map +1 -0
- package/dist/{table-4oHfV-Ql.js → table-UJVYsrB7.js} +2 -2
- package/dist/{table-4oHfV-Ql.js.map → table-UJVYsrB7.js.map} +1 -1
- package/package.json +19 -8
- package/src/enter-rule/index.ts +18 -191
- package/src/math/index.ts +22 -0
- package/src/math/math-block.ts +89 -0
- package/src/math/math-inline.ts +89 -0
- package/src/math/math-plugin.ts +8 -0
- package/src/math/math.ts +39 -0
- package/src/testing/index.ts +3 -0
- package/src/testing/katex.ts +9 -0
- package/src/yjs/yjs-types.ts +0 -2
- package/dist/enter-rule-D-p4ykfv.js +0 -96
- package/dist/enter-rule-D-p4ykfv.js.map +0 -1
- package/dist/file-iLVR0eM0.js.map +0 -1
- package/dist/index-cp1u4e0e.d.ts.map +0 -1
- package/dist/input-rule-COGr_GBb.js +0 -90
- package/dist/input-rule-COGr_GBb.js.map +0 -1
- package/dist/paste-rule-BaDghcaU.js.map +0 -1
- package/dist/shiki-highlighter-chunk-DNNm2Vow.d.ts +0 -19
- package/dist/shiki-highlighter-chunk-DNNm2Vow.d.ts.map +0 -1
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import { defineFacet, defineFacetPayload, getMarkType, getNodeType, isMarkAbsent, maybeRun, pluginFacet } from "@prosekit/core";
|
|
2
|
-
import { InputRule, inputRules, textblockTypeInputRule, wrappingInputRule } from "@prosekit/pm/inputrules";
|
|
3
|
-
|
|
4
|
-
//#region src/input-rule/index.ts
|
|
5
|
-
/**
|
|
6
|
-
* Defines an input rule extension.
|
|
7
|
-
*
|
|
8
|
-
* @param rule - The ProseMirror input rule to add.
|
|
9
|
-
*
|
|
10
|
-
* @public
|
|
11
|
-
*/
|
|
12
|
-
function defineInputRule(rule) {
|
|
13
|
-
return defineInputRuleFacetPayload(() => rule);
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* @internal
|
|
17
|
-
*/
|
|
18
|
-
function createMarkInputRule({ regex, type, attrs = null, inCodeMark = false }) {
|
|
19
|
-
return new InputRule(regex, (state, match, start, end) => {
|
|
20
|
-
const { tr, schema } = state;
|
|
21
|
-
const [fullText, markText] = match;
|
|
22
|
-
if (!markText) return null;
|
|
23
|
-
const markStart = start + fullText.indexOf(markText);
|
|
24
|
-
const markEnd = markStart + markText.length;
|
|
25
|
-
if (!(start <= markStart && markStart < markEnd && markEnd <= end)) return null;
|
|
26
|
-
const markType = getMarkType(schema, type);
|
|
27
|
-
const mark = markType.create(maybeRun(attrs, match));
|
|
28
|
-
if (!isMarkAbsent(tr.doc, markStart, markEnd, markType, attrs)) return null;
|
|
29
|
-
const initialStoredMarks = tr.storedMarks ?? [];
|
|
30
|
-
tr.addMark(markStart, markEnd, mark);
|
|
31
|
-
if (markEnd < end) tr.delete(markEnd, end);
|
|
32
|
-
if (start < markStart) tr.delete(start, markStart);
|
|
33
|
-
tr.setStoredMarks(initialStoredMarks);
|
|
34
|
-
return tr;
|
|
35
|
-
}, { inCodeMark });
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Defines an input rule for automatically adding inline marks when a given
|
|
39
|
-
* pattern is typed.
|
|
40
|
-
*
|
|
41
|
-
* @public
|
|
42
|
-
*/
|
|
43
|
-
function defineMarkInputRule(options) {
|
|
44
|
-
return defineInputRule(createMarkInputRule(options));
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Defines an input rule that changes the type of a textblock when the matched
|
|
48
|
-
* text is typed into it.
|
|
49
|
-
*
|
|
50
|
-
* See also [textblockTypeInputRule](https://prosemirror.net/docs/ref/#inputrules.textblockTypeInputRule)
|
|
51
|
-
*
|
|
52
|
-
* @param options
|
|
53
|
-
*
|
|
54
|
-
* @public
|
|
55
|
-
*/
|
|
56
|
-
function defineTextBlockInputRule({ regex, type, attrs }) {
|
|
57
|
-
return defineInputRuleFacetPayload(({ schema }) => {
|
|
58
|
-
return textblockTypeInputRule(regex, getNodeType(schema, type), attrs);
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Defines an input rule for automatically wrapping a textblock when a given
|
|
63
|
-
* string is typed.
|
|
64
|
-
*
|
|
65
|
-
* See also [wrappingInputRule](https://prosemirror.net/docs/ref/#inputrules.wrappingInputRule)
|
|
66
|
-
*
|
|
67
|
-
* @param options
|
|
68
|
-
*
|
|
69
|
-
* @public
|
|
70
|
-
*/
|
|
71
|
-
function defineWrappingInputRule({ regex, type, attrs, join }) {
|
|
72
|
-
return defineInputRuleFacetPayload(({ schema }) => {
|
|
73
|
-
return wrappingInputRule(regex, getNodeType(schema, type), attrs, join);
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
function defineInputRuleFacetPayload(input) {
|
|
77
|
-
return defineFacetPayload(inputRuleFacet, [input]);
|
|
78
|
-
}
|
|
79
|
-
const inputRuleFacet = defineFacet({
|
|
80
|
-
reducer: (inputs) => {
|
|
81
|
-
return (context) => {
|
|
82
|
-
return [inputRules({ rules: inputs.flatMap((callback) => callback(context)) })];
|
|
83
|
-
};
|
|
84
|
-
},
|
|
85
|
-
parent: pluginFacet
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
//#endregion
|
|
89
|
-
export { defineWrappingInputRule as a, defineTextBlockInputRule as i, defineInputRule as n, defineMarkInputRule as r, createMarkInputRule as t };
|
|
90
|
-
//# sourceMappingURL=input-rule-COGr_GBb.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"input-rule-COGr_GBb.js","names":[],"sources":["../src/input-rule/index.ts"],"sourcesContent":["import {\n defineFacet,\n defineFacetPayload,\n getMarkType,\n getNodeType,\n isMarkAbsent,\n maybeRun,\n pluginFacet,\n type PlainExtension,\n type PluginPayload,\n} from '@prosekit/core'\nimport { InputRule, inputRules, textblockTypeInputRule, wrappingInputRule } from '@prosekit/pm/inputrules'\nimport type { Attrs, MarkType, NodeType, ProseMirrorNode, Schema } from '@prosekit/pm/model'\nimport type { Plugin } from '@prosekit/pm/state'\n\n/**\n * Defines an input rule extension.\n *\n * @param rule - The ProseMirror input rule to add.\n *\n * @public\n */\nexport function defineInputRule(rule: InputRule): PlainExtension {\n return defineInputRuleFacetPayload(() => rule)\n}\n\n/**\n * Options for {@link defineMarkInputRule}.\n *\n * @public\n */\nexport interface MarkInputRuleOptions {\n /**\n * The regular expression to match against, which should end with `$` and has\n * exactly one capture group. All other matched text outside the capture group\n * will be deleted.\n */\n regex: RegExp\n\n /**\n * The type of mark to set.\n */\n type: string | MarkType\n\n /**\n * Attributes to set on the mark.\n */\n attrs?: Attrs | null | ((match: RegExpMatchArray) => Attrs | null)\n\n /**\n * Whether this rule should fire inside marks marked as [code](https://prosemirror.net/docs/ref/#model.MarkSpec.code).\n *\n * @default `false`\n */\n inCodeMark?: boolean\n}\n\n/**\n * @internal\n */\nexport function createMarkInputRule({\n regex,\n type,\n attrs = null,\n inCodeMark = false,\n}: MarkInputRuleOptions): InputRule {\n const rule = new InputRule(regex, (state, match, start, end) => {\n const { tr, schema } = state\n const [fullText, markText] = match\n\n if (!markText) {\n return null\n }\n\n const markStart = start + fullText.indexOf(markText)\n const markEnd = markStart + markText.length\n\n if (!(start <= markStart && markStart < markEnd && markEnd <= end)) {\n // Incorrect regex.\n return null\n }\n\n const markType = getMarkType(schema, type)\n const mark = markType.create(maybeRun(attrs, match))\n\n if (!isMarkAbsent(tr.doc, markStart, markEnd, markType, attrs)) {\n // The mark is already active.\n return null\n }\n\n const initialStoredMarks = tr.storedMarks ?? []\n\n tr.addMark(markStart, markEnd, mark)\n\n if (markEnd < end) {\n tr.delete(markEnd, end)\n }\n if (start < markStart) {\n tr.delete(start, markStart)\n }\n\n // Make sure not to reactivate any marks which had previously been\n // deactivated. By keeping track of the initial stored marks we are able to\n // discard any unintended consequences of deleting text and adding it again.\n tr.setStoredMarks(initialStoredMarks)\n\n return tr\n }, { inCodeMark })\n\n return rule\n}\n\n/**\n * Defines an input rule for automatically adding inline marks when a given\n * pattern is typed.\n *\n * @public\n */\nexport function defineMarkInputRule(\n options: MarkInputRuleOptions,\n): PlainExtension {\n return defineInputRule(createMarkInputRule(options))\n}\n\n/**\n * Defines an input rule that changes the type of a textblock when the matched\n * text is typed into it.\n *\n * See also [textblockTypeInputRule](https://prosemirror.net/docs/ref/#inputrules.textblockTypeInputRule)\n *\n * @param options\n *\n * @public\n */\nexport function defineTextBlockInputRule({\n regex,\n type,\n attrs,\n}: {\n /**\n * The regular expression to match against, which should end with `$`. It\n * usually also starts with `^` to that it is only matched at the start of a\n * textblock.\n */\n regex: RegExp\n\n /**\n * The node type to replace the matched text with.\n */\n type: string | NodeType\n\n /**\n * Attributes to set on the node.\n */\n attrs?: Attrs | null | ((match: RegExpMatchArray) => Attrs | null)\n}): PlainExtension {\n return defineInputRuleFacetPayload(({ schema }): InputRule => {\n const nodeType = getNodeType(schema, type)\n return textblockTypeInputRule(regex, nodeType, attrs)\n })\n}\n\n/**\n * Defines an input rule for automatically wrapping a textblock when a given\n * string is typed.\n *\n * See also [wrappingInputRule](https://prosemirror.net/docs/ref/#inputrules.wrappingInputRule)\n *\n * @param options\n *\n * @public\n */\nexport function defineWrappingInputRule({\n regex,\n type,\n attrs,\n join,\n}: {\n /**\n * The regular expression to match against, which should end with `$`. It\n * usually also starts with `^` to that it is only matched at the start of a\n * textblock.\n */\n regex: RegExp\n\n /**\n * The type of node to wrap in.\n */\n type: string | NodeType\n\n /**\n * Attributes to set on the node.\n */\n attrs?: Attrs | null | ((match: RegExpMatchArray) => Attrs | null)\n\n /**\n * By default, if there's a node with the same type above the newly wrapped\n * node, the rule will try to\n * [join](https://prosemirror.net/docs/ref/#transform.Transform.join) those\n * two nodes. You can pass a join predicate, which takes a regular expression\n * match and the node before the wrapped node, and can return a boolean to\n * indicate whether a join should happen.\n */\n join?: (match: RegExpMatchArray, node: ProseMirrorNode) => boolean\n}): PlainExtension {\n return defineInputRuleFacetPayload(({ schema }): InputRule => {\n const nodeType = getNodeType(schema, type)\n return wrappingInputRule(regex, nodeType, attrs, join)\n })\n}\n\nfunction defineInputRuleFacetPayload(input: InputRulePayload): PlainExtension {\n return defineFacetPayload(inputRuleFacet, [input]) as PlainExtension\n}\n\ntype InputRulePayload = (context: { schema: Schema }) => InputRule\n\nconst inputRuleFacet = defineFacet<InputRulePayload, PluginPayload>({\n reducer: (inputs: InputRulePayload[]): PluginPayload => {\n return (context): Plugin[] => {\n const rules: InputRule[] = inputs.flatMap((callback) => callback(context))\n return [inputRules({ rules })]\n }\n },\n parent: pluginFacet,\n})\n"],"mappings":";;;;;;;;;;;AAsBA,SAAgB,gBAAgB,MAAiC;AAC/D,QAAO,kCAAkC,KAAK;;;;;AAqChD,SAAgB,oBAAoB,EAClC,OACA,MACA,QAAQ,MACR,aAAa,SACqB;AA4ClC,QA3Ca,IAAI,UAAU,QAAQ,OAAO,OAAO,OAAO,QAAQ;EAC9D,MAAM,EAAE,IAAI,WAAW;EACvB,MAAM,CAAC,UAAU,YAAY;AAE7B,MAAI,CAAC,SACH,QAAO;EAGT,MAAM,YAAY,QAAQ,SAAS,QAAQ,SAAS;EACpD,MAAM,UAAU,YAAY,SAAS;AAErC,MAAI,EAAE,SAAS,aAAa,YAAY,WAAW,WAAW,KAE5D,QAAO;EAGT,MAAM,WAAW,YAAY,QAAQ,KAAK;EAC1C,MAAM,OAAO,SAAS,OAAO,SAAS,OAAO,MAAM,CAAC;AAEpD,MAAI,CAAC,aAAa,GAAG,KAAK,WAAW,SAAS,UAAU,MAAM,CAE5D,QAAO;EAGT,MAAM,qBAAqB,GAAG,eAAe,EAAE;AAE/C,KAAG,QAAQ,WAAW,SAAS,KAAK;AAEpC,MAAI,UAAU,IACZ,IAAG,OAAO,SAAS,IAAI;AAEzB,MAAI,QAAQ,UACV,IAAG,OAAO,OAAO,UAAU;AAM7B,KAAG,eAAe,mBAAmB;AAErC,SAAO;IACN,EAAE,YAAY,CAAC;;;;;;;;AAWpB,SAAgB,oBACd,SACgB;AAChB,QAAO,gBAAgB,oBAAoB,QAAQ,CAAC;;;;;;;;;;;;AAatD,SAAgB,yBAAyB,EACvC,OACA,MACA,SAkBiB;AACjB,QAAO,6BAA6B,EAAE,aAAwB;AAE5D,SAAO,uBAAuB,OADb,YAAY,QAAQ,KAAK,EACK,MAAM;GACrD;;;;;;;;;;;;AAaJ,SAAgB,wBAAwB,EACtC,OACA,MACA,OACA,QA4BiB;AACjB,QAAO,6BAA6B,EAAE,aAAwB;AAE5D,SAAO,kBAAkB,OADR,YAAY,QAAQ,KAAK,EACA,OAAO,KAAK;GACtD;;AAGJ,SAAS,4BAA4B,OAAyC;AAC5E,QAAO,mBAAmB,gBAAgB,CAAC,MAAM,CAAC;;AAKpD,MAAM,iBAAiB,YAA6C;CAClE,UAAU,WAA8C;AACtD,UAAQ,YAAsB;AAE5B,UAAO,CAAC,WAAW,EAAE,OADM,OAAO,SAAS,aAAa,SAAS,QAAQ,CAAC,EAC9C,CAAC,CAAC;;;CAGlC,QAAQ;CACT,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"paste-rule-BaDghcaU.js","names":[],"sources":["../src/paste-rule/paste-rule-plugin.ts","../src/paste-rule/paste-rule.ts","../src/paste-rule/split-text-by-regex.ts","../src/paste-rule/mark-paste-rule.ts"],"sourcesContent":["import { defineFacet, defineFacetPayload, pluginFacet, type PlainExtension, type PluginPayload } from '@prosekit/core'\nimport type { Slice } from '@prosekit/pm/model'\nimport { PluginKey, ProseMirrorPlugin } from '@prosekit/pm/state'\nimport type { EditorView } from '@prosekit/pm/view'\n\ntype PasteRulePayload = (options: { slice: Slice; view: EditorView; plain: boolean }) => Slice\n\n/**\n * @internal\n */\nconst pasteRuleFacet = defineFacet<PasteRulePayload, PluginPayload>({\n reduce: () => {\n let handlers: PasteRulePayload[] = []\n\n const transformPasted = (slice: Slice, view: EditorView, plain: boolean): Slice => {\n for (const handler of handlers) {\n slice = handler({ slice, view, plain })\n }\n return slice\n }\n\n const plugin = new ProseMirrorPlugin({\n key: new PluginKey('prosekit-paste-rule'),\n props: {\n transformPasted,\n },\n })\n\n return (inputs: PasteRulePayload[]) => {\n // Last added rule (highest priority) is applied first\n handlers = [...inputs].reverse()\n return plugin\n }\n },\n singleton: true,\n parent: pluginFacet,\n})\n\n/**\n * @internal\n */\nexport function definePasteRulePlugin(payload: PasteRulePayload): PlainExtension {\n return defineFacetPayload(pasteRuleFacet, [payload]) as PlainExtension\n}\n","import type { PlainExtension } from '@prosekit/core'\nimport type { Slice } from '@prosekit/pm/model'\nimport type { EditorView } from '@prosekit/pm/view'\n\nimport { definePasteRulePlugin } from './paste-rule-plugin'\n\n/**\n * @public\n *\n * Options for {@link PasteRuleHandler}.\n */\nexport interface PasteRuleHandlerOptions {\n /**\n * The slice to be pasted.\n */\n slice: Slice\n\n /**\n * The editor view.\n */\n view: EditorView\n\n /**\n * Whether the pasted content is treated as plain text. This is true when the\n * `Shift` key is held when pasting.\n */\n plain: boolean\n}\n\n/**\n * @public\n *\n * Can be used to transform pasted or dragged-and-dropped content before it is\n * applied to the document.\n */\nexport type PasteRuleHandler = (options: PasteRuleHandlerOptions) => Slice\n\n/**\n * Options for {@link definePasteRule}.\n *\n * @public\n */\nexport interface PasteRuleOptions {\n /**\n * A function to be called when a paste rule is triggered.\n */\n handler: PasteRuleHandler\n}\n\n/**\n * Defines a paste rule. This rule allows you to modify pasted or dragged\n * content before it is inserted into the document.\n *\n * @param options\n *\n * @public\n */\nexport function definePasteRule({ handler }: PasteRuleOptions): PlainExtension {\n return definePasteRulePlugin(handler)\n}\n","/**\n * Splits text into chunks based on regex matches, preserving both matched and unmatched segments.\n * Returns an array of tuples where each tuple contains a text segment and either the match data\n * (for matched segments) or undefined (for unmatched segments).\n */\nexport function splitTextByRegex(\n text: string,\n regex: RegExp,\n): Array<[string, RegExpExecArray | undefined]> | undefined {\n regex.lastIndex = 0\n\n const chunks: Array<[string, RegExpExecArray | undefined]> = []\n let lastIndex = 0\n let match: RegExpExecArray | null\n let matched = false\n\n while ((match = regex.exec(text))) {\n const start = match.index\n const end = regex.lastIndex\n\n // Push the unmatched prefix, if any.\n if (start > lastIndex) {\n chunks.push([text.slice(lastIndex, start), undefined])\n }\n\n // Push the matched segment.\n chunks.push([text.slice(start, end), match])\n matched = true\n\n if (lastIndex === end) {\n // Safeguard against zero-width matches that would otherwise cause an infinite loop.\n return\n }\n lastIndex = end\n }\n\n if (matched && lastIndex < text.length) {\n chunks.push([text.slice(lastIndex), undefined])\n }\n\n regex.lastIndex = 0\n\n return matched ? chunks : undefined\n}\n","import { getMarkType, type PlainExtension } from '@prosekit/core'\nimport type { Attrs, MarkType, ProseMirrorNode } from '@prosekit/pm/model'\nimport { Fragment, Slice } from '@prosekit/pm/model'\n\nimport { definePasteRule } from './paste-rule'\nimport { splitTextByRegex } from './split-text-by-regex'\n\n/**\n * The options for {@link defineMarkPasteRule}.\n *\n * @public\n */\nexport interface MarkPasteRuleOptions {\n /**\n * The regular expression to match against. It must have a `g` flag to match\n * all instances of the mark.\n */\n regex: RegExp\n\n /**\n * The mark type to apply to the matched text.\n */\n type: string | MarkType\n\n /**\n * A function used to compute attributes to set on the mark created by this\n * rule. When it returns `false`, the rule won't match. When it returns `null`\n * or `undefined`, that is interpreted as an empty/default set of attributes.\n * @default null\n */\n getAttrs?: (match: RegExpExecArray) => Attrs | null | undefined | false\n\n /**\n * Optional function to determine if a text node should be skipped.\n * Default behavior: skip code nodes and nodes that already have the target mark.\n */\n shouldSkip?: (node: ProseMirrorNode) => boolean\n}\n\n/**\n * Defines a paste rule that applies marks based on regex patterns.\n *\n * @public\n */\nexport function defineMarkPasteRule(options: MarkPasteRuleOptions): PlainExtension {\n return definePasteRule({\n handler: ({ slice, view, plain }) => {\n if (plain) {\n return slice\n }\n\n const markType = getMarkType(view.state.schema, options.type)\n\n return replaceMarkInSlice({\n markType,\n regex: options.regex,\n getAttrs: options.getAttrs,\n shouldSkip: options.shouldSkip,\n }, slice)\n },\n })\n}\n\ninterface MarkPasteRuleHandlerOptions {\n markType: MarkType\n regex: RegExp\n getAttrs?: (match: RegExpExecArray) => Attrs | null | undefined | false\n shouldSkip?: (node: ProseMirrorNode) => boolean\n}\n\nfunction replaceMarkInSlice(options: MarkPasteRuleHandlerOptions, slice: Slice): Slice {\n const newFragment = replaceMarkInFragment(options, slice.content)\n if (!newFragment) {\n return slice\n }\n return new Slice(newFragment, slice.openStart, slice.openEnd)\n}\n\nfunction replaceMarkInFragment(options: MarkPasteRuleHandlerOptions, fragment: Fragment): Fragment | undefined {\n let changed = false\n const children: ProseMirrorNode[] = []\n\n for (const child of fragment.content) {\n const newChild = replaceMarkInNode(options, child)\n if (newChild) {\n changed = true\n }\n children.push(newChild || child)\n }\n\n if (changed) {\n return Fragment.from(children)\n }\n\n return\n}\n\nfunction replaceMarkInNode(options: MarkPasteRuleHandlerOptions, node: ProseMirrorNode): ProseMirrorNode | undefined {\n if (node.type.spec.code) {\n return\n }\n if (node.type.isInline) {\n return\n }\n if (node.type.isTextblock) {\n return replaceMarkInTextblockNode(options, node)\n }\n\n const newChildren = replaceMarkInFragment(options, node.content)\n if (!newChildren) {\n return\n }\n return node.copy(newChildren)\n}\n\nfunction replaceMarkInTextblockNode(options: MarkPasteRuleHandlerOptions, node: ProseMirrorNode): ProseMirrorNode | undefined {\n const newChildren: ProseMirrorNode[] = []\n let changed = false\n\n for (const inlineNode of node.content.content) {\n const newInlineNodes = replaceMarkInInlineNode(options, inlineNode)\n if (newInlineNodes) {\n changed = true\n newChildren.push(...newInlineNodes)\n } else {\n newChildren.push(inlineNode)\n }\n }\n if (changed) {\n return node.copy(Fragment.from(newChildren))\n }\n return\n}\n\nfunction replaceMarkInInlineNode(options: MarkPasteRuleHandlerOptions, node: ProseMirrorNode): ProseMirrorNode[] | undefined {\n const text = node.text\n if (!text) {\n return\n }\n\n const { markType, shouldSkip } = options\n\n // Use custom skip logic if provided, otherwise use default\n if (shouldSkip) {\n if (shouldSkip(node)) {\n return\n }\n } else {\n // Default skip logic: skip if already has the target mark or has code mark\n if (node.marks.some((mark) => mark.type === markType)) {\n return\n }\n if (node.marks.some((mark) => mark.type.spec.code)) {\n return\n }\n }\n\n const chunks = splitTextByRegex(text, options.regex)\n if (!chunks) {\n return\n }\n\n const schema = node.type.schema\n const nodes: ProseMirrorNode[] = []\n\n for (const [text, match] of chunks) {\n if (!text) {\n continue\n }\n if (match) {\n const attrs = options.getAttrs?.(match) ?? null\n if (attrs !== false) {\n const mark = markType.create(attrs)\n nodes.push(schema.text(text, [...node.marks, mark]))\n } else {\n nodes.push(schema.text(text, node.marks))\n }\n } else {\n nodes.push(schema.text(text, node.marks))\n }\n }\n\n return nodes\n}\n"],"mappings":"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"}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { BundledHighlighterOptions, BundledLanguage, BundledTheme, Highlighter, SpecialLanguage } from "shiki";
|
|
2
|
-
|
|
3
|
-
//#region src/code-block/shiki-highlighter-chunk.d.ts
|
|
4
|
-
interface ShikiHighlighterOptions extends BundledHighlighterOptions<BundledLanguage, BundledTheme> {}
|
|
5
|
-
interface HighlighterOptions extends Omit<ShikiHighlighterOptions, 'langs' | 'themes'> {
|
|
6
|
-
themes: BundledTheme[];
|
|
7
|
-
langs: (BundledLanguage | SpecialLanguage)[];
|
|
8
|
-
}
|
|
9
|
-
type HighlighterResult = {
|
|
10
|
-
highlighter: Highlighter;
|
|
11
|
-
promise?: undefined;
|
|
12
|
-
} | {
|
|
13
|
-
highlighter?: undefined;
|
|
14
|
-
promise: Promise<void>;
|
|
15
|
-
};
|
|
16
|
-
declare function createOrGetHighlighter(options: HighlighterOptions): HighlighterResult;
|
|
17
|
-
//#endregion
|
|
18
|
-
export { createOrGetHighlighter as i, HighlighterResult as n, ShikiHighlighterOptions as r, HighlighterOptions as t };
|
|
19
|
-
//# sourceMappingURL=shiki-highlighter-chunk-DNNm2Vow.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"shiki-highlighter-chunk-DNNm2Vow.d.ts","names":[],"sources":["../src/code-block/shiki-highlighter-chunk.ts"],"mappings":";;;UASiB,uBAAA,SAAgC,yBAAA,CAA0B,eAAA,EAAiB,YAAA;AAAA,UAE3E,kBAAA,SAA2B,IAAA,CAAK,uBAAA;EAC/C,MAAA,EAAQ,YAAA;EACR,KAAA,GAAQ,eAAA,GAAkB,eAAA;AAAA;AAAA,KAoChB,iBAAA;EAER,WAAA,EAAa,WAAA;EACb,OAAA;AAAA;EAGA,WAAA;EACA,OAAA,EAAS,OAAA;AAAA;AAAA,iBAGG,sBAAA,CACd,OAAA,EAAS,kBAAA,GACR,iBAAA"}
|