hanford / remark-slate

Remark plugin to compile Markdown as a slate 0.50+ compatible object.
155 stars 42 forks source link

Custom Elements #43

Closed tubbo closed 2 years ago

tubbo commented 3 years ago

Slate has the power to create all sorts of custom elements that cannot be easily represented in Markdown. If one passes an element that remark-slate does not recognize, it will basically just ignore it and render its element as text. This is somewhat limiting as Markdown can just bypass regular HTML, and it means you can't really use Slate to its full potential as an editor while still relying on Markdown as a wire format.

On my own project I extended the serialize() function to only escape HTML if there's no a recognizable element type, and to encode the attributes for each node into HTML attributes:

    default:
      if (!type) return escapeHtml(children)

      const {
        type: _type,
        children: _children,
        parentType: _parentType,
        ...element
      } = chunk as BlockType
      const attributes = Object.entries(element)
        .map(([attribute, value]) => `${attribute}="${value as string}"`)
        .join(' ')

      return `<myproject-${type} ${attributes} />`

This seems to work pretty well, the custom elements are represented in Markdown as <myproject-element id="foo" />, and I can use a Rehype plugin to transform them into React components when these need to get rendered. Wondering if this is the right approach and whether this could be utilized in remark-slate directly if anyone else is having this problem?