extwee 1.5.3 → 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 -0
- package/.github/workflows/nodejs.yml +24 -0
- package/.travis.yml +13 -0
- package/CODE_OF_CONDUCT.md +82 -0
- package/LICENSE +21 -21
- package/README.md +36 -203
- 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 -39
- package/src/FileReader.js +33 -0
- package/src/HTMLParser.js +343 -0
- package/src/HTMLWriter.js +196 -0
- package/src/Passage.js +202 -0
- package/src/Story.js +461 -0
- package/src/StoryFormat.js +300 -0
- package/src/StoryFormatParser.js +142 -0
- package/src/TweeParser.js +166 -0
- package/src/TweeWriter.js +98 -0
- 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/CLI/example6.twee +16 -0
- 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/t1.txt +1 -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 -0
- 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/creator.html +51 -0
- package/test/HTMLWriter/example6.twee +16 -0
- package/test/HTMLWriter/missingStoryTitle.twee +29 -0
- package/test/HTMLWriter/test11.html +123 -0
- package/test/HTMLWriter/test2.html +59 -0
- package/test/HTMLWriter/test3.html +50 -0
- package/test/HTMLWriter/test4.html +51 -0
- package/test/HTMLWriter/test6.html +50 -0
- 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 -0
- package/test/Story/test.twee +25 -0
- package/test/Story.test.js +282 -0
- package/test/StoryFormat.test.js +152 -0
- package/test/StoryFormatParser/example.js +3 -0
- package/test/StoryFormatParser/example2.js +3 -0
- package/test/StoryFormatParser/format.js +1 -0
- package/test/StoryFormatParser/format_doublename.js +1 -0
- package/test/StoryFormatParser/harlowe.js +3 -0
- 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 -0
- package/test/TweeParser/example.twee +32 -0
- package/test/TweeParser/missing.twee +19 -0
- package/test/TweeParser/multipleScriptPassages.twee +19 -0
- package/test/TweeParser/multipleStyleTag.twee +19 -0
- package/test/TweeParser/multipletags.twee +10 -0
- package/test/TweeParser/noTitle.twee +2 -0
- package/test/TweeParser/notes.twee +16 -0
- package/test/TweeParser/pasagemetadataerror.twee +2 -0
- package/test/TweeParser/scriptPassage.twee +16 -0
- package/test/TweeParser/singletag.twee +13 -0
- package/test/TweeParser/startMetadata.twee +14 -0
- package/test/TweeParser/storydataerror.twee +25 -0
- package/test/TweeParser/stylePassage.twee +16 -0
- package/test/TweeParser/test.twee +25 -0
- package/test/TweeParser.test.js +79 -0
- package/test/TweeWriter/test1.twee +18 -0
- package/test/TweeWriter/test3.twee +12 -0
- package/test/TweeWriter/test4.twee +14 -0
- package/test/TweeWriter/test5.twee +20 -0
- package/test/TweeWriter.test.js +82 -0
- package/DirectoryReader.js +0 -128
- package/DirectoryWatcher.js +0 -63
- package/FileReader.js +0 -36
- package/HTMLParser.js +0 -206
- package/HTMLWriter.js +0 -177
- package/Passage.js +0 -20
- package/Story.js +0 -148
- package/StoryFormat.js +0 -41
- package/StoryFormatParser.js +0 -65
- package/TweeParser.js +0 -255
- package/TweeWriter.js +0 -111
- package/main.js +0 -103
package/HTMLParser.js
DELETED
|
@@ -1,206 +0,0 @@
|
|
|
1
|
-
const { parse } = require('node-html-parser');
|
|
2
|
-
const htmlparser = parse;
|
|
3
|
-
const Story = require('./Story.js');
|
|
4
|
-
const Passage = require('./Passage.js');
|
|
5
|
-
/**
|
|
6
|
-
* @class HTMLParser
|
|
7
|
-
* @module HTMLParser
|
|
8
|
-
*/
|
|
9
|
-
class HTMLParser {
|
|
10
|
-
/**
|
|
11
|
-
* @method HTMLParser
|
|
12
|
-
* @constructor
|
|
13
|
-
*/
|
|
14
|
-
constructor (content) {
|
|
15
|
-
|
|
16
|
-
this.story = null;
|
|
17
|
-
|
|
18
|
-
this.parse(content);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
parse(content) {
|
|
22
|
-
|
|
23
|
-
// Send to node-html-parser
|
|
24
|
-
// Enable getting the content of 'script', 'style', and 'pre' elements
|
|
25
|
-
// Get back a DOM
|
|
26
|
-
let dom = new htmlparser(
|
|
27
|
-
content,
|
|
28
|
-
{
|
|
29
|
-
lowerCaseTagName: false,
|
|
30
|
-
script: true,
|
|
31
|
-
style: true,
|
|
32
|
-
pre: true
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
// Pull out the tw-storydata element
|
|
36
|
-
let storyData = dom.querySelector('tw-storydata');
|
|
37
|
-
|
|
38
|
-
if(storyData != null) {
|
|
39
|
-
|
|
40
|
-
this.story = new Story();
|
|
41
|
-
this.story.name = storyData.attributes["name"];
|
|
42
|
-
this.story.creator = storyData.attributes["creator"];
|
|
43
|
-
this.story.creatorVersion = storyData.attributes["creator-version"];
|
|
44
|
-
|
|
45
|
-
this.story.metadata = {};
|
|
46
|
-
this.story.metadata.ifid = storyData.attributes["ifid"];
|
|
47
|
-
this.story.metadata.format = storyData.attributes["format"];
|
|
48
|
-
this.story.metadata.formatVersion = storyData.attributes["format-version"];
|
|
49
|
-
this.story.metadata.zoom = storyData.attributes["zoom"];
|
|
50
|
-
this.story.metadata.start = storyData.attributes["startnode"];
|
|
51
|
-
|
|
52
|
-
} else {
|
|
53
|
-
|
|
54
|
-
throw new Error("Error: Not a Twine 2-style file!");
|
|
55
|
-
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// Pull out the tw-passagedata elements
|
|
59
|
-
let storyPassages = dom.querySelectorAll("tw-passagedata");
|
|
60
|
-
|
|
61
|
-
// Create an empty array
|
|
62
|
-
this.story.passages = new Array();
|
|
63
|
-
|
|
64
|
-
// Set default pid
|
|
65
|
-
let pid = 1;
|
|
66
|
-
|
|
67
|
-
// Add StoryTitle
|
|
68
|
-
this.story.passages.push(
|
|
69
|
-
new Passage(
|
|
70
|
-
"StoryTitle",
|
|
71
|
-
[],
|
|
72
|
-
{},
|
|
73
|
-
this.story.name,
|
|
74
|
-
pid
|
|
75
|
-
)
|
|
76
|
-
);
|
|
77
|
-
|
|
78
|
-
// Increase PID by one before parsing any other passages
|
|
79
|
-
pid++;
|
|
80
|
-
|
|
81
|
-
// Move through the passages
|
|
82
|
-
for(let passage in storyPassages) {
|
|
83
|
-
|
|
84
|
-
// Get the passage attributes
|
|
85
|
-
let attr = storyPassages[passage].attributes;
|
|
86
|
-
// Get the passage text
|
|
87
|
-
let text = storyPassages[passage].rawText;
|
|
88
|
-
|
|
89
|
-
// Save position
|
|
90
|
-
let position = attr.position;
|
|
91
|
-
|
|
92
|
-
// Save size
|
|
93
|
-
let size = attr.size;
|
|
94
|
-
|
|
95
|
-
// Escape the name
|
|
96
|
-
let name = this._escapeMetacharacters(attr.name);
|
|
97
|
-
|
|
98
|
-
// Create empty tags
|
|
99
|
-
let tags = "";
|
|
100
|
-
|
|
101
|
-
// Escape any tags
|
|
102
|
-
// (Attributes can, themselves, be emtpy strings.)
|
|
103
|
-
if(attr.tags.length > 0 && attr.tags != '""') {
|
|
104
|
-
|
|
105
|
-
tags = this._escapeMetacharacters(attr.tags);
|
|
106
|
-
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// Split by spaces
|
|
110
|
-
tags = tags.split(" ");
|
|
111
|
-
|
|
112
|
-
// Remove any empty strings
|
|
113
|
-
tags = tags.filter(tag => tag != "");
|
|
114
|
-
|
|
115
|
-
// Add a new Passage into an array
|
|
116
|
-
this.story.passages.push(
|
|
117
|
-
new Passage(
|
|
118
|
-
name,
|
|
119
|
-
tags,
|
|
120
|
-
{
|
|
121
|
-
"position": position,
|
|
122
|
-
"size": size
|
|
123
|
-
|
|
124
|
-
},
|
|
125
|
-
text,
|
|
126
|
-
pid
|
|
127
|
-
)
|
|
128
|
-
);
|
|
129
|
-
|
|
130
|
-
pid++;
|
|
131
|
-
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// Look for the style element
|
|
135
|
-
let styleElement = dom.querySelector('#twine-user-stylesheet');
|
|
136
|
-
|
|
137
|
-
// Check if there is any content.
|
|
138
|
-
// If not, we won't add empty passages
|
|
139
|
-
if(styleElement.rawText.length > 0) {
|
|
140
|
-
|
|
141
|
-
// Add UserStylesheet
|
|
142
|
-
this.story.passages.push(
|
|
143
|
-
new Passage(
|
|
144
|
-
"UserStylesheet",
|
|
145
|
-
["stylesheet"],
|
|
146
|
-
{},
|
|
147
|
-
styleElement.rawText
|
|
148
|
-
)
|
|
149
|
-
);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// Look for the script element
|
|
153
|
-
let scriptElement = dom.querySelector('#twine-user-script');
|
|
154
|
-
|
|
155
|
-
// Check if there is any content.
|
|
156
|
-
// If not, we won't add empty passages
|
|
157
|
-
if(scriptElement.rawText.length > 0) {
|
|
158
|
-
|
|
159
|
-
// Add UserScript
|
|
160
|
-
this.story.passages.push(
|
|
161
|
-
new Passage(
|
|
162
|
-
"UserScript",
|
|
163
|
-
["script"],
|
|
164
|
-
{},
|
|
165
|
-
scriptElement.rawText
|
|
166
|
-
)
|
|
167
|
-
);
|
|
168
|
-
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// Now that all passages have been handled,
|
|
172
|
-
// change the start name
|
|
173
|
-
this.story.metadata.start = this.story.getStartingPassage();
|
|
174
|
-
|
|
175
|
-
// Add StoryData
|
|
176
|
-
this.story.passages.push(
|
|
177
|
-
new Passage(
|
|
178
|
-
"StoryData",
|
|
179
|
-
[],
|
|
180
|
-
{},
|
|
181
|
-
JSON.stringify(this.story.metadata, null, 4)
|
|
182
|
-
)
|
|
183
|
-
);
|
|
184
|
-
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
_escapeMetacharacters(result) {
|
|
188
|
-
|
|
189
|
-
// Replace any single backslash with two of them
|
|
190
|
-
result = result.replace(/\\/g, "\\");
|
|
191
|
-
// Double-escape escaped {
|
|
192
|
-
result = result.replace(/\\\{/g, "\\\\{");
|
|
193
|
-
// Double-escape escaped }
|
|
194
|
-
result = result.replace(/\\\}/g, "\\\\}");
|
|
195
|
-
// Double-escape escaped [
|
|
196
|
-
result = result.replace(/\\\[/g, "\\\\[");
|
|
197
|
-
// Double-escape escaped ]
|
|
198
|
-
result = result.replace(/\\\]/g, "\\\\]");
|
|
199
|
-
|
|
200
|
-
return result;
|
|
201
|
-
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
module.exports = HTMLParser;
|
package/HTMLWriter.js
DELETED
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
const fs = require("fs");
|
|
2
|
-
const Story = require('./Story.js');
|
|
3
|
-
const StoryFormat = require('./StoryFormat.js');
|
|
4
|
-
/**
|
|
5
|
-
* @class HTMLWriter
|
|
6
|
-
* @module HTMLWriter
|
|
7
|
-
*/
|
|
8
|
-
class HTMLWriter {
|
|
9
|
-
/**
|
|
10
|
-
* @method HTMLWriter
|
|
11
|
-
* @constructor
|
|
12
|
-
*/
|
|
13
|
-
constructor (file, story, storyFormat, css, js) {
|
|
14
|
-
|
|
15
|
-
if( !(story instanceof Story) ) {
|
|
16
|
-
throw new Error("Error: story must be a Story object!");
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
if( !(storyFormat instanceof StoryFormat)) {
|
|
20
|
-
|
|
21
|
-
throw new Error("storyFormat must be a StoryFormat object!");
|
|
22
|
-
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
let cssContent = css || null;
|
|
26
|
-
let jsContent = js || null;
|
|
27
|
-
|
|
28
|
-
this.writeFile(file, story, storyFormat, cssContent, jsContent);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
writeFile(file, story, storyFormat, cssContent, jsContent) {
|
|
32
|
-
|
|
33
|
-
let outputContents = "";
|
|
34
|
-
|
|
35
|
-
// Build <tw-storydata>
|
|
36
|
-
let storyData =
|
|
37
|
-
'<tw-storydata name="' + story.name + '" ' +
|
|
38
|
-
'startnode="' + story.getStartingPassage() + '" ' +
|
|
39
|
-
'creator="' + story.creator + '" ' +
|
|
40
|
-
'creator-version="' + story.creatorVersion + '" ' +
|
|
41
|
-
'ifid="' + story.metadata.ifid + '" ' +
|
|
42
|
-
'zoom="' + story.metadata.zoom + '" ' +
|
|
43
|
-
'format="' + storyFormat.name + '" ' +
|
|
44
|
-
'format-version="' + storyFormat.version + '" ' +
|
|
45
|
-
'options hidden>\n';
|
|
46
|
-
|
|
47
|
-
// Build the STYLE
|
|
48
|
-
storyData += '<style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css">';
|
|
49
|
-
|
|
50
|
-
// Get any passages tagged with 'stylesheet'
|
|
51
|
-
let stylePassages = story.getStylePassages();
|
|
52
|
-
|
|
53
|
-
// CSS passed through from DirectoryReader
|
|
54
|
-
if(cssContent != null) {
|
|
55
|
-
storyData += cssContent;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// Iterate through the collection and add to storyData
|
|
59
|
-
for(let content of stylePassages) {
|
|
60
|
-
storyData += content.text;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
storyData += '</style>\n';
|
|
64
|
-
|
|
65
|
-
// Build the SCRIPT
|
|
66
|
-
storyData += '<script role="script" id="twine-user-script" type="text/twine-javascript">';
|
|
67
|
-
|
|
68
|
-
// Get any passages tagged with 'script'
|
|
69
|
-
let scriptPassages = story.getScriptPassages();
|
|
70
|
-
|
|
71
|
-
// JS passed through from DirectoryReader
|
|
72
|
-
if(jsContent != null) {
|
|
73
|
-
storyData += jsContent;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// Iterate through the collection and add to storyData
|
|
77
|
-
for(let content of scriptPassages) {
|
|
78
|
-
storyData += content.text;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
storyData += '</script>\n';
|
|
82
|
-
|
|
83
|
-
// All the script data has been written.
|
|
84
|
-
// Delete all 'script'-tagged passages
|
|
85
|
-
story.deleteAllByTag("script");
|
|
86
|
-
|
|
87
|
-
// All the style data has been written.
|
|
88
|
-
// Delete all 'style'-tagged passages
|
|
89
|
-
story.deleteAllByTag("stylesheet");
|
|
90
|
-
|
|
91
|
-
// Build the passages
|
|
92
|
-
for(let passage of story.passages) {
|
|
93
|
-
|
|
94
|
-
storyData += '<tw-passagedata pid="' + passage.pid + '" name="' + passage.name + '"';
|
|
95
|
-
|
|
96
|
-
// Write out any tags
|
|
97
|
-
if(passage.tags.length > 1) {
|
|
98
|
-
|
|
99
|
-
storyData += ' tags="';
|
|
100
|
-
|
|
101
|
-
for(let t of passage.tags) {
|
|
102
|
-
|
|
103
|
-
storyData += t + ', ';
|
|
104
|
-
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
storyData += '" ';
|
|
108
|
-
|
|
109
|
-
} else if(passage.tags.length == 1) {
|
|
110
|
-
|
|
111
|
-
storyData += ' tags="' + passage.tags[0] + '" ';
|
|
112
|
-
|
|
113
|
-
} else {
|
|
114
|
-
|
|
115
|
-
storyData += ' tags ';
|
|
116
|
-
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// Write out position
|
|
120
|
-
if(passage.metadata.hasOwnProperty("position")) {
|
|
121
|
-
|
|
122
|
-
storyData += 'position="' +
|
|
123
|
-
passage.metadata.position + '" ';
|
|
124
|
-
|
|
125
|
-
} else {
|
|
126
|
-
|
|
127
|
-
// Didn't have a position.
|
|
128
|
-
// Make one up.
|
|
129
|
-
storyData += 'position="100,100" ';
|
|
130
|
-
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
// Write out size
|
|
134
|
-
if(passage.metadata.hasOwnProperty("size") ) {
|
|
135
|
-
|
|
136
|
-
storyData += 'size="' +
|
|
137
|
-
passage.metadata.size + '" ';
|
|
138
|
-
|
|
139
|
-
} else {
|
|
140
|
-
|
|
141
|
-
// Didn't have a size.
|
|
142
|
-
// Make one up.
|
|
143
|
-
storyData += 'size="100,100" ';
|
|
144
|
-
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
storyData += '>' + passage.text + '</tw-passagedata>\n';
|
|
148
|
-
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
storyData += '</tw-storydata>';
|
|
152
|
-
|
|
153
|
-
// Replace the story name in the source file
|
|
154
|
-
storyFormat.source = storyFormat.source.replace("{{STORY_NAME}}", story.name);
|
|
155
|
-
|
|
156
|
-
// Replace the story data
|
|
157
|
-
storyFormat.source = storyFormat.source.replace("{{STORY_DATA}}", storyData);
|
|
158
|
-
|
|
159
|
-
outputContents += storyFormat.source
|
|
160
|
-
|
|
161
|
-
try {
|
|
162
|
-
|
|
163
|
-
// Try to write
|
|
164
|
-
fs.writeFileSync(file, outputContents);
|
|
165
|
-
|
|
166
|
-
} catch(event) {
|
|
167
|
-
|
|
168
|
-
// Throw error
|
|
169
|
-
throw new Error("Error: Cannot write HTML file!");
|
|
170
|
-
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
module.exports = HTMLWriter;
|
package/Passage.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @class Passage
|
|
3
|
-
* @module Passage
|
|
4
|
-
*/
|
|
5
|
-
class Passage {
|
|
6
|
-
/**
|
|
7
|
-
* @method Passage
|
|
8
|
-
* @constructor
|
|
9
|
-
*/
|
|
10
|
-
constructor (name = "", tags = [], metadata = {}, text = "", pid = 1) {
|
|
11
|
-
this.name = name;
|
|
12
|
-
this.tags = tags;
|
|
13
|
-
this.metadata = metadata;
|
|
14
|
-
this.text = text;
|
|
15
|
-
this.pid = pid;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
module.exports = Passage;
|
package/Story.js
DELETED
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
const pkg = require('./package.json');
|
|
2
|
-
/**
|
|
3
|
-
* @class Story
|
|
4
|
-
* @module Story
|
|
5
|
-
*/
|
|
6
|
-
class Story {
|
|
7
|
-
/**
|
|
8
|
-
* @method Story
|
|
9
|
-
* @constructor
|
|
10
|
-
*/
|
|
11
|
-
constructor () {
|
|
12
|
-
this.name = "Unknown";
|
|
13
|
-
this.metadata = {
|
|
14
|
-
"ifid": "",
|
|
15
|
-
"format": "",
|
|
16
|
-
"formatVersion": "",
|
|
17
|
-
"zoom": "",
|
|
18
|
-
"start": ""
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
this.passages = [];
|
|
22
|
-
|
|
23
|
-
// Store the creator and version
|
|
24
|
-
this.creator = pkg.name;
|
|
25
|
-
this.creatorVersion = pkg.version;
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* @method getStylePassages()
|
|
31
|
-
*/
|
|
32
|
-
getStylePassages() {
|
|
33
|
-
|
|
34
|
-
let stylePassages = [];
|
|
35
|
-
|
|
36
|
-
if(this.passages.length > 0) {
|
|
37
|
-
|
|
38
|
-
stylePassages = this.passages.filter(function(passage){
|
|
39
|
-
|
|
40
|
-
let results = passage.tags.filter(tag => tag == "stylesheet");
|
|
41
|
-
|
|
42
|
-
return (results.length > 0);
|
|
43
|
-
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return stylePassages;
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* @method getScriptPassages()
|
|
54
|
-
*/
|
|
55
|
-
getScriptPassages() {
|
|
56
|
-
|
|
57
|
-
let scriptPassages = [];
|
|
58
|
-
|
|
59
|
-
if(this.passages.length > 0) {
|
|
60
|
-
|
|
61
|
-
scriptPassages = this.passages.filter(function(passage) {
|
|
62
|
-
|
|
63
|
-
let results = passage.tags.filter(tag => tag == "script");
|
|
64
|
-
|
|
65
|
-
return (results.length > 0);
|
|
66
|
-
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return scriptPassages;
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* @method deleteAllByTag()
|
|
77
|
-
*/
|
|
78
|
-
deleteAllByTag(searchTag) {
|
|
79
|
-
|
|
80
|
-
if(this.passages.length > 0) {
|
|
81
|
-
|
|
82
|
-
this.passages = this.passages.filter(function(passage) {
|
|
83
|
-
|
|
84
|
-
return !passage.tags.includes(searchTag);
|
|
85
|
-
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* @method getStartingPassage()
|
|
94
|
-
* @return String
|
|
95
|
-
*/
|
|
96
|
-
getStartingPassage() {
|
|
97
|
-
|
|
98
|
-
let pid = null;
|
|
99
|
-
let searchName = null;
|
|
100
|
-
|
|
101
|
-
if(this.metadata.hasOwnProperty("start")) {
|
|
102
|
-
|
|
103
|
-
// Check if the property is an empty string
|
|
104
|
-
// If so, ignore it.
|
|
105
|
-
if(this.metadata.start != "") {
|
|
106
|
-
|
|
107
|
-
searchName = this.metadata.start;
|
|
108
|
-
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
if(this.passages.length > 0) {
|
|
114
|
-
|
|
115
|
-
for(let passage in this.passages) {
|
|
116
|
-
|
|
117
|
-
if(this.passages[passage].name == searchName) {
|
|
118
|
-
|
|
119
|
-
pid = this.passages[passage].pid;
|
|
120
|
-
break;
|
|
121
|
-
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
if(this.passages[passage].name == "Start") {
|
|
125
|
-
|
|
126
|
-
pid = this.passages[passage].pid;
|
|
127
|
-
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
if(pid == null) {
|
|
135
|
-
|
|
136
|
-
throw new Error("Starting passage not found!");
|
|
137
|
-
|
|
138
|
-
} else {
|
|
139
|
-
|
|
140
|
-
return pid;
|
|
141
|
-
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
module.exports = Story;
|
package/StoryFormat.js
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @class StoryFormat
|
|
3
|
-
* @module StoryFormat
|
|
4
|
-
*/
|
|
5
|
-
class StoryFormat {
|
|
6
|
-
/**
|
|
7
|
-
* @method StoryFormat
|
|
8
|
-
* @constructor
|
|
9
|
-
*/
|
|
10
|
-
constructor (object) {
|
|
11
|
-
|
|
12
|
-
// Borrowed from Underscore
|
|
13
|
-
// https://github.com/jashkenas/underscore/blob/master/underscore.js#L1319-L1323
|
|
14
|
-
let isObject = function(obj) {
|
|
15
|
-
var type = typeof obj;
|
|
16
|
-
return type === 'function' || type === 'object' && !!obj;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
if(isObject(object) ) {
|
|
20
|
-
|
|
21
|
-
this.name = object.name || null;
|
|
22
|
-
this.version = object.version || null;
|
|
23
|
-
this.description = object.description || null;
|
|
24
|
-
this.author = object.author || null;
|
|
25
|
-
this.image = object.image || null;
|
|
26
|
-
this.url = object.url || null;
|
|
27
|
-
this.license = object.license || null;
|
|
28
|
-
this.proofing = object.proofing || null;
|
|
29
|
-
this.source = object.source || null;
|
|
30
|
-
|
|
31
|
-
} else {
|
|
32
|
-
|
|
33
|
-
throw new Error("Expected JSON object!");
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
module.exports = StoryFormat;
|
package/StoryFormatParser.js
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
const StoryFormat = require('./StoryFormat.js');
|
|
2
|
-
const FileReader = require('./FileReader.js');
|
|
3
|
-
/**
|
|
4
|
-
* @class StoryFormatParser
|
|
5
|
-
* @module StoryFormatParser
|
|
6
|
-
*/
|
|
7
|
-
class StoryFormatParser {
|
|
8
|
-
/**
|
|
9
|
-
* @method StoryFormatParser
|
|
10
|
-
* @constructor
|
|
11
|
-
*/
|
|
12
|
-
constructor (file) {
|
|
13
|
-
|
|
14
|
-
this.storyformat = null;
|
|
15
|
-
|
|
16
|
-
this.parse(file);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
parse(file) {
|
|
20
|
-
|
|
21
|
-
let contents = new FileReader(file).contents;
|
|
22
|
-
|
|
23
|
-
// Harlowe has malformed JSON, so we have to test for it
|
|
24
|
-
let harlowePosition = contents.indexOf('harlowe');
|
|
25
|
-
|
|
26
|
-
if(harlowePosition != -1) {
|
|
27
|
-
// The 'setup' property is malformed
|
|
28
|
-
let setupPosition = contents.lastIndexOf(',"setup": function');
|
|
29
|
-
contents = contents.slice(0, setupPosition) + '}';
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
let openingCurlyBracketPosition = contents.indexOf('{');
|
|
34
|
-
let closingCurlyBracketPosition = contents.lastIndexOf('}');
|
|
35
|
-
|
|
36
|
-
if(openingCurlyBracketPosition != -1 && closingCurlyBracketPosition != -1) {
|
|
37
|
-
|
|
38
|
-
// Slice out the JSON
|
|
39
|
-
contents = contents.slice(openingCurlyBracketPosition, closingCurlyBracketPosition+1);
|
|
40
|
-
|
|
41
|
-
} else {
|
|
42
|
-
|
|
43
|
-
throw new Error("Unable to find Twine2 JSON chunk!");
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
let jsonContent = "";
|
|
48
|
-
|
|
49
|
-
try {
|
|
50
|
-
|
|
51
|
-
jsonContent = JSON.parse(contents);
|
|
52
|
-
|
|
53
|
-
} catch (event) {
|
|
54
|
-
|
|
55
|
-
throw new Error("Unable to parse Twine2 JSON chunk!");
|
|
56
|
-
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
this.storyformat = new StoryFormat(jsonContent);
|
|
60
|
-
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
module.exports = StoryFormatParser;
|