extwee 2.2.2 → 2.2.3
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 +7 -13
- package/build/extwee +0 -0
- package/build/extwee.web.min.js +1 -1
- package/jest.config.json +5 -0
- package/package.json +18 -15
- package/src/Story.js +1 -1
- package/test/{Passage.test.js → Objects/Passage.test.js} +4 -4
- package/test/{Story.test.js → Objects/Story.test.js} +10 -11
- package/test/{StoryFormat.test.js → Objects/StoryFormat.test.js} +2 -2
- package/types/IFID/generate.d.ts +14 -0
- package/types/JSON/parse.d.ts +51 -0
- package/types/Passage.d.ts +117 -0
- package/types/Story.d.ts +230 -0
- package/types/StoryFormat/parse.d.ts +50 -0
- package/types/StoryFormat.d.ts +121 -0
- package/types/TWS/parse.d.ts +10 -0
- package/types/Twee/parse.d.ts +9 -0
- package/types/Twine1HTML/compile.d.ts +19 -0
- package/types/Twine1HTML/parse.d.ts +9 -0
- package/types/Twine2ArchiveHTML/compile.d.ts +14 -0
- package/types/Twine2ArchiveHTML/parse.d.ts +36 -0
- package/types/Twine2HTML/compile.d.ts +14 -0
- package/types/Twine2HTML/parse.d.ts +20 -0
package/jest.config.json
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "extwee",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.3",
|
|
4
4
|
"description": "A story compiler tool using Twine-compatible formats",
|
|
5
5
|
"author": "Dan Cox",
|
|
6
6
|
"main": "index.js",
|
|
@@ -8,12 +8,13 @@
|
|
|
8
8
|
"extwee": "src/extwee.js"
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
|
-
"test": "jest --runInBand
|
|
11
|
+
"test": "jest --runInBand",
|
|
12
12
|
"lint": "eslint ./src/**/*.js --fix",
|
|
13
13
|
"lint:test": "eslint ./test/**/*.test.js --fix",
|
|
14
14
|
"build:web": "webpack",
|
|
15
15
|
"build:bin": "esbuild ./src/extwee.js --bundle --platform=node --target=node12 --outfile=out.js && pkg -t node18-macos-x64 out.js --output ./build/extwee && rm out.js",
|
|
16
|
-
"
|
|
16
|
+
"gen-types": "npx -p typescript tsc src/**/*.js --declaration --allowJs --emitDeclarationOnly --outDir types",
|
|
17
|
+
"all": "npm run lint && npm run lint:test && npm run test && npm run gen-types"
|
|
17
18
|
},
|
|
18
19
|
"keywords": [
|
|
19
20
|
"twine",
|
|
@@ -24,36 +25,38 @@
|
|
|
24
25
|
"license": "MIT",
|
|
25
26
|
"dependencies": {
|
|
26
27
|
"commander": "^12.0.0",
|
|
28
|
+
"graphemer": "^1.4.0",
|
|
27
29
|
"html-entities": "^2.5.2",
|
|
28
|
-
"node-html-parser": "^6.1.
|
|
30
|
+
"node-html-parser": "^6.1.13",
|
|
29
31
|
"pickleparser": "^0.2.1",
|
|
30
32
|
"semver": "^7.6.0",
|
|
31
33
|
"uuid": "^9.0.1"
|
|
32
34
|
},
|
|
33
35
|
"devDependencies": {
|
|
34
|
-
"@babel/cli": "^7.
|
|
35
|
-
"@babel/core": "^7.24.
|
|
36
|
-
"@babel/eslint-parser": "^7.
|
|
36
|
+
"@babel/cli": "^7.24.1",
|
|
37
|
+
"@babel/core": "^7.24.4",
|
|
38
|
+
"@babel/eslint-parser": "^7.24.1",
|
|
37
39
|
"@babel/eslint-plugin": "^7.23.5",
|
|
38
|
-
"@babel/preset-env": "^7.24.
|
|
40
|
+
"@babel/preset-env": "^7.24.4",
|
|
39
41
|
"@types/uuid": "^9.0.7",
|
|
40
42
|
"babel-loader": "^9.1.3",
|
|
41
|
-
"clean-jsdoc-theme": "^4.2.
|
|
42
|
-
"core-js": "^3.36.
|
|
43
|
-
"esbuild": "^0.20.
|
|
43
|
+
"clean-jsdoc-theme": "^4.2.18",
|
|
44
|
+
"core-js": "^3.36.1",
|
|
45
|
+
"esbuild": "^0.20.2",
|
|
44
46
|
"eslint": "^8.57.0",
|
|
45
47
|
"eslint-config-standard": "^17.1.0",
|
|
46
48
|
"eslint-plugin-import": "^2.29.1",
|
|
47
|
-
"eslint-plugin-jest": "^
|
|
48
|
-
"eslint-plugin-jsdoc": "^48.2.
|
|
49
|
+
"eslint-plugin-jest": "^28.2.0",
|
|
50
|
+
"eslint-plugin-jsdoc": "^48.2.3",
|
|
51
|
+
"eslint-plugin-n": "^16.6.2",
|
|
49
52
|
"eslint-plugin-node": "^11.1.0",
|
|
50
53
|
"eslint-plugin-promise": "^6.1.1",
|
|
51
54
|
"jest": "^29.7.0",
|
|
52
55
|
"pkg": "^5.8.1",
|
|
53
56
|
"regenerator-runtime": "^0.14.1",
|
|
54
57
|
"shelljs": "^0.8.5",
|
|
55
|
-
"typescript": "^5.4.
|
|
56
|
-
"webpack": "^5.
|
|
58
|
+
"typescript": "^5.4.5",
|
|
59
|
+
"webpack": "^5.91.0",
|
|
57
60
|
"webpack-cli": "^5.1.4"
|
|
58
61
|
},
|
|
59
62
|
"repository": {
|
package/src/Story.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import Passage from '
|
|
1
|
+
import Passage from '../../src/Passage.js';
|
|
2
2
|
import { parse as HTMLParser } from 'node-html-parser';
|
|
3
3
|
|
|
4
4
|
describe('Passage', () => {
|
|
@@ -218,8 +218,8 @@ describe('Passage', () => {
|
|
|
218
218
|
});
|
|
219
219
|
|
|
220
220
|
it('Should escape meta-characters safely in Twee header', function () {
|
|
221
|
-
const p = new Passage('Where do tags begin? [well',
|
|
222
|
-
expect(p.toTwee().includes('Where do tags begin?
|
|
221
|
+
const p = new Passage('Where do tags begin? [well', '', ['hmm']);
|
|
222
|
+
expect(p.toTwee().includes('Where do tags begin? [well [hmm]')).toBe(true);
|
|
223
223
|
});
|
|
224
224
|
|
|
225
225
|
it('Should produce valid HTML attributes', function () {
|
|
@@ -232,7 +232,7 @@ describe('Passage', () => {
|
|
|
232
232
|
expect(d.querySelector('tw-passagedata').getAttribute('tags')).toBe('&tag "bad"');
|
|
233
233
|
expect(d.querySelector('tw-passagedata').getAttribute('position')).toBe('100,100');
|
|
234
234
|
// Use Twine 2 result.
|
|
235
|
-
const s =
|
|
235
|
+
const s = '<tw-passagedata pid="1" name=""Test"" tags="&tag "bad"" position="100,100" size="100,100"></tw-passagedata>';
|
|
236
236
|
// Parse HTML.
|
|
237
237
|
const t = new HTMLParser(s);
|
|
238
238
|
// Test Twine 2 attributes.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { Story, creatorName, creatorVersion } from '
|
|
2
|
-
import Passage from '
|
|
3
|
-
import { parse as parseTwee } from '
|
|
1
|
+
import { Story, creatorName, creatorVersion } from '../../src/Story.js';
|
|
2
|
+
import Passage from '../../src/Passage.js';
|
|
3
|
+
import { parse as parseTwee } from '../../src/Twee/parse.js';
|
|
4
4
|
import { readFileSync } from 'node:fs';
|
|
5
5
|
import { parse as HTMLParser } from 'node-html-parser';
|
|
6
|
-
import { generate as generateIFID } from '
|
|
6
|
+
import { generate as generateIFID } from '../../src/IFID/generate.js';
|
|
7
7
|
|
|
8
8
|
// Pull the name and version of this project from package.json.
|
|
9
9
|
// These are used as the 'creator' and 'creator-version'.
|
|
@@ -444,7 +444,7 @@ describe('Story', () => {
|
|
|
444
444
|
const t = s.toTwee();
|
|
445
445
|
|
|
446
446
|
// Test for format in metadata, should not exist.
|
|
447
|
-
expect(t.includes(
|
|
447
|
+
expect(t.includes('"\'format":')).not.toBe(true);
|
|
448
448
|
});
|
|
449
449
|
|
|
450
450
|
it('Should not generate formatVersion if empty', function () {
|
|
@@ -461,7 +461,7 @@ describe('Story', () => {
|
|
|
461
461
|
const t = s.toTwee();
|
|
462
462
|
|
|
463
463
|
// Test for formatVersion in metadata, should not exist.
|
|
464
|
-
expect(t.includes(
|
|
464
|
+
expect(t.includes('"\'format-version":')).not.toBe(true);
|
|
465
465
|
});
|
|
466
466
|
|
|
467
467
|
it('Should not generate zoom if zero', function () {
|
|
@@ -478,7 +478,7 @@ describe('Story', () => {
|
|
|
478
478
|
const t = s.toTwee();
|
|
479
479
|
|
|
480
480
|
// Test for zoom in metadata, should not exist.
|
|
481
|
-
expect(t.includes(
|
|
481
|
+
expect(t.includes('"\'zoom":')).not.toBe(true);
|
|
482
482
|
});
|
|
483
483
|
|
|
484
484
|
it('Should not generate start if empty', function () {
|
|
@@ -495,7 +495,7 @@ describe('Story', () => {
|
|
|
495
495
|
const t = s.toTwee();
|
|
496
496
|
|
|
497
497
|
// Test for start in metadata, should not exist.
|
|
498
|
-
expect(t.includes(
|
|
498
|
+
expect(t.includes('"\'start":')).not.toBe(true);
|
|
499
499
|
});
|
|
500
500
|
|
|
501
501
|
it('Should detect StoryTitle text', function () {
|
|
@@ -781,7 +781,7 @@ describe('Story', () => {
|
|
|
781
781
|
expect(result.includes(`creator-version="${creatorVersion}"`)).not.toBe(true);
|
|
782
782
|
});
|
|
783
783
|
|
|
784
|
-
|
|
784
|
+
it('Should not encode creator if not set', () => {
|
|
785
785
|
// Add passage.
|
|
786
786
|
s.addPassage(new Passage('Start', 'Word'));
|
|
787
787
|
// Set start.
|
|
@@ -793,7 +793,6 @@ describe('Story', () => {
|
|
|
793
793
|
// Expect the creator to be encoded.
|
|
794
794
|
expect(result.includes(`creator="${creatorName}"`)).not.toBe(true);
|
|
795
795
|
});
|
|
796
|
-
|
|
797
796
|
});
|
|
798
797
|
|
|
799
798
|
describe('toTwine1HTML()', function () {
|
|
@@ -828,7 +827,7 @@ describe('Story', () => {
|
|
|
828
827
|
// Expect correct name attribute for tw-passagedata.
|
|
829
828
|
expect(root.querySelector('tw-passagedata').getAttribute('name')).toBe('"Test"');
|
|
830
829
|
// Use Twine 2 result.
|
|
831
|
-
const s2 =
|
|
830
|
+
const s2 = '<tw-storydata name=""Abuse" &test" startnode="1" creator="Twine" creator-version="2.8.1" format="Harlowe" format-version="3.3.8" ifid="452A9D80-C759-42C5-B001-5B861A2410C5" options="" tags="" zoom="1" hidden><style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style><script role="script" id="twine-user-script" type="text/twine-javascript"></script><tw-passagedata pid="1" name=""Test"" tags="&tag "bad"" position="300,100" size="100,100"></tw-passagedata></tw-storydata>';
|
|
832
831
|
// Parse HTML.
|
|
833
832
|
const root2 = HTMLParser(s2);
|
|
834
833
|
// Expect correct name attribute for tw-storydata.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import StoryFormat from '
|
|
1
|
+
import StoryFormat from '../../src/StoryFormat.js';
|
|
2
2
|
|
|
3
3
|
describe('StoryFormat', () => {
|
|
4
4
|
describe('Default values', () => {
|
|
@@ -153,7 +153,7 @@ describe('StoryFormat', () => {
|
|
|
153
153
|
describe('toString', () => {
|
|
154
154
|
it('Should return string representation', () => {
|
|
155
155
|
const sf = new StoryFormat();
|
|
156
|
-
expect(sf.toString()).toBe(JSON.stringify(sf, null,
|
|
156
|
+
expect(sf.toString()).toBe(JSON.stringify(sf, null, '\t'));
|
|
157
157
|
});
|
|
158
158
|
});
|
|
159
159
|
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates an Interactive Fiction Identification (IFID) based the Treaty of Babel.
|
|
3
|
+
*
|
|
4
|
+
* For Twine works, the IFID is a UUID (v4) in uppercase.
|
|
5
|
+
* @see Treaty of Babel ({@link https://babel.ifarchive.org/babel_rev11.html#the-ifid-for-an-html-story-file})
|
|
6
|
+
* @function generate
|
|
7
|
+
* @description Generates a new IFID.
|
|
8
|
+
* @returns {string} IFID
|
|
9
|
+
* @example
|
|
10
|
+
* const ifid = generate();
|
|
11
|
+
* console.log(ifid);
|
|
12
|
+
* // => 'A1B2C3D4-E5F6-G7H8-I9J0-K1L2M3N4O5P6'
|
|
13
|
+
*/
|
|
14
|
+
export function generate(): string;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse JSON representation into Story.
|
|
3
|
+
* @see {@link https://github.com/iftechfoundation/twine-specs/blob/master/twine-2-jsonoutput-doc.md Twine 2 JSON Specification}
|
|
4
|
+
* @function parse
|
|
5
|
+
* @param {string} jsonString - JSON string to convert to Story.
|
|
6
|
+
* @throws {Error} - Invalid JSON!
|
|
7
|
+
* @returns {Story} Story object.
|
|
8
|
+
* @example
|
|
9
|
+
* const jsonString = `{
|
|
10
|
+
* "name": "My Story",
|
|
11
|
+
* "start": "First Passage",
|
|
12
|
+
* "ifid": "A1B2C3D4-E5F6-G7H8-I9J0-K1L2M3N4O5P6",
|
|
13
|
+
* "format": "SugarCube",
|
|
14
|
+
* "formatVersion": "2.31.0",
|
|
15
|
+
* "creator": "Twine",
|
|
16
|
+
* "creatorVersion": "2.3.9",
|
|
17
|
+
* "zoom": 1,
|
|
18
|
+
* "passages": [
|
|
19
|
+
* {
|
|
20
|
+
* "name": "First Passage",
|
|
21
|
+
* "tags": "",
|
|
22
|
+
* "metadata": "",
|
|
23
|
+
* "text": "This is the first passage."
|
|
24
|
+
* },
|
|
25
|
+
* ]
|
|
26
|
+
* }`;
|
|
27
|
+
* const story = parse(jsonString);
|
|
28
|
+
* console.log(story);
|
|
29
|
+
* // => Story {
|
|
30
|
+
* // name: 'My Story',
|
|
31
|
+
* // start: 'First Passage',
|
|
32
|
+
* // IFID: 'A1B2C3D4-E5F6-G7H8-I9J0-K1L2M3N4O5P6',
|
|
33
|
+
* // format: 'SugarCube',
|
|
34
|
+
* // formatVersion: '2.31.0',
|
|
35
|
+
* // creator: 'Twine',
|
|
36
|
+
* // creatorVersion: '2.3.9',
|
|
37
|
+
* // zoom: 1,
|
|
38
|
+
* // tagColors: {},
|
|
39
|
+
* // metadata: {},
|
|
40
|
+
* // passages: [
|
|
41
|
+
* // Passage {
|
|
42
|
+
* // name: 'First Passage',
|
|
43
|
+
* // tags: '',
|
|
44
|
+
* // metadata: '',
|
|
45
|
+
* // text: 'This is the first passage.'
|
|
46
|
+
* // }
|
|
47
|
+
* // ]
|
|
48
|
+
* // }
|
|
49
|
+
*/
|
|
50
|
+
export function parse(jsonString: string): Story;
|
|
51
|
+
import { Story } from '../Story.js';
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Passage class.
|
|
3
|
+
* @class
|
|
4
|
+
* @classdesc Represents a passage in a Twine story.
|
|
5
|
+
* @property {string} name - Name of the passage.
|
|
6
|
+
* @property {Array} tags - Tags for the passage.
|
|
7
|
+
* @property {object} metadata - Metadata for the passage.
|
|
8
|
+
* @property {string} text - Text content of the passage.
|
|
9
|
+
* @method {string} toTwee - Return a Twee representation.
|
|
10
|
+
* @method {string} toJSON - Return JSON representation.
|
|
11
|
+
* @method {string} toTwine2HTML - Return Twine 2 HTML representation.
|
|
12
|
+
* @method {string} toTwine1HTML - Return Twine 1 HTML representation.
|
|
13
|
+
* @example
|
|
14
|
+
* const p = new Passage('Start', 'This is the start of the story.');
|
|
15
|
+
* console.log(p.toTwee());
|
|
16
|
+
* // :: Start
|
|
17
|
+
* // This is the start of the story.
|
|
18
|
+
* //
|
|
19
|
+
* console.log(p.toJSON());
|
|
20
|
+
* // {"name":"Start","tags":[],"metadata":{},"text":"This is the start of the story."}
|
|
21
|
+
* console.log(p.toTwine2HTML());
|
|
22
|
+
* // <tw-passagedata pid="1" name="Start" tags="" >This is the start of the story.</tw-passagedata>
|
|
23
|
+
* console.log(p.toTwine1HTML());
|
|
24
|
+
* // <div tiddler="Start" tags="" modifier="extwee" twine-position="10,10">This is the start of the story.</div>
|
|
25
|
+
* @example
|
|
26
|
+
* const p = new Passage('Start', 'This is the start of the story.', ['start', 'beginning'], {position: '10,10', size: '100,100'});
|
|
27
|
+
* console.log(p.toTwee());
|
|
28
|
+
* // :: Start [start beginning] {"position":"10,10","size":"100,100"}
|
|
29
|
+
* // This is the start of the story.
|
|
30
|
+
* //
|
|
31
|
+
* console.log(p.toJSON());
|
|
32
|
+
* // {"name":"Start","tags":["start","beginning"],"metadata":{"position":"10,10","size":"100,100"},"text":"This is the start of the story."}
|
|
33
|
+
* console.log(p.toTwine2HTML());
|
|
34
|
+
* // <tw-passagedata pid="1" name="Start" tags="start beginning" position="10,10" size="100,100">This is the start of the story.</tw-passagedata>
|
|
35
|
+
* console.log(p.toTwine1HTML());
|
|
36
|
+
* // <div tiddler="Start" tags="start beginning" modifier="extwee" twine-position="10,10">This is the start of the story.</div>
|
|
37
|
+
*/
|
|
38
|
+
export default class Passage {
|
|
39
|
+
/**
|
|
40
|
+
* Create a passage.
|
|
41
|
+
* @param {string} name - Name
|
|
42
|
+
* @param {string} text - Content
|
|
43
|
+
* @param {Array} tags - Tags
|
|
44
|
+
* @param {object} metadata - Metadata
|
|
45
|
+
*/
|
|
46
|
+
constructor(name?: string, text?: string, tags?: any[], metadata?: object);
|
|
47
|
+
/**
|
|
48
|
+
* @param {string} s - Name to replace
|
|
49
|
+
* @throws {Error} Name must be a String!
|
|
50
|
+
*/
|
|
51
|
+
set name(s: string);
|
|
52
|
+
/**
|
|
53
|
+
* Name
|
|
54
|
+
* @returns {string} Name
|
|
55
|
+
*/
|
|
56
|
+
get name(): string;
|
|
57
|
+
/**
|
|
58
|
+
* @param {Array} t - Replacement array
|
|
59
|
+
* @throws {Error} Tags must be an array!
|
|
60
|
+
*/
|
|
61
|
+
set tags(t: any[]);
|
|
62
|
+
/**
|
|
63
|
+
* Tags
|
|
64
|
+
* @returns {Array} Tags
|
|
65
|
+
*/
|
|
66
|
+
get tags(): any[];
|
|
67
|
+
/**
|
|
68
|
+
* @param {object} m - Replacement object
|
|
69
|
+
* @throws {Error} Metadata must be an object literal!
|
|
70
|
+
*/
|
|
71
|
+
set metadata(m: any);
|
|
72
|
+
/**
|
|
73
|
+
* Metadata
|
|
74
|
+
* @returns {object} Metadata
|
|
75
|
+
*/
|
|
76
|
+
get metadata(): any;
|
|
77
|
+
/**
|
|
78
|
+
* @param {string} t - Replacement text
|
|
79
|
+
* @throws {Error} Text should be a String!
|
|
80
|
+
*/
|
|
81
|
+
set text(t: string);
|
|
82
|
+
/**
|
|
83
|
+
* Text
|
|
84
|
+
* @returns {string} Text
|
|
85
|
+
*/
|
|
86
|
+
get text(): string;
|
|
87
|
+
/**
|
|
88
|
+
* Return a Twee representation.
|
|
89
|
+
*
|
|
90
|
+
* See: https://github.com/iftechfoundation/twine-specs/blob/master/twee-3-specification.md
|
|
91
|
+
*
|
|
92
|
+
* @method toTwee
|
|
93
|
+
* @returns {string} String form of passage.
|
|
94
|
+
*/
|
|
95
|
+
toTwee(): string;
|
|
96
|
+
/**
|
|
97
|
+
* Return JSON representation.
|
|
98
|
+
* @method toJSON
|
|
99
|
+
* @returns {string} JSON string.
|
|
100
|
+
*/
|
|
101
|
+
toJSON(): string;
|
|
102
|
+
/**
|
|
103
|
+
* Return Twine 2 HTML representation.
|
|
104
|
+
* (Default Passage ID is 1.)
|
|
105
|
+
* @method toTwine2HTML
|
|
106
|
+
* @param {number} pid - Passage ID (PID) to record in HTML.
|
|
107
|
+
* @returns {string} Twine 2 HTML string.
|
|
108
|
+
*/
|
|
109
|
+
toTwine2HTML(pid?: number): string;
|
|
110
|
+
/**
|
|
111
|
+
* Return Twine 1 HTML representation.
|
|
112
|
+
* @method toTwine1HTML
|
|
113
|
+
* @returns {string} Twine 1 HTML string.
|
|
114
|
+
*/
|
|
115
|
+
toTwine1HTML(): string;
|
|
116
|
+
#private;
|
|
117
|
+
}
|
package/types/Story.d.ts
ADDED
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Story class.
|
|
3
|
+
* @class
|
|
4
|
+
* @classdesc Represents a Twine story.
|
|
5
|
+
* @property {string} name - Name of the story.
|
|
6
|
+
* @property {string} IFID - Interactive Fiction ID (IFID) of Story.
|
|
7
|
+
* @property {string} start - Name of start passage.
|
|
8
|
+
* @property {string} format - Story format of Story.
|
|
9
|
+
* @property {string} formatVersion - Story format version of Story.
|
|
10
|
+
* @property {number} zoom - Zoom level.
|
|
11
|
+
* @property {Array} passages - Array of Passage objects. @see {@link Passage}
|
|
12
|
+
* @property {string} creator - Program used to create Story.
|
|
13
|
+
* @property {string} creatorVersion - Version used to create Story.
|
|
14
|
+
* @property {object} metadata - Metadata of Story.
|
|
15
|
+
* @property {object} tagColors - Tag Colors
|
|
16
|
+
* @method {number} addPassage - Add a passage to the story and returns the new length of the passages array.
|
|
17
|
+
* @method {number} removePassageByName - Remove a passage from the story by name and returns the new length of the passages array.
|
|
18
|
+
* @method {Array} getPassagesByTag - Find passages by tag.
|
|
19
|
+
* @method {Array} getPassageByName - Find passage by name.
|
|
20
|
+
* @method {number} size - Size (number of passages).
|
|
21
|
+
* @method {string} toJSON - Export Story as JSON representation.
|
|
22
|
+
* @method {string} toTwee - Return Twee representation.
|
|
23
|
+
* @method {string} toTwine2HTML - Return Twine 2 HTML representation.
|
|
24
|
+
* @method {string} toTwine1HTML - Return Twine 1 HTML representation.
|
|
25
|
+
* @example
|
|
26
|
+
* const story = new Story('My Story');
|
|
27
|
+
* story.IFID = '12345678-1234-5678-1234-567812345678';
|
|
28
|
+
* story.start = 'Start';
|
|
29
|
+
* story.format = 'SugarCube';
|
|
30
|
+
* story.formatVersion = '2.31.0';
|
|
31
|
+
* story.zoom = 1;
|
|
32
|
+
* story.creator = 'extwee';
|
|
33
|
+
* story.creatorVersion = '2.2.1';
|
|
34
|
+
*/
|
|
35
|
+
export class Story {
|
|
36
|
+
/**
|
|
37
|
+
* Creates a story.
|
|
38
|
+
* @param {string} name - Name of the story.
|
|
39
|
+
*/
|
|
40
|
+
constructor(name?: string);
|
|
41
|
+
/**
|
|
42
|
+
* @param {string} a - Replacement story name
|
|
43
|
+
*/
|
|
44
|
+
set name(a: string);
|
|
45
|
+
/**
|
|
46
|
+
* Each story has a name
|
|
47
|
+
* @returns {string} Name
|
|
48
|
+
*/
|
|
49
|
+
get name(): string;
|
|
50
|
+
/**
|
|
51
|
+
* @param {object} a - Replacement tag colors
|
|
52
|
+
*/
|
|
53
|
+
set tagColors(a: any);
|
|
54
|
+
/**
|
|
55
|
+
* Tag Colors object (each property is a tag and its color)
|
|
56
|
+
* @returns {object} tag colors array
|
|
57
|
+
*/
|
|
58
|
+
get tagColors(): any;
|
|
59
|
+
/**
|
|
60
|
+
* @param {string} i - Replacement IFID.
|
|
61
|
+
*/
|
|
62
|
+
set IFID(i: string);
|
|
63
|
+
/**
|
|
64
|
+
* Interactive Fiction ID (IFID) of Story.
|
|
65
|
+
* @returns {string} IFID
|
|
66
|
+
*/
|
|
67
|
+
get IFID(): string;
|
|
68
|
+
/**
|
|
69
|
+
* @param {string} s - Replacement start
|
|
70
|
+
*/
|
|
71
|
+
set start(s: string);
|
|
72
|
+
/**
|
|
73
|
+
* Name of start passage.
|
|
74
|
+
* @returns {string} start
|
|
75
|
+
*/
|
|
76
|
+
get start(): string;
|
|
77
|
+
/**
|
|
78
|
+
* @param {string} f - Replacement format version
|
|
79
|
+
*/
|
|
80
|
+
set formatVersion(f: string);
|
|
81
|
+
/**
|
|
82
|
+
* Story format version of Story.
|
|
83
|
+
* @returns {string} story format version
|
|
84
|
+
*/
|
|
85
|
+
get formatVersion(): string;
|
|
86
|
+
/**
|
|
87
|
+
* @param {object} o - Replacement metadata
|
|
88
|
+
*/
|
|
89
|
+
set metadata(o: any);
|
|
90
|
+
/**
|
|
91
|
+
* Metadata of Story.
|
|
92
|
+
* @returns {object} metadata of story
|
|
93
|
+
*/
|
|
94
|
+
get metadata(): any;
|
|
95
|
+
/**
|
|
96
|
+
* @param {string} f - Replacement format
|
|
97
|
+
*/
|
|
98
|
+
set format(f: string);
|
|
99
|
+
/**
|
|
100
|
+
* Story format of Story.
|
|
101
|
+
* @returns {string} format
|
|
102
|
+
*/
|
|
103
|
+
get format(): string;
|
|
104
|
+
/**
|
|
105
|
+
* @param {string} c - Creator Program of Story
|
|
106
|
+
*/
|
|
107
|
+
set creator(c: string);
|
|
108
|
+
/**
|
|
109
|
+
* Program used to create Story.
|
|
110
|
+
* @returns {string} Creator Program
|
|
111
|
+
*/
|
|
112
|
+
get creator(): string;
|
|
113
|
+
/**
|
|
114
|
+
* @param {string} c - Version of creator program
|
|
115
|
+
*/
|
|
116
|
+
set creatorVersion(c: string);
|
|
117
|
+
/**
|
|
118
|
+
* Version used to create Story.
|
|
119
|
+
* @returns {string} Version
|
|
120
|
+
*/
|
|
121
|
+
get creatorVersion(): string;
|
|
122
|
+
/**
|
|
123
|
+
* @param {number} n - Replacement zoom level
|
|
124
|
+
*/
|
|
125
|
+
set zoom(n: number);
|
|
126
|
+
/**
|
|
127
|
+
* Zoom level.
|
|
128
|
+
* @returns {number} Zoom level
|
|
129
|
+
*/
|
|
130
|
+
get zoom(): number;
|
|
131
|
+
/**
|
|
132
|
+
* Set passages in Story.
|
|
133
|
+
* @param {Array} p - Replacement passages
|
|
134
|
+
* @property {Array} passages - Passages
|
|
135
|
+
* @throws {Error} Passages must be an Array!
|
|
136
|
+
* @throws {Error} Passages must be an Array of Passage objects!
|
|
137
|
+
*/
|
|
138
|
+
set passages(p: any[]);
|
|
139
|
+
/**
|
|
140
|
+
* Passages in Story.
|
|
141
|
+
* @returns {Array} Passages
|
|
142
|
+
* @property {Array} passages - Passages
|
|
143
|
+
*/
|
|
144
|
+
get passages(): any[];
|
|
145
|
+
/**
|
|
146
|
+
* Add a passage to the story.
|
|
147
|
+
* Passing `StoryData` will override story metadata and `StoryTitle` will override story name.
|
|
148
|
+
* @method addPassage
|
|
149
|
+
* @param {Passage} p - Passage to add to Story.
|
|
150
|
+
* @returns {number} Return new length of passages array.
|
|
151
|
+
*/
|
|
152
|
+
addPassage(p: Passage): number;
|
|
153
|
+
/**
|
|
154
|
+
* Remove a passage from the story by name.
|
|
155
|
+
* @method removePassageByName
|
|
156
|
+
* @param {string} name - Passage name to remove.
|
|
157
|
+
* @returns {number} Return new length of passages array.
|
|
158
|
+
*/
|
|
159
|
+
removePassageByName(name: string): number;
|
|
160
|
+
/**
|
|
161
|
+
* Find passages by tag.
|
|
162
|
+
* @method getPassagesByTag
|
|
163
|
+
* @param {string} t - Passage name to search for
|
|
164
|
+
* @returns {Array} Return array of passages
|
|
165
|
+
*/
|
|
166
|
+
getPassagesByTag(t: string): any[];
|
|
167
|
+
/**
|
|
168
|
+
* Find passage by name.
|
|
169
|
+
* @method getPassageByName
|
|
170
|
+
* @param {string} name - Passage name to search for
|
|
171
|
+
* @returns {Passage | null} Return passage or null
|
|
172
|
+
*/
|
|
173
|
+
getPassageByName(name: string): Passage | null;
|
|
174
|
+
/**
|
|
175
|
+
* Size (number of passages).
|
|
176
|
+
* @method size
|
|
177
|
+
* @returns {number} Return number of passages
|
|
178
|
+
*/
|
|
179
|
+
size(): number;
|
|
180
|
+
/**
|
|
181
|
+
* Export Story as JSON representation.
|
|
182
|
+
* @method toJSON
|
|
183
|
+
* @returns {string} JSON string.
|
|
184
|
+
*/
|
|
185
|
+
toJSON(): string;
|
|
186
|
+
/**
|
|
187
|
+
* Return Twee representation.
|
|
188
|
+
*
|
|
189
|
+
* See: Twee 3 Specification
|
|
190
|
+
* (https://github.com/iftechfoundation/twine-specs/blob/master/twee-3-specification.md)
|
|
191
|
+
*
|
|
192
|
+
* @method toTwee
|
|
193
|
+
* @returns {string} Twee String
|
|
194
|
+
*/
|
|
195
|
+
toTwee(): string;
|
|
196
|
+
/**
|
|
197
|
+
* Return Twine 2 HTML.
|
|
198
|
+
*
|
|
199
|
+
* See: Twine 2 HTML Output
|
|
200
|
+
* (https://github.com/iftechfoundation/twine-specs/blob/master/twine-2-htmloutput-spec.md)
|
|
201
|
+
*
|
|
202
|
+
* The only required attributes are `name` and `ifid` of the `<tw-storydata>` element. All others are optional.
|
|
203
|
+
*
|
|
204
|
+
* The `<tw-storydata>` element may have any number of optional attributes, which are:
|
|
205
|
+
* - `startnode`: (integer) Optional. The PID of the starting passage.
|
|
206
|
+
* - `creator`: (string) Optional. The name of the program that created the story.
|
|
207
|
+
* - `creator-version`: (string) Optional. The version of the program that created the story.
|
|
208
|
+
* - `zoom`: (decimal) Optional. The zoom level of the story.
|
|
209
|
+
* - `format`: (string) Optional. The format of the story.
|
|
210
|
+
* - `format-version`: (string) Optional. The version of the format of the story.
|
|
211
|
+
*
|
|
212
|
+
* @method toTwine2HTML
|
|
213
|
+
* @returns {string} Twine 2 HTML string
|
|
214
|
+
*/
|
|
215
|
+
toTwine2HTML(): string;
|
|
216
|
+
/**
|
|
217
|
+
* Return Twine 1 HTML.
|
|
218
|
+
*
|
|
219
|
+
* See: Twine 1 HTML Output
|
|
220
|
+
* (https://github.com/iftechfoundation/twine-specs/blob/master/twine-1-htmloutput-doc.md)
|
|
221
|
+
*
|
|
222
|
+
* @method toTwine1HTML
|
|
223
|
+
* @returns {string} Twine 1 HTML string.
|
|
224
|
+
*/
|
|
225
|
+
toTwine1HTML(): string;
|
|
226
|
+
#private;
|
|
227
|
+
}
|
|
228
|
+
export const creatorName: "extwee";
|
|
229
|
+
export const creatorVersion: "2.2.3";
|
|
230
|
+
import Passage from './Passage.js';
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parses story format content into a {@link StoryFormat} object.
|
|
3
|
+
*
|
|
4
|
+
* Story formats are generally JSONP files containing a JSON object with the following properties:
|
|
5
|
+
* - name: (string) Optional. (Omitting the name will lead to an Untitled Story Format.)
|
|
6
|
+
* - version: (string) Required, and semantic version-style formatting (x.y.z, e.g., 1.2.1) of the version is also required.
|
|
7
|
+
* - author: (string) Optional.
|
|
8
|
+
* - description: (string) Optional.
|
|
9
|
+
* - image: (string) Optional.
|
|
10
|
+
* - url: (string) Optional.
|
|
11
|
+
* - license: (string) Optional.
|
|
12
|
+
* - proofing: (boolean) Optional (defaults to false).
|
|
13
|
+
* - source: (string) Required.
|
|
14
|
+
*
|
|
15
|
+
* If existing properties do not match their expected type, a warning will be produced and incoming value will be ignored.
|
|
16
|
+
*
|
|
17
|
+
* This function does "soft parsing." It will not throw an error if a specific property is missing or malformed.
|
|
18
|
+
* @see {@link https://github.com/iftechfoundation/twine-specs/blob/master/twine-2-storyformats-spec.md Twine 2 Story Formats Specification}
|
|
19
|
+
* @function parse
|
|
20
|
+
* @param {string} contents - JSONP content.
|
|
21
|
+
* @throws {Error} - Unable to find Twine 2 JSON chunk!
|
|
22
|
+
* @throws {Error} - Unable to parse Twine 2 JSON chunk!
|
|
23
|
+
* @returns {StoryFormat} StoryFormat object.
|
|
24
|
+
* @example
|
|
25
|
+
* const contents = `{
|
|
26
|
+
* "name": "My Story Format",
|
|
27
|
+
* "version": "1.0.0",
|
|
28
|
+
* "author": "Twine",
|
|
29
|
+
* "description": "A story format.",
|
|
30
|
+
* "image": "icon.svg",
|
|
31
|
+
* "url": "https://example.com",
|
|
32
|
+
* "license": "MIT",
|
|
33
|
+
* "proofing": false,
|
|
34
|
+
* "source": "<html></html>"
|
|
35
|
+
* }`;
|
|
36
|
+
* const storyFormat = parse(contents);
|
|
37
|
+
* console.log(storyFormat);
|
|
38
|
+
* // => StoryFormat {
|
|
39
|
+
* // name: 'My Story Format',
|
|
40
|
+
* // version: '1.0.0',
|
|
41
|
+
* // description: 'A story format.',
|
|
42
|
+
* // image: 'icon.svg',
|
|
43
|
+
* // url: 'https://example.com',
|
|
44
|
+
* // license: 'MIT',
|
|
45
|
+
* // proofing: false,
|
|
46
|
+
* // source: '<html></html>'
|
|
47
|
+
* // }
|
|
48
|
+
*/
|
|
49
|
+
export function parse(contents: string): StoryFormat;
|
|
50
|
+
import StoryFormat from '../StoryFormat.js';
|