@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.
- package/.eslintrc.json +77 -0
- package/.github/ISSUE_TEMPLATE.md +12 -0
- package/.idea/mammoth.js.iml +12 -0
- package/.idea/modules.xml +8 -0
- package/.idea/vcs.xml +6 -0
- package/.travis.yml +10 -0
- package/LICENSE +22 -0
- package/NEWS +373 -0
- package/README.md +883 -0
- package/bin/mammoth +38 -0
- package/browser/docx/files.js +14 -0
- package/browser/unzip.js +12 -0
- package/lib/document-to-html.js +453 -0
- package/lib/documents.js +238 -0
- package/lib/docx/body-reader.js +636 -0
- package/lib/docx/comments-reader.js +31 -0
- package/lib/docx/content-types-reader.js +58 -0
- package/lib/docx/document-xml-reader.js +26 -0
- package/lib/docx/docx-reader.js +222 -0
- package/lib/docx/files.js +67 -0
- package/lib/docx/notes-reader.js +28 -0
- package/lib/docx/numbering-xml.js +69 -0
- package/lib/docx/office-xml-reader.js +58 -0
- package/lib/docx/relationships-reader.js +43 -0
- package/lib/docx/style-map.js +75 -0
- package/lib/docx/styles-reader.js +70 -0
- package/lib/docx/uris.js +21 -0
- package/lib/html/ast.js +50 -0
- package/lib/html/index.js +41 -0
- package/lib/html/simplify.js +88 -0
- package/lib/images.js +29 -0
- package/lib/index.js +115 -0
- package/lib/main.js +63 -0
- package/lib/options-reader.js +98 -0
- package/lib/promises.js +42 -0
- package/lib/results.js +72 -0
- package/lib/style-reader.js +321 -0
- package/lib/styles/document-matchers.js +74 -0
- package/lib/styles/html-paths.js +81 -0
- package/lib/styles/parser/tokeniser.js +30 -0
- package/lib/transforms.js +61 -0
- package/lib/underline.js +11 -0
- package/lib/unzip.js +22 -0
- package/lib/writers/html-writer.js +160 -0
- package/lib/writers/index.js +14 -0
- package/lib/writers/markdown-writer.js +163 -0
- package/lib/xml/index.js +7 -0
- package/lib/xml/nodes.js +69 -0
- package/lib/xml/reader.js +83 -0
- package/lib/xml/writer.js +61 -0
- package/lib/zipfile.js +77 -0
- package/mammoth.browser.js +32950 -0
- package/mammoth.browser.min.js +18 -0
- package/package.json +65 -0
- package/test/.eslintrc.json +7 -0
- package/test/document-to-html.tests.js +834 -0
- package/test/docx/body-reader.tests.js +1342 -0
- package/test/docx/comments-reader.tests.js +52 -0
- package/test/docx/content-types-reader.tests.js +45 -0
- package/test/docx/document-matchers.js +37 -0
- package/test/docx/docx-reader.tests.js +179 -0
- package/test/docx/files.tests.js +94 -0
- package/test/docx/notes-reader.tests.js +35 -0
- package/test/docx/numbering-xml.tests.js +65 -0
- package/test/docx/office-xml-reader.tests.js +24 -0
- package/test/docx/relationships-reader.tests.js +65 -0
- package/test/docx/style-map.tests.js +112 -0
- package/test/docx/styles-reader.tests.js +133 -0
- package/test/docx/uris.tests.js +22 -0
- package/test/html/simplify.tests.js +134 -0
- package/test/html/write.tests.js +42 -0
- package/test/images.tests.js +34 -0
- package/test/main.tests.js +89 -0
- package/test/mammoth.tests.js +429 -0
- package/test/mocha.opts +1 -0
- package/test/options-reader.tests.js +63 -0
- package/test/results.tests.js +15 -0
- package/test/style-reader.tests.js +256 -0
- package/test/styles/document-matchers.tests.js +71 -0
- package/test/styles/html-paths.tests.js +20 -0
- package/test/styles/parser/tokeniser.tests.js +104 -0
- package/test/test-data/comments.docx +0 -0
- package/test/test-data/embedded-style-map.docx +0 -0
- package/test/test-data/empty.docx +0 -0
- package/test/test-data/empty.zip +0 -0
- package/test/test-data/endnotes.docx +0 -0
- package/test/test-data/external-picture.docx +0 -0
- package/test/test-data/footnote-hyperlink.docx +0 -0
- package/test/test-data/footnotes.docx +0 -0
- package/test/test-data/hello.zip +0 -0
- package/test/test-data/hyperlinks/word/_rels/document.xml.rels +10 -0
- package/test/test-data/hyperlinks/word/document.xml +18 -0
- package/test/test-data/simple/word/document.xml +18 -0
- package/test/test-data/simple-list.docx +0 -0
- package/test/test-data/single-paragraph.docx +0 -0
- package/test/test-data/strikethrough.docx +0 -0
- package/test/test-data/tables.docx +0 -0
- package/test/test-data/text-box.docx +0 -0
- package/test/test-data/tiny-picture-target-base-relative.docx +0 -0
- package/test/test-data/tiny-picture.docx +0 -0
- package/test/test-data/tiny-picture.png +0 -0
- package/test/test-data/underline.docx +0 -0
- package/test/test-data/utf8-bom.docx +0 -0
- package/test/test.js +11 -0
- package/test/testing.js +55 -0
- package/test/transforms.tests.js +125 -0
- package/test/unzip.tests.js +38 -0
- package/test/writers/html-writer.tests.js +133 -0
- package/test/writers/markdown-writer.tests.js +304 -0
- package/test/xml/reader.tests.js +85 -0
- package/test/xml/writer.tests.js +81 -0
- 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
|
|
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
|
|
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
|
+
};
|
package/test/testing.js
ADDED
|
@@ -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
|
+
}
|