export interface IMarkdownSection { title : string ; body : string | string [ ] ; subsections ? : IMarkdownSection [ ] ; } /**
 * Render IMarkdownSection recursively tracking its level depth
 */ export function renderMarkdownSections ( sections , level = 1 ) { return sections . map ( ( section ) => { const parts = section . title ? [ `${ "\n" + "#" . repeat ( level ) } ${ section . title }` ] : [ "" ] ; if ( section . body ) { parts . push ( Array . isArray ( section . body ) ? section . body . join ( "\n\n" ) : section . body ) ; } if ( section . subsections ) { parts . push ( renderMarkdownSections ( section . subsections , level + 1 ) ) ; } return parts . join ( section . title ? "\n" : "" ) ; } ) . join ( "\n" ) ; } /**
 * Render an array of objects as a markdown table
 */ export function toMarkdownTable < T extends { [ key ] : string ; } > ( rows , headers ) { return [ toMarkdownTableRow ( headers as string [ ] ) , toMarkdownTableRow ( headers . map ( ( ) => "---" ) ) , ... rows . map ( ( row ) => toMarkdownTableRow ( headers . map ( ( key ) => row [ key ] ) ) ) , ] . join ( "\n" ) ; } /**
 * Render an array of items as a markdown table row
 */ export function toMarkdownTableRow ( row ) { return `| ${ row . join ( " | " ) } |` ; }