extwee 1.6.2 → 2.0.0
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 +25 -24
- package/.github/workflows/nodejs.yml +24 -24
- package/.travis.yml +13 -13
- package/CODE_OF_CONDUCT.md +82 -0
- package/LICENSE +21 -21
- package/README.md +36 -205
- package/SECURITY.md +12 -0
- package/babel.config.json +22 -0
- package/bin/extwee.js +49 -0
- package/index.js +31 -26
- package/package.json +60 -45
- package/src/FileReader.js +33 -35
- package/src/HTMLParser.js +343 -206
- package/src/HTMLWriter.js +196 -172
- package/src/Passage.js +202 -24
- package/src/Story.js +461 -122
- package/src/StoryFormat.js +300 -28
- package/src/StoryFormatParser.js +142 -59
- package/src/TweeParser.js +166 -207
- package/src/TweeWriter.js +98 -96
- package/story-formats/chapbook-1.2.0/format.js +1 -0
- package/story-formats/chapbook-1.2.0/logo.svg +1 -0
- package/story-formats/harlowe-1.2.4/format.js +1 -0
- package/story-formats/harlowe-1.2.4/icon.svg +78 -0
- package/story-formats/harlowe-2.1.0/format.js +2 -0
- package/story-formats/harlowe-2.1.0/icon.svg +78 -0
- package/story-formats/harlowe-3.1.0/format.js +3 -0
- package/story-formats/harlowe-3.1.0/icon.svg +78 -0
- package/story-formats/paperthin-1.0.0/format.js +1 -0
- package/story-formats/paperthin-1.0.0/icon.svg +5 -0
- package/story-formats/snowman-1.4.0/format.js +1 -0
- package/story-formats/snowman-1.4.0/icon.svg +436 -0
- package/story-formats/snowman-2.0.2/format.js +1 -0
- package/story-formats/snowman-2.0.2/icon.svg +436 -0
- package/story-formats/sugarcube-1.0.35/LICENSE +23 -0
- package/story-formats/sugarcube-1.0.35/format.js +1 -0
- package/story-formats/sugarcube-1.0.35/icon.svg +56 -0
- package/story-formats/sugarcube-2.31.1/LICENSE +22 -0
- package/story-formats/sugarcube-2.31.1/format.js +1 -0
- package/story-formats/sugarcube-2.31.1/icon.svg +56 -0
- package/test/{HTMLWriter/example7.twee → CLI/example6.twee} +16 -16
- package/test/CLI/harlowe.js +3 -0
- package/test/CLI/input.html +47 -0
- package/test/CLI/test.twee +18 -0
- package/test/CLI/test2.html +47 -0
- package/test/CLI/tweeExample.twee +17 -0
- package/test/CLI/twineExample.html +15 -0
- package/test/CLI.test.js +30 -0
- package/test/FileReader.test.js +14 -0
- package/test/HTMLParser/Example1.html +53 -0
- package/test/HTMLParser/Tags.html +15 -0
- package/test/HTMLParser/lyingStartnode.html +15 -0
- package/test/HTMLParser/lyingTagColors.html +48 -0
- package/test/HTMLParser/missingCreator.html +11 -0
- package/test/HTMLParser/missingCreatorVersion.html +11 -0
- package/test/HTMLParser/missingFormat.html +11 -0
- package/test/HTMLParser/missingFormatVersion.html +11 -0
- package/test/HTMLParser/missingIFID.html +11 -0
- package/test/HTMLParser/missingName.html +33 -0
- package/test/HTMLParser/missingPID.html +15 -0
- package/test/HTMLParser/missingPassageName.html +15 -0
- package/test/HTMLParser/missingPassageTags.html +15 -0
- package/test/HTMLParser/missingPosition.html +15 -0
- package/test/HTMLParser/missingScript.html +14 -0
- package/test/HTMLParser/missingSize.html +35 -0
- package/test/HTMLParser/missingStartnode.html +11 -0
- package/test/HTMLParser/missingStyle.html +14 -0
- package/test/HTMLParser/missingZoom.html +11 -0
- package/test/HTMLParser/tagColors.html +31 -0
- package/test/HTMLParser/twineExample.html +15 -46
- package/test/HTMLParser/twineExample2.html +15 -0
- package/test/HTMLParser/twineExample3.html +15 -0
- package/test/HTMLParser.test.js +177 -0
- package/test/HTMLWriter/TestTags.html +42 -0
- package/test/HTMLWriter/{test10.html → creator.html} +8 -5
- package/test/HTMLWriter/example6.twee +16 -16
- package/test/HTMLWriter/{example.twee → missingStoryTitle.twee} +29 -29
- package/test/HTMLWriter/test11.html +123 -0
- package/test/HTMLWriter/test2.html +15 -12
- package/test/HTMLWriter/test3.html +7 -13
- package/test/HTMLWriter/test4.html +8 -5
- package/test/HTMLWriter/test6.html +7 -5
- package/test/HTMLWriter.test.js +279 -0
- package/test/Passage.test.js +104 -0
- package/test/Roundtrip/Example1.html +64 -0
- package/test/Roundtrip/example1.twee +21 -0
- package/test/Roundtrip/example2.twee +18 -0
- package/test/Roundtrip/harlowe.js +3 -0
- package/test/Roundtrip/round.html +50 -0
- package/test/Roundtrip.test.js +48 -0
- package/test/Story/startmeta.twee +29 -29
- package/test/Story/test.twee +25 -25
- package/test/Story.test.js +282 -0
- package/test/StoryFormat.test.js +152 -0
- package/test/StoryFormatParser/example.js +3 -0
- package/test/StoryFormatParser/{test2.js → example2.js} +3 -3
- package/test/StoryFormatParser/format_doublename.js +1 -0
- package/test/StoryFormatParser/harlowe.js +2 -2
- package/test/StoryFormatParser/missingAuthor.js +1 -0
- package/test/StoryFormatParser/missingDescription.js +1 -0
- package/test/StoryFormatParser/missingImage.js +1 -0
- package/test/StoryFormatParser/missingLicense.js +1 -0
- package/test/StoryFormatParser/missingName.js +1 -0
- package/test/StoryFormatParser/missingProofing.js +1 -0
- package/test/StoryFormatParser/missingSource.js +1 -0
- package/test/StoryFormatParser/missingURL.js +1 -0
- package/test/StoryFormatParser/missingVersion.js +1 -0
- package/test/StoryFormatParser/versionWrong.js +1 -0
- package/test/StoryFormatParser.test.js +91 -0
- package/test/TweeParser/emptytags.twee +2 -2
- package/test/TweeParser/example.twee +32 -29
- package/test/TweeParser/missing.twee +19 -0
- package/test/{HTMLWriter/example5.twee → TweeParser/multipleScriptPassages.twee} +19 -13
- package/test/{HTMLWriter/example4.twee → TweeParser/multipleStyleTag.twee} +19 -13
- package/test/TweeParser/multipletags.twee +10 -2
- package/test/TweeParser/noTitle.twee +2 -0
- package/test/TweeParser/notes.twee +16 -32
- package/test/TweeParser/pasagemetadataerror.twee +2 -2
- package/test/{HTMLWriter/example2.twee → TweeParser/scriptPassage.twee} +16 -13
- package/test/TweeParser/singletag.twee +13 -2
- package/test/TweeParser/startMetadata.twee +14 -0
- package/test/TweeParser/storydataerror.twee +25 -25
- package/test/{HTMLWriter/example3.twee → TweeParser/stylePassage.twee} +16 -13
- package/test/TweeParser/test.twee +25 -25
- package/test/TweeParser.test.js +79 -0
- package/test/TweeWriter/test1.twee +14 -9
- package/test/TweeWriter/test3.twee +7 -10
- package/test/TweeWriter/test4.twee +14 -0
- package/test/TweeWriter/test5.twee +20 -0
- package/test/TweeWriter.test.js +82 -0
- package/main.js +0 -106
- package/src/DirectoryReader.js +0 -114
- package/src/DirectoryWatcher.js +0 -87
- package/test/DirectoryReader/css/test.css +0 -3
- package/test/DirectoryReader1/js/Site.js +0 -1
- package/test/DirectoryReader2/error.js +0 -1
- package/test/DirectoryReader2/example.css +0 -3
- package/test/DirectoryReader2/index.twee +0 -6
- package/test/DirectoryReader3/twee/index.twee +0 -6
- package/test/DirectoryWatcher/example.txt +0 -0
- package/test/DirectoryWatcher/test.txt +0 -0
- package/test/DirectoryWatcher/test1.txt +0 -0
- package/test/HTMLWriter/test5.html +0 -48
- package/test/HTMLWriter/test7.html +0 -48
- package/test/HTMLWriter/test8.html +0 -48
- package/test/HTMLWriter/test9.html +0 -48
- package/test/StoryFormatParser/test.js +0 -2
- package/test/TweeParser/test.twee3 +0 -11
- package/test/TweeWriter/metatest.twee +0 -12
- package/test/TweeWriter/test2.twee +0 -15
- package/test/test.js +0 -736
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<title>twineExample</title>
|
|
6
|
+
</head>
|
|
7
|
+
<body>
|
|
8
|
+
<tw-story></tw-story>
|
|
9
|
+
<tw-storydata name="twineExample" startnode="1" creator="Twine" creator-version="2.2.1" ifid="2B68ECD6-348F-4CF5-96F8-549A512A8128" zoom="1" format="Harlowe" format-version="2.1.0" options="" hidden><style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css">html{font-size: 1.2em;}</style><script role="script" id="twine-user-script" type="text/twine-javascript"></script><tw-passagedata pid="1" name="Start" tags="" position="102,104" size="100,100">[[Another passage]]
|
|
10
|
+
|
|
11
|
+
[[A third passage]]</tw-passagedata><tw-passagedata pid="2" name="Another passage" tags="" position="353,60" size="100,100">[[A fourth passage]]
|
|
12
|
+
|
|
13
|
+
[[A third passage]] </tw-passagedata><tw-passagedata pid="3" name="A third passage" tags="" position="350,288" size="100,100">[[Start]]</tw-passagedata><tw-passagedata pid="4" name="A fourth passage" tags="" position="587,197" size="100,100">[[A fifth passage]]</tw-passagedata><tw-passagedata pid="5" name="A fifth passage" tags="" position="800,306" size="100,100">Double-click this passage to edit it.</tw-passagedata></tw-storydata>
|
|
14
|
+
</body>
|
|
15
|
+
</html>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<title>twineExample</title>
|
|
6
|
+
</head>
|
|
7
|
+
<body>
|
|
8
|
+
<tw-story></tw-story>
|
|
9
|
+
<tw-storydata name="twineExample" startnode="1" creator="Twine" creator-version="2.2.1" ifid="2B68ECD6-348F-4CF5-96F8-549A512A8128" zoom="1" format="Harlowe" format-version="2.1.0" options="" hidden><style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css">html{font-size: 1.2em;}</style><script role="script" id="twine-user-script" type="text/twine-javascript">window.test = {};</script><tw-passagedata pid="1" name="Start" tags="" position="102,104" size="100,100">[[Another passage]]
|
|
10
|
+
|
|
11
|
+
[[A third passage]]</tw-passagedata><tw-passagedata pid="2" name="Another passage" tags="" position="353,60" size="100,100">[[A fourth passage]]
|
|
12
|
+
|
|
13
|
+
[[A third passage]] </tw-passagedata><tw-passagedata pid="3" name="A third passage" tags="" position="350,288" size="100,100">[[Start]]</tw-passagedata><tw-passagedata pid="4" name="A fourth passage" tags="" position="587,197" size="100,100">[[A fifth passage]]</tw-passagedata><tw-passagedata pid="5" name="A fifth passage" tags="" position="800,306" size="100,100">Double-click this passage to edit it.</tw-passagedata></tw-storydata>
|
|
14
|
+
</body>
|
|
15
|
+
</html>
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import FileReader from '../src/FileReader.js';
|
|
2
|
+
import HTMLParser from '../src/HTMLParser.js';
|
|
3
|
+
|
|
4
|
+
// Pull the name and version of this project from package.json.
|
|
5
|
+
// These are used as the 'creator' and 'creator-version'.
|
|
6
|
+
const { version } = JSON.parse(FileReader.read('package.json'));
|
|
7
|
+
|
|
8
|
+
describe('HTMLParser', function () {
|
|
9
|
+
describe('#parse()', function () {
|
|
10
|
+
test('Should throw error if content is not Twine-2 style HTML', function () {
|
|
11
|
+
expect(() => { HTMLParser.parse(''); }).toThrow();
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test('Should be able to parse Twine 2 HTML for story name', function () {
|
|
15
|
+
const fr = FileReader.read('test/HTMLParser/twineExample.html');
|
|
16
|
+
const story = HTMLParser.parse(fr);
|
|
17
|
+
const storyTitle = story.getPassageByName('StoryTitle');
|
|
18
|
+
expect(storyTitle.text).toBe('twineExample');
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test('Should be able to parse Twine 2 HTML for correct number of passages', function () {
|
|
22
|
+
const fr = FileReader.read('test/HTMLParser/twineExample.html');
|
|
23
|
+
const tp = HTMLParser.parse(fr);
|
|
24
|
+
expect(tp.size()).toBe(6);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test('Should be able to correctly parse passage tags', function () {
|
|
28
|
+
const fr = FileReader.read('test/HTMLParser/Tags.html');
|
|
29
|
+
const story = HTMLParser.parse(fr);
|
|
30
|
+
const p = story.getPassageByName('Untitled Passage');
|
|
31
|
+
expect(p.tags).toHaveLength(2);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test('Should set a missing name to Untitled', function () {
|
|
35
|
+
const fr = FileReader.read('test/HTMLParser/missingName.html');
|
|
36
|
+
const story = HTMLParser.parse(fr);
|
|
37
|
+
const p = story.getPassageByName('StoryTitle');
|
|
38
|
+
expect(p.text).toBe('Untitled');
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test('Should set a missing IFID to an empty string', function () {
|
|
42
|
+
const fr = FileReader.read('test/HTMLParser/missingIFID.html');
|
|
43
|
+
const tp = HTMLParser.parse(fr);
|
|
44
|
+
expect(tp.IFID).toBe('');
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test('Should have Extwee for creator when missing', function () {
|
|
48
|
+
const fr = FileReader.read('test/HTMLParser/missingCreator.html');
|
|
49
|
+
const tp = HTMLParser.parse(fr);
|
|
50
|
+
expect(tp.creator).toBe('extwee');
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
test('Should have correct for creatorVersion when missing', function () {
|
|
54
|
+
const fr = FileReader.read('test/HTMLParser/missingCreatorVersion.html');
|
|
55
|
+
const tp = HTMLParser.parse(fr);
|
|
56
|
+
expect(tp.creatorVersion).toBe(version);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test('Should have empty string as format when missing', function () {
|
|
60
|
+
const fr = FileReader.read('test/HTMLParser/missingFormat.html');
|
|
61
|
+
const tp = HTMLParser.parse(fr);
|
|
62
|
+
expect(tp.format).toBe('');
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
test('Should have empty string as formatVersion when missing', function () {
|
|
66
|
+
const fr = FileReader.read('test/HTMLParser/missingFormatVersion.html');
|
|
67
|
+
const tp = HTMLParser.parse(fr);
|
|
68
|
+
expect(tp.formatVersion).toBe('');
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
test('Should have empty string as zoom when missing', function () {
|
|
72
|
+
const fr = FileReader.read('test/HTMLParser/missingZoom.html');
|
|
73
|
+
const tp = HTMLParser.parse(fr);
|
|
74
|
+
expect(tp.zoom).toBe(0);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
test('Should not have position if passage does not', function () {
|
|
78
|
+
const fr = FileReader.read('test/HTMLParser/missingPosition.html');
|
|
79
|
+
const story = HTMLParser.parse(fr);
|
|
80
|
+
const p = story.getPassageByName('Untitled Passage');
|
|
81
|
+
expect(Object.prototype.hasOwnProperty.call(p.metadata, 'position')).toBe(false);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
test('Should not have size if passage does not', function () {
|
|
85
|
+
const fr = FileReader.read('test/HTMLParser/missingSize.html');
|
|
86
|
+
const story = HTMLParser.parse(fr);
|
|
87
|
+
const p = story.getPassageByName('Untitled Passage');
|
|
88
|
+
expect(Object.prototype.hasOwnProperty.call(p.metadata, 'size')).toBe(false);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
test('Should have empty array as tags if tags is missing', function () {
|
|
92
|
+
const fr = FileReader.read('test/HTMLParser/missingPassageTags.html');
|
|
93
|
+
const story = HTMLParser.parse(fr);
|
|
94
|
+
const p = story.getPassageByName('Untitled Passage');
|
|
95
|
+
expect(p.tags).toHaveLength(0);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
test('Should not have stylesheet tag if no passages exist with it', function () {
|
|
99
|
+
const fr = FileReader.read('test/HTMLParser/missingStyle.html');
|
|
100
|
+
const story = HTMLParser.parse(fr);
|
|
101
|
+
const passages = story.getPassagesByTag('stylesheet');
|
|
102
|
+
expect(passages.length).toBe(0);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
test('Should not have script tag if no passages exist with it', function () {
|
|
106
|
+
const fr = FileReader.read('test/HTMLParser/missingScript.html');
|
|
107
|
+
const story = HTMLParser.parse(fr);
|
|
108
|
+
const passages = story.getPassagesByTag('script');
|
|
109
|
+
expect(passages.length).toBe(0);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
test('Should have script and style tags normally', function () {
|
|
113
|
+
const fr = FileReader.read('test/HTMLParser/Example1.html');
|
|
114
|
+
const story = HTMLParser.parse(fr);
|
|
115
|
+
const scriptPassages = story.getPassagesByTag('script');
|
|
116
|
+
const stylesheetPassages = story.getPassagesByTag('stylesheet');
|
|
117
|
+
expect(scriptPassages.length).toBe(1);
|
|
118
|
+
expect(stylesheetPassages.length).toBe(1);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
test('Should not have start property if startNode does not exist when parsed', function () {
|
|
122
|
+
const fr = FileReader.read('test/HTMLParser/missingStartnode.html');
|
|
123
|
+
const story = HTMLParser.parse(fr);
|
|
124
|
+
expect(story.start).toBe('');
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
test('Should not add passages without names', function () {
|
|
128
|
+
const fr = FileReader.read('test/HTMLParser/missingPassageName.html');
|
|
129
|
+
const story = HTMLParser.parse(fr);
|
|
130
|
+
// There is only one passage, StoryTitle
|
|
131
|
+
expect(story.size()).toBe(1);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
test('Should not add passages without PID', function () {
|
|
135
|
+
const fr = FileReader.read('test/HTMLParser/missingPID.html');
|
|
136
|
+
const story = HTMLParser.parse(fr);
|
|
137
|
+
// There is only one passage, StoryTitle
|
|
138
|
+
expect(story.size()).toBe(1);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
test('Parse tag colors', function () {
|
|
142
|
+
const fr = FileReader.read('test/HTMLParser/tagColors.html');
|
|
143
|
+
const story = HTMLParser.parse(fr);
|
|
144
|
+
// Test for tag colors
|
|
145
|
+
const tagColors = story.tagColors;
|
|
146
|
+
expect(tagColors.a).toBe('red');
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
test('Will not set start if startnode is missing', function () {
|
|
150
|
+
const fr = FileReader.read('test/HTMLParser/missingStartnode.html');
|
|
151
|
+
const story = HTMLParser.parse(fr);
|
|
152
|
+
// Test for default start
|
|
153
|
+
expect(story.start).toBe('');
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
test('Throw error when startnode has PID that does not exist', function () {
|
|
157
|
+
const fr = FileReader.read('test/HTMLParser/lyingStartnode.html');
|
|
158
|
+
expect(() => {
|
|
159
|
+
HTMLParser.parse(fr);
|
|
160
|
+
}).toThrow();
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
test('Do not update name and color if those attributes do not exist', function () {
|
|
164
|
+
const fr = FileReader.read('test/HTMLParser/lyingTagColors.html');
|
|
165
|
+
const story = HTMLParser.parse(fr);
|
|
166
|
+
const tagColorProperties = Object.keys(story.tagColors).length;
|
|
167
|
+
expect(tagColorProperties).toBe(0);
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
describe('#escapeMetacharacters()', function () {
|
|
172
|
+
test('Should escape metacharacters', function () {
|
|
173
|
+
/* eslint no-useless-escape: "off" */
|
|
174
|
+
expect(HTMLParser.escapeMetacharacters('\\\{\\\}\\\[\\\]\\\\')).toBe('\\\\{\\\\}\\\\[\\\\]\\\\');
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
});
|