Skip to content

Instantly share code, notes, and snippets.

@amaxwell01
Created October 15, 2017 04:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amaxwell01/ca885abf9d19514bc22f62f5360721da to your computer and use it in GitHub Desktop.
Save amaxwell01/ca885abf9d19514bc22f62f5360721da to your computer and use it in GitHub Desktop.
const BLOCK_TAGS = {
p: 'paragraph',
li: 'list-item',
ul: 'bulleted-list',
ol: 'numbered-list',
blockquote: 'quote',
pre: 'code',
h1: 'heading-one',
h2: 'heading-two',
h3: 'heading-three',
h4: 'heading-four',
h5: 'heading-five',
h6: 'heading-six'
};
const MARK_TAGS = {
strong: 'bold',
em: 'italic',
u: 'underline',
s: 'strikethrough',
code: 'code'
};
const RULES = [
{
// Special case for images, to grab their attributes.
deserialize(el, next) {
const tagName = el.tagName.toLowerCase();
const block = BLOCK_TAGS[tagName];
const mark = MARK_TAGS[tagName]
let nodeObject = null;
switch (tagName) {
case 'p':
case 'ul':
case 'ol':
case 'li':
case 'blockquote':
case 'h1':
case 'h2':
case 'h3':
case 'h4':
case 'h5':
case 'h6':
nodeObject = {
kind: 'block',
type: block,
nodes: next(el.childNodes)
};
break;
case 'strong':
case 'em':
case 'u':
case 's':
case 'code':
nodeObject = {
kind: 'mark',
type: mark,
nodes: next(el.childNodes)
};
break;
case 'img':
nodeObject = {
kind: 'inline',
type: 'image',
isVoid: true,
nodes: next(el.childNodes),
data: el.attrs.reduce((obj, item) => (obj[item.name] = item.value, obj) ,{})
};
break;
case 'pre':
const code = el.childNodes[0];
const childNodes = code && code.tagName.toLowerCase() == 'code' ?
code.childNodes :
el.childNodes;
nodeObject = {
kind: 'block',
type: 'code',
nodes: next(childNodes)
};
break;
case 'a':
nodeObject = {
kind: 'inline',
type: 'link',
nodes: next(el.childNodes),
data: {
href: el.getAttribute('href')
}
}
break;
}
return nodeObject;
}
},
{
// Special case for links, to grab their href.
serialize(object, children) {
if (object.kind == 'block' && object.type == 'image') {
let src = object.data.get('src');
let alt = object.data.get('alt');
return (<img src={src} alt={alt} />);
}
if (object.kind == 'block' && object.type == 'paragraph') {
return (<p>{children}</p>);
}
if (object.kind == 'inline' && object.type == 'text') {
return (<span>{children}</span>);
}
if (object.kind == 'block' && object.type == 'heading-one') {
return (<h1>{children}</h1>);
}
if (object.kind == 'block' && object.type == 'heading-three') {
return (<h3>{children}</h3>);
}
if (object.kind == 'mark' && object.type == 'bold') {
return (<strong>{children}</strong>);
}
if (object.kind == 'block' && object.type == 'code') {
return (<code>{children}</code>);
}
if (object.kind == 'block' && object.type == 'bulleted-list') {
return (<ul>{children}</ul>);
}
if (object.kind == 'block' && object.type == 'list-item') {
return (<li>{children}</li>);
}
}
}
];
export default RULES;
const BLOCK_TAGS = {
p: 'paragraph',
li: 'list-item',
ul: 'bulleted-list',
ol: 'numbered-list',
blockquote: 'quote',
pre: 'code',
h1: 'heading-one',
h2: 'heading-two',
h3: 'heading-three',
h4: 'heading-four',
h5: 'heading-five',
h6: 'heading-six'
};
const MARK_TAGS = {
strong: 'bold',
em: 'italic',
u: 'underline',
s: 'strikethrough',
code: 'code'
};
const RULES = [
{
deserialize(el, next) {
const block = BLOCK_TAGS[el.tagName.toLowerCase()]
if (!block) return
return {
kind: 'block',
type: block,
nodes: next(el.childNodes)
}
}
},
{
deserialize(el, next) {
const mark = MARK_TAGS[el.tagName.toLowerCase()]
if (!mark) return
return {
kind: 'mark',
type: mark,
nodes: next(el.childNodes)
}
}
},
{
// Special case for code blocks, which need to grab the nested childNodes.
deserialize(el, next) {
if (el.tagName.toLowerCase() != 'pre') return
const code = el.childNodes[0]
const childNodes = code && code.tagName.toLowerCase() == 'code'
? code.childNodes
: el.childNodes
return {
kind: 'block',
type: 'code',
nodes: next(childNodes)
}
}
},
{
// Special case for links, to grab their href.
deserialize(el, next) {
if (el.tagName.toLowerCase() != 'a') return
return {
kind: 'inline',
type: 'link',
nodes: next(el.childNodes),
data: {
href: el.getAttribute('href')
}
}
}
},
{
// Special case for images
deserialize(el, next) {
if (el.tagName.toLowerCase() != 'img') return
return {
kind: 'inline',
type: 'image',
isVoid: true,
nodes: next(el.childNodes),
data: el.attrs.reduce((obj, item) => (obj[item.name] = item.value, obj) ,{})
}
}
},
{
// Special case for links, to grab their href.
serialize(object, children) {
if (object.kind == 'block' && object.type == 'image') {
let src = object.data.get('src');
let alt = object.data.get('alt');
return (<img src={src} alt={alt} />);
}
if (object.kind == 'block' && object.type == 'paragraph') {
return (<p>{children}</p>);
}
if (object.kind == 'inline' && object.type == 'text') {
return (<span>{children}</span>);
}
if (object.kind == 'block' && object.type == 'heading-one') {
return (<h1>{children}</h1>);
}
if (object.kind == 'block' && object.type == 'heading-three') {
return (<h3>{children}</h3>);
}
if (object.kind == 'mark' && object.type == 'bold') {
return (<strong>{children}</strong>);
}
if (object.kind == 'block' && object.type == 'code') {
return (<code>{children}</code>);
}
if (object.kind == 'block' && object.type == 'bulleted-list') {
return (<ul>{children}</ul>);
}
if (object.kind == 'block' && object.type == 'list-item') {
return (<li>{children}</li>);
}
}
}
];
export default RULES;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment