summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2016-11-20 12:15:39 +0000
committerMichael Williamson <mike@zwobble.org>2016-11-20 12:16:49 +0000
commite09b1f797d646e240e405831a9ddccd21ca4b3f9 (patch)
tree4f5fd0a872457d5aab7c6882e43485ac076d9d6e
parentf4a6e9f3077e009ce36d03ff9fb704dc8bcff31b (diff)
Add getDescendants and getDescendantsOfType to tranforms
-rw-r--r--NEWS4
-rw-r--r--README.md13
-rw-r--r--lib/transforms.js34
-rw-r--r--test/transforms.tests.js50
4 files changed, 99 insertions, 2 deletions
diff --git a/NEWS b/NEWS
index facee0e..08f350d 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,7 @@
+# 1.3.1
+
+* Add getDescendants() and getDescendantsOfType() to transforms module.
+
# 1.3.0
* Allow style names to be mapped by prefix. For instance:
diff --git a/README.md b/README.md
index 491f687..0a6add2 100644
--- a/README.md
+++ b/README.md
@@ -544,6 +544,19 @@ Returns a function that can be used as the `transformDocument` option.
This will apply the function `transformParagraph` to each paragraph element.
`transformParagraph` should return the new paragraph.
+#### `mammoth.transforms.getDescendants(element)`
+
+Gets all descendants of an element.
+
+#### `mammoth.transforms.getDescendantsOfType(element, type)`
+
+Gets all descendants of a particular type of an element.
+For instance, to get all runs within an element `paragraph`:
+
+```javascript
+var runs = mammoth.transforms.getDescendantsOfType(paragraph, "run");
+```
+
## Writing style maps
A style map is made up of a number of style mappings separated by new lines.
diff --git a/lib/transforms.js b/lib/transforms.js
index 5078387..22be1af 100644
--- a/lib/transforms.js
+++ b/lib/transforms.js
@@ -1,6 +1,10 @@
var _ = require("underscore");
-exports.paragraph = function(transform) {
+exports.paragraph = paragraph;
+exports.getDescendantsOfType = getDescendantsOfType;
+exports.getDescendants = getDescendants;
+
+function paragraph(transform) {
function transformElement(element) {
if (element.children) {
var children = _.map(element.children, transformElement);
@@ -14,4 +18,30 @@ exports.paragraph = function(transform) {
return element;
}
return transformElement;
-};
+}
+
+
+function getDescendantsOfType(element, type) {
+ return getDescendants(element).filter(function(descendant) {
+ return descendant.type === type;
+ });
+}
+
+function getDescendants(element) {
+ var descendants = [];
+
+ visitDescendants(element, function(descendant) {
+ descendants.push(descendant);
+ });
+
+ return descendants;
+}
+
+function visitDescendants(element, visit) {
+ if (element.children) {
+ element.children.forEach(function(child) {
+ visitDescendants(child, visit);
+ visit(child);
+ });
+ }
+}
diff --git a/test/transforms.tests.js b/test/transforms.tests.js
new file mode 100644
index 0000000..c6656dd
--- /dev/null
+++ b/test/transforms.tests.js
@@ -0,0 +1,50 @@
+var assert = require("assert");
+
+var transforms = require("../lib/transforms");
+var test = require("./test")(module);
+
+
+test("getDescendants()", {
+ "returns nothing if element has no children property": function() {
+ assert.deepEqual(transforms.getDescendants({}), []);
+ },
+
+ "returns nothing if element has empty children": function() {
+ assert.deepEqual(transforms.getDescendants({children: []}), []);
+ },
+
+ "includes children": function() {
+ var element = {
+ children: [{name: "child 1"}, {name: "child 2"}]
+ }
+ assert.deepEqual(
+ transforms.getDescendants(element),
+ [{name: "child 1"}, {name: "child 2"}]
+ );
+ },
+
+ "includes indirect descendants": function() {
+ var grandchild = {name: "grandchild"};
+ var child = {name: "child", children: [grandchild]};
+ var element = {children: [child]};
+ assert.deepEqual(
+ transforms.getDescendants(element),
+ [grandchild, child]
+ );
+ }
+});
+
+
+test("getDescendantsOfType()", {
+ "filters descendants to type": function() {
+ var paragraph = {type: "paragraph"};
+ var run = {type: "run"};
+ var element = {
+ children: [paragraph, run]
+ };
+ assert.deepEqual(
+ transforms.getDescendantsOfType(element, "run"),
+ [run]
+ );
+ }
+});