11import { Client } from "@notionhq/client" ;
2+ import { NotionAPI } from "notion-client" ;
23import { NotionToMarkdown } from "notion-to-md" ;
34import { ListBlockChildrenResponseResult } from "notion-to-md/build/types" ;
45import { getBlockChildren } from "./CustomTransformers" ;
@@ -21,9 +22,45 @@ export async function notionColumnToMarkdown(
2122
2223 const childrenStrings : string [ ] = await Promise . all ( childrenPromise ) ;
2324
25+ const columnWidth = await getColumnWidth ( block ) ;
26+
2427 // note: it would look better in the markup with \n, but that
2528 // causes notion-to-md to give us ":::A" instead of \n for some reason.
26- return `<div class='notion-column'>\n\n${ childrenStrings . join (
27- "\n\n"
28- ) } \n\n</div>`;
29+ return (
30+ `<div class='notion-column' style={{width: '${ columnWidth } '}}>\n\n${ childrenStrings . join (
31+ "\n\n"
32+ ) } \n\n</div>` +
33+ // Spacer between columns. CSS takes care of hiding this for the last column
34+ // and when the screen is too narrow for multiple columns.
35+ `<div className='notion-spacer' />`
36+ ) ;
37+ }
38+
39+ // The official API doesn't give us access to the format information, including column_ratio.
40+ // So we use 'notion-client' which uses the unofficial API.
41+ // Once the official API gives us access to the format information, we can remove this
42+ // and the 'notion-client' dependency.
43+ // This logic was mostly taken from react-notion-x (sister project of notion-client).
44+ async function getColumnWidth (
45+ block : ListBlockChildrenResponseResult
46+ ) : Promise < string > {
47+ const notion = new NotionAPI ( ) ;
48+ const blockId = block . id ;
49+ // Yes, it is odd to call 'getPage' for a block, but that's how we access the format info.
50+ const recordMap = await notion . getPage ( blockId ) ;
51+ const blockResult = recordMap . block [ blockId ] ;
52+
53+ const columnFormat = blockResult ?. value ?. format as any ;
54+ const columnRatio = ( columnFormat ?. column_ratio as number ) || 0.5 ;
55+
56+ const parentBlock = recordMap . block [ blockResult ?. value ?. parent_id ] ?. value ;
57+ // I'm not sure why we wouldn't get a parent, but the react-notion-x has
58+ // this fallback to a guess based on the columnRatio.
59+ const columnCount =
60+ parentBlock ?. content ?. length || Math . max ( 2 , Math . ceil ( 1.0 / columnRatio ) ) ;
61+
62+ const spacerWidth = `min(32px, 4vw)` ; // This matches the value in css for 'notion-spacer'.
63+ return `calc((100% - (${ spacerWidth } * ${
64+ columnCount - 1
65+ } )) * ${ columnRatio } )`;
2966}
0 commit comments