@jvs-milkdown/core 1.0.0
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/LICENSE +21 -0
- package/README.md +11 -0
- package/lib/__internal__/index.d.ts +3 -0
- package/lib/__internal__/index.d.ts.map +1 -0
- package/lib/__internal__/remark-handlers.d.ts +3 -0
- package/lib/__internal__/remark-handlers.d.ts.map +1 -0
- package/lib/__internal__/utils.d.ts +3 -0
- package/lib/__internal__/utils.d.ts.map +1 -0
- package/lib/editor/editor.d.ts +28 -0
- package/lib/editor/editor.d.ts.map +1 -0
- package/lib/editor/index.d.ts +2 -0
- package/lib/editor/index.d.ts.map +1 -0
- package/lib/index.d.ts +3 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +676 -0
- package/lib/index.js.map +1 -0
- package/lib/internal-plugin/atoms.d.ts +22 -0
- package/lib/internal-plugin/atoms.d.ts.map +1 -0
- package/lib/internal-plugin/commands.d.ts +38 -0
- package/lib/internal-plugin/commands.d.ts.map +1 -0
- package/lib/internal-plugin/config.d.ts +5 -0
- package/lib/internal-plugin/config.d.ts.map +1 -0
- package/lib/internal-plugin/editor-state.d.ts +22 -0
- package/lib/internal-plugin/editor-state.d.ts.map +1 -0
- package/lib/internal-plugin/editor-view.d.ts +13 -0
- package/lib/internal-plugin/editor-view.d.ts.map +1 -0
- package/lib/internal-plugin/index.d.ts +12 -0
- package/lib/internal-plugin/index.d.ts.map +1 -0
- package/lib/internal-plugin/init.d.ts +5 -0
- package/lib/internal-plugin/init.d.ts.map +1 -0
- package/lib/internal-plugin/keymap.d.ts +22 -0
- package/lib/internal-plugin/keymap.d.ts.map +1 -0
- package/lib/internal-plugin/keymap.test.d.ts +2 -0
- package/lib/internal-plugin/keymap.test.d.ts.map +1 -0
- package/lib/internal-plugin/parser.d.ts +7 -0
- package/lib/internal-plugin/parser.d.ts.map +1 -0
- package/lib/internal-plugin/paste-rule.d.ts +12 -0
- package/lib/internal-plugin/paste-rule.d.ts.map +1 -0
- package/lib/internal-plugin/schema.d.ts +10 -0
- package/lib/internal-plugin/schema.d.ts.map +1 -0
- package/lib/internal-plugin/serializer.d.ts +7 -0
- package/lib/internal-plugin/serializer.d.ts.map +1 -0
- package/lib/tsconfig.tsbuildinfo +1 -0
- package/package.json +45 -0
- package/src/__internal__/index.ts +2 -0
- package/src/__internal__/remark-handlers.ts +48 -0
- package/src/__internal__/utils.ts +14 -0
- package/src/editor/editor.ts +300 -0
- package/src/editor/index.ts +1 -0
- package/src/index.ts +2 -0
- package/src/internal-plugin/atoms.ts +69 -0
- package/src/internal-plugin/commands.ts +176 -0
- package/src/internal-plugin/config.ts +34 -0
- package/src/internal-plugin/editor-state.ts +140 -0
- package/src/internal-plugin/editor-view.ts +166 -0
- package/src/internal-plugin/index.ts +11 -0
- package/src/internal-plugin/init.ts +78 -0
- package/src/internal-plugin/keymap.test.ts +136 -0
- package/src/internal-plugin/keymap.ts +167 -0
- package/src/internal-plugin/parser.ts +51 -0
- package/src/internal-plugin/paste-rule.ts +53 -0
- package/src/internal-plugin/schema.ts +88 -0
- package/src/internal-plugin/serializer.ts +61 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { MilkdownPlugin, TimerType } from '@jvs-milkdown/ctx'
|
|
2
|
+
import type { Parser } from '@jvs-milkdown/transformer'
|
|
3
|
+
|
|
4
|
+
import { createSlice, createTimer } from '@jvs-milkdown/ctx'
|
|
5
|
+
import { ctxCallOutOfScope } from '@jvs-milkdown/exception'
|
|
6
|
+
import { ParserState } from '@jvs-milkdown/transformer'
|
|
7
|
+
|
|
8
|
+
import { withMeta } from '../__internal__'
|
|
9
|
+
import { remarkCtx } from './atoms'
|
|
10
|
+
import { SchemaReady, schemaCtx } from './schema'
|
|
11
|
+
|
|
12
|
+
/// The timer which will be resolved when the parser plugin is ready.
|
|
13
|
+
export const ParserReady = createTimer('ParserReady')
|
|
14
|
+
|
|
15
|
+
const outOfScope = (() => {
|
|
16
|
+
throw ctxCallOutOfScope()
|
|
17
|
+
}) as Parser
|
|
18
|
+
|
|
19
|
+
/// A slice which contains the parser.
|
|
20
|
+
export const parserCtx = createSlice(outOfScope, 'parser')
|
|
21
|
+
|
|
22
|
+
/// A slice which stores timers that need to be waited for before starting to run the plugin.
|
|
23
|
+
/// By default, it's `[SchemaReady]`.
|
|
24
|
+
export const parserTimerCtx = createSlice([] as TimerType[], 'parserTimer')
|
|
25
|
+
|
|
26
|
+
/// The parser plugin.
|
|
27
|
+
/// This plugin will create a parser.
|
|
28
|
+
///
|
|
29
|
+
/// This plugin will wait for the schema plugin.
|
|
30
|
+
export const parser: MilkdownPlugin = (ctx) => {
|
|
31
|
+
ctx
|
|
32
|
+
.inject(parserCtx, outOfScope)
|
|
33
|
+
.inject(parserTimerCtx, [SchemaReady])
|
|
34
|
+
.record(ParserReady)
|
|
35
|
+
|
|
36
|
+
return async () => {
|
|
37
|
+
await ctx.waitTimers(parserTimerCtx)
|
|
38
|
+
const remark = ctx.get(remarkCtx)
|
|
39
|
+
const schema = ctx.get(schemaCtx)
|
|
40
|
+
|
|
41
|
+
ctx.set(parserCtx, ParserState.create(schema, remark))
|
|
42
|
+
ctx.done(ParserReady)
|
|
43
|
+
return () => {
|
|
44
|
+
ctx.remove(parserCtx).remove(parserTimerCtx).clearTimer(ParserReady)
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
withMeta(parser, {
|
|
50
|
+
displayName: 'Parser',
|
|
51
|
+
})
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { Slice } from '@jvs-milkdown/prose/model'
|
|
2
|
+
import type { EditorView } from '@jvs-milkdown/prose/view'
|
|
3
|
+
|
|
4
|
+
import { createSlice, createTimer, type MilkdownPlugin } from '@jvs-milkdown/ctx'
|
|
5
|
+
|
|
6
|
+
import { withMeta } from '../__internal__'
|
|
7
|
+
import { SchemaReady } from './schema'
|
|
8
|
+
|
|
9
|
+
/// A paste rule function which takes a slice and returns a new slice.
|
|
10
|
+
export type PasteRule = {
|
|
11
|
+
/// The function to run the paste rule.
|
|
12
|
+
run: (slice: Slice, view: EditorView, isPlainText: boolean) => Slice
|
|
13
|
+
/// The priority of the paste rule. Higher priority rules will be run first. Default is 50.
|
|
14
|
+
priority?: number
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/// A slice which contains the paste rules.
|
|
18
|
+
export const pasteRulesCtx = createSlice([] as PasteRule[], 'pasteRule')
|
|
19
|
+
|
|
20
|
+
/// A slice which stores timers that need to be waited for before starting to run the paste rule plugin.
|
|
21
|
+
/// By default, it's `[SchemaReady]`.
|
|
22
|
+
export const pasteRulesTimerCtx = createSlice([SchemaReady], 'pasteRuleTimer')
|
|
23
|
+
|
|
24
|
+
/// The timer which will be resolved when the paste rule plugin is ready.
|
|
25
|
+
export const PasteRulesReady = createTimer('PasteRuleReady')
|
|
26
|
+
|
|
27
|
+
/// The paste rule plugin.
|
|
28
|
+
/// This plugin will collect the paste rules to the editor view.
|
|
29
|
+
///
|
|
30
|
+
/// This plugin will wait for the schema plugin.
|
|
31
|
+
export const pasteRule: MilkdownPlugin = (ctx) => {
|
|
32
|
+
ctx
|
|
33
|
+
.inject(pasteRulesCtx, [])
|
|
34
|
+
.inject(pasteRulesTimerCtx, [SchemaReady])
|
|
35
|
+
.record(PasteRulesReady)
|
|
36
|
+
|
|
37
|
+
return async () => {
|
|
38
|
+
await ctx.waitTimers(pasteRulesTimerCtx)
|
|
39
|
+
|
|
40
|
+
ctx.done(PasteRulesReady)
|
|
41
|
+
|
|
42
|
+
return () => {
|
|
43
|
+
ctx
|
|
44
|
+
.remove(pasteRulesCtx)
|
|
45
|
+
.remove(pasteRulesTimerCtx)
|
|
46
|
+
.clearTimer(PasteRulesReady)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
withMeta(pasteRule, {
|
|
52
|
+
displayName: 'PasteRule',
|
|
53
|
+
})
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import type { MilkdownPlugin, TimerType } from '@jvs-milkdown/ctx'
|
|
2
|
+
import type {
|
|
3
|
+
MarkSchema,
|
|
4
|
+
NodeSchema,
|
|
5
|
+
RemarkParser,
|
|
6
|
+
} from '@jvs-milkdown/transformer'
|
|
7
|
+
|
|
8
|
+
import { createSlice, createTimer } from '@jvs-milkdown/ctx'
|
|
9
|
+
import { Schema } from '@jvs-milkdown/prose/model'
|
|
10
|
+
|
|
11
|
+
import { withMeta } from '../__internal__'
|
|
12
|
+
import { remarkCtx, remarkPluginsCtx } from './atoms'
|
|
13
|
+
import { InitReady } from './init'
|
|
14
|
+
|
|
15
|
+
/// The timer which will be resolved when the schema plugin is ready.
|
|
16
|
+
export const SchemaReady = createTimer('SchemaReady')
|
|
17
|
+
|
|
18
|
+
/// A slice which stores timers that need to be waited for before starting to run the plugin.
|
|
19
|
+
/// By default, it's `[InitReady]`.
|
|
20
|
+
export const schemaTimerCtx = createSlice([] as TimerType[], 'schemaTimer')
|
|
21
|
+
|
|
22
|
+
/// A slice which contains the schema.
|
|
23
|
+
export const schemaCtx = createSlice({} as Schema, 'schema')
|
|
24
|
+
|
|
25
|
+
/// A slice which stores the nodes spec.
|
|
26
|
+
export const nodesCtx = createSlice([] as Array<[string, NodeSchema]>, 'nodes')
|
|
27
|
+
|
|
28
|
+
/// A slice which stores the marks spec.
|
|
29
|
+
export const marksCtx = createSlice([] as Array<[string, MarkSchema]>, 'marks')
|
|
30
|
+
|
|
31
|
+
function extendPriority<T extends NodeSchema | MarkSchema>(x: T): T {
|
|
32
|
+
return {
|
|
33
|
+
...x,
|
|
34
|
+
parseDOM: x.parseDOM?.map((rule) => ({ priority: x.priority, ...rule })),
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/// The schema plugin.
|
|
39
|
+
/// This plugin will load all nodes spec and marks spec and create a schema.
|
|
40
|
+
///
|
|
41
|
+
/// This plugin will wait for the init plugin.
|
|
42
|
+
export const schema: MilkdownPlugin = (ctx) => {
|
|
43
|
+
ctx
|
|
44
|
+
.inject(schemaCtx, {} as Schema)
|
|
45
|
+
.inject(nodesCtx, [])
|
|
46
|
+
.inject(marksCtx, [])
|
|
47
|
+
.inject(schemaTimerCtx, [InitReady])
|
|
48
|
+
.record(SchemaReady)
|
|
49
|
+
|
|
50
|
+
return async () => {
|
|
51
|
+
await ctx.waitTimers(schemaTimerCtx)
|
|
52
|
+
|
|
53
|
+
const remark = ctx.get(remarkCtx)
|
|
54
|
+
const remarkPlugins = ctx.get(remarkPluginsCtx)
|
|
55
|
+
|
|
56
|
+
const processor = remarkPlugins.reduce(
|
|
57
|
+
(acc: RemarkParser, plug) =>
|
|
58
|
+
acc.use(plug.plugin, plug.options) as unknown as RemarkParser,
|
|
59
|
+
remark
|
|
60
|
+
)
|
|
61
|
+
ctx.set(remarkCtx, processor)
|
|
62
|
+
|
|
63
|
+
const nodes = Object.fromEntries(
|
|
64
|
+
ctx.get(nodesCtx).map(([key, x]) => [key, extendPriority(x)])
|
|
65
|
+
)
|
|
66
|
+
const marks = Object.fromEntries(
|
|
67
|
+
ctx.get(marksCtx).map(([key, x]) => [key, extendPriority(x)])
|
|
68
|
+
)
|
|
69
|
+
const schema = new Schema({ nodes, marks })
|
|
70
|
+
|
|
71
|
+
ctx.set(schemaCtx, schema)
|
|
72
|
+
|
|
73
|
+
ctx.done(SchemaReady)
|
|
74
|
+
|
|
75
|
+
return () => {
|
|
76
|
+
ctx
|
|
77
|
+
.remove(schemaCtx)
|
|
78
|
+
.remove(nodesCtx)
|
|
79
|
+
.remove(marksCtx)
|
|
80
|
+
.remove(schemaTimerCtx)
|
|
81
|
+
.clearTimer(SchemaReady)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
withMeta(schema, {
|
|
87
|
+
displayName: 'Schema',
|
|
88
|
+
})
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { MilkdownPlugin, TimerType } from '@jvs-milkdown/ctx'
|
|
2
|
+
import type { Serializer } from '@jvs-milkdown/transformer'
|
|
3
|
+
|
|
4
|
+
import { createSlice, createTimer } from '@jvs-milkdown/ctx'
|
|
5
|
+
import { ctxCallOutOfScope } from '@jvs-milkdown/exception'
|
|
6
|
+
import { SerializerState } from '@jvs-milkdown/transformer'
|
|
7
|
+
|
|
8
|
+
import { withMeta } from '../__internal__'
|
|
9
|
+
import { remarkCtx } from './atoms'
|
|
10
|
+
import { SchemaReady, schemaCtx } from './schema'
|
|
11
|
+
|
|
12
|
+
/// The timer which will be resolved when the serializer plugin is ready.
|
|
13
|
+
export const SerializerReady = createTimer('SerializerReady')
|
|
14
|
+
|
|
15
|
+
/// A slice which stores timers that need to be waited for before starting to run the plugin.
|
|
16
|
+
/// By default, it's `[SchemaReady]`.
|
|
17
|
+
export const serializerTimerCtx = createSlice(
|
|
18
|
+
[] as TimerType[],
|
|
19
|
+
'serializerTimer'
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
const outOfScope = (() => {
|
|
23
|
+
throw ctxCallOutOfScope()
|
|
24
|
+
}) as Serializer
|
|
25
|
+
|
|
26
|
+
/// A slice which contains the serializer.
|
|
27
|
+
export const serializerCtx = createSlice<Serializer, 'serializer'>(
|
|
28
|
+
outOfScope,
|
|
29
|
+
'serializer'
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
/// The serializer plugin.
|
|
33
|
+
/// This plugin will create a serializer.
|
|
34
|
+
///
|
|
35
|
+
/// This plugin will wait for the schema plugin.
|
|
36
|
+
export const serializer: MilkdownPlugin = (ctx) => {
|
|
37
|
+
ctx
|
|
38
|
+
.inject(serializerCtx, outOfScope)
|
|
39
|
+
.inject(serializerTimerCtx, [SchemaReady])
|
|
40
|
+
.record(SerializerReady)
|
|
41
|
+
|
|
42
|
+
return async () => {
|
|
43
|
+
await ctx.waitTimers(serializerTimerCtx)
|
|
44
|
+
const remark = ctx.get(remarkCtx)
|
|
45
|
+
const schema = ctx.get(schemaCtx)
|
|
46
|
+
|
|
47
|
+
ctx.set(serializerCtx, SerializerState.create(schema, remark))
|
|
48
|
+
ctx.done(SerializerReady)
|
|
49
|
+
|
|
50
|
+
return () => {
|
|
51
|
+
ctx
|
|
52
|
+
.remove(serializerCtx)
|
|
53
|
+
.remove(serializerTimerCtx)
|
|
54
|
+
.clearTimer(SerializerReady)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
withMeta(serializer, {
|
|
60
|
+
displayName: 'Serializer',
|
|
61
|
+
})
|