1+ open Belt ;
12open ReactNative ;
23
34type htmlProps = {
@@ -30,14 +31,14 @@ let rec jsTreeToReason = (jsChild: t) =>
3031 let props = jsChild## p;
3132 let children =
3233 switch (Js . Undefined . toOption(jsChild## c)) {
33- | Some (c ) => c-> Belt . Array . map(jsTreeToReason)
34+ | Some (c ) => c-> Array . map(jsTreeToReason)
3435 | None => [||]
3536 };
3637 Element (tag, props, children);
3738 | _ => Empty
3839 };
3940
40- let stringMapPartial = (f , s ) => {
41+ let stringMapPartial = (s , f ) => {
4142 let b = Buffer . create(String . length(s));
4243 s
4344 |> String . iter(c =>
@@ -49,76 +50,126 @@ let stringMapPartial = (f, s) => {
4950 b-> Buffer . contents;
5051};
5152
52- let lastSiblingHasLineBreaking = ref (false );
53+ // let cleanupNewlines = s =>
54+ // s->stringMapPartial(char => char === '\n' ? None : Some(char));
55+ let cleanupNewlines = s =>
56+ s-> stringMapPartial(char => char === '\n' ? Some (' ' ) : Some (char));
5357
54- let cleanupNewlines = (string, siblingHasLineBreaking) =>
55- stringMapPartial(
56- char =>
57- char === '\n' && siblingHasLineBreaking
58- ? None : Some (char === '\n' ? ' ' : char),
59- string,
60- );
58+ let optionalCleanString = (s, keepNewlines) => {
59+ let sc = keepNewlines ? s : cleanupNewlines(s)-> Js . String . trim;
60+ sc === "" ? None : Some (sc);
61+ };
62+
63+ let keepNewlines = ref (false );
6164
62- let cleanupNewlinesPre = (string, siblingHasLineBreaking) =>
63- stringMapPartial(
64- char => char === '\n' && siblingHasLineBreaking ? None : Some (char),
65- string,
66- );
65+ let inlineBreakIfParentIsInline = parentTag => {
66+ switch (parentTag) {
67+ | "li" => <Html . Br />
68+ | _ => React . null
69+ };
70+ };
6771
68- let rec renderChild = (parentTag, index: int , child) => {
69- /* @todo we can do better */
72+ let rec renderChild = (~keepNewlines = false , parentTag, index: int , child) => {
73+ /* @todo we can do better for the key */
7074 let key = index-> string_of_int;
71- let siblingHasLineBreaking = lastSiblingHasLineBreaking ^;
72- lastSiblingHasLineBreaking := false ;
73- let renderChildren = (parentTag , children) =>
74- if (children -> Belt . Array . length == 0 ) {
75- React . null ;
76- } else {
77- children -> Belt . Array . mapWithIndex(renderChild(parentTag)) -> React . array ;
78- } ;
75+
76+ let renderChildren = (~keepNewlines , parentTag , children) =>
77+ children-> Array . length > 0
78+ ? children
79+ -> Array . mapWithIndex(renderChild(~keepNewlines , parentTag))
80+ -> React . array
81+ : React . null ;
82+
7983 switch (child) {
8084 | String (string ) =>
8185 switch (parentTag) {
82- | "ul" => React . null
8386 | "ol" => React . null
87+ | "ul" => React . null
8488 | "li" =>
85- <Html . Text >
86- {cleanupNewlines(string, siblingHasLineBreaking)-> React . string}
87- </Html . Text >
88- | "code" =>
89- cleanupNewlinesPre(string, siblingHasLineBreaking)-> React . string
90- | _ => cleanupNewlines(string, siblingHasLineBreaking)-> React . string
89+ string
90+ -> optionalCleanString(keepNewlines)
91+ -> Option . map(s => <Html . TextNode > s-> React . string </Html . TextNode >)
92+ -> Option . getWithDefault(React . null)
93+ | _ =>
94+ string
95+ -> optionalCleanString(keepNewlines)
96+ -> Option . map(React . string)
97+ -> Option . getWithDefault(React . null)
9198 }
9299 | Element (tag , props , children ) =>
93100 switch (tag) {
94101 /* html tags */
95102 | "a" =>
96- <Html . A key href= props##href> {renderChildren(tag, children)} </Html . A >
97- | "h1" => <Html . H1 key> {renderChildren(tag, children)} </Html . H1 >
98- | "h2" => <Html . H2 key> {renderChildren(tag, children)} </Html . H2 >
99- | "h3" => <Html . H3 key> {renderChildren(tag, children)} </Html . H3 >
100- | "h4" => <Html . H4 key> {renderChildren(tag, children)} </Html . H4 >
101- | "h5" => <Html . H5 key> {renderChildren(tag, children)} </Html . H5 >
102- | "h6" => <Html . H6 key> {renderChildren(tag, children)} </Html . H6 >
103- | "p" => <Html . P key> {renderChildren(tag, children)} </Html . P >
104- | "ul" => <Html . Ul key> {renderChildren(tag, children)} </Html . Ul >
105- | "li" => <Html . Li key> {renderChildren(tag, children)} </Html . Li >
103+ <Html . A key props>
104+ {renderChildren(~keepNewlines, tag, children)}
105+ </Html . A >
106+ | "h1" =>
107+ <Html . H1 key props>
108+ {renderChildren(~keepNewlines, tag, children)}
109+ </Html . H1 >
110+ | "h2" =>
111+ <Html . H2 key props>
112+ {renderChildren(~keepNewlines, tag, children)}
113+ </Html . H2 >
114+ | "h3" =>
115+ <Html . H3 key props>
116+ {renderChildren(~keepNewlines, tag, children)}
117+ </Html . H3 >
118+ | "h4" =>
119+ <Html . H4 key props>
120+ {renderChildren(~keepNewlines, tag, children)}
121+ </Html . H4 >
122+ | "h5" =>
123+ <Html . H5 key props>
124+ {renderChildren(~keepNewlines, tag, children)}
125+ </Html . H5 >
126+ | "h6" =>
127+ <Html . H6 key props>
128+ {renderChildren(~keepNewlines, tag, children)}
129+ </Html . H6 >
130+ | "p" =>
131+ <Html . P key props>
132+ {renderChildren(~keepNewlines, tag, children)}
133+ </Html . P >
134+ | "ol" =>
135+ <>
136+ {inlineBreakIfParentIsInline(parentTag)}
137+ <Html . Ul key props>
138+ {renderChildren(~keepNewlines, tag, children)}
139+ </Html . Ul >
140+ </>
141+ | "ul" =>
142+ <>
143+ {inlineBreakIfParentIsInline(parentTag)}
144+ <Html . Ul key props>
145+ {renderChildren(~keepNewlines, tag, children)}
146+ </Html . Ul >
147+ </>
148+ | "li" =>
149+ <Html . Li key props>
150+ {renderChildren(~keepNewlines, tag, children)}
151+ </Html . Li >
106152 | "blockquote" =>
107- <Html . BlockQuote key> {renderChildren(tag, children)} </Html . BlockQuote >
153+ <Html . BlockQuote key props>
154+ {renderChildren(~keepNewlines, tag, children)}
155+ </Html . BlockQuote >
108156 | "pre" =>
109- <Html . Pre key props> {renderChildren(tag, children)} </Html . Pre >
157+ <Html . Pre key props>
158+ {renderChildren(~keepNewlines= true , tag, children)}
159+ </Html . Pre >
110160 | "code" =>
111161 switch (parentTag) {
112162 | "pre" =>
113163 <Html . CodeBlock key props>
114- {renderChildren(tag, children)}
164+ {renderChildren(~keepNewlines , tag, children)}
115165 </Html . CodeBlock >
116- | _ => <Html . Code key> {renderChildren(tag, children)} </Html . Code >
166+ | _ =>
167+ <Html . Code key>
168+ {renderChildren(~keepNewlines, tag, children)}
169+ </Html . Code >
117170 }
118- | "br" =>
119- lastSiblingHasLineBreaking := true ;
120- <Html . Br key />;
121- | "hr" => <Html . Hr key />
171+ | "br" => <Html . Br key props />
172+ | "hr" => <Html . Hr key props />
122173 | _ =>
123174 ReactDOMRe . createElement(
124175 tag,
@@ -128,7 +179,7 @@ let rec renderChild = (parentTag, index: int, child) => {
128179 -> Js . Obj . assign({"key" : key})
129180 -> Js . Obj . assign(props),
130181 ),
131- [| renderChildren(tag, children)|] ,
182+ [| renderChildren(~keepNewlines , tag, children)|] ,
132183 )
133184 }
134185 | Empty => React . null
0 commit comments