11import { IJsonToMarkdownElementTags , IJsonToMarkdownTextTags } from './types'
2+ import { cloneDeep } from 'lodash'
3+ import { Node } from 'slate'
4+
5+ let listTypes = [ 'ol' , 'ul' ]
6+ const elementsToAvoidWithinMarkdownTable = [ 'ol' , 'ul' , 'h1' , 'h2' , 'h3' , 'h4' , 'h5' , 'h6' , 'blockquote' , 'code' , 'reference' , 'img' , 'fragment' ]
27
38const ELEMENT_TYPES : IJsonToMarkdownElementTags = {
49 'blockquote' : ( attrs : any , child : any ) => {
510 return `
611
7- > ${ child } ${ attrs } `
12+ > ${ child } `
813 } ,
914 'h1' : ( attrs : any , child : string ) => {
1015 return `
@@ -97,6 +102,42 @@ ${child}`
97102 fragment : ( attrs : any , child : any ) => {
98103 return child
99104 } ,
105+ table : ( attrs : any , child : any ) => {
106+ return `${ child } `
107+ } ,
108+ tbody : ( attrs : any , child : any ) => {
109+ return `${ child } `
110+ } ,
111+ thead : ( attrs : any , child : any ) => {
112+ let tableBreak = '|'
113+ if ( attrs . cols ) {
114+ if ( attrs . addEmptyThead ) {
115+ let tHeadChildren = '| '
116+ for ( let i = 0 ; i < attrs . cols ; i ++ ) {
117+ tHeadChildren += '| '
118+ tableBreak += ' ----- |'
119+ }
120+ return `${ tHeadChildren } \n${ tableBreak } \n`
121+ }
122+ else {
123+ for ( let i = 0 ; i < attrs . cols ; i ++ ) {
124+ tableBreak += ' ----- |'
125+ }
126+ return `${ child } \n${ tableBreak } \n`
127+ }
128+ }
129+
130+ return `${ child } `
131+ } ,
132+ tr : ( attrs : any , child : any ) => {
133+ return `| ${ child } \n`
134+ } ,
135+ td : ( attrs : any , child : any ) => {
136+ return ` ${ child . trim ( ) } |`
137+ } ,
138+ th : ( attrs : any , child : any ) => {
139+ return ` ${ child . trim ( ) } |`
140+ }
100141}
101142const TEXT_WRAPPERS : IJsonToMarkdownTextTags = {
102143 'bold' : ( child : any , value : any ) => {
@@ -105,18 +146,9 @@ const TEXT_WRAPPERS: IJsonToMarkdownTextTags = {
105146 'italic' : ( child : any , value : any ) => {
106147 return `*${ child } *` ;
107148 } ,
108- // 'underline': (child: any, value: any) => {
109- // return `<u>${child}</u>`;
110- // }, underline is not supported in markdown
111149 'strikethrough' : ( child : any , value : any ) => {
112150 return `~~${ child } ~~` ;
113151 } ,
114- 'superscript' : ( child : any , value : any ) => {
115- return `^${ child } ^` ;
116- } ,
117- 'subscript' : ( child : any , value : any ) => {
118- return `~${ child } ~` ;
119- } ,
120152 'inlineCode' : ( child : any , value : any ) => {
121153 return `\`${ child } \``
122154 } ,
@@ -125,39 +157,29 @@ const TEXT_WRAPPERS: IJsonToMarkdownTextTags = {
125157const getOLOrULStringFromJson = ( value : any ) => {
126158 let child = ''
127159 let nestedListFound = false
128- if ( value . type === 'ol' ) {
160+ if ( listTypes . includes ( value . type ) ) {
129161 let start = parseInt ( value ?. attrs ?. start || 1 )
162+ let symbol = value ?. attrs ?. listStyleType || '- '
130163 Array . from ( value . children ) . forEach ( ( val : any , index ) => {
131- if ( val . hasOwnProperty ( 'type' ) && val . type === 'li' && value . children [ index + 1 ] && value . children [ index + 1 ] ?. type === 'ol' ) {
164+ if ( val . hasOwnProperty ( 'type' ) && val . type === 'li' && value . children [ index + 1 ] && value . children [ index + 1 ] ?. type && listTypes . includes ( value . children [ index + 1 ] . type ) ) {
132165 let liChildren = jsonToMarkdownSerializer ( val )
133166 let nestedListChildren = getOLOrULStringFromJson ( value . children [ index + 1 ] )
134167 let indentedNestedListChildren = nestedListChildren . split ( '\n' ) . filter ( ( child ) => child . length ) . map ( ( child ) => ` ${ child } ` ) . join ( '\n' )
135- child += `${ index + start } . ${ liChildren } \n${ indentedNestedListChildren } \n`
136- nestedListFound = true
168+ if ( value . type === 'ol' ) {
169+ child += `${ index + start } . ${ liChildren } \n${ indentedNestedListChildren } \n`
170+ nestedListFound = true
171+ }
172+ if ( value . type === 'ul' ) child += `${ symbol } ${ liChildren } \n${ indentedNestedListChildren } \n`
137173 }
138- else if ( val . hasOwnProperty ( 'type' ) && val . type !== 'ol' ) {
174+ else if ( val . hasOwnProperty ( 'type' ) && ! listTypes . includes ( val . type ) ) {
139175 let liChildren = jsonToMarkdownSerializer ( val )
140- child += `${ nestedListFound ? ( index + start - 1 ) : index + start } . ${ liChildren } \n`
176+ if ( value . type === 'ol' ) child += `${ nestedListFound ? ( index + start - 1 ) : index + start } . ${ liChildren } \n`
177+ if ( value . type === 'ul' ) child += `${ symbol } ${ liChildren } \n`
141178 }
142-
143179 } )
144180 }
145- if ( value . type === 'ul' ) {
146- let symbol = value ?. attrs ?. listStyleType || '- '
147- Array . from ( value . children ) . forEach ( ( val : any , index ) => {
148- if ( val . hasOwnProperty ( 'type' ) && val . type === 'li' && value . children [ index + 1 ] && value . children [ index + 1 ] ?. type === 'ol' ) {
149- let liChildren = jsonToMarkdownSerializer ( val )
150- let nestedListChildren = getOLOrULStringFromJson ( value . children [ index + 1 ] )
151- let indentedNestedListChildren = nestedListChildren . split ( '\n' ) . filter ( ( child ) => child . length ) . map ( ( child ) => ` ${ child } ` ) . join ( '\n' )
152- child += `${ symbol } ${ liChildren } \n${ indentedNestedListChildren } \n`
153- }
154- else if ( val . hasOwnProperty ( 'type' ) && val . type !== 'ol' ) {
155- let liChildren = jsonToMarkdownSerializer ( val )
156- child += `${ symbol } ${ liChildren } \n`
157- }
158- } )
159- }
160181 return `
182+
161183${ child } `
162184}
163185
@@ -178,6 +200,7 @@ export const jsonToMarkdownSerializer = (jsonValue: any): string => {
178200 return text
179201 }
180202 let children : any = ''
203+ if ( ! jsonValue [ 'type' ] ) return children
181204 if ( jsonValue . children ) {
182205 children = Array . from ( jsonValue . children ) . map ( ( child ) => jsonToMarkdownSerializer ( child ) )
183206 if ( jsonValue [ 'type' ] === 'blockquote' ) {
@@ -192,13 +215,25 @@ export const jsonToMarkdownSerializer = (jsonValue: any): string => {
192215 }
193216
194217 if ( ELEMENT_TYPES [ jsonValue [ 'type' ] ] ) {
218+ let tableAttrs = { }
195219 if ( jsonValue [ 'type' ] === 'ol' || jsonValue [ 'type' ] === 'ul' ) {
196220 //@ts -ignore
197221 return getOLOrULStringFromJson ( jsonValue )
198222 }
199-
223+ if ( jsonValue [ 'type' ] === 'table' ) {
224+ tableAttrs = cloneDeep ( jsonValue [ 'attrs' ] )
225+ let thead = Array . from ( jsonValue [ 'children' ] ) . find ( ( child : any ) => child . type && child . type === 'thead' )
226+ if ( ! thead ) {
227+ tableAttrs [ 'addEmptyThead' ] = true
228+ let emptyTableHead = ELEMENT_TYPES [ 'thead' ] ( tableAttrs , children )
229+ if ( emptyTableHead ) children = emptyTableHead + children
230+ }
231+ }
232+ if ( jsonValue [ 'type' ] === 'td' || jsonValue [ 'type' ] === 'th' ) {
233+ let NonAllowedTableChild = Array . from ( jsonValue [ 'children' ] ) . find ( ( child : any ) => elementsToAvoidWithinMarkdownTable . includes ( child . type ) )
234+ if ( NonAllowedTableChild ) children = Node . string ( jsonValue )
235+ }
200236 return ELEMENT_TYPES [ jsonValue [ 'type' ] ] ( jsonValue [ 'attrs' ] , children )
201- }
202-
237+ }
203238 return children
204239}
0 commit comments