Improve table heading row conversion

This commit is contained in:
Dom Christie 2017-11-24 11:18:27 +00:00
parent 42e4a09b57
commit a4ef6870b7
2 changed files with 137 additions and 3 deletions

View File

@ -1,3 +1,5 @@
var indexOf = Array.prototype.indexOf
var every = Array.prototype.every
var rules = {}
rules.tableCell = {
@ -13,10 +15,10 @@ rules.tableRow = {
var borderCells = ''
var alignMap = { left: ':--', right: '--:', center: ':-:' }
if (node.parentNode.nodeName === 'THEAD') {
if (isHeadingRow(node)) {
for (var i = 0; i < node.childNodes.length; i++) {
var align = node.childNodes[i].attributes.align
var border = '---'
var align = node.childNodes[i].attributes.align
if (align) border = alignMap[align.value] || border
@ -43,8 +45,38 @@ rules.tableSection = {
}
}
// A tr is a heading row if:
// - the parent is a THEAD
// - or if its the first child of the TABLE or the first TBODY (possibly
// following a blank THEAD)
// - and every cell is a TH
function isHeadingRow (tr) {
var parentNode = tr.parentNode
return (
parentNode.nodeName === 'THEAD' ||
(
parentNode.firstChild === tr &&
(parentNode.nodeName === 'TABLE' || isFirstTbody(parentNode)) &&
every.call(tr.childNodes, function (n) { return n.nodeName === 'TH' })
)
)
}
function isFirstTbody (element) {
var previousSibling = element.previousSibling
return (
element.nodeName === 'TBODY' && (
!previousSibling ||
(
previousSibling.nodeName === 'THEAD' &&
/^\s*$/i.test(previousSibling.textContent)
)
)
)
}
function cell (content, node) {
var index = Array.prototype.indexOf.call(node.parentNode.childNodes, node)
var index = indexOf.call(node.parentNode.childNodes, node)
var prefix = ' '
if (index === 0) prefix = '| '
return prefix + content + ' |'

View File

@ -171,6 +171,108 @@
| Row 3 | Row 3 |</pre>
</div>
<div class="case" data-name="th in first row">
<div class="input">
<table>
<tr>
<th>Heading</th>
</tr>
<tr>
<td>Content</td>
</tr>
</table>
</div>
<pre class="expected">| Heading |
| --- |
| Content |</pre>
</div>
<div class="case" data-name="th first row in tbody">
<div class="input">
<table>
<tbody>
<tr>
<th>Heading</th>
</tr>
<tr>
<td>Content</td>
</tr>
</tbody>
</table>
</div>
<pre class="expected">| Heading |
| --- |
| Content |</pre>
</div>
<div class="case" data-name="table with two tbodies">
<div class="input">
<table>
<tbody>
<tr>
<th>Heading</th>
</tr>
<tr>
<td>Content</td>
</tr>
</tbody>
<tbody>
<tr>
<th>Heading</th>
</tr>
<tr>
<td>Content</td>
</tr>
</tbody>
</table>
</div>
<pre class="expected">| Heading |
| --- |
| Content |
| Heading |
| Content |</pre>
</div>
<div class="case" data-name="th in first row">
<div class="input">
<table>
<tr>
<th>Heading</th>
<td>Not a heading</td>
</tr>
<tr>
<td>Heading</td>
<td>Not a heading</td>
</tr>
</table>
</div>
<pre class="expected">| Heading | Not a heading |
| Heading | Not a heading |</pre>
</div>
<div class="case" data-name="heading cells in both thead and tbody">
<div class="input">
<table>
<thead><tr><th>Heading</th></tr></thead>
<tbody><tr><th>Cell</th></tr></tbody>
</table>
</div>
<pre class="expected">| Heading |
| --- |
| Cell |</pre>
</div>
<div class="case" data-name="empty head">
<div class="input">
<table>
<thead><tr><th></th></tr></thead>
<tbody><tr><th>Heading</th></tr></tbody>
</table>
</div>
<pre class="expected">| Heading |
| --- |</pre>
</div>
<!-- /TEST CASES -->
<script src="turndown-plugin-gfm-test.browser.js"></script>