aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2017-05-20 16:20:21 +0100
committerMichael Williamson <mike@zwobble.org>2017-05-20 16:20:21 +0100
commit3d8d9c116f3f939abbfbfd28bee6bcca7a5ba076 (patch)
tree163635267854ab56c5fc9de69ff0984e57db5625
parent9a4da2889ceaaed5351e4bb50d9f1660c5e3ee27 (diff)
Write thead and th for headers in table
-rw-r--r--lib/document-to-html.js55
-rw-r--r--npm-shrinkwrap.json6
-rw-r--r--package.json2
-rw-r--r--test/document-to-html.tests.js31
4 files changed, 79 insertions, 15 deletions
diff --git a/lib/document-to-html.js b/lib/document-to-html.js
index d56ad1d..5e7079a 100644
--- a/lib/document-to-html.js
+++ b/lib/document-to-html.js
@@ -79,16 +79,17 @@ function DocumentConversion(options, comments) {
});
}
- function convertElements(elements, messages) {
+ function convertElements(elements, messages, options) {
return flatMap(elements, function(element) {
- return elementToHtml(element, messages);
+ return elementToHtml(element, messages, options);
});
}
- function elementToHtml(element, messages) {
+ function elementToHtml(element, messages, options) {
+ options = options || {};
var handler = elementConverters[element.type];
if (handler) {
- return handler(element, messages);
+ return handler(element, messages, options);
} else {
return [];
}
@@ -213,14 +214,46 @@ function DocumentConversion(options, comments) {
}
function convertTable(element, messages) {
- return wrapChildrenInFreshElement(element, "table", messages);
+ var bodyIndex = _.findIndex(element.children, function(child) {
+ return !child.isHeader;
+ });
+ if (bodyIndex === -1) {
+ bodyIndex = element.children.length;
+ }
+ var children;
+ if (bodyIndex === 0) {
+ children = convertElements(
+ element.children,
+ messages,
+ {isTableHeader: false}
+ );
+ } else {
+ var headRows = convertElements(
+ element.children.slice(0, bodyIndex),
+ messages,
+ {isTableHeader: true}
+ );
+ var bodyRows = convertElements(
+ element.children.slice(bodyIndex),
+ messages,
+ {isTableHeader: false}
+ );
+ children = [
+ Html.freshElement("thead", {}, headRows),
+ Html.freshElement("tbody", {}, bodyRows)
+ ];
+ }
+ return [
+ Html.freshElement("table", {}, [Html.forceWrite].concat(children))
+ ];
}
- function convertTableRow(element, messages) {
- return wrapChildrenInFreshElement(element, "tr", messages);
+ function convertTableRow(element, messages, options) {
+ return wrapChildrenInFreshElement(element, "tr", messages, options);
}
- function convertTableCell(element, messages) {
+ function convertTableCell(element, messages, options) {
+ var tagName = options.isTableHeader ? "th" : "td";
var children = convertElements(element.children, messages);
var attributes = {};
if (element.colSpan !== 1) {
@@ -231,7 +264,7 @@ function DocumentConversion(options, comments) {
}
return [
- Html.freshElement("td", attributes, [Html.forceWrite].concat(children))
+ Html.freshElement(tagName, attributes, [Html.forceWrite].concat(children))
];
}
@@ -292,8 +325,8 @@ function DocumentConversion(options, comments) {
}
}
- function wrapChildrenInFreshElement(element, wrapElementName, messages) {
- var children = convertElements(element.children, messages);
+ function wrapChildrenInFreshElement(element, wrapElementName, messages, options) {
+ var children = convertElements(element.children, messages, options);
return [
Html.freshElement(wrapElementName, {}, [Html.forceWrite].concat(children))
];
diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json
index ce2d026..cc58b2c 100644
--- a/npm-shrinkwrap.json
+++ b/npm-shrinkwrap.json
@@ -1720,9 +1720,9 @@
"dev": true
},
"underscore": {
- "version": "1.6.0",
- "from": "underscore@>=1.6.0 <1.7.0",
- "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz"
+ "version": "1.8.3",
+ "from": "underscore@>=1.8.3 <1.9.0",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz"
},
"url": {
"version": "0.11.0",
diff --git a/package.json b/package.json
index e7f1bcf..fb57ff6 100644
--- a/package.json
+++ b/package.json
@@ -19,7 +19,7 @@
"dependencies": {
"bluebird": "~3.4.0",
"sax": "~1.1.1",
- "underscore": "~1.6.0",
+ "underscore": "~1.8.3",
"lop": "~0.4.0",
"argparse": "~1.0.3",
"jszip": "~2.5.0",
diff --git a/test/document-to-html.tests.js b/test/document-to-html.tests.js
index 8124ad1..baa7df9 100644
--- a/test/document-to-html.tests.js
+++ b/test/document-to-html.tests.js
@@ -384,6 +384,37 @@ test('docx table is converted to table in HTML', function() {
});
});
+test('header rows are wrapped in thead', function() {
+ var table = new documents.Table([
+ new documents.TableRow([new documents.TableCell([])], {isHeader: true}),
+ new documents.TableRow([new documents.TableCell([])], {isHeader: true}),
+ new documents.TableRow([new documents.TableCell([])], {isHeader: false})
+ ]);
+ var converter = new DocumentConverter();
+
+ return converter.convertToHtml(table).then(function(result) {
+ var expectedHtml = "<table>" +
+ "<thead><tr><th></th></tr><tr><th></th></tr></thead>" +
+ "<tbody><tr><td></td></tr></tbody>" +
+ "</table>";
+ assert.equal(result.value, expectedHtml);
+ });
+});
+
+test('tbody is omitted if all rows are headers', function() {
+ var table = new documents.Table([
+ new documents.TableRow([new documents.TableCell([])], {isHeader: true})
+ ]);
+ var converter = new DocumentConverter();
+
+ return converter.convertToHtml(table).then(function(result) {
+ var expectedHtml = "<table>" +
+ "<thead><tr><th></th></tr></thead>" +
+ "</table>";
+ assert.equal(result.value, expectedHtml);
+ });
+});
+
test('empty cells are preserved in table', function() {
var table = new documents.Table([
new documents.TableRow([