All checks were successful
Publish To Prod / deploy_and_publish (push) Successful in 35s
136 lines
2.7 KiB
JavaScript
136 lines
2.7 KiB
JavaScript
'use strict'
|
|
|
|
module.exports = table
|
|
|
|
var convert = require('hast-util-is-element/convert')
|
|
var visit = require('unist-util-visit')
|
|
var all = require('../all')
|
|
|
|
var thead = convert('thead')
|
|
var tr = convert('tr')
|
|
var cell = convert(['th', 'td'])
|
|
|
|
function table(h, node) {
|
|
var info = inspect(node)
|
|
return h(node, 'table', {align: info.align}, toRows(all(h, node), info))
|
|
}
|
|
|
|
// Infer whether the HTML table has a head and how it aligns.
|
|
function inspect(node) {
|
|
var headless = true
|
|
var align = [null]
|
|
var rowIndex = 0
|
|
var cellIndex = 0
|
|
|
|
visit(node, 'element', visitor)
|
|
|
|
return {align: align, headless: headless}
|
|
|
|
function visitor(child) {
|
|
// If there is a `thead`, assume there is a header row.
|
|
if (thead(child)) {
|
|
headless = false
|
|
} else if (tr(child)) {
|
|
rowIndex++
|
|
cellIndex = 0
|
|
} else if (cell(child)) {
|
|
if (!align[cellIndex]) {
|
|
align[cellIndex] = child.properties.align || null
|
|
}
|
|
|
|
// If there is a th in the first row, assume there is a header row.
|
|
if (headless && rowIndex < 2 && child.tagName === 'th') {
|
|
headless = false
|
|
}
|
|
|
|
cellIndex++
|
|
}
|
|
}
|
|
}
|
|
|
|
// Ensure the rows are properly structured.
|
|
function toRows(children, info) {
|
|
var nodes = []
|
|
var index = -1
|
|
var node
|
|
var queue
|
|
|
|
// Add an empty header row.
|
|
if (info.headless) {
|
|
nodes.push({type: 'tableRow', children: []})
|
|
}
|
|
|
|
while (++index < children.length) {
|
|
node = children[index]
|
|
|
|
if (node.type === 'tableRow') {
|
|
if (queue) {
|
|
node.children = queue.concat(node.children)
|
|
queue = undefined
|
|
}
|
|
|
|
nodes.push(node)
|
|
} else {
|
|
if (!queue) queue = []
|
|
queue.push(node)
|
|
}
|
|
}
|
|
|
|
if (queue) {
|
|
node = nodes[nodes.length - 1]
|
|
node.children = node.children.concat(queue)
|
|
}
|
|
|
|
index = -1
|
|
|
|
while (++index < nodes.length) {
|
|
node = nodes[index]
|
|
node.children = toCells(node.children, info)
|
|
}
|
|
|
|
return nodes
|
|
}
|
|
|
|
// Ensure the cells in a row are properly structured.
|
|
function toCells(children, info) {
|
|
var nodes = []
|
|
var index = -1
|
|
var node
|
|
var queue
|
|
|
|
while (++index < children.length) {
|
|
node = children[index]
|
|
|
|
if (node.type === 'tableCell') {
|
|
if (queue) {
|
|
node.children = queue.concat(node.children)
|
|
queue = undefined
|
|
}
|
|
|
|
nodes.push(node)
|
|
} else {
|
|
if (!queue) queue = []
|
|
queue.push(node)
|
|
}
|
|
}
|
|
|
|
if (queue) {
|
|
node = nodes[nodes.length - 1]
|
|
|
|
if (!node) {
|
|
node = {type: 'tableCell', children: []}
|
|
nodes.push(node)
|
|
}
|
|
|
|
node.children = node.children.concat(queue)
|
|
}
|
|
|
|
index = nodes.length - 1
|
|
|
|
while (++index < info.align.length) {
|
|
nodes.push({type: 'tableCell', children: []})
|
|
}
|
|
|
|
return nodes
|
|
}
|