@depup/mammoth 1.12.0-depup.54

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/.eslintrc.json +75 -0
  2. package/.github/ISSUE_TEMPLATE.md +12 -0
  3. package/.github/pull_request_template.md +3 -0
  4. package/.github/workflows/tests.yml +26 -0
  5. package/LICENSE +22 -0
  6. package/NEWS +530 -0
  7. package/README.md +37 -0
  8. package/bin/mammoth +38 -0
  9. package/browser/docx/files.js +14 -0
  10. package/browser/unzip.js +12 -0
  11. package/changes.json +34 -0
  12. package/lib/document-to-html.js +469 -0
  13. package/lib/documents.js +254 -0
  14. package/lib/docx/body-reader.js +798 -0
  15. package/lib/docx/comments-reader.js +31 -0
  16. package/lib/docx/content-types-reader.js +58 -0
  17. package/lib/docx/document-xml-reader.js +30 -0
  18. package/lib/docx/docx-reader.js +226 -0
  19. package/lib/docx/files.js +80 -0
  20. package/lib/docx/notes-reader.js +28 -0
  21. package/lib/docx/numbering-xml.js +111 -0
  22. package/lib/docx/office-xml-reader.js +73 -0
  23. package/lib/docx/relationships-reader.js +43 -0
  24. package/lib/docx/style-map.js +75 -0
  25. package/lib/docx/styles-reader.js +90 -0
  26. package/lib/docx/uris.js +21 -0
  27. package/lib/html/ast.js +51 -0
  28. package/lib/html/index.js +41 -0
  29. package/lib/html/simplify.js +88 -0
  30. package/lib/images.js +31 -0
  31. package/lib/index.d.ts +86 -0
  32. package/lib/index.js +111 -0
  33. package/lib/main.js +63 -0
  34. package/lib/options-reader.js +107 -0
  35. package/lib/promises.js +42 -0
  36. package/lib/raw-text.js +14 -0
  37. package/lib/results.js +72 -0
  38. package/lib/style-reader.js +365 -0
  39. package/lib/styles/document-matchers.js +100 -0
  40. package/lib/styles/html-paths.js +75 -0
  41. package/lib/styles/parser/tokeniser.js +30 -0
  42. package/lib/transforms.js +62 -0
  43. package/lib/underline.js +11 -0
  44. package/lib/unzip.js +20 -0
  45. package/lib/writers/html-writer.js +159 -0
  46. package/lib/writers/index.js +14 -0
  47. package/lib/writers/markdown-writer.js +163 -0
  48. package/lib/xml/index.js +8 -0
  49. package/lib/xml/nodes.js +70 -0
  50. package/lib/xml/reader.js +69 -0
  51. package/lib/xml/writer.js +61 -0
  52. package/lib/xml/xmldom.js +23 -0
  53. package/lib/zipfile.js +72 -0
  54. package/mammoth.browser.js +22096 -0
  55. package/mammoth.browser.min.js +20 -0
  56. package/package.json +106 -0
  57. package/test/.eslintrc.json +7 -0
  58. package/test/document-to-html.tests.js +892 -0
  59. package/test/docx/body-reader.tests.js +2037 -0
  60. package/test/docx/comments-reader.tests.js +53 -0
  61. package/test/docx/content-types-reader.tests.js +45 -0
  62. package/test/docx/document-matchers.js +42 -0
  63. package/test/docx/document-xml-reader.tests.js +41 -0
  64. package/test/docx/docx-reader.tests.js +179 -0
  65. package/test/docx/files.tests.js +107 -0
  66. package/test/docx/notes-reader.tests.js +36 -0
  67. package/test/docx/numbering-xml.tests.js +183 -0
  68. package/test/docx/office-xml-reader.tests.js +41 -0
  69. package/test/docx/relationships-reader.tests.js +65 -0
  70. package/test/docx/style-map.tests.js +113 -0
  71. package/test/docx/styles-reader.tests.js +143 -0
  72. package/test/docx/testing.js +12 -0
  73. package/test/docx/uris.tests.js +22 -0
  74. package/test/html/simplify.tests.js +141 -0
  75. package/test/html/write.tests.js +42 -0
  76. package/test/images.tests.js +112 -0
  77. package/test/main.tests.js +89 -0
  78. package/test/mammoth.tests.js +523 -0
  79. package/test/mocha.opts +1 -0
  80. package/test/options-reader.tests.js +63 -0
  81. package/test/raw-text.tests.js +61 -0
  82. package/test/results.tests.js +15 -0
  83. package/test/style-reader.tests.js +291 -0
  84. package/test/styles/document-matchers.tests.js +91 -0
  85. package/test/styles/html-paths.tests.js +20 -0
  86. package/test/styles/parser/tokeniser.tests.js +104 -0
  87. package/test/test-data/comments.docx +0 -0
  88. package/test/test-data/embedded-style-map.docx +0 -0
  89. package/test/test-data/empty.docx +0 -0
  90. package/test/test-data/empty.zip +0 -0
  91. package/test/test-data/endnotes.docx +0 -0
  92. package/test/test-data/external-picture.docx +0 -0
  93. package/test/test-data/footnote-hyperlink.docx +0 -0
  94. package/test/test-data/footnotes.docx +0 -0
  95. package/test/test-data/hello.zip +0 -0
  96. package/test/test-data/hyperlinks/word/_rels/document.xml.rels +10 -0
  97. package/test/test-data/hyperlinks/word/document.xml +18 -0
  98. package/test/test-data/simple/word/document.xml +18 -0
  99. package/test/test-data/simple-list.docx +0 -0
  100. package/test/test-data/single-paragraph.docx +0 -0
  101. package/test/test-data/strict-format.docx +0 -0
  102. package/test/test-data/strikethrough.docx +0 -0
  103. package/test/test-data/tables.docx +0 -0
  104. package/test/test-data/text-box.docx +0 -0
  105. package/test/test-data/tiny-picture-target-base-relative.docx +0 -0
  106. package/test/test-data/tiny-picture.docx +0 -0
  107. package/test/test-data/tiny-picture.png +0 -0
  108. package/test/test-data/underline.docx +0 -0
  109. package/test/test-data/utf8-bom.docx +0 -0
  110. package/test/test.js +11 -0
  111. package/test/testing.js +55 -0
  112. package/test/transforms.tests.js +125 -0
  113. package/test/unzip.tests.js +38 -0
  114. package/test/writers/html-writer.tests.js +133 -0
  115. package/test/writers/markdown-writer.tests.js +304 -0
  116. package/test/xml/reader.tests.js +85 -0
  117. package/test/xml/writer.tests.js +81 -0
  118. package/test/zipfile.tests.js +61 -0
@@ -0,0 +1,53 @@
1
+ var assert = require("assert");
2
+
3
+ var createCommentsReader = require("../../lib/docx/comments-reader").createCommentsReader;
4
+ var createBodyReader = require("../../lib/docx/body-reader").createBodyReader;
5
+ var stylesReader = require("../../lib/docx/styles-reader");
6
+ var documents = require("../../lib/documents");
7
+ var xml = require("../../lib/xml");
8
+ var test = require("../test")(module);
9
+
10
+
11
+ function readComment(element) {
12
+ var bodyReader = createBodyReader({styles: stylesReader.defaultStyles});
13
+ var commentsReader = createCommentsReader(bodyReader);
14
+ var comments = commentsReader(element);
15
+ assert.equal(comments.value.length, 1);
16
+ return comments.value[0];
17
+ }
18
+
19
+ test('ID and body of comment are read', function() {
20
+ var body = [xml.element("w:p")];
21
+ var comment = readComment(xml.element("w:comments", {}, [
22
+ xml.element("w:comment", {"w:id": "1"}, body)
23
+ ]));
24
+ assert.deepEqual(comment.body, [new documents.Paragraph([])]);
25
+ assert.deepEqual(comment.commentId, "1");
26
+ });
27
+
28
+
29
+ test('when optional attributes of comment are missing then they are read as null', function() {
30
+ var comment = readComment(xml.element("w:comments", {}, [
31
+ xml.element("w:comment", {"w:id": "1"})
32
+ ]));
33
+ assert.strictEqual(comment.authorName, null);
34
+ assert.strictEqual(comment.authorInitials, null);
35
+ });
36
+
37
+
38
+ test('when optional attributes of comment are blank then they are read as null', function() {
39
+ var comment = readComment(xml.element("w:comments", {}, [
40
+ xml.element("w:comment", {"w:id": "1", "w:author": " ", "w:initials": " "})
41
+ ]));
42
+ assert.strictEqual(comment.authorName, null);
43
+ assert.strictEqual(comment.authorInitials, null);
44
+ });
45
+
46
+
47
+ test('when optional attributes of comment are not blank then they are read', function() {
48
+ var comment = readComment(xml.element("w:comments", {}, [
49
+ xml.element("w:comment", {"w:id": "1", "w:author": "The Piemaker", "w:initials": "TP"})
50
+ ]));
51
+ assert.strictEqual(comment.authorName, "The Piemaker");
52
+ assert.strictEqual(comment.authorInitials, "TP");
53
+ });
@@ -0,0 +1,45 @@
1
+ var assert = require("assert");
2
+
3
+ var readContentTypesFromXml = require("../../lib/docx/content-types-reader").readContentTypesFromXml;
4
+ var XmlElement = require("../../lib/xml").Element;
5
+ var test = require("../test")(module);
6
+
7
+
8
+ test('reads default-per-extension from XML', function() {
9
+ var contentTypes = readContentTypesFromXml(
10
+ new XmlElement("content-types:Types", {}, [
11
+ new XmlElement("content-types:Default", {Extension: "png", ContentType: "image/png"})
12
+ ])
13
+ );
14
+ assert.equal(contentTypes.findContentType("word/media/hat.png"), "image/png");
15
+ });
16
+
17
+ test('reads overrides in preference to defaults', function() {
18
+ var contentTypes = readContentTypesFromXml(
19
+ new XmlElement("content-types:Types", {}, [
20
+ new XmlElement("content-types:Default", {Extension: "png", ContentType: "image/png"}),
21
+ new XmlElement("content-types:Override", {PartName: "/word/media/hat.png", ContentType: "image/hat"})
22
+ ])
23
+ );
24
+ assert.equal(contentTypes.findContentType("word/media/hat.png"), "image/hat");
25
+ });
26
+
27
+ test('fallback content types have common image types', function() {
28
+ var contentTypes = readContentTypesFromXml(
29
+ new XmlElement("content-types:Types", {}, [])
30
+ );
31
+ assert.equal(contentTypes.findContentType("word/media/hat.png"), "image/png");
32
+ assert.equal(contentTypes.findContentType("word/media/hat.gif"), "image/gif");
33
+ assert.equal(contentTypes.findContentType("word/media/hat.jpg"), "image/jpeg");
34
+ assert.equal(contentTypes.findContentType("word/media/hat.jpeg"), "image/jpeg");
35
+ assert.equal(contentTypes.findContentType("word/media/hat.bmp"), "image/bmp");
36
+ assert.equal(contentTypes.findContentType("word/media/hat.tif"), "image/tiff");
37
+ assert.equal(contentTypes.findContentType("word/media/hat.tiff"), "image/tiff");
38
+ });
39
+
40
+ test('fallback content types are case insensitive on extension', function() {
41
+ var contentTypes = readContentTypesFromXml(
42
+ new XmlElement("content-types:Types", {}, [])
43
+ );
44
+ assert.equal(contentTypes.findContentType("word/media/hat.PnG"), "image/png");
45
+ });
@@ -0,0 +1,42 @@
1
+ var hamjest = require("hamjest");
2
+ var _ = require("underscore");
3
+
4
+ var documents = require("../../lib/documents");
5
+
6
+
7
+ exports.isEmptyRun = isRun({children: []});
8
+ exports.isRun = isRun;
9
+ exports.isText = isText;
10
+ exports.isCheckbox = isCheckbox;
11
+ exports.isHyperlink = isHyperlink;
12
+ exports.isTable = isTable;
13
+ exports.isRow = isRow;
14
+
15
+
16
+ function isRun(properties) {
17
+ return isDocumentElement(documents.types.run, properties);
18
+ }
19
+
20
+ function isText(text) {
21
+ return isDocumentElement(documents.types.text, {value: text});
22
+ }
23
+
24
+ function isCheckbox(properties) {
25
+ return isDocumentElement(documents.types.checkbox, properties);
26
+ }
27
+
28
+ function isHyperlink(properties) {
29
+ return isDocumentElement(documents.types.hyperlink, properties);
30
+ }
31
+
32
+ function isTable(options) {
33
+ return isDocumentElement(documents.types.table, options);
34
+ }
35
+
36
+ function isRow(options) {
37
+ return isDocumentElement(documents.types.tableRow, options);
38
+ }
39
+
40
+ function isDocumentElement(type, properties) {
41
+ return hamjest.hasProperties(_.extend({type: hamjest.equalTo(type)}, properties));
42
+ }
@@ -0,0 +1,41 @@
1
+ var assert = require("assert");
2
+
3
+ var documents = require("../../lib/documents");
4
+ var DocumentXmlReader = require("../../lib/docx/document-xml-reader").DocumentXmlReader;
5
+ var xml = require("../../lib/xml");
6
+ var test = require("../test")(module);
7
+ var createBodyReaderForTests = require("./testing").createBodyReaderForTests;
8
+
9
+ test("when body element is present then body is read", function() {
10
+ var bodyReader = createBodyReaderForTests({});
11
+ var documentXmlReader = new DocumentXmlReader({
12
+ bodyReader: bodyReader
13
+ });
14
+ var textXml = xml.element("w:t", {}, [xml.text("Hello!")]);
15
+ var runXml = xml.element("w:r", {}, [textXml]);
16
+ var paragraphXml = xml.element("w:p", {}, [runXml]);
17
+ var bodyXml = xml.element("w:body", {}, [paragraphXml]);
18
+ var documentXml = xml.element("w:document", {}, [bodyXml]);
19
+
20
+ var result = documentXmlReader.convertXmlToDocument(documentXml);
21
+
22
+ assert.deepEqual(result.messages, []);
23
+ assert.deepEqual(result.value, documents.document(
24
+ [documents.paragraph([documents.run([documents.text("Hello!")])])],
25
+ {}
26
+ ));
27
+ });
28
+
29
+ test("when body element is not present then error is thrown", function() {
30
+ var bodyReader = createBodyReaderForTests({});
31
+ var documentXmlReader = new DocumentXmlReader({
32
+ bodyReader: bodyReader
33
+ });
34
+ var paragraphXml = xml.element("w:p", {}, []);
35
+ var bodyXml = xml.element("w:body2", {}, [paragraphXml]);
36
+ var documentXml = xml.element("w:document", {}, [bodyXml]);
37
+
38
+ assert.throws(function() {
39
+ documentXmlReader.convertXmlToDocument(documentXml);
40
+ }, /Could not find the body element: are you sure this is a docx file?/);
41
+ });
@@ -0,0 +1,179 @@
1
+ var assert = require("assert");
2
+
3
+ var docxReader = require("../../lib/docx/docx-reader");
4
+ var documents = require("../../lib/documents");
5
+ var xml = require("../../lib/xml");
6
+
7
+ var testing = require("../testing");
8
+ var test = require("../test")(module);
9
+ var testData = testing.testData;
10
+ var createFakeDocxFile = testing.createFakeDocxFile;
11
+
12
+
13
+ test("can read document with single paragraph with single run of text", function() {
14
+ var expectedDocument = documents.Document([
15
+ documents.Paragraph([
16
+ documents.Run([
17
+ documents.Text("Hello.")
18
+ ])
19
+ ])
20
+ ]);
21
+ var docxFile = createFakeDocxFile({
22
+ "word/document.xml": testData("simple/word/document.xml")
23
+ });
24
+ return docxReader.read(docxFile).then(function(result) {
25
+ assert.deepEqual(expectedDocument, result.value);
26
+ });
27
+ });
28
+
29
+ test("hyperlink hrefs are read from relationships file", function() {
30
+ var docxFile = createFakeDocxFile({
31
+ "word/document.xml": testData("hyperlinks/word/document.xml"),
32
+ "word/_rels/document.xml.rels": testData("hyperlinks/word/_rels/document.xml.rels")
33
+ });
34
+ return docxReader.read(docxFile).then(function(result) {
35
+ var paragraph = result.value.children[0];
36
+ assert.equal(1, paragraph.children.length);
37
+ var hyperlink = paragraph.children[0];
38
+ assert.equal(hyperlink.href, "http://www.example.com");
39
+ assert.equal(hyperlink.children.length, 1);
40
+ });
41
+ });
42
+
43
+ var relationshipNamespaces = {
44
+ "r": "http://schemas.openxmlformats.org/package/2006/relationships"
45
+ };
46
+
47
+ test("main document is found using _rels/.rels", function() {
48
+ var relationships = xml.element("r:Relationships", {}, [
49
+ xml.element("r:Relationship", {
50
+ "Type": "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument",
51
+ "Target": "/word/document2.xml"
52
+ })
53
+ ]);
54
+
55
+ var docxFile = createFakeDocxFile({
56
+ "word/document2.xml": testData("simple/word/document.xml"),
57
+ "_rels/.rels": xml.writeString(relationships, relationshipNamespaces)
58
+ });
59
+ var expectedDocument = documents.Document([
60
+ documents.Paragraph([
61
+ documents.Run([
62
+ documents.Text("Hello.")
63
+ ])
64
+ ])
65
+ ]);
66
+ return docxReader.read(docxFile).then(function(result) {
67
+ assert.deepEqual(expectedDocument, result.value);
68
+ });
69
+ });
70
+
71
+
72
+ test("error is thrown when main document part does not exist", function() {
73
+ var relationships = xml.element("r:Relationships", {}, [
74
+ xml.element("r:Relationship", {
75
+ "Type": "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument",
76
+ "Target": "/word/document2.xml"
77
+ })
78
+ ]);
79
+
80
+ var docxFile = createFakeDocxFile({
81
+ "_rels/.rels": xml.writeString(relationships, relationshipNamespaces)
82
+ });
83
+ return docxReader.read(docxFile).then(function(result) {
84
+ assert.ok(false, "Expected error");
85
+ }, function(error) {
86
+ assert.equal(error.message, "Could not find main document part. Are you sure this is a valid .docx file?");
87
+ });
88
+ });
89
+
90
+
91
+ test("part paths", {
92
+ "main document part is found using package relationships": function() {
93
+ var relationships = xml.element("r:Relationships", {}, [
94
+ xml.element("r:Relationship", {
95
+ "Type": "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument",
96
+ "Target": "/word/document2.xml"
97
+ })
98
+ ]);
99
+
100
+ var docxFile = createFakeDocxFile({
101
+ "word/document2.xml": " ",
102
+ "_rels/.rels": xml.writeString(relationships, relationshipNamespaces)
103
+ });
104
+ return docxReader._findPartPaths(docxFile).then(function(partPaths) {
105
+ assert.equal(partPaths.mainDocument, "word/document2.xml");
106
+ });
107
+ },
108
+
109
+ "word/document.xml is used as fallback location for main document part": function() {
110
+ var docxFile = createFakeDocxFile({
111
+ "word/document.xml": " "
112
+ });
113
+ return docxReader._findPartPaths(docxFile).then(function(partPaths) {
114
+ assert.equal(partPaths.mainDocument, "word/document.xml");
115
+ });
116
+ }
117
+ });
118
+
119
+ [
120
+ {
121
+ name: "comments",
122
+ type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments"
123
+ },
124
+ {
125
+ name: "endnotes",
126
+ type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes"
127
+ },
128
+ {
129
+ name: "footnotes",
130
+ type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes"
131
+ },
132
+ {
133
+ name: "numbering",
134
+ type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering"
135
+ },
136
+ {
137
+ name: "styles",
138
+ type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles"
139
+ }
140
+ ].forEach(function(options) {
141
+ test(options.name + " part is found using main document relationships", function() {
142
+ var docxFile = createFakeDocxFile({
143
+ "_rels/.rels": createPackageRelationships("word/document.xml"),
144
+ "word/document.xml": " ",
145
+ "word/_rels/document.xml.rels": xml.writeString(xml.element("r:Relationships", {}, [
146
+ xml.element("r:Relationship", {
147
+ "Type": options.type,
148
+ "Target": "target-path.xml"
149
+ })
150
+ ]), relationshipNamespaces),
151
+ "word/target-path.xml": " "
152
+ });
153
+ return docxReader._findPartPaths(docxFile).then(function(partPaths) {
154
+ assert.equal(partPaths[options.name], "word/target-path.xml");
155
+ });
156
+ });
157
+
158
+ test("word/" + options.name + ".xml is used as fallback location for " + options.name + " part", function() {
159
+ var zipContents = {
160
+ "_rels/.rels": createPackageRelationships("word/document.xml"),
161
+ "word/document.xml": " "
162
+ };
163
+ zipContents["word/" + options.name + ".xml"] = " ";
164
+ var docxFile = createFakeDocxFile(zipContents);
165
+ return docxReader._findPartPaths(docxFile).then(function(partPaths) {
166
+ assert.equal(partPaths[options.name], "word/" + options.name + ".xml");
167
+ });
168
+ });
169
+ });
170
+
171
+
172
+ function createPackageRelationships(mainDocumentPath) {
173
+ return xml.writeString(xml.element("r:Relationships", {}, [
174
+ xml.element("r:Relationship", {
175
+ "Type": "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument",
176
+ "Target": mainDocumentPath
177
+ })
178
+ ]), relationshipNamespaces);
179
+ }
@@ -0,0 +1,107 @@
1
+ var path = require("path");
2
+ var fs = require("fs");
3
+ var assert = require("assert");
4
+
5
+ var promises = require("../../lib/promises");
6
+ var Files = require("../../lib/docx/files").Files;
7
+ var uriToPath = require("../../lib/docx/files").uriToPath;
8
+
9
+ var testing = require("../testing");
10
+ var test = require("../test")(module);
11
+
12
+ var readFile = promises.promisify(fs.readFile.bind(fs));
13
+
14
+
15
+ test("Files", {
16
+ "when external file access is disabled then reading file raises error": function() {
17
+ var files = new Files({externalFileAccess: false});
18
+ return assertError(files.read("/tmp/image.png", "base64"), function(err) {
19
+ assert.strictEqual(err.message, "could not read external image '/tmp/image.png', external file access is disabled");
20
+ });
21
+ },
22
+
23
+ "can open files with file URI": function() {
24
+ var filePath = path.resolve(testing.testPath("tiny-picture.png"));
25
+ var files = new Files({externalFileAccess: true});
26
+ return files.read("file:///" + filePath.replace(/^\//, ""), "base64").then(function(contents) {
27
+ return readFile(filePath, "base64").then(function(expectedContents) {
28
+ assert.deepEqual(contents, expectedContents);
29
+ });
30
+ });
31
+ },
32
+
33
+ "can open files with relative URI": function() {
34
+ var filePath = path.resolve(testing.testPath("tiny-picture.png"));
35
+ var files = new Files({
36
+ externalFileAccess: true,
37
+ relativeToFile: testing.testPath("./document.docx")
38
+ });
39
+ return files.read("tiny-picture.png", "base64").then(function(contents) {
40
+ return readFile(filePath, "base64").then(function(expectedContents) {
41
+ assert.deepEqual(contents, expectedContents);
42
+ });
43
+ });
44
+ },
45
+
46
+ "given base is not set when opening relative uri then error is raised": function() {
47
+ var files = new Files({externalFileAccess: true});
48
+ return assertError(files.read("not-a-real-file.png", "base64"), function(err) {
49
+ assert.equal(err.message, "could not find external image 'not-a-real-file.png', path of input document is unknown");
50
+ });
51
+ },
52
+
53
+ "error if relative uri cannot be opened": function() {
54
+ var files = new Files({
55
+ externalFileAccess: true,
56
+ relativeToFile: "/tmp/document.docx"
57
+ });
58
+ return assertError(files.read("not-a-real-file.png", "base64"), function(err) {
59
+ assertRegex(err.message, /could not open external image: 'not-a-real-file.png' \(document directory: '\/tmp'\)\nENOENT.*\/tmp\/not-a-real-file.png.*/);
60
+ });
61
+ }
62
+ });
63
+
64
+ function assertError(promise, func) {
65
+ return promise.then(function() {
66
+ assert(false, "Expected error");
67
+ }, func);
68
+ }
69
+
70
+ function assertRegex(actual, expected) {
71
+ assert.ok(expected.test(actual), "Expected regex: " + expected + "\nbut was: " + actual);
72
+ }
73
+
74
+
75
+ test("uriToPath", {
76
+ "leading slash is retained on non-Windows file URIs": function() {
77
+ assert.equal(uriToPath("file:///a/b/c", "linux"), "/a/b/c");
78
+ assert.equal(uriToPath("file:///a/b/c", "win32"), "/a/b/c");
79
+ },
80
+
81
+ "URI is unquoted": function() {
82
+ assert.equal(uriToPath("file:///a%20b"), "/a b");
83
+ },
84
+
85
+ "when host is set to localhost then path can be found": function() {
86
+ assert.equal(uriToPath("file://localhost/a/b/c"), "/a/b/c");
87
+ },
88
+
89
+ "when host is set but not localhost then path cannot be found": function() {
90
+ assert.throws(function() {
91
+ uriToPath("file://example/a/b/c");
92
+ }, /Could not convert URI to path: file:\/\/example\/a\/b\/c/);
93
+ },
94
+
95
+ "leading slash is not dropped on Windows file URIs when platform is not Windows": function() {
96
+ assert.equal(uriToPath("file:///c:/a", "linux"), "/c:/a");
97
+ },
98
+
99
+ "leading slash is dropped on Windows file URIs when platform is Windows": function() {
100
+ assert.equal(uriToPath("file:///c:/a", "win32"), "c:/a");
101
+ assert.equal(uriToPath("file:///C:/a", "win32"), "C:/a");
102
+ },
103
+
104
+ "relative URI is unquoted": function() {
105
+ assert.equal(uriToPath("a%20b/c"), "a b/c");
106
+ }
107
+ });
@@ -0,0 +1,36 @@
1
+ var assert = require("assert");
2
+
3
+ var createFootnotesReader = require("../../lib/docx/notes-reader").createFootnotesReader;
4
+ var createBodyReader = require("../../lib/docx/body-reader").createBodyReader;
5
+ var stylesReader = require("../../lib/docx/styles-reader");
6
+ var documents = require("../../lib/documents");
7
+ var XmlElement = require("../../lib/xml").Element;
8
+ var test = require("../test")(module);
9
+
10
+
11
+ test('ID and body of footnote are read', function() {
12
+ var bodyReader = new createBodyReader({styles: stylesReader.defaultStyles});
13
+ var footnoteBody = [new XmlElement("w:p", {}, [])];
14
+ var footnotes = createFootnotesReader(bodyReader)(
15
+ new XmlElement("w:footnotes", {}, [
16
+ new XmlElement("w:footnote", {"w:id": "1"}, footnoteBody)
17
+ ])
18
+ );
19
+ assert.equal(footnotes.value.length, 1);
20
+ assert.deepEqual(footnotes.value[0].body, [new documents.Paragraph([])]);
21
+ assert.deepEqual(footnotes.value[0].noteId, "1");
22
+ });
23
+
24
+ footnoteTypeIsIgnored('continuationSeparator');
25
+ footnoteTypeIsIgnored('separator');
26
+
27
+ function footnoteTypeIsIgnored(type) {
28
+ test('footnotes of type ' + type + ' are ignored', function() {
29
+ var footnotes = createFootnotesReader()(
30
+ new XmlElement("w:footnotes", {}, [
31
+ new XmlElement("w:footnote", {"w:id": "1", "w:type": type}, [])
32
+ ])
33
+ );
34
+ assert.equal(footnotes.value.length, 0);
35
+ });
36
+ }