hanford / remark-slate

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

Different node types in remark-slate vs slate? #57

Open lostinpatterns opened 2 years ago

lostinpatterns commented 2 years ago

I'm new to Slate, so there's probably something obvious I'm missing. However, when I try to serialize the Slate editor's JSON tree to Markdown using this lib's serialize function, it spits out the text from the leaves and ignores any block elements. This appears to be because the node types in the value passed to my editor's onChange are different from the default node types that remark-slate uses.

E.g., when I create a blockquote, it will be represented as this object with a type of blockquote:

{
    "type": "blockquote",
    "id": 1647999105634,
    "children": [
        {
            "text": "test quote"
        }
    ]
}

but this library looks for a node with a type of block_quote instead. The same goes for headings too as the types my editor uses are different from this library's. Is this a versioning issue or is there something basic I'm misunderstanding about how Slate works?

janaka commented 2 years ago

@lostinpatterns are you using Slate with Plate? I think you are having the same issue I had. I had to override as follows.

The image caption and source override are to solve an image note parsing issue. More here

import { plateNodeTypes } from './remarkslate-nodetypes.js';

...
.use(slate, { nodeTypes: plateNodeTypes, imageCaptionKey: 'cap', imageSourceKey: 'src' })
...

./remarkslate-nodetypes.js:

import { InputNodeTypes } from "remark-slate";

// Override the default remark-slate node type names to match Plate defaults
// Note these were copied from Plate rather than directly referencing in order to avoid having to bring in a load of web 
// dependencies in backend code.
//format: <remark-slate type>:<plate type>;

const ELEMENT_BLOCKQUOTE = 'blockquote';
const ELEMENT_CODE_BLOCK = 'code_block';
const ELEMENT_CODE_LINE = 'code_line';
const ELEMENT_EXCALIDRAW = 'excalidraw';
const ELEMENT_H1 = 'h1';
const ELEMENT_H2 = 'h2';
const ELEMENT_H3 = 'h3';
const ELEMENT_H4 = 'h4';
const ELEMENT_H5 = 'h5';
const ELEMENT_H6 = 'h6';
const ELEMENT_IMAGE = 'img';
const ELEMENT_LI = 'li';
const ELEMENT_LIC = 'lic';
const ELEMENT_LINK = 'a';
const ELEMENT_MEDIA_EMBED = 'media_embed';
const ELEMENT_MENTION = 'mention';
const ELEMENT_MENTION_INPUT = 'mention_input';
const ELEMENT_OL = 'ol';
const ELEMENT_PARAGRAPH = 'p';
const ELEMENT_TABLE = 'table';
const ELEMENT_TD = 'td';
const ELEMENT_TH = 'th';
const ELEMENT_TODO_LI = 'action_item';
const ELEMENT_TR = 'tr';
const ELEMENT_UL = 'ul';
const MARK_BOLD = 'bold';
const MARK_CODE = 'code';
const MARK_ITALIC = 'italic';
const MARK_STRIKETHROUGH = 'strikethrough';

export const plateNodeTypes: InputNodeTypes = {
  paragraph: ELEMENT_PARAGRAPH,
  block_quote: ELEMENT_BLOCKQUOTE,
  code_block: ELEMENT_CODE_BLOCK,
  link: ELEMENT_LINK,
  ul_list: ELEMENT_UL,
  ol_list: ELEMENT_OL,
  listItem: ELEMENT_LI,
  heading: {
    1: ELEMENT_H1,
    2: ELEMENT_H2,
    3: ELEMENT_H3,
    4: ELEMENT_H4,
    5: ELEMENT_H5,
    6: ELEMENT_H6,
  },
  emphasis_mark: MARK_ITALIC,
  strong_mark: MARK_BOLD,
  delete_mark: MARK_STRIKETHROUGH, //'strikeThrough',
  inline_code_mark: MARK_CODE, //'code',
  thematic_break: 'thematic_break',
  image: ELEMENT_IMAGE,
};
siawyoung commented 2 years ago

@janaka thank you, this was very helpful.