Created
July 12, 2016 22:27
-
-
Save gscottolson/855a690c5ebcb977cfb2735b625f0146 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as Ensure from '../../../../utils/lib/Ensure' | |
import markdownBlockDelimiter from './markdownBlockDelimiter' | |
import {BlockTypes, BlockTypeRegExps} from './Types' | |
import { | |
CharacterMetadata, | |
ContentState, | |
ContentBlock, | |
EditorState, | |
genKey, | |
} from 'draft-js' | |
import {List, OrderedSet} from 'immutable' | |
import {parse} from 'markdown-to-ast' | |
const unescapedAngleBracket = /^>/ | |
const unescapedSquareBrackets = /([^\\])(\[|\])/g | |
function parseBlock(block, text = [], metadatas = [], style = '') { | |
const tree = (typeof block === 'string') ? parse(block) : block | |
if (tree.value) { | |
[...tree.value].forEach((char) => { | |
let config = null | |
switch (style) { | |
case 'Strong': config = {style: OrderedSet(['BOLD'])}; break | |
case 'Emphasis': config = {style: OrderedSet(['ITALIC'])}; break | |
case 'delete': config = {style: OrderedSet(['STRIKETHROUGH'])}; break | |
default: config = {} | |
} | |
text.push(char) | |
metadatas.push(CharacterMetadata.create(config)) | |
}) | |
} | |
if (tree.children) { | |
tree.children.forEach((child) => { | |
parseBlock(child, text, metadatas, tree.type) | |
}) | |
} | |
return {metadatas, rawText: text.join('')} | |
} | |
function getBlockModel(text) { | |
Ensure.isString(text, 'text') | |
let blockText = text | |
let blockType = BlockTypes.Paragraph | |
let checked = false | |
if (BlockTypeRegExps.Title.test(text)) { | |
blockText = text.replace(BlockTypeRegExps.Title, '') | |
blockType = BlockTypes.Title | |
// | |
} else if (BlockTypeRegExps.Subtitle.test(text)) { | |
blockText = text.replace(BlockTypeRegExps.Subtitle, '') | |
blockType = BlockTypes.Subtitle | |
// | |
} else if (BlockTypeRegExps.Task.test(text)) { | |
blockText = text.replace(BlockTypeRegExps.Task, '') | |
blockType = BlockTypes.Task | |
checked = text.match(BlockTypeRegExps.Task)[1] !== ' ' | |
// | |
} else if (BlockTypeRegExps.Bullet.test(text)) { | |
blockText = text.replace(BlockTypeRegExps.Bullet, '') | |
blockType = BlockTypes.Bullet | |
// | |
} | |
// We should be escaping [ and ] when serializing to Markdown. | |
// Find unescaped square brackets and escape before parsing Markdown. | |
if (unescapedSquareBrackets.test(blockText)) { | |
blockText = blockText.replace(unescapedSquareBrackets, '$1\\$2') | |
} | |
// Same story as above but with leading angle brackets | |
if (unescapedAngleBracket.test(blockText)) { | |
blockText = blockText.replace(unescapedAngleBracket, '\\>') | |
} | |
const {metadatas, rawText} = parseBlock(blockText) | |
return {blockText: rawText, blockType, checked, metadatas} | |
} | |
export default function convertFromMarkdownToEditorState(props, decorator) { | |
Ensure.isObject(props, 'props') | |
const markdown = props && props.content || '' | |
Ensure.isString(markdown, 'markdown') | |
const blocks = markdown.split(markdownBlockDelimiter) | |
const contentBlocks = [] | |
const taskBlockMap = {} | |
for (const text of blocks) { | |
const {blockText, blockType, checked, metadatas} = getBlockModel(text) | |
const blockKey = genKey() | |
taskBlockMap[blockKey] = checked | |
contentBlocks.push(new ContentBlock({ | |
characterList: new List(metadatas), | |
depth: 0, | |
key: blockKey, | |
text: blockText, | |
type: blockType, | |
})) | |
} | |
const contentState = ContentState.createFromBlockArray(contentBlocks) | |
const editorState = EditorState.createWithContent(contentState, decorator) | |
return {editorState, taskBlockMap} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment