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
package/src/HTMLWriter.js
CHANGED
|
@@ -1,172 +1,196 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @external Story
|
|
3
|
-
* @see Story.js
|
|
4
|
-
* @external StoryFormat
|
|
5
|
-
* @see StoryFormat.js
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* @
|
|
22
|
-
* @
|
|
23
|
-
* @
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
//
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @external Story
|
|
3
|
+
* @see Story.js
|
|
4
|
+
* @external StoryFormat
|
|
5
|
+
* @see StoryFormat.js
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import fs from 'fs';
|
|
9
|
+
import Story from './Story.js';
|
|
10
|
+
import StoryFormat from './StoryFormat.js';
|
|
11
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @class HTMLWriter
|
|
15
|
+
* @module HTMLWriter
|
|
16
|
+
*/
|
|
17
|
+
export default class HTMLWriter {
|
|
18
|
+
/**
|
|
19
|
+
* Write story to file using story format and adding any CSS and JS
|
|
20
|
+
*
|
|
21
|
+
* @public
|
|
22
|
+
* @static
|
|
23
|
+
* @function writeFile
|
|
24
|
+
* @param {string} file - File to write
|
|
25
|
+
* @param {Story} story - Story object to write
|
|
26
|
+
* @param {StoryFormat} storyFormat - StoryFormat to write
|
|
27
|
+
*/
|
|
28
|
+
static write (file, story, storyFormat) {
|
|
29
|
+
if (!(story instanceof Story)) {
|
|
30
|
+
throw new Error('Error: story must be a Story object!');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (!(storyFormat instanceof StoryFormat)) {
|
|
34
|
+
throw new Error('storyFormat must be a StoryFormat object!');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
let outputContents = '';
|
|
38
|
+
let storyData = '';
|
|
39
|
+
|
|
40
|
+
// Look for StoryTitle
|
|
41
|
+
const storyTitle = story.getPassageByName('StoryTitle');
|
|
42
|
+
|
|
43
|
+
if (storyTitle != null) {
|
|
44
|
+
// Use StoryTitle for name
|
|
45
|
+
storyData += `<tw-storydata name="${storyTitle.text}"`;
|
|
46
|
+
} else {
|
|
47
|
+
throw new Error("'name' is required attribute. (Add StoryTitle to story.)");
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Does start exist?
|
|
51
|
+
if (story.start !== '') {
|
|
52
|
+
// Try to get starting passage
|
|
53
|
+
const startingPassage = story.getPassageByName(story.start);
|
|
54
|
+
// Does it exist currently?
|
|
55
|
+
if (startingPassage !== null) {
|
|
56
|
+
// Add the starting passage
|
|
57
|
+
storyData += ` startnode="${startingPassage.pid}"`;
|
|
58
|
+
} else {
|
|
59
|
+
// Throw error if no starting passage exists
|
|
60
|
+
throw new Error('Starting passage not found');
|
|
61
|
+
}
|
|
62
|
+
} else {
|
|
63
|
+
// Throw error if no starting passage exists
|
|
64
|
+
throw new Error('No starting passage found!');
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Defaults to 'extwee' if missing.
|
|
68
|
+
storyData += ` creator="${story.creator}"`;
|
|
69
|
+
|
|
70
|
+
// Default to extwee version.
|
|
71
|
+
storyData += ` creator-version="${story.creatorVersion}"`;
|
|
72
|
+
|
|
73
|
+
// Check if IFID exists.
|
|
74
|
+
if (story.IFID !== '') {
|
|
75
|
+
// Write the existing IFID
|
|
76
|
+
storyData += ` ifid="${story.IFID}"`;
|
|
77
|
+
} else {
|
|
78
|
+
// Generate a new IFID
|
|
79
|
+
// Twine 2 uses v4 (random) UUIDs, using only capital letters
|
|
80
|
+
storyData += ` ifid="${uuidv4().toUpperCase()}"`;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Write existing or default value.
|
|
84
|
+
storyData += ` zoom="${story.zoom}"`;
|
|
85
|
+
|
|
86
|
+
// Write existing or default value.
|
|
87
|
+
storyData += ` format="${storyFormat.name}"`;
|
|
88
|
+
|
|
89
|
+
// Write existing or default value.
|
|
90
|
+
storyData += ` format-version="${storyFormat.version}"`;
|
|
91
|
+
|
|
92
|
+
// Add the default.
|
|
93
|
+
storyData += ' options hidden>\n';
|
|
94
|
+
|
|
95
|
+
// Start the STYLE.
|
|
96
|
+
storyData += '\t<style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css">';
|
|
97
|
+
|
|
98
|
+
// Get stylesheet passages
|
|
99
|
+
const stylesheetPassages = story.getPassagesByTag('stylesheet');
|
|
100
|
+
|
|
101
|
+
// Concatenate passages
|
|
102
|
+
stylesheetPassages.forEach((passage) => {
|
|
103
|
+
// Add text of passages
|
|
104
|
+
storyData += passage.text;
|
|
105
|
+
// Remove from story
|
|
106
|
+
story.removePassage(passage);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// Close the STYLE
|
|
110
|
+
storyData += '</style>\n';
|
|
111
|
+
|
|
112
|
+
// Start the SCRIPT
|
|
113
|
+
storyData += '\t<script role="script" id="twine-user-script" type="text/twine-javascript">';
|
|
114
|
+
|
|
115
|
+
// Get stylesheet passages
|
|
116
|
+
const scriptPassages = story.getPassagesByTag('script');
|
|
117
|
+
|
|
118
|
+
// Concatenate passages
|
|
119
|
+
scriptPassages.forEach((passage) => {
|
|
120
|
+
// Add text of passages
|
|
121
|
+
storyData += passage.text;
|
|
122
|
+
// Remove from story
|
|
123
|
+
story.removePassage(passage);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
// Close SCRIPT
|
|
127
|
+
storyData += '</script>\n';
|
|
128
|
+
|
|
129
|
+
// Build the passages
|
|
130
|
+
story.forEach((passage) => {
|
|
131
|
+
// Start the passage element
|
|
132
|
+
storyData += '\t<tw-passagedata';
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* pid: (string) Required.
|
|
136
|
+
* The Passage ID (PID).
|
|
137
|
+
*/
|
|
138
|
+
storyData += ` pid="${passage.pid}"`;
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* name: (string) Required.
|
|
142
|
+
* The name of the passage.
|
|
143
|
+
*/
|
|
144
|
+
storyData += ` name="${passage.name}"`;
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* tags: (string) Optional.
|
|
148
|
+
* Any tags for the passage separated by spaces.
|
|
149
|
+
*/
|
|
150
|
+
if (passage.tags.length > 1) {
|
|
151
|
+
storyData += ` tags="${passage.tags.join(' ')}" `;
|
|
152
|
+
} else if (passage.tags.length === 1) {
|
|
153
|
+
storyData += ` tags="${passage.tags[0]}" `;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* position: (string) Optional.
|
|
158
|
+
* Comma-separated X and Y position of the upper-left of the passage
|
|
159
|
+
* when viewed within the Twine 2 editor.
|
|
160
|
+
*/
|
|
161
|
+
if (Object.prototype.hasOwnProperty.call(passage.metadata, 'position')) {
|
|
162
|
+
storyData += ` position="${passage.metadata.position}" `;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* size: (string) Optional.
|
|
167
|
+
* Comma-separated width and height of the passage
|
|
168
|
+
* when viewed within the Twine 2 editor.
|
|
169
|
+
*/
|
|
170
|
+
if (Object.prototype.hasOwnProperty.call(passage.metadata, 'size')) {
|
|
171
|
+
storyData += `size="${passage.metadata.size}" `;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
storyData += `>${passage.text}</tw-passagedata>\n`;
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
storyData += '</tw-storydata>';
|
|
178
|
+
|
|
179
|
+
// Replace the story name in the source file
|
|
180
|
+
storyFormat.source = storyFormat.source.replace(/{{STORY_NAME}}/g, story.name);
|
|
181
|
+
|
|
182
|
+
// Replace the story data
|
|
183
|
+
storyFormat.source = storyFormat.source.replace('{{STORY_DATA}}', storyData);
|
|
184
|
+
|
|
185
|
+
// Combine everything together.
|
|
186
|
+
outputContents += storyFormat.source;
|
|
187
|
+
|
|
188
|
+
try {
|
|
189
|
+
// Try to write.
|
|
190
|
+
fs.writeFileSync(file, outputContents);
|
|
191
|
+
} catch (event) {
|
|
192
|
+
// Throw error
|
|
193
|
+
throw new Error('Error: Cannot write HTML file!');
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
package/src/Passage.js
CHANGED
|
@@ -1,24 +1,202 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @class Passage
|
|
3
|
-
* @module Passage
|
|
4
|
-
*/
|
|
5
|
-
class Passage {
|
|
6
|
-
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* @
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @class Passage
|
|
3
|
+
* @module Passage
|
|
4
|
+
*/
|
|
5
|
+
export default class Passage {
|
|
6
|
+
/**
|
|
7
|
+
* Name of the Passage
|
|
8
|
+
*
|
|
9
|
+
* @private
|
|
10
|
+
*/
|
|
11
|
+
#_name = null;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Internal array of tags
|
|
15
|
+
*
|
|
16
|
+
* @private
|
|
17
|
+
*/
|
|
18
|
+
#_tags = [];
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Internal metadata of passage
|
|
22
|
+
*
|
|
23
|
+
* @private
|
|
24
|
+
*/
|
|
25
|
+
#_metadata = {};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Internal text of the passage
|
|
29
|
+
*
|
|
30
|
+
* @private
|
|
31
|
+
*/
|
|
32
|
+
#_text = '';
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Internal PID of passage
|
|
36
|
+
*
|
|
37
|
+
* @private
|
|
38
|
+
*/
|
|
39
|
+
#_pid = -1;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @function Passage
|
|
43
|
+
* @class
|
|
44
|
+
* @param {string} name - Name
|
|
45
|
+
* @param {string} text - Content
|
|
46
|
+
* @param {Array} tags - Tags
|
|
47
|
+
* @param {object} metadata - Metadata
|
|
48
|
+
* @param {number} pid - Passage ID (PID)
|
|
49
|
+
*/
|
|
50
|
+
constructor (name = '', text = '', tags = [], metadata = {}, pid = -1) {
|
|
51
|
+
// Set name
|
|
52
|
+
this.name = name;
|
|
53
|
+
|
|
54
|
+
// Set tags
|
|
55
|
+
this.tags = tags;
|
|
56
|
+
|
|
57
|
+
// Set metadata
|
|
58
|
+
this.metadata = metadata;
|
|
59
|
+
|
|
60
|
+
// Sets text
|
|
61
|
+
this.text = text;
|
|
62
|
+
|
|
63
|
+
// Sets pid
|
|
64
|
+
this.pid = pid;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Name
|
|
69
|
+
*
|
|
70
|
+
* @public
|
|
71
|
+
* @memberof Passage
|
|
72
|
+
* @returns {string} Name
|
|
73
|
+
*/
|
|
74
|
+
get name () { return this.#_name; }
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* @param {string} s - Name to replace
|
|
78
|
+
*/
|
|
79
|
+
set name (s) {
|
|
80
|
+
if (typeof s === 'string') {
|
|
81
|
+
this.#_name = s;
|
|
82
|
+
} else {
|
|
83
|
+
throw new Error('Name must be a String!');
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Tags
|
|
89
|
+
*
|
|
90
|
+
* @public
|
|
91
|
+
* @memberof Passage
|
|
92
|
+
* @returns {Array} Tags
|
|
93
|
+
*/
|
|
94
|
+
get tags () { return this.#_tags; }
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* @param {Array} t - Replacement array
|
|
98
|
+
*/
|
|
99
|
+
set tags (t) {
|
|
100
|
+
// Test if tags is an array
|
|
101
|
+
if (Array.isArray(t)) {
|
|
102
|
+
this.#_tags = t;
|
|
103
|
+
} else {
|
|
104
|
+
throw new Error('Tags must be an array!');
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Metadata
|
|
110
|
+
*
|
|
111
|
+
* @public
|
|
112
|
+
* @memberof Passage
|
|
113
|
+
* @returns {object} Metadata
|
|
114
|
+
*/
|
|
115
|
+
get metadata () { return this.#_metadata; }
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* @param {object} m - Replacement object
|
|
119
|
+
*/
|
|
120
|
+
set metadata (m) {
|
|
121
|
+
// Test if metadata was an object
|
|
122
|
+
if (typeof m === 'object') {
|
|
123
|
+
this.#_metadata = m;
|
|
124
|
+
} else {
|
|
125
|
+
throw new Error('Metadata should be an object literal!');
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Text
|
|
131
|
+
*
|
|
132
|
+
* @public
|
|
133
|
+
* @memberof Passage
|
|
134
|
+
* @returns {string} Text
|
|
135
|
+
*/
|
|
136
|
+
get text () { return this.#_text; }
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* @param {string} t - Replacement text
|
|
140
|
+
*/
|
|
141
|
+
set text (t) {
|
|
142
|
+
// Test if text is a String
|
|
143
|
+
if (typeof t === 'string') {
|
|
144
|
+
this.#_text = t;
|
|
145
|
+
} else {
|
|
146
|
+
throw new Error('Text should be a String!');
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Passage ID (PID)
|
|
152
|
+
*
|
|
153
|
+
* @public
|
|
154
|
+
* @memberof Passage
|
|
155
|
+
* @returns {number} Passage ID (PID)
|
|
156
|
+
*/
|
|
157
|
+
get pid () { return this.#_pid; }
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* @param {number} p - Replacement PID
|
|
161
|
+
*/
|
|
162
|
+
set pid (p) {
|
|
163
|
+
// Test if PID is a number
|
|
164
|
+
if (Number.isInteger(p)) {
|
|
165
|
+
this.#_pid = p;
|
|
166
|
+
} else {
|
|
167
|
+
throw new Error('PID should be a number!');
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Return a String representation
|
|
173
|
+
*
|
|
174
|
+
* @public
|
|
175
|
+
* @memberof Passage
|
|
176
|
+
* @returns {string} String form of passage
|
|
177
|
+
*/
|
|
178
|
+
toString () {
|
|
179
|
+
// Start empty string.
|
|
180
|
+
let content = '';
|
|
181
|
+
// Write the name
|
|
182
|
+
content += `:: ${this.name}`;
|
|
183
|
+
|
|
184
|
+
// Test if it has any tags
|
|
185
|
+
if (this.tags.length > 0) {
|
|
186
|
+
// Write output of tags
|
|
187
|
+
content += ` [${this.tags.join(' ')}]`;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Check if any properties exist
|
|
191
|
+
if (Object.keys(this.metadata).length > 0) {
|
|
192
|
+
// Write out a space and then passage metadata
|
|
193
|
+
content += ` ${JSON.stringify(this.metadata)}`;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Add newline, text, and two newlines
|
|
197
|
+
content += `\n${this.text}\n\n`;
|
|
198
|
+
|
|
199
|
+
// Return string.
|
|
200
|
+
return content;
|
|
201
|
+
}
|
|
202
|
+
}
|