@@ -24,8 +24,74 @@ const cell = convertElement(['th', 'td'])
2424 * @param {Element } node
2525 */
2626export function table ( h , node ) {
27- const info = inspect ( node )
28- return h ( node , 'table' , { align : info . align } , toRows ( all ( h , node ) , info ) )
27+ const { headless, align} = inspect ( node )
28+ const rows = toRows ( all ( h , node ) , headless )
29+ let columns = 1
30+ let rowIndex = - 1
31+
32+ while ( ++ rowIndex < rows . length ) {
33+ const cells = rows [ rowIndex ] . children
34+ let cellIndex = - 1
35+
36+ while ( ++ cellIndex < cells . length ) {
37+ const cell = cells [ cellIndex ]
38+
39+ if ( cell . data ) {
40+ const colSpan = Number . parseInt ( String ( cell . data . colSpan ) , 10 ) || 1
41+ const rowSpan = Number . parseInt ( String ( cell . data . rowSpan ) , 10 ) || 1
42+
43+ if ( colSpan > 1 || rowSpan > 1 ) {
44+ let otherRowIndex = rowIndex - 1
45+
46+ while ( ++ otherRowIndex < rowIndex + rowSpan ) {
47+ let colIndex = cellIndex - 1
48+
49+ while ( ++ colIndex < cellIndex + colSpan ) {
50+ if ( ! rows [ otherRowIndex ] ) {
51+ // Don’t add rows that don’t exist.
52+ // Browsers don’t render them either.
53+ break
54+ }
55+
56+ /** @type {Array.<MdastRowContent> } */
57+ const newCells = [ ]
58+
59+ if ( otherRowIndex !== rowIndex || colIndex !== cellIndex ) {
60+ newCells . push ( { type : 'tableCell' , children : [ ] } )
61+ }
62+
63+ rows [ otherRowIndex ] . children . splice ( colIndex , 0 , ...newCells )
64+ }
65+ }
66+ }
67+
68+ // Clean the data fields.
69+ if ( 'colSpan' in cell . data ) delete cell . data . colSpan
70+ if ( 'rowSpan' in cell . data ) delete cell . data . rowSpan
71+ if ( Object . keys ( cell . data ) . length === 0 ) delete cell . data
72+ }
73+ }
74+
75+ if ( cells . length > columns ) columns = cells . length
76+ }
77+
78+ // Add extra empty cells.
79+ rowIndex = - 1
80+
81+ while ( ++ rowIndex < rows . length ) {
82+ const cells = rows [ rowIndex ] . children
83+ let cellIndex = cells . length - 1
84+ while ( ++ cellIndex < columns ) {
85+ cells . push ( { type : 'tableCell' , children : [ ] } )
86+ }
87+ }
88+
89+ let alignIndex = align . length - 1
90+ while ( ++ alignIndex < columns ) {
91+ align . push ( null )
92+ }
93+
94+ return h ( node , 'table' , { align} , rows )
2995}
3096
3197/**
@@ -69,25 +135,23 @@ function inspect(node) {
69135 * Ensure the rows are properly structured.
70136 *
71137 * @param {Array.<MdastNode> } children
72- * @param {Info } info
138+ * @param {boolean } headless
73139 * @returns {Array.<MdastTableContent> }
74140 */
75- function toRows ( children , info ) {
141+ function toRows ( children , headless ) {
142+ let index = - 1
76143 /** @type {Array.<MdastTableContent> } */
77144 const nodes = [ ]
78- let index = - 1
79- /** @type {MdastNode } */
80- let node
81145 /** @type {Array.<MdastRowContent>|undefined } */
82146 let queue
83147
84148 // Add an empty header row.
85- if ( info . headless ) {
149+ if ( headless ) {
86150 nodes . push ( { type : 'tableRow' , children : [ ] } )
87151 }
88152
89153 while ( ++ index < children . length ) {
90- node = children [ index ]
154+ const node = children [ index ]
91155
92156 if ( node . type === 'tableRow' ) {
93157 if ( queue ) {
@@ -110,7 +174,7 @@ function toRows(children, info) {
110174 index = - 1
111175
112176 while ( ++ index < nodes . length ) {
113- nodes [ index ] . children = toCells ( nodes [ index ] . children , info )
177+ nodes [ index ] . children = toCells ( nodes [ index ] . children )
114178 }
115179
116180 return nodes
@@ -120,10 +184,9 @@ function toRows(children, info) {
120184 * Ensure the cells in a row are properly structured.
121185 *
122186 * @param {Array.<MdastNode> } children
123- * @param {Info } info
124187 * @returns {Array.<MdastRowContent> }
125188 */
126- function toCells ( children , info ) {
189+ function toCells ( children ) {
127190 /** @type {Array.<MdastRowContent> } */
128191 const nodes = [ ]
129192 let index = - 1
@@ -160,11 +223,5 @@ function toCells(children, info) {
160223 node . children . push ( ...queue )
161224 }
162225
163- index = nodes . length - 1
164-
165- while ( ++ index < info . align . length ) {
166- nodes . push ( { type : 'tableCell' , children : [ ] } )
167- }
168-
169226 return nodes
170227}
0 commit comments