-
Notifications
You must be signed in to change notification settings - Fork 0
/
block-tree-parser.jsx
79 lines (67 loc) · 1.56 KB
/
block-tree-parser.jsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import React from 'react';
import {
flip,
head,
propOr,
tap
} from 'ramda';
import CommentBlock from './comment-block';
import LinkBlock from './link-block';
import PostBlock from './post-block';
import SiteBlock from './site-block';
import TypedBlock from './typed-block';
import UserBlock from './user-block';
const HtmlBlock = Element => ( { children } ) =>
<Element>{ children }</Element>;
const blockMapping = flip( propOr( TypedBlock ) )( {
b: HtmlBlock( 'b' ),
blockquote: HtmlBlock( 'blockquote' ),
code: HtmlBlock( 'code' ),
comment: CommentBlock,
em: HtmlBlock( 'em' ),
i: HtmlBlock( 'i' ),
link: LinkBlock,
post: PostBlock,
site: SiteBlock,
strong: HtmlBlock( 'strong' ),
user: UserBlock
} );
export const addKey = ( element, key ) =>
React.cloneElement( element, { key } );
const reduceTree = ( elements, node ) => {
if ( 'string' === typeof node ) {
return [
...elements,
<span>{ node }</span>
];
}
const Element = blockMapping( node.type );
if ( ! node.children ) {
return [
...elements,
<Element { ...node } />
];
}
const firstChild = head( node.children );
if ( 1 === node.children.length && 'string' === typeof firstChild ) {
return [
...elements,
<Element { ...node }>{ firstChild }</Element>
];
}
const children = node
.children
.reduce( reduceTree, [] );
return [
...elements,
<Element { ...node }>{ children.map( addKey ) }</Element>
];
};
export const parseBlockTree = tree => {
return (
<span>
{ tree.reduce( reduceTree, [] ).map( addKey ) }
</span>
);
};
export default parseBlockTree;