extwee 2.0.5 → 2.0.6
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/bin/extwee.js +1 -1
- package/package.json +4 -4
- package/src/HTMLParser.js +2 -0
- package/src/HTMLWriter.js +2 -2
- package/src/Story.js +40 -6
- package/src/TweeWriter.js +23 -0
- package/test/CLI/test2.html +1 -3
- package/test/CLI.test.js +6 -6
- package/test/FileReader.test.js +4 -4
- package/test/HTMLParser/twineExample.html +11 -3
- package/test/HTMLParser.test.js +31 -31
- package/test/HTMLWriter/creator.html +1 -2
- package/test/HTMLWriter/test11.html +1 -3
- package/test/HTMLWriter/test2.html +0 -3
- package/test/HTMLWriter/test3.html +0 -1
- package/test/HTMLWriter/test4.html +1 -2
- package/test/HTMLWriter/test6.html +1 -2
- package/test/HTMLWriter.test.js +1 -3
- package/test/Passage.test.js +14 -14
- package/test/Roundtrip/example4.twee +27 -0
- package/test/Roundtrip/round.html +1 -4
- package/test/Roundtrip.test.js +2 -2
- package/test/Story.test.js +74 -20
- package/test/StoryFormat.test.js +30 -30
- package/test/StoryFormatParser.test.js +16 -16
- package/test/TweeWriter/test1.twee +1 -1
- package/test/TweeWriter/test3.twee +3 -3
- package/test/TweeWriter/test5.twee +1 -1
- package/test/TweeWriter/test6.twee +15 -0
- package/test/TweeWriter/test7.twee +15 -0
- package/test/TweeWriter.test.js +25 -3
package/bin/extwee.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "extwee",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.6",
|
|
4
4
|
"description": "A Twee 3 compiler written in JS.",
|
|
5
5
|
"author": "Dan Cox",
|
|
6
6
|
"main": "index.js",
|
|
@@ -22,17 +22,17 @@
|
|
|
22
22
|
"license": "MIT",
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"commander": "^9.3.0",
|
|
25
|
-
"node-html-parser": "^
|
|
25
|
+
"node-html-parser": "^5.3.3",
|
|
26
26
|
"semver": "^7.3.7",
|
|
27
27
|
"uuid": "^8.3.2"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@babel/cli": "^7.17.10",
|
|
31
|
-
"@babel/core": "^7.18.
|
|
31
|
+
"@babel/core": "^7.18.5",
|
|
32
32
|
"@babel/eslint-parser": "^7.12.1",
|
|
33
33
|
"@babel/eslint-plugin": "^7.12.1",
|
|
34
34
|
"@babel/plugin-proposal-class-properties": "^7.12.1",
|
|
35
|
-
"@babel/plugin-transform-runtime": "^7.
|
|
35
|
+
"@babel/plugin-transform-runtime": "^7.18.5",
|
|
36
36
|
"@babel/preset-env": "^7.18.2",
|
|
37
37
|
"babel-loader": "^8.2.2",
|
|
38
38
|
"core-js": "^3.22.8",
|
package/src/HTMLParser.js
CHANGED
|
@@ -51,6 +51,8 @@ export default class HTMLParser {
|
|
|
51
51
|
if (Object.prototype.hasOwnProperty.call(storyData.attributes, 'name')) {
|
|
52
52
|
// Create StoryTitle passage based on name
|
|
53
53
|
story.addPassage(new Passage('StoryTitle', storyData.attributes.name));
|
|
54
|
+
// Set the story name
|
|
55
|
+
story.name = storyData.attributes.name;
|
|
54
56
|
} else {
|
|
55
57
|
// Name is a required filed. Warn user.
|
|
56
58
|
console.warn('Twine 2 HTML must have a name!');
|
package/src/HTMLWriter.js
CHANGED
|
@@ -107,7 +107,7 @@ export default class HTMLWriter {
|
|
|
107
107
|
// Add text of passages
|
|
108
108
|
storyData += passage.text;
|
|
109
109
|
// Remove from story
|
|
110
|
-
story.
|
|
110
|
+
story.removePassageByName(passage.name);
|
|
111
111
|
});
|
|
112
112
|
|
|
113
113
|
// Close the STYLE
|
|
@@ -124,7 +124,7 @@ export default class HTMLWriter {
|
|
|
124
124
|
// Add text of passages
|
|
125
125
|
storyData += passage.text;
|
|
126
126
|
// Remove from story
|
|
127
|
-
story.
|
|
127
|
+
story.removePassageByName(passage.name);
|
|
128
128
|
});
|
|
129
129
|
|
|
130
130
|
// Close SCRIPT
|
package/src/Story.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import Passage from './Passage.js';
|
|
2
2
|
|
|
3
3
|
const name = 'extwee';
|
|
4
|
-
const version = '2.0.
|
|
4
|
+
const version = '2.0.6';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @class Story
|
|
@@ -369,7 +369,7 @@ export default class Story {
|
|
|
369
369
|
}
|
|
370
370
|
|
|
371
371
|
// Test for default value.
|
|
372
|
-
// (This might occur if using Story
|
|
372
|
+
// (This might occur if using Story directly
|
|
373
373
|
// outside of using HTMLParser or TweeParser.)
|
|
374
374
|
if (p.pid === -1) {
|
|
375
375
|
// Set the internal counter.
|
|
@@ -395,11 +395,11 @@ export default class Story {
|
|
|
395
395
|
* Remove a passage from the story by name
|
|
396
396
|
*
|
|
397
397
|
* @public
|
|
398
|
-
* @function
|
|
398
|
+
* @function removePassageByName
|
|
399
399
|
* @memberof Story
|
|
400
400
|
* @param {string} name - Passage name to remove
|
|
401
401
|
*/
|
|
402
|
-
|
|
402
|
+
removePassageByName (name) {
|
|
403
403
|
this.#_passages = this.#_passages.filter(passage => passage.name !== name);
|
|
404
404
|
}
|
|
405
405
|
|
|
@@ -454,7 +454,8 @@ export default class Story {
|
|
|
454
454
|
|
|
455
455
|
/**
|
|
456
456
|
* Size (number of passages).
|
|
457
|
-
* Does not include StoryAuthor
|
|
457
|
+
* Does not include StoryAuthor or StoryTitle.
|
|
458
|
+
* Does not include passages with 'script' or 'stylesheet' tags.
|
|
458
459
|
*
|
|
459
460
|
* @public
|
|
460
461
|
* @function size
|
|
@@ -462,7 +463,26 @@ export default class Story {
|
|
|
462
463
|
* @returns {number} Return number of passages
|
|
463
464
|
*/
|
|
464
465
|
size () {
|
|
465
|
-
|
|
466
|
+
let count = 0;
|
|
467
|
+
this.#_passages.forEach((passage) => {
|
|
468
|
+
// Exclude StoryTitle
|
|
469
|
+
if (passage.name === 'StoryTitle') {
|
|
470
|
+
return;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
// Exclude if 'script' tags exists
|
|
474
|
+
if (passage.tags.includes('script')) {
|
|
475
|
+
return;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
// Exclude if 'stylesheet' exists
|
|
479
|
+
if (passage.tags.includes('stylesheet')) {
|
|
480
|
+
return;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
count++;
|
|
484
|
+
});
|
|
485
|
+
return count;
|
|
466
486
|
}
|
|
467
487
|
|
|
468
488
|
/**
|
|
@@ -482,6 +502,20 @@ export default class Story {
|
|
|
482
502
|
|
|
483
503
|
// Use internal forEach
|
|
484
504
|
this.#_passages.forEach((element, index) => {
|
|
505
|
+
// Exclude StoryTitle
|
|
506
|
+
if (element.name === 'StoryTitle') {
|
|
507
|
+
return;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
// Exclude if 'script' tags exists
|
|
511
|
+
if (element.tags.includes('script')) {
|
|
512
|
+
return;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
// Exclude if 'stylesheet' exists
|
|
516
|
+
if (element.tags.includes('stylesheet')) {
|
|
517
|
+
return;
|
|
518
|
+
}
|
|
485
519
|
// Call callback function with element and index
|
|
486
520
|
callback(element, index);
|
|
487
521
|
});
|
package/src/TweeWriter.js
CHANGED
|
@@ -81,12 +81,35 @@ export default class TweeWriter {
|
|
|
81
81
|
// Add two newlines.
|
|
82
82
|
outputContents += '\n\n';
|
|
83
83
|
|
|
84
|
+
// Look for StoryTitle
|
|
85
|
+
const storyTitlePassage = story.getPassageByName('StoryTitle');
|
|
86
|
+
|
|
87
|
+
// Does it exist?
|
|
88
|
+
if (storyTitlePassage !== null) {
|
|
89
|
+
// Append StoryTitle content
|
|
90
|
+
outputContents += storyTitlePassage.toString();
|
|
91
|
+
}
|
|
92
|
+
|
|
84
93
|
// For each passage, append it to the output.
|
|
85
94
|
story.forEach((passage) => {
|
|
86
95
|
// For each passage, append it to the output.
|
|
87
96
|
outputContents += passage.toString();
|
|
88
97
|
});
|
|
89
98
|
|
|
99
|
+
// Look for 'script' passages
|
|
100
|
+
const scriptPassages = story.getPassagesByTag('script');
|
|
101
|
+
// For each 'script', add it back
|
|
102
|
+
scriptPassages.forEach(passage => {
|
|
103
|
+
outputContents += passage.toString();
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// Look for 'stylesheet' passages
|
|
107
|
+
const stylesheetPassages = story.getPassagesByTag('stylesheet');
|
|
108
|
+
// For each 'stylesheet', add it back
|
|
109
|
+
stylesheetPassages.forEach(passage => {
|
|
110
|
+
outputContents += passage.toString();
|
|
111
|
+
});
|
|
112
|
+
|
|
90
113
|
try {
|
|
91
114
|
// Try to write
|
|
92
115
|
fs.writeFileSync(file, outputContents);
|
package/test/CLI/test2.html
CHANGED
|
@@ -11,12 +11,10 @@
|
|
|
11
11
|
|
|
12
12
|
<tw-story></tw-story>
|
|
13
13
|
|
|
14
|
-
<tw-storydata name="twineExample" startnode="2" creator="extwee" creator-version="2.0.
|
|
14
|
+
<tw-storydata name="twineExample" startnode="2" creator="extwee" creator-version="2.0.6" ifid="2B68ECD6-348F-4CF5-96F8-549A512A8128" zoom="0" format="Harlowe" format-version="3.0.2" options hidden>
|
|
15
15
|
<style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css">body {background-color: green;}</style>
|
|
16
16
|
<script role="script" id="twine-user-script" type="text/twine-javascript"></script>
|
|
17
|
-
<tw-passagedata pid="1" name="StoryTitle">twineExample</tw-passagedata>
|
|
18
17
|
<tw-passagedata pid="2" name="Start" tags="tag tags" position="200,200" size="100,100" >Content</tw-passagedata>
|
|
19
|
-
<tw-passagedata pid="3" name="Style1" tags="stylesheet" >body {background-color: green;}</tw-passagedata>
|
|
20
18
|
</tw-storydata>
|
|
21
19
|
|
|
22
20
|
<script title="Twine engine code" data-main="harlowe">"use strict";function _defineProperty(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function _toConsumableArray(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t<e.length;t++)n[t]=e[t];return n}return Array.from(e)}var _slicedToArray=function(){function e(e,t){var n=[],r=!0,i=!1,o=void 0;try{for(var a,s=e[Symbol.iterator]();!(r=(a=s.next()).done)&&(n.push(a.value),!t||n.length!==t);r=!0);}catch(e){i=!0,o=e}finally{try{!r&&s.return&&s.return()}finally{if(i)throw o}}return n}return function(t,n){if(Array.isArray(t))return t;if(Symbol.iterator in Object(t))return e(t,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};!function(){/**
|
package/test/CLI.test.js
CHANGED
|
@@ -6,23 +6,23 @@ import shell from 'shelljs';
|
|
|
6
6
|
const currentPath = shell.pwd().stdout;
|
|
7
7
|
const testFilePath = currentPath + '/test/CLI';
|
|
8
8
|
|
|
9
|
-
describe('CLI',
|
|
9
|
+
describe('CLI', () => {
|
|
10
10
|
// Remove the test files, if they exist
|
|
11
|
-
beforeAll(
|
|
11
|
+
beforeAll(() => {
|
|
12
12
|
shell.rm(`${testFilePath}/test.*`);
|
|
13
13
|
});
|
|
14
14
|
|
|
15
15
|
// Test generating Twee files
|
|
16
|
-
describe('Decompile',
|
|
17
|
-
|
|
16
|
+
describe('Decompile', () => {
|
|
17
|
+
it('Decompile: HTML into Twee', () => {
|
|
18
18
|
shell.exec(`node ${currentPath}/bin/extwee.js -d -i ${testFilePath}/input.html -o ${testFilePath}/test.twee`);
|
|
19
19
|
expect(shell.test('-e', `${testFilePath}/test.twee`)).toBe(true);
|
|
20
20
|
});
|
|
21
21
|
});
|
|
22
22
|
|
|
23
23
|
// Test generating HTML files
|
|
24
|
-
describe('Compile',
|
|
25
|
-
|
|
24
|
+
describe('Compile', () => {
|
|
25
|
+
it('Compile: Twee + StoryFormat into Twee', () => {
|
|
26
26
|
shell.exec(`node ${currentPath}/bin/extwee.js -c -i ${testFilePath}/example6.twee -s ${testFilePath}/harlowe.js -o ${testFilePath}/test2.html`);
|
|
27
27
|
expect(shell.test('-e', `${testFilePath}/test2.html`)).toBe(true);
|
|
28
28
|
});
|
package/test/FileReader.test.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import FileReader from '../src/FileReader.js';
|
|
2
2
|
|
|
3
|
-
describe('FileReader',
|
|
4
|
-
describe('#readFile()',
|
|
5
|
-
|
|
3
|
+
describe('FileReader', () => {
|
|
4
|
+
describe('#readFile()', () => {
|
|
5
|
+
it('Should throw error if file not found', () => {
|
|
6
6
|
expect(() => { FileReader.read('test/FileReader/t2.txt'); }).toThrow();
|
|
7
7
|
});
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
it('Should read the contents of a file', () => {
|
|
10
10
|
const fr = FileReader.read('test/FileReader/t1.txt');
|
|
11
11
|
expect(fr).toBe('Gibberish');
|
|
12
12
|
});
|
|
@@ -6,10 +6,18 @@
|
|
|
6
6
|
</head>
|
|
7
7
|
<body>
|
|
8
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
|
|
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>
|
|
10
|
+
<style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style>
|
|
11
|
+
<script role="script" id="twine-user-script" type="text/twine-javascript"></script>
|
|
12
|
+
<tw-passagedata pid="1" name="Start" tags="" position="102,104" size="100,100">[[Another passage]]
|
|
10
13
|
|
|
11
|
-
[[A third passage]]</tw-passagedata
|
|
14
|
+
[[A third passage]]</tw-passagedata>
|
|
15
|
+
<tw-passagedata pid="2" name="Another passage" tags="" position="353,60" size="100,100">[[A fourth passage]]
|
|
12
16
|
|
|
13
|
-
[[A third passage]] </tw-passagedata
|
|
17
|
+
[[A third passage]] </tw-passagedata>
|
|
18
|
+
<tw-passagedata pid="3" name="A third passage" tags="" position="350,288" size="100,100">[[Start]]</tw-passagedata>
|
|
19
|
+
<tw-passagedata pid="4" name="A fourth passage" tags="" position="587,197" size="100,100">[[A fifth passage]]</tw-passagedata>
|
|
20
|
+
<tw-passagedata pid="5" name="A fifth passage" tags="" position="800,306" size="100,100">Double-click this passage to edit it.</tw-passagedata>
|
|
21
|
+
</tw-storydata>
|
|
14
22
|
</body>
|
|
15
23
|
</html>
|
package/test/HTMLParser.test.js
CHANGED
|
@@ -5,111 +5,111 @@ import HTMLParser from '../src/HTMLParser.js';
|
|
|
5
5
|
// These are used as the 'creator' and 'creator-version'.
|
|
6
6
|
const { version } = JSON.parse(FileReader.read('package.json'));
|
|
7
7
|
|
|
8
|
-
describe('HTMLParser',
|
|
9
|
-
describe('#parse()',
|
|
10
|
-
|
|
8
|
+
describe('HTMLParser', () => {
|
|
9
|
+
describe('#parse()', () => {
|
|
10
|
+
it('Should throw error if content is not Twine-2 style HTML', () => {
|
|
11
11
|
expect(() => { HTMLParser.parse(''); }).toThrow();
|
|
12
12
|
});
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
it('Should be able to parse Twine 2 HTML for story name', () => {
|
|
15
15
|
const fr = FileReader.read('test/HTMLParser/twineExample.html');
|
|
16
16
|
const story = HTMLParser.parse(fr);
|
|
17
17
|
const storyTitle = story.getPassageByName('StoryTitle');
|
|
18
18
|
expect(storyTitle.text).toBe('twineExample');
|
|
19
19
|
});
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
it('Should be able to parse Twine 2 HTML for correct number of passages', () => {
|
|
22
22
|
const fr = FileReader.read('test/HTMLParser/twineExample.html');
|
|
23
23
|
const tp = HTMLParser.parse(fr);
|
|
24
|
-
expect(tp.size()).toBe(
|
|
24
|
+
expect(tp.size()).toBe(5);
|
|
25
25
|
});
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
it('Should be able to correctly parse passage tags', () => {
|
|
28
28
|
const fr = FileReader.read('test/HTMLParser/Tags.html');
|
|
29
29
|
const story = HTMLParser.parse(fr);
|
|
30
30
|
const p = story.getPassageByName('Untitled Passage');
|
|
31
31
|
expect(p.tags).toHaveLength(2);
|
|
32
32
|
});
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
it('Should set a missing name to Untitled', () => {
|
|
35
35
|
const fr = FileReader.read('test/HTMLParser/missingName.html');
|
|
36
36
|
const story = HTMLParser.parse(fr);
|
|
37
37
|
const p = story.getPassageByName('StoryTitle');
|
|
38
38
|
expect(p.text).toBe('Untitled');
|
|
39
39
|
});
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
it('Should set a missing IFID to an empty string', () => {
|
|
42
42
|
const fr = FileReader.read('test/HTMLParser/missingIFID.html');
|
|
43
43
|
const tp = HTMLParser.parse(fr);
|
|
44
44
|
expect(tp.IFID).toBe('');
|
|
45
45
|
});
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
it('Should have Extwee for creator when missing', () => {
|
|
48
48
|
const fr = FileReader.read('test/HTMLParser/missingCreator.html');
|
|
49
49
|
const tp = HTMLParser.parse(fr);
|
|
50
50
|
expect(tp.creator).toBe('extwee');
|
|
51
51
|
});
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
it('Should have correct for creatorVersion when missing', () => {
|
|
54
54
|
const fr = FileReader.read('test/HTMLParser/missingCreatorVersion.html');
|
|
55
55
|
const tp = HTMLParser.parse(fr);
|
|
56
56
|
expect(tp.creatorVersion).toBe(version);
|
|
57
57
|
});
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
it('Should have empty string as format when missing', () => {
|
|
60
60
|
const fr = FileReader.read('test/HTMLParser/missingFormat.html');
|
|
61
61
|
const tp = HTMLParser.parse(fr);
|
|
62
62
|
expect(tp.format).toBe('');
|
|
63
63
|
});
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
it('Should have empty string as formatVersion when missing', () => {
|
|
66
66
|
const fr = FileReader.read('test/HTMLParser/missingFormatVersion.html');
|
|
67
67
|
const tp = HTMLParser.parse(fr);
|
|
68
68
|
expect(tp.formatVersion).toBe('');
|
|
69
69
|
});
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
it('Should have empty string as zoom when missing', () => {
|
|
72
72
|
const fr = FileReader.read('test/HTMLParser/missingZoom.html');
|
|
73
73
|
const tp = HTMLParser.parse(fr);
|
|
74
74
|
expect(tp.zoom).toBe(0);
|
|
75
75
|
});
|
|
76
76
|
|
|
77
|
-
|
|
77
|
+
it('Should not have position if passage does not', () => {
|
|
78
78
|
const fr = FileReader.read('test/HTMLParser/missingPosition.html');
|
|
79
79
|
const story = HTMLParser.parse(fr);
|
|
80
80
|
const p = story.getPassageByName('Untitled Passage');
|
|
81
81
|
expect(Object.prototype.hasOwnProperty.call(p.metadata, 'position')).toBe(false);
|
|
82
82
|
});
|
|
83
83
|
|
|
84
|
-
|
|
84
|
+
it('Should not have size if passage does not', () => {
|
|
85
85
|
const fr = FileReader.read('test/HTMLParser/missingSize.html');
|
|
86
86
|
const story = HTMLParser.parse(fr);
|
|
87
87
|
const p = story.getPassageByName('Untitled Passage');
|
|
88
88
|
expect(Object.prototype.hasOwnProperty.call(p.metadata, 'size')).toBe(false);
|
|
89
89
|
});
|
|
90
90
|
|
|
91
|
-
|
|
91
|
+
it('Should have empty array as tags if tags is missing', () => {
|
|
92
92
|
const fr = FileReader.read('test/HTMLParser/missingPassageTags.html');
|
|
93
93
|
const story = HTMLParser.parse(fr);
|
|
94
94
|
const p = story.getPassageByName('Untitled Passage');
|
|
95
95
|
expect(p.tags).toHaveLength(0);
|
|
96
96
|
});
|
|
97
97
|
|
|
98
|
-
|
|
98
|
+
it('Should not have stylesheet tag if no passages exist with it', () => {
|
|
99
99
|
const fr = FileReader.read('test/HTMLParser/missingStyle.html');
|
|
100
100
|
const story = HTMLParser.parse(fr);
|
|
101
101
|
const passages = story.getPassagesByTag('stylesheet');
|
|
102
102
|
expect(passages.length).toBe(0);
|
|
103
103
|
});
|
|
104
104
|
|
|
105
|
-
|
|
105
|
+
it('Should not have script tag if no passages exist with it', () => {
|
|
106
106
|
const fr = FileReader.read('test/HTMLParser/missingScript.html');
|
|
107
107
|
const story = HTMLParser.parse(fr);
|
|
108
108
|
const passages = story.getPassagesByTag('script');
|
|
109
109
|
expect(passages.length).toBe(0);
|
|
110
110
|
});
|
|
111
111
|
|
|
112
|
-
|
|
112
|
+
it('Should have script and style tags normally', () => {
|
|
113
113
|
const fr = FileReader.read('test/HTMLParser/Example1.html');
|
|
114
114
|
const story = HTMLParser.parse(fr);
|
|
115
115
|
const scriptPassages = story.getPassagesByTag('script');
|
|
@@ -118,27 +118,27 @@ describe('HTMLParser', function () {
|
|
|
118
118
|
expect(stylesheetPassages.length).toBe(1);
|
|
119
119
|
});
|
|
120
120
|
|
|
121
|
-
|
|
121
|
+
it('Should not have start property if startNode does not exist when parsed', () => {
|
|
122
122
|
const fr = FileReader.read('test/HTMLParser/missingStartnode.html');
|
|
123
123
|
const story = HTMLParser.parse(fr);
|
|
124
124
|
expect(story.start).toBe('');
|
|
125
125
|
});
|
|
126
126
|
|
|
127
|
-
|
|
127
|
+
it('Should not add passages without names', () => {
|
|
128
128
|
const fr = FileReader.read('test/HTMLParser/missingPassageName.html');
|
|
129
129
|
const story = HTMLParser.parse(fr);
|
|
130
130
|
// There is only one passage, StoryTitle
|
|
131
|
-
expect(story.size()).toBe(
|
|
131
|
+
expect(story.size()).toBe(0);
|
|
132
132
|
});
|
|
133
133
|
|
|
134
|
-
|
|
134
|
+
it('Should not add passages without PID', () => {
|
|
135
135
|
const fr = FileReader.read('test/HTMLParser/missingPID.html');
|
|
136
136
|
const story = HTMLParser.parse(fr);
|
|
137
137
|
// There is only one passage, StoryTitle
|
|
138
|
-
expect(story.size()).toBe(
|
|
138
|
+
expect(story.size()).toBe(0);
|
|
139
139
|
});
|
|
140
140
|
|
|
141
|
-
|
|
141
|
+
it('Parse tag colors', () => {
|
|
142
142
|
const fr = FileReader.read('test/HTMLParser/tagColors.html');
|
|
143
143
|
const story = HTMLParser.parse(fr);
|
|
144
144
|
// Test for tag colors
|
|
@@ -146,21 +146,21 @@ describe('HTMLParser', function () {
|
|
|
146
146
|
expect(tagColors.a).toBe('red');
|
|
147
147
|
});
|
|
148
148
|
|
|
149
|
-
|
|
149
|
+
it('Will not set start if startnode is missing', () => {
|
|
150
150
|
const fr = FileReader.read('test/HTMLParser/missingStartnode.html');
|
|
151
151
|
const story = HTMLParser.parse(fr);
|
|
152
152
|
// Test for default start
|
|
153
153
|
expect(story.start).toBe('');
|
|
154
154
|
});
|
|
155
155
|
|
|
156
|
-
|
|
156
|
+
it('Throw error when startnode has PID that does not exist', () => {
|
|
157
157
|
const fr = FileReader.read('test/HTMLParser/lyingStartnode.html');
|
|
158
158
|
expect(() => {
|
|
159
159
|
HTMLParser.parse(fr);
|
|
160
160
|
}).toThrow();
|
|
161
161
|
});
|
|
162
162
|
|
|
163
|
-
|
|
163
|
+
it('Do not update name and color if those attributes do not exist', () => {
|
|
164
164
|
const fr = FileReader.read('test/HTMLParser/lyingTagColors.html');
|
|
165
165
|
const story = HTMLParser.parse(fr);
|
|
166
166
|
const tagColorProperties = Object.keys(story.tagColors).length;
|
|
@@ -168,8 +168,8 @@ describe('HTMLParser', function () {
|
|
|
168
168
|
});
|
|
169
169
|
});
|
|
170
170
|
|
|
171
|
-
describe('#escapeMetacharacters()',
|
|
172
|
-
|
|
171
|
+
describe('#escapeMetacharacters()', () => {
|
|
172
|
+
it('Should escape metacharacters', () => {
|
|
173
173
|
/* eslint no-useless-escape: "off" */
|
|
174
174
|
expect(HTMLParser.escapeMetacharacters('\\\{\\\}\\\[\\\]\\\\')).toBe('\\\\{\\\\}\\\\[\\\\]\\\\');
|
|
175
175
|
});
|
|
@@ -9,12 +9,11 @@
|
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
11
|
<tw-story tags></tw-story>
|
|
12
|
-
<tw-storydata name="Title" startnode="4" creator="extwee" creator-version="2.0.
|
|
12
|
+
<tw-storydata name="Title" startnode="4" creator="extwee" creator-version="2.0.6" ifid="AE48EB3C-00FE-41CF-A659-E48068758B06" zoom="0" format="Snowman" format-version="2.0.0" options hidden>
|
|
13
13
|
<style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style>
|
|
14
14
|
<script role="script" id="twine-user-script" type="text/twine-javascript"></script>
|
|
15
15
|
<tw-passagedata pid="1" name="A"></tw-passagedata>
|
|
16
16
|
<tw-passagedata pid="2" name="B"></tw-passagedata>
|
|
17
|
-
<tw-passagedata pid="3" name="StoryTitle">Title</tw-passagedata>
|
|
18
17
|
<tw-passagedata pid="4" name="Start">Content</tw-passagedata>
|
|
19
18
|
</tw-storydata>
|
|
20
19
|
<script>
|
|
@@ -100,12 +100,10 @@ var saveAs=saveAs||navigator.msSaveBlob&&navigator.msSaveBlob.bind(navigator)||f
|
|
|
100
100
|
<div id="init-lacking">Your browser lacks required capabilities. Please upgrade it or switch to another to continue.</div>
|
|
101
101
|
<div id="init-loading"><div>Loading…</div></div>
|
|
102
102
|
</div>
|
|
103
|
-
<tw-storydata name="twineExample" startnode="2" creator="extwee" creator-version="2.0.
|
|
103
|
+
<tw-storydata name="twineExample" startnode="2" creator="extwee" creator-version="2.0.6" ifid="2B68ECD6-348F-4CF5-96F8-549A512A8128" zoom="0" format="SugarCube" format-version="2.31.1" options hidden>
|
|
104
104
|
<style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css">body {background-color: green;}</style>
|
|
105
105
|
<script role="script" id="twine-user-script" type="text/twine-javascript"></script>
|
|
106
|
-
<tw-passagedata pid="1" name="StoryTitle">twineExample</tw-passagedata>
|
|
107
106
|
<tw-passagedata pid="2" name="Start" tags="tag tags" position="200,200" size="100,100" >Content</tw-passagedata>
|
|
108
|
-
<tw-passagedata pid="3" name="Style1" tags="stylesheet" >body {background-color: green;}</tw-passagedata>
|
|
109
107
|
</tw-storydata>
|
|
110
108
|
<script id="script-sugarcube" type="text/javascript">
|
|
111
109
|
/*! SugarCube JS */
|
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
<tw-storydata name="twineExample" startnode="1" creator="Twine" creator-version="2.2.1" ifid="2B68ECD6-348F-4CF5-96F8-549A512A8128" zoom="1" format="Snowman" format-version="2.0.0" options hidden>
|
|
13
13
|
<style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css">html{font-size: 1.2em;}</style>
|
|
14
14
|
<script role="script" id="twine-user-script" type="text/twine-javascript">window.test = {};</script>
|
|
15
|
-
<tw-passagedata pid="1" name="StoryTitle">twineExample</tw-passagedata>
|
|
16
15
|
<tw-passagedata pid="1" name="Start" position="102,104" size="100,100" >[[Another passage]]
|
|
17
16
|
|
|
18
17
|
[[A third passage]]</tw-passagedata>
|
|
@@ -22,8 +21,6 @@
|
|
|
22
21
|
<tw-passagedata pid="3" name="A third passage" position="350,288" size="100,100" >[[Start]]</tw-passagedata>
|
|
23
22
|
<tw-passagedata pid="4" name="A fourth passage" position="587,197" size="100,100" >[[A fifth passage]]</tw-passagedata>
|
|
24
23
|
<tw-passagedata pid="5" name="A fifth passage" position="800,306" size="100,100" >Double-click this passage to edit it.</tw-passagedata>
|
|
25
|
-
<tw-passagedata pid="2" name="UserStylesheet" tags="stylesheet" >html{font-size: 1.2em;}</tw-passagedata>
|
|
26
|
-
<tw-passagedata pid="3" name="UserScript" tags="script" >window.test = {};</tw-passagedata>
|
|
27
24
|
</tw-storydata>
|
|
28
25
|
<script>
|
|
29
26
|
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
|
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
<tw-storydata name="TestTags" startnode="1" creator="Twine" creator-version="2.3.9" ifid="5B4E374F-E8B0-4FBB-A78E-A4150401BF24" zoom="1" format="Snowman" format-version="2.0.0" options hidden>
|
|
13
13
|
<style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style>
|
|
14
14
|
<script role="script" id="twine-user-script" type="text/twine-javascript"></script>
|
|
15
|
-
<tw-passagedata pid="1" name="StoryTitle">TestTags</tw-passagedata>
|
|
16
15
|
<tw-passagedata pid="1" name="Untitled Passage" tags="one" position="199,100" size="100,100" >[[Another]]</tw-passagedata>
|
|
17
16
|
<tw-passagedata pid="2" name="Another" tags="two three" position="399,99" size="100,100" >Double-click this passage to edit it.</tw-passagedata>
|
|
18
17
|
</tw-storydata>
|
|
@@ -9,12 +9,11 @@
|
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
11
|
<tw-story tags></tw-story>
|
|
12
|
-
<tw-storydata name="Title" startnode="4" creator="extwee" creator-version="2.0.
|
|
12
|
+
<tw-storydata name="Title" startnode="4" creator="extwee" creator-version="2.0.6" ifid="1096FE8A-C8B0-4485-8628-61B25490AB7E" zoom="0" format="Snowman" format-version="2.0.0" options hidden>
|
|
13
13
|
<style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style>
|
|
14
14
|
<script role="script" id="twine-user-script" type="text/twine-javascript"></script>
|
|
15
15
|
<tw-passagedata pid="1" name="A"></tw-passagedata>
|
|
16
16
|
<tw-passagedata pid="2" name="B"></tw-passagedata>
|
|
17
|
-
<tw-passagedata pid="3" name="StoryTitle">Title</tw-passagedata>
|
|
18
17
|
<tw-passagedata pid="4" name="Start">Content</tw-passagedata>
|
|
19
18
|
</tw-storydata>
|
|
20
19
|
<script>
|
|
@@ -9,11 +9,10 @@
|
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
11
|
<tw-story tags></tw-story>
|
|
12
|
-
<tw-storydata name="Name" startnode="3" creator="extwee" creator-version="2.0.
|
|
12
|
+
<tw-storydata name="Name" startnode="3" creator="extwee" creator-version="2.0.6" ifid="AD1FF443-CFE8-4651-99AD-FD9E1DCB0304" zoom="0" format="Snowman" format-version="2.0.0" options hidden>
|
|
13
13
|
<style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style>
|
|
14
14
|
<script role="script" id="twine-user-script" type="text/twine-javascript"></script>
|
|
15
15
|
<tw-passagedata pid="1" name="A"></tw-passagedata>
|
|
16
|
-
<tw-passagedata pid="2" name="StoryTitle">Name</tw-passagedata>
|
|
17
16
|
<tw-passagedata pid="3" name="Start">Content</tw-passagedata>
|
|
18
17
|
</tw-storydata>
|
|
19
18
|
<script>
|
package/test/HTMLWriter.test.js
CHANGED
|
@@ -38,10 +38,8 @@ describe('HTMLWriter', () => {
|
|
|
38
38
|
// Parse HTML.
|
|
39
39
|
const story2 = HTMLParser.parse(fr3);
|
|
40
40
|
|
|
41
|
-
const s2Title = story2.getPassageByName('StoryTitle').text;
|
|
42
|
-
|
|
43
41
|
// Test both names to be the same.
|
|
44
|
-
expect(s1Title).toBe(
|
|
42
|
+
expect(s1Title).toBe(story2.name);
|
|
45
43
|
});
|
|
46
44
|
|
|
47
45
|
it('Should write one and two-tag passages', () => {
|