3.0.0 • Published 7 years ago
slate-mdast-serializer v3.0.0
Slate Mdast Serializer
Convert Slate trees to MDAST trees.
See @orbiting/remark-preset for a good preset to parse markdown and stringify mdast to markdown.
API
rule object
{
match: fn(slateJson): Boolean,
matchMdast: fn(mdast, index, parent): Boolean,
fromMdast: fn(mdast, index, parent, {visitChildren, context}): SlateJson,
toMdast: fn(slateJson, index, parent, {visitChildren, context}): Mdast
}matchReturn true if the rule should serialize the slate object.matchMdastReturn true if the rule should deserialize the mdast node.fromMdastReturn slate objects for a given mdast node.toMdastReturn mdast nodes for a given slate object.
See most common rules below.
constructor(options): instance
options.rules array of rule objects
instance.deserialize(mdast, options): Slate.Value
mdast: Mdastoptions: Object
instance.deserialize(value, options): Mdast
value: Slate.Valueoptions: Object
instance.fromMdast(mdast, index = 0, parent = null, options)
instance.toMdast(slateJson, index = 0, parent = null, options)
instance.parse(markdown): Mdast
instance.stringify(mdast): String
Most Common Rules
Arbitrary Children
Delegate children processing back to the serializer.
{
match: matchBlock(TYPE),
matchMdast: (node) => node.type === 'heading' && node.depth === 1,
fromMdast: (node, index, parent, {visitChildren}) => ({
kind: 'block',
type: TYPE,
nodes: visitChildren(node)
}),
toMdast: (object, index, parent, {visitChildren}) => ({
type: 'heading',
depth: 1,
children: visitChildren(object)
})
}Block with Specific Children
Delegate to a childSerializer. Another instance with just the rules you want.
Make sure to forward parent information and rest (e.g. context) to the childSerializer.
{
match: matchBlock(TYPE),
matchMdast: rule.matchMdast,
fromMdast: (node, index, parent, rest) => ({
kind: 'block',
type: TYPE,
nodes: childSerializer.fromMdast(node.children, 0, node, rest)
}),
toMdast: (object, index, parent, rest) => ({
type: 'zone',
identifier: TYPE,
children: childSerializer.toMdast(object.nodes, 0, object, rest)
})
}Void Node
Skip processing children further.
{
match: matchBlock(TYPE),
matchMdast: (node) => node.type === 'image',
fromMdast: (node) => {
return ({
kind: 'block',
type: TYPE,
data: {
alt: node.alt,
src: node.url
},
isVoid: true,
nodes: []
})
},
toMdast: (object) => ({
type: 'image',
alt: object.data.alt,
url: object.data.src
})
}Example
const MarkdownSerializer = require('slate-mdast-serializer')
const { parse, stringify } = require('@orbiting/remark-preset')
const assert = require('assert')
const paragraph = {
match: node => node.kind === 'block' && node.type === 'PARAGRAPH',
matchMdast: node => node.type === 'paragraph',
fromMdast: (node, index, parent, {visitChildren}) => ({
kind: 'block',
type: 'PARAGRAPH',
nodes: visitChildren(node)
}),
toMdast: (object, index, parent, {visitChildren}) => ({
type: 'paragraph',
children: visitChildren(object)
})
}
const bold = {
match: node => node.kind === 'mark' && node.type === 'BOLD',
matchMdast: node => node.type === 'strong',
fromMdast: (node, index, parent, {visitChildren}) => ({
kind: 'mark',
type: 'BOLD',
nodes: visitChildren(node)
}),
toMdast: (mark, index, parent, {visitChildren}) => ({
type: 'strong',
children: visitChildren(mark)
})
}
const serializer = new MarkdownSerializer({
rules: [
paragraph,
bold
]
})
const md = 'Hello **World**\n'
const value = serializer.deserialize(parse(md))
const node = value.document.nodes.first()
assert.equal(node.kind, 'block')
assert.equal(node.type, 'PARAGRAPH')
assert.equal(node.text, 'Hello World')
const textKey = node.getFirstText().key
const worldMarks = value.change().select({
anchorKey: textKey,
anchorOffset: 5,
focusKey: textKey,
focusOffset: 10
}).value.marks
assert.equal(worldMarks.size, 1)
assert.equal(worldMarks.first().type, 'BOLD')
assert.equal(stringify(serializer.serialize(value)), md)