JSPM

slate-mdast-serializer

3.0.0
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 155
  • Score
    100M100P100Q81057F
  • License BSD-3-Clause

serialize slate to mdast and vice versa

Package Exports

  • slate-mdast-serializer

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (slate-mdast-serializer) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

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
}
  • match Return true if the rule should serialize the slate object.
  • matchMdast Return true if the rule should deserialize the mdast node.
  • fromMdast Return slate objects for a given mdast node.
  • toMdast Return 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: Mdast
options: Object

instance.deserialize(value, options): Mdast

value: Slate.Value
options: 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

Try it in your browser.

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)