@hyperlex/mammoth 1.4.9-beta

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 (112) hide show
  1. package/.eslintrc.json +77 -0
  2. package/.github/ISSUE_TEMPLATE.md +12 -0
  3. package/.idea/mammoth.js.iml +12 -0
  4. package/.idea/modules.xml +8 -0
  5. package/.idea/vcs.xml +6 -0
  6. package/.travis.yml +10 -0
  7. package/LICENSE +22 -0
  8. package/NEWS +373 -0
  9. package/README.md +883 -0
  10. package/bin/mammoth +38 -0
  11. package/browser/docx/files.js +14 -0
  12. package/browser/unzip.js +12 -0
  13. package/lib/document-to-html.js +453 -0
  14. package/lib/documents.js +238 -0
  15. package/lib/docx/body-reader.js +636 -0
  16. package/lib/docx/comments-reader.js +31 -0
  17. package/lib/docx/content-types-reader.js +58 -0
  18. package/lib/docx/document-xml-reader.js +26 -0
  19. package/lib/docx/docx-reader.js +222 -0
  20. package/lib/docx/files.js +67 -0
  21. package/lib/docx/notes-reader.js +28 -0
  22. package/lib/docx/numbering-xml.js +69 -0
  23. package/lib/docx/office-xml-reader.js +58 -0
  24. package/lib/docx/relationships-reader.js +43 -0
  25. package/lib/docx/style-map.js +75 -0
  26. package/lib/docx/styles-reader.js +70 -0
  27. package/lib/docx/uris.js +21 -0
  28. package/lib/html/ast.js +50 -0
  29. package/lib/html/index.js +41 -0
  30. package/lib/html/simplify.js +88 -0
  31. package/lib/images.js +29 -0
  32. package/lib/index.js +115 -0
  33. package/lib/main.js +63 -0
  34. package/lib/options-reader.js +98 -0
  35. package/lib/promises.js +42 -0
  36. package/lib/results.js +72 -0
  37. package/lib/style-reader.js +321 -0
  38. package/lib/styles/document-matchers.js +74 -0
  39. package/lib/styles/html-paths.js +81 -0
  40. package/lib/styles/parser/tokeniser.js +30 -0
  41. package/lib/transforms.js +61 -0
  42. package/lib/underline.js +11 -0
  43. package/lib/unzip.js +22 -0
  44. package/lib/writers/html-writer.js +160 -0
  45. package/lib/writers/index.js +14 -0
  46. package/lib/writers/markdown-writer.js +163 -0
  47. package/lib/xml/index.js +7 -0
  48. package/lib/xml/nodes.js +69 -0
  49. package/lib/xml/reader.js +83 -0
  50. package/lib/xml/writer.js +61 -0
  51. package/lib/zipfile.js +77 -0
  52. package/mammoth.browser.js +32950 -0
  53. package/mammoth.browser.min.js +18 -0
  54. package/package.json +65 -0
  55. package/test/.eslintrc.json +7 -0
  56. package/test/document-to-html.tests.js +834 -0
  57. package/test/docx/body-reader.tests.js +1342 -0
  58. package/test/docx/comments-reader.tests.js +52 -0
  59. package/test/docx/content-types-reader.tests.js +45 -0
  60. package/test/docx/document-matchers.js +37 -0
  61. package/test/docx/docx-reader.tests.js +179 -0
  62. package/test/docx/files.tests.js +94 -0
  63. package/test/docx/notes-reader.tests.js +35 -0
  64. package/test/docx/numbering-xml.tests.js +65 -0
  65. package/test/docx/office-xml-reader.tests.js +24 -0
  66. package/test/docx/relationships-reader.tests.js +65 -0
  67. package/test/docx/style-map.tests.js +112 -0
  68. package/test/docx/styles-reader.tests.js +133 -0
  69. package/test/docx/uris.tests.js +22 -0
  70. package/test/html/simplify.tests.js +134 -0
  71. package/test/html/write.tests.js +42 -0
  72. package/test/images.tests.js +34 -0
  73. package/test/main.tests.js +89 -0
  74. package/test/mammoth.tests.js +429 -0
  75. package/test/mocha.opts +1 -0
  76. package/test/options-reader.tests.js +63 -0
  77. package/test/results.tests.js +15 -0
  78. package/test/style-reader.tests.js +256 -0
  79. package/test/styles/document-matchers.tests.js +71 -0
  80. package/test/styles/html-paths.tests.js +20 -0
  81. package/test/styles/parser/tokeniser.tests.js +104 -0
  82. package/test/test-data/comments.docx +0 -0
  83. package/test/test-data/embedded-style-map.docx +0 -0
  84. package/test/test-data/empty.docx +0 -0
  85. package/test/test-data/empty.zip +0 -0
  86. package/test/test-data/endnotes.docx +0 -0
  87. package/test/test-data/external-picture.docx +0 -0
  88. package/test/test-data/footnote-hyperlink.docx +0 -0
  89. package/test/test-data/footnotes.docx +0 -0
  90. package/test/test-data/hello.zip +0 -0
  91. package/test/test-data/hyperlinks/word/_rels/document.xml.rels +10 -0
  92. package/test/test-data/hyperlinks/word/document.xml +18 -0
  93. package/test/test-data/simple/word/document.xml +18 -0
  94. package/test/test-data/simple-list.docx +0 -0
  95. package/test/test-data/single-paragraph.docx +0 -0
  96. package/test/test-data/strikethrough.docx +0 -0
  97. package/test/test-data/tables.docx +0 -0
  98. package/test/test-data/text-box.docx +0 -0
  99. package/test/test-data/tiny-picture-target-base-relative.docx +0 -0
  100. package/test/test-data/tiny-picture.docx +0 -0
  101. package/test/test-data/tiny-picture.png +0 -0
  102. package/test/test-data/underline.docx +0 -0
  103. package/test/test-data/utf8-bom.docx +0 -0
  104. package/test/test.js +11 -0
  105. package/test/testing.js +55 -0
  106. package/test/transforms.tests.js +125 -0
  107. package/test/unzip.tests.js +38 -0
  108. package/test/writers/html-writer.tests.js +133 -0
  109. package/test/writers/markdown-writer.tests.js +304 -0
  110. package/test/xml/reader.tests.js +85 -0
  111. package/test/xml/writer.tests.js +81 -0
  112. package/test/zipfile.tests.js +59 -0
@@ -0,0 +1,256 @@
1
+ var assert = require("assert");
2
+ var htmlPaths = require("../lib/styles/html-paths");
3
+ var documentMatchers = require("../lib/styles/document-matchers");
4
+ var styleReader = require("../lib/style-reader");
5
+ var results = require("../lib/results");
6
+ var test = require("./test")(module);
7
+
8
+
9
+ var readHtmlPath = styleReader.readHtmlPath;
10
+ var readDocumentMatcher = styleReader.readDocumentMatcher;
11
+ var readStyle = styleReader.readStyle;
12
+
13
+
14
+ test('styleReader.readHtmlPath', {
15
+ 'reads empty path': function() {
16
+ assertHtmlPath("", htmlPaths.empty);
17
+ },
18
+
19
+ 'reads single element': function() {
20
+ assertHtmlPath("p", htmlPaths.elements(["p"]));
21
+ },
22
+
23
+ 'reads choice of elements': function() {
24
+ assertHtmlPath(
25
+ "ul|ol",
26
+ htmlPaths.elements([
27
+ htmlPaths.element(["ul", "ol"])
28
+ ])
29
+ );
30
+ },
31
+
32
+ 'reads nested elements': function() {
33
+ assertHtmlPath("ul > li", htmlPaths.elements(["ul", "li"]));
34
+ },
35
+
36
+ 'reads class on element': function() {
37
+ var expected = htmlPaths.elements([
38
+ htmlPaths.element("p", {"class": "tip"})
39
+ ]);
40
+ assertHtmlPath("p.tip", expected);
41
+ },
42
+
43
+ 'reads class with escaped colon': function() {
44
+ var expected = htmlPaths.elements([
45
+ htmlPaths.element("p", {"class": "a:b"})
46
+ ]);
47
+ assertHtmlPath("p.a\\:b", expected);
48
+ },
49
+
50
+ 'reads multiple classes on element': function() {
51
+ var expected = htmlPaths.elements([
52
+ htmlPaths.element("p", {"class": "tip help"})
53
+ ]);
54
+ assertHtmlPath("p.tip.help", expected);
55
+ },
56
+
57
+ 'reads when element must be fresh': function() {
58
+ var expected = htmlPaths.elements([
59
+ htmlPaths.element("p", {}, {"fresh": true})
60
+ ]);
61
+ assertHtmlPath("p:fresh", expected);
62
+ },
63
+
64
+ 'reads separator for elements': function() {
65
+ var expected = htmlPaths.elements([
66
+ htmlPaths.element("p", {}, {separator: "x"})
67
+ ]);
68
+ assertHtmlPath("p:separator('x')", expected);
69
+ },
70
+
71
+ 'reads separator with escape sequence': function() {
72
+ var expected = htmlPaths.elements([
73
+ htmlPaths.element("p", {}, {separator: "\r\n\t\'\\"})
74
+ ]);
75
+ assertHtmlPath("p:separator('\\r\\n\\t\\'\\\\')", expected);
76
+ },
77
+
78
+ 'reads ignore element': function() {
79
+ assertHtmlPath("!", htmlPaths.ignore);
80
+ }
81
+ });
82
+
83
+ function assertHtmlPath(input, expected) {
84
+ assert.deepEqual(readHtmlPath(input), results.success(expected));
85
+ }
86
+
87
+ test("styleReader.readDocumentMatcher", {
88
+ "reads plain paragraph": function() {
89
+ assertDocumentMatcher("p", documentMatchers.paragraph());
90
+ },
91
+
92
+ "reads paragraph with style ID": function() {
93
+ assertDocumentMatcher(
94
+ "p.Heading1",
95
+ documentMatchers.paragraph({styleId: "Heading1"})
96
+ );
97
+ },
98
+
99
+ "reads paragraph with exact style name": function() {
100
+ assertDocumentMatcher(
101
+ "p[style-name='Heading 1']",
102
+ documentMatchers.paragraph({styleName: documentMatchers.equalTo("Heading 1")})
103
+ );
104
+ },
105
+
106
+ "reads paragraph with style name prefix": function() {
107
+ assertDocumentMatcher(
108
+ "p[style-name^='Heading']",
109
+ documentMatchers.paragraph({styleName: documentMatchers.startsWith("Heading")})
110
+ );
111
+ },
112
+
113
+ "reads p:ordered-list(1) as ordered list with index of 0": function() {
114
+ assertDocumentMatcher(
115
+ "p:ordered-list(1)",
116
+ documentMatchers.paragraph({list: {isOrdered: true, levelIndex: 0}})
117
+ );
118
+ },
119
+
120
+ "reads p:unordered-list(1) as unordered list with index of 0": function() {
121
+ assertDocumentMatcher(
122
+ "p:unordered-list(1)",
123
+ documentMatchers.paragraph({list: {isOrdered: false, levelIndex: 0}})
124
+ );
125
+ },
126
+
127
+ "reads plain run": function() {
128
+ assertDocumentMatcher(
129
+ "r",
130
+ documentMatchers.run()
131
+ );
132
+ },
133
+
134
+ "reads plain table": function() {
135
+ assertDocumentMatcher("table", documentMatchers.table());
136
+ },
137
+
138
+ "reads table with style ID": function() {
139
+ assertDocumentMatcher(
140
+ "table.TableNormal",
141
+ documentMatchers.table({
142
+ styleId: "TableNormal"
143
+ })
144
+ );
145
+ },
146
+
147
+ "reads table with style name": function() {
148
+ assertDocumentMatcher(
149
+ "table[style-name='Normal Table']",
150
+ documentMatchers.table({
151
+ styleName: documentMatchers.equalTo("Normal Table")
152
+ })
153
+ );
154
+ },
155
+
156
+ "reads bold": function() {
157
+ assertDocumentMatcher(
158
+ "b",
159
+ documentMatchers.bold
160
+ );
161
+ },
162
+
163
+ "reads italic": function() {
164
+ assertDocumentMatcher(
165
+ "i",
166
+ documentMatchers.italic
167
+ );
168
+ },
169
+
170
+ "reads underline": function() {
171
+ assertDocumentMatcher(
172
+ "u",
173
+ documentMatchers.underline
174
+ );
175
+ },
176
+
177
+ "reads strikethrough": function() {
178
+ assertDocumentMatcher(
179
+ "strike",
180
+ documentMatchers.strikethrough
181
+ );
182
+ },
183
+
184
+ "reads smallcaps": function() {
185
+ assertDocumentMatcher(
186
+ "small-caps",
187
+ documentMatchers.smallCaps
188
+ );
189
+ },
190
+
191
+ "reads comment-reference": function() {
192
+ assertDocumentMatcher(
193
+ "comment-reference",
194
+ documentMatchers.commentReference
195
+ );
196
+ },
197
+
198
+ "reads line breaks": function() {
199
+ assertDocumentMatcher(
200
+ "br[type='line']",
201
+ documentMatchers.lineBreak
202
+ );
203
+ },
204
+
205
+ "reads page breaks": function() {
206
+ assertDocumentMatcher(
207
+ "br[type='page']",
208
+ documentMatchers.pageBreak
209
+ );
210
+ },
211
+
212
+ "reads column breaks": function() {
213
+ assertDocumentMatcher(
214
+ "br[type='column']",
215
+ documentMatchers.columnBreak
216
+ );
217
+ }
218
+
219
+ });
220
+
221
+ function assertDocumentMatcher(input, expected) {
222
+ assert.deepEqual(readDocumentMatcher(input), results.success(expected));
223
+ }
224
+
225
+ test("styleReader.read", {
226
+ "document matcher is mapped to HTML path using arrow": function() {
227
+ assertStyleMapping(
228
+ "p => h1",
229
+ {
230
+ from: documentMatchers.paragraph(),
231
+ to: htmlPaths.elements(["h1"])
232
+ }
233
+ );
234
+ },
235
+
236
+ "reads style mapping with no HTML path": function() {
237
+ assertStyleMapping(
238
+ "r =>",
239
+ {
240
+ from: documentMatchers.run(),
241
+ to: htmlPaths.empty
242
+ }
243
+ );
244
+ },
245
+
246
+ "error when not all input is consumed": function() {
247
+ assert.deepEqual(
248
+ readStyle("r => span a"),
249
+ new results.Result(null, [results.warning("Did not understand this style mapping, so ignored it: r => span a\nError was at character number 10: Expected end but got whitespace")])
250
+ );
251
+ }
252
+ });
253
+
254
+ function assertStyleMapping(input, expected) {
255
+ assert.deepEqual(readStyle(input), results.success(expected));
256
+ }
@@ -0,0 +1,71 @@
1
+ var assert = require("assert");
2
+
3
+ var test = require("../test")(module);
4
+ var documentMatchers = require("../../lib/styles/document-matchers");
5
+ var documents = require("../../lib/documents");
6
+ var Paragraph = documents.Paragraph;
7
+
8
+ test("paragraph with no options matches any paragraph", function() {
9
+ var matcher = documentMatchers.paragraph();
10
+ assert.ok(matcher.matches(new Paragraph()));
11
+ assert.ok(matcher.matches(paragraphWithStyle("Heading1", "Heading 1")));
12
+ });
13
+
14
+ test("paragraph style ID only matches paragraphs with that style ID", function() {
15
+ var matcher = documentMatchers.paragraph({styleId: "Heading1"});
16
+ assert.ok(!matcher.matches(new Paragraph()));
17
+ assert.ok(matcher.matches(paragraphWithStyle("Heading1", "Heading 1")));
18
+ assert.ok(!matcher.matches(paragraphWithStyle("Heading2", "Heading 2")));
19
+ });
20
+
21
+ test("paragraph style name only matches paragraphs with that style name", function() {
22
+ var matcher = documentMatchers.paragraph({styleName: documentMatchers.equalTo("Heading 1")});
23
+ assert.ok(!matcher.matches(new Paragraph()));
24
+ assert.ok(matcher.matches(paragraphWithStyle("Heading1", "Heading 1")));
25
+ assert.ok(!matcher.matches(paragraphWithStyle("Heading2", "Heading 2")));
26
+ });
27
+
28
+ test("ordered-list(index) matches an ordered list with specified level index", function() {
29
+ var matcher = documentMatchers.paragraph({list: {isOrdered: true, levelIndex: 1}});
30
+ assert.ok(!matcher.matches(new Paragraph()));
31
+ assert.ok(matcher.matches(new Paragraph([], {numbering: {level: 1, isOrdered: true}})));
32
+ assert.ok(!matcher.matches(new Paragraph([], {numbering: {level: 0, isOrdered: true}})));
33
+ assert.ok(!matcher.matches(new Paragraph([], {numbering: {level: 1, isOrdered: false}})));
34
+ });
35
+
36
+ test("unordered-list(index) matches an unordered list with specified level index", function() {
37
+ var matcher = documentMatchers.paragraph({list: {isOrdered: false, levelIndex: 1}});
38
+ assert.ok(!matcher.matches(new Paragraph()));
39
+ assert.ok(matcher.matches(new Paragraph([], {numbering: {level: 1, isOrdered: false}})));
40
+ assert.ok(!matcher.matches(new Paragraph([], {numbering: {level: 1, isOrdered: true}})));
41
+ });
42
+
43
+ test("matchers for lists with index 0 do not match elements that are not lists", function() {
44
+ var matcher = documentMatchers.paragraph({list: {isOrdered: true, levelIndex: 0}});
45
+ assert.ok(!matcher.matches(new Paragraph()));
46
+ });
47
+
48
+ function paragraphWithStyle(styleId, styleName) {
49
+ return new Paragraph([], {styleId: styleId, styleName: styleName});
50
+ }
51
+
52
+
53
+ test("equalTo matcher is case insensitive", function() {
54
+ var matcher = documentMatchers.equalTo("Heading 1");
55
+ assert.ok(matcher.operator(matcher.operand, "heaDING 1"));
56
+ assert.ok(!matcher.operator(matcher.operand, "heaDING 2"));
57
+ });
58
+
59
+ test("startsWith matches strings with prefix", function() {
60
+ var matcher = documentMatchers.startsWith("Heading");
61
+ assert.ok(matcher.operator(matcher.operand, "Heading"));
62
+ assert.ok(matcher.operator(matcher.operand, "Heading 1"));
63
+ assert.ok(!matcher.operator(matcher.operand, "Custom Heading"));
64
+ assert.ok(!matcher.operator(matcher.operand, "Head"));
65
+ assert.ok(!matcher.operator(matcher.operand, "Header 2"));
66
+ });
67
+
68
+ test("startsWith matcher is case insensitive", function() {
69
+ var matcher = documentMatchers.startsWith("Heading");
70
+ assert.ok(matcher.operator(matcher.operand, "heaDING"));
71
+ });
@@ -0,0 +1,20 @@
1
+ var assert = require("assert");
2
+
3
+ var test = require("../test")(module);
4
+ var htmlPaths = require("../../lib/styles/html-paths");
5
+
6
+
7
+ test("element can match multiple tag names", function() {
8
+ var pathPart = htmlPaths.element(["ul", "ol"]);
9
+ assert.ok(pathPart.matchesElement({tagName: "ul"}));
10
+ assert.ok(pathPart.matchesElement({tagName: "ol"}));
11
+ assert.ok(!pathPart.matchesElement({tagName: "p"}));
12
+ });
13
+
14
+ test("element matches if attributes are the same", function() {
15
+ var pathPart = htmlPaths.element(["p"], {"class": "tip"});
16
+ assert.ok(!pathPart.matchesElement({tagName: "p"}));
17
+ assert.ok(!pathPart.matchesElement({tagName: "p", attributes: {"class": "tip help"}}));
18
+ assert.ok(pathPart.matchesElement({tagName: "p", attributes: {"class": "tip"}}));
19
+ });
20
+
@@ -0,0 +1,104 @@
1
+ var hamjest = require("hamjest");
2
+ var assertThat = hamjest.assertThat;
3
+ var contains = hamjest.contains;
4
+ var hasProperties = hamjest.hasProperties;
5
+
6
+ var tokenise = require("../../../lib/styles/parser/tokeniser").tokenise;
7
+ var test = require("../../test")(module);
8
+
9
+
10
+ test("unknown tokens are tokenised", function() {
11
+ assertTokens("~", [isToken("unrecognisedCharacter", "~")]);
12
+ });
13
+
14
+ test("empty string is tokenised to end of file token", function() {
15
+ assertTokens("", []);
16
+ });
17
+
18
+ test("whitespace is tokenised", function() {
19
+ assertTokens(" \t\t ", [isToken("whitespace")]);
20
+ });
21
+
22
+ test("identifiers are tokenised", function() {
23
+ assertTokens("Overture", [isToken("identifier", "Overture")]);
24
+ });
25
+
26
+ test("integers are tokenised", function() {
27
+ assertTokens("123", [isToken("integer", "123")]);
28
+ });
29
+
30
+ test("strings are tokenised", function() {
31
+ assertTokens("'Tristan'", [isToken("string", "Tristan")]);
32
+ });
33
+
34
+ test("unterminated strings are tokenised", function() {
35
+ assertTokens("'Tristan", [isToken("unterminated-string", "Tristan")]);
36
+ });
37
+
38
+ test("arrows are tokenised", function() {
39
+ assertTokens("=>", [isToken("arrow")]);
40
+ });
41
+
42
+ test("classes are tokenised", function() {
43
+ assertTokens(".overture", [isToken("dot"), isToken("identifier", "overture")]);
44
+ });
45
+
46
+ test("colons are tokenised", function() {
47
+ assertTokens("::", [isToken("colon"), isToken("colon")]);
48
+ });
49
+
50
+ test("greater thans are tokenised", function() {
51
+ assertTokens(">>", [isToken("gt"), isToken("gt")]);
52
+ });
53
+
54
+ test("equals are tokenised", function() {
55
+ assertTokens("==", [isToken("equals"), isToken("equals")]);
56
+ });
57
+
58
+ test("startsWith symbols are tokenised", function() {
59
+ assertTokens("^=^=", [isToken("startsWith"), isToken("startsWith")]);
60
+ });
61
+
62
+ test("open parens are tokenised", function() {
63
+ assertTokens("((", [isToken("open-paren"), isToken("open-paren")]);
64
+ });
65
+
66
+ test("close parens are tokenised", function() {
67
+ assertTokens("))", [isToken("close-paren"), isToken("close-paren")]);
68
+ });
69
+
70
+ test("open square brackets are tokenised", function() {
71
+ assertTokens("[[", [isToken("open-square-bracket"), isToken("open-square-bracket")]);
72
+ });
73
+
74
+ test("close square brackets are tokenised", function() {
75
+ assertTokens("]]", [isToken("close-square-bracket"), isToken("close-square-bracket")]);
76
+ });
77
+
78
+ test("choices are tokenised", function() {
79
+ assertTokens("||", [isToken("choice"), isToken("choice")]);
80
+ });
81
+
82
+ test("can tokenise multiple tokens", function() {
83
+ assertTokens("The Magic Position", [
84
+ isToken("identifier", "The"),
85
+ isToken("whitespace"),
86
+ isToken("identifier", "Magic"),
87
+ isToken("whitespace"),
88
+ isToken("identifier", "Position")
89
+ ]);
90
+ });
91
+
92
+ function assertTokens(input, expectedTokens) {
93
+ assertThat(
94
+ tokenise(input),
95
+ contains.apply(null, expectedTokens.concat([isToken("end", null)]))
96
+ );
97
+ }
98
+
99
+ function isToken(tokenType, value) {
100
+ return hasProperties({
101
+ name: tokenType,
102
+ value: value
103
+ });
104
+ }
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,10 @@
1
+ <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
2
+ <Relationship Id="rId8" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme" Target="theme/theme1.xml" />
3
+ <Relationship Id="rId3" Type="http://schemas.microsoft.com/office/2007/relationships/stylesWithEffects" Target="stylesWithEffects.xml" />
4
+ <Relationship Id="rId7" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable" Target="fontTable.xml" />
5
+ <Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml" />
6
+ <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering" Target="numbering.xml" />
7
+ <Relationship Id="rId6" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" Target="http://www.example.com" TargetMode="External" />
8
+ <Relationship Id="rId5" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettings" Target="webSettings.xml" />
9
+ <Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings" Target="settings.xml" />
10
+ </Relationships>
@@ -0,0 +1,18 @@
1
+ <?xml version="1.0" ?>
2
+ <w:document mc:Ignorable="w14 wp14" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape">
3
+ <w:body>
4
+ <w:p w:rsidR="00E01ECE" w:rsidRDefault="000636A7">
5
+ <w:hyperlink r:id="rId6" w:history="1">
6
+ <w:r>
7
+ <w:t>coconuts</w:t>
8
+ </w:r>
9
+ </w:hyperlink>
10
+ </w:p>
11
+ <w:sectPr w:rsidR="00E01ECE">
12
+ <w:pgSz w:h="16838" w:w="11906"/>
13
+ <w:pgMar w:bottom="1440" w:footer="708" w:gutter="0" w:header="708" w:left="1440" w:right="1440" w:top="1440"/>
14
+ <w:cols w:space="708"/>
15
+ <w:docGrid w:linePitch="360"/>
16
+ </w:sectPr>
17
+ </w:body>
18
+ </w:document>
@@ -0,0 +1,18 @@
1
+ <?xml version="1.0" ?>
2
+ <w:document mc:Ignorable="w14 wp14" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape">
3
+ <w:body>
4
+ <w:p w:rsidR="00E01ECE" w:rsidRDefault="000636A7">
5
+ <w:r>
6
+ <w:t>Hello.</w:t>
7
+ </w:r>
8
+ <w:bookmarkStart w:id="0" w:name="_GoBack"/>
9
+ <w:bookmarkEnd w:id="0"/>
10
+ </w:p>
11
+ <w:sectPr w:rsidR="00E01ECE">
12
+ <w:pgSz w:h="16838" w:w="11906"/>
13
+ <w:pgMar w:bottom="1440" w:footer="708" w:gutter="0" w:header="708" w:left="1440" w:right="1440" w:top="1440"/>
14
+ <w:cols w:space="708"/>
15
+ <w:docGrid w:linePitch="360"/>
16
+ </w:sectPr>
17
+ </w:body>
18
+ </w:document>
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
package/test/test.js ADDED
@@ -0,0 +1,11 @@
1
+ var path = require("path");
2
+
3
+
4
+ var root = path.dirname(__dirname);
5
+
6
+ module.exports = function(testModule) {
7
+ var tests = testModule.exports[path.relative(root, testModule.filename)] = {};
8
+ return function(name, func) {
9
+ tests[name] = func;
10
+ };
11
+ };
@@ -0,0 +1,55 @@
1
+ var path = require("path");
2
+ var fs = require("fs");
3
+ var promises = require("../lib/promises");
4
+ var _ = require("underscore");
5
+
6
+ exports.testPath = testPath;
7
+ exports.testData = testData;
8
+ exports.createFakeDocxFile = createFakeDocxFile;
9
+ exports.createFakeFiles = createFakeFiles;
10
+
11
+
12
+ function testPath(filename) {
13
+ return path.join(__dirname, "test-data", filename);
14
+ }
15
+
16
+ function testData(testDataPath) {
17
+ var fullPath = testPath(testDataPath);
18
+ return promises.nfcall(fs.readFile, fullPath, "utf-8");
19
+ }
20
+
21
+ function createFakeDocxFile(files) {
22
+ function exists(path) {
23
+ return !!files[path];
24
+ }
25
+
26
+ return {
27
+ read: createRead(files),
28
+ exists: exists
29
+ };
30
+ }
31
+
32
+ function createFakeFiles(files) {
33
+ return {
34
+ read: createRead(files)
35
+ };
36
+ }
37
+
38
+ function createRead(files) {
39
+ function read(path, encoding) {
40
+ return promises.when(files[path], function(buffer) {
41
+ if (_.isString(buffer)) {
42
+ buffer = new Buffer(buffer);
43
+ }
44
+
45
+ if (!Buffer.isBuffer(buffer)) {
46
+ return promises.reject(new Error("file was not a buffer"));
47
+ } else if (encoding) {
48
+ return promises.when(buffer.toString(encoding));
49
+ } else {
50
+ return promises.when(buffer);
51
+ }
52
+ });
53
+ }
54
+ return read;
55
+ }