extwee 2.2.6 → 2.3.1
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/.github/dependabot.yml +1 -1
- package/.github/workflows/dependabot-automerge.yml +23 -0
- package/.github/workflows/nodejs.yml +4 -1
- package/README.md +9 -0
- package/SECURITY.md +1 -1
- package/build/extwee.web.min.js +2 -0
- package/build/extwee.web.min.js.LICENSE.txt +1 -0
- package/docs/README.md +79 -55
- package/docs/_sidebar.md +0 -1
- package/docs/install/npm.md +0 -4
- package/docs/install/npx.md +70 -0
- package/extwee.config.json +6 -0
- package/extwee.config.md +67 -0
- package/package.json +22 -22
- package/src/CLI/CommandLineProcessing.js +196 -0
- package/src/CLI/ProcessConfig/loadStoryFormat.js +102 -0
- package/src/CLI/ProcessConfig/readDirectories.js +46 -0
- package/src/CLI/ProcessConfig.js +175 -0
- package/src/CLI/isDirectory.js +27 -0
- package/src/CLI/isFile.js +28 -0
- package/src/Config/parser.js +30 -8
- package/src/Passage.js +17 -2
- package/src/Story.js +92 -1
- package/src/extwee.js +20 -195
- package/test/Config/Config.test.js +40 -10
- package/test/Config/files/full.json +8 -0
- package/test/Config/files/valid.json +4 -3
- package/test/Config/isDirectory.test.js +44 -0
- package/test/Config/isFile.test.js +50 -0
- package/test/Config/loadStoryFormat.test.js +101 -0
- package/test/Config/readDirectories.test.js +68 -0
- package/test/Objects/Passage.test.js +5 -0
- package/test/Objects/Story.test.js +131 -0
- package/test/TWS/Parse.test.js +0 -22
- package/test/Web/window.Extwee.test.js +85 -0
- package/types/Story.d.ts +25 -0
- package/types/index.d.ts +4 -2
- package/types/src/CLI/CommandLineProcessing.d.ts +8 -0
- package/types/src/CLI/ProcessConfig/loadStoryFormat.d.ts +20 -0
- package/types/src/CLI/ProcessConfig/readDirectories.d.ts +9 -0
- package/types/src/CLI/ProcessConfig.d.ts +12 -0
- package/types/src/CLI/isDirectory.d.ts +1 -0
- package/types/src/CLI/isFile.d.ts +1 -0
- package/types/src/Config/parser.d.ts +6 -0
- package/types/src/Config/reader.d.ts +11 -0
- package/types/src/IFID/generate.d.ts +14 -0
- package/types/src/JSON/parse.d.ts +44 -1
- package/types/src/Passage.d.ts +49 -4
- package/types/src/Story.d.ts +110 -16
- package/types/src/StoryFormat/compile.d.ts +8 -0
- package/types/src/StoryFormat/parse.d.ts +46 -3
- package/types/src/StoryFormat.d.ts +69 -38
- package/types/src/TWS/parse.d.ts +3 -3
- package/types/src/Twee/parse.d.ts +3 -4
- package/types/src/Twine1HTML/compile.d.ts +3 -1
- package/types/src/Twine1HTML/parse.d.ts +3 -4
- package/types/src/Twine2ArchiveHTML/compile.d.ts +8 -0
- package/types/src/Twine2ArchiveHTML/parse.d.ts +31 -1
- package/types/src/Twine2HTML/compile.d.ts +7 -2
- package/types/src/Twine2HTML/parse.d.ts +12 -9
- package/docs/install/binaries.md +0 -9
- package/index.html +0 -22
- package/test/TWS/TWSParser/Example1.tws +0 -150
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/*! https://mths.be/he v1.2.0 by @mathias | MIT license */
|
package/docs/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
<a name="readme-top"></a>
|
|
2
2
|
|
|
3
3
|
[](https://codecov.io/gh/videlais/extwee)
|
|
4
4
|
|
|
@@ -8,13 +8,31 @@
|
|
|
8
8
|
|
|
9
9
|
[](https://www.npmjs.com/package/extwee)
|
|
10
10
|
|
|
11
|
+
## Table of Contents
|
|
12
|
+
|
|
13
|
+
<ol>
|
|
14
|
+
<li><a href="#story-compilation">Story Compilation</a></li>
|
|
15
|
+
<li><a href="#format-support">Format Support</a></li>
|
|
16
|
+
<li><a href="#usage">Node and Web API</a></li>
|
|
17
|
+
<ol>
|
|
18
|
+
<li><a href="#objects">Objects</a></li>
|
|
19
|
+
<li><a href="#parsers">Parsers</a></li>
|
|
20
|
+
<li><a href="#compilers">Compilers</a></li>
|
|
21
|
+
</ol>
|
|
22
|
+
<li><a href="#documentation">Documentation</a></li>
|
|
23
|
+
<li><a href="#command-line-usage">Command-Line Usage</a></li>
|
|
24
|
+
<li><a href="#config-file-usage">Config File Usage</a></li>
|
|
25
|
+
<li><a href="#escaping- meta-characters">Escaping Meta-Characters</a></li>
|
|
26
|
+
<li><a href="#license">License</a></li>
|
|
27
|
+
</ol>
|
|
28
|
+
|
|
11
29
|
## Story Compilation
|
|
12
30
|
|
|
13
|
-
The process of *story compilation* converts human-readable content, what is generally called a *story*, into a playable format such as HyperText Markup Language (HTML)
|
|
31
|
+
The process of *story compilation* converts human-readable content, what is generally called a *story*, into a playable format such as HyperText Markup Language (HTML). The result is then presented as links or other visual, interactive elements for another party.
|
|
14
32
|
|
|
15
|
-
The term *compilation* is used because different parts of code are put together in a specific arrangement to enable later play. As part of Twine-compatible HTML, this means combining story format
|
|
33
|
+
The term *compilation* is used because different parts of code are put together in a specific arrangement to enable later play. As part of Twine-compatible HTML, this means combining JavaScript code (generally a "story format") with story HTML data.
|
|
16
34
|
|
|
17
|
-
Extwee is **not** an authoring tool. It cannot be used to create story content. This data must be created using other tools or processes. Extwee can then *compile* the
|
|
35
|
+
Extwee is **not** an authoring tool. It cannot be used to create story content. This data must be created using other tools or processes. Extwee can then *compile* the content with story format code to produce something playable.
|
|
18
36
|
|
|
19
37
|
Playable formats are the following and require external story formats[^1] to enable play:
|
|
20
38
|
|
|
@@ -38,48 +56,22 @@ Twine 2 supports exporting a collection of stories (known as a *library*) in the
|
|
|
38
56
|
|
|
39
57
|
## Format Support
|
|
40
58
|
|
|
41
|
-
Extwee
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
<td>Partial support. Twine 1 HTML can be produced, but the StorySettings optional passage introduced in Twine 1.4.0 requires external libraries like jQuery not included with Extwee.</td>
|
|
53
|
-
</tr>
|
|
54
|
-
<tr>
|
|
55
|
-
<td><a href="https://github.com/iftechfoundation/twine-specs/blob/master/twine-1-twsoutput.md">Twine 1 TWS (2009 - 2015)</a></td>
|
|
56
|
-
<td>Yes</td>
|
|
57
|
-
<td>Extwee does not support TWS (Python pickle) output because no current version of Twine or other story compilation tool produces this historical format.</td>
|
|
58
|
-
</tr>
|
|
59
|
-
<tr>
|
|
60
|
-
<td><a href="https://github.com/iftechfoundation/twine-specs/blob/master/twine-2-htmloutput-spec.md">Twine 2 HTML (2015 - Present)</a></td>
|
|
61
|
-
<td>Yes</td>
|
|
62
|
-
<td>Yes</td>
|
|
63
|
-
</tr>
|
|
64
|
-
<tr>
|
|
65
|
-
<td><a href="https://github.com/iftechfoundation/twine-specs/blob/master/twine-2-archive-spec.md">Twine 2 Archive HTML (2015 - Present)</a></td>
|
|
66
|
-
<td>Yes</td>
|
|
67
|
-
<td>Yes</td>
|
|
68
|
-
</tr>
|
|
69
|
-
<tr>
|
|
70
|
-
<td><a href="https://github.com/iftechfoundation/twine-specs/blob/master/twee-3-specification.md">Twee 3 (2021 - Present)</a></td>
|
|
71
|
-
<td>Yes</td>
|
|
72
|
-
<td>Yes</td>
|
|
73
|
-
</tr>
|
|
74
|
-
<tr>
|
|
75
|
-
<td><a href="https://github.com/iftechfoundation/twine-specs/blob/master/twine-2-jsonoutput-doc.md">Twine 2 JSON (2023 - Present)</a></td>
|
|
76
|
-
<td>Yes</td>
|
|
77
|
-
<td>Yes</td>
|
|
78
|
-
</tr>
|
|
79
|
-
</table>
|
|
59
|
+
Extwee supports multiple historical and current Twine-compatible formats.
|
|
60
|
+
|
|
61
|
+
| Format | Input | Output |
|
|
62
|
+
|----------------------------------------------------------------------------------------------------------------------------------|-------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
63
|
+
| [Twine 1 HTML (2006 - 2015)]( https://github.com/iftechfoundation/twine-specs/blob/master/twine-1-htmloutput-doc.md ) | Yes | Partial support. Twine 1 HTML can be produced, but the `StorySettings` optional passage introduced in Twine 1.4.0 requires external libraries like jQuery not included with Extwee. |
|
|
64
|
+
| [Twine 1 TWS (2009 - 2015)]( https://github.com/iftechfoundation/twine-specs/blob/master/twine-1-twsoutput.md ) | Yes | Extwee does not support TWS (Python pickle) output because no current version of Twine or other story compilation tool produces this historical format. |
|
|
65
|
+
| [Twine 2 HTML (2015 - Present)]( https://github.com/iftechfoundation/twine-specs/blob/master/twine-2-htmloutput-spec.md ) | Yes | Yes |
|
|
66
|
+
| [Twine 2 Archive HTML (2015 - Present)]( https://github.com/iftechfoundation/twine-specs/blob/master/twine-2-archive-spec.md ) | Yes | Yes |
|
|
67
|
+
| [Twee 3 (2021 - Present)]( https://github.com/iftechfoundation/twine-specs/blob/master/twee-3-specification.md ) | Yes | Yes |
|
|
68
|
+
| [Twine 2 JSON (2023 - Present)]( https://github.com/iftechfoundation/twine-specs/blob/master/twine-2-jsonoutput-doc.md ) | Yes | Yes |
|
|
69
|
+
| [Twine 2 Story Format (2015 - Present)]( https://github.com/iftechfoundation/twine-specs/blob/master/twine-2-storyformats-spec.md ) | Yes | Yes |
|
|
80
70
|
|
|
81
71
|
**Note:** Round-trip translations can present problems because of required fields and properties per format. Some metadata may be added or removed based on the specification being followed.
|
|
82
72
|
|
|
73
|
+
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
|
74
|
+
|
|
83
75
|
## Node and Web API
|
|
84
76
|
|
|
85
77
|
The following objects and methods are available in Node.js or browser contexts.
|
|
@@ -96,6 +88,10 @@ An object must be created using either the `new` keyword in JavaScript or as the
|
|
|
96
88
|
|
|
97
89
|
Story and Passage objects can generate multiple output formats: `toTwee()`, `toTwine1HTML()`, `toTwine2HTML()`, and `toJSON()`. Stories cannot be played in a browser without the corresponding compiler combining it with story format data.
|
|
98
90
|
|
|
91
|
+
The StoryFormat object supports `toString()` method of producing a tab-separated JSON output and `toJSON()` method of generating JSON output matching the Twine 2 Story Format Specification.
|
|
92
|
+
|
|
93
|
+
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
|
94
|
+
|
|
99
95
|
### Parsers
|
|
100
96
|
|
|
101
97
|
Translates output formats such as HTML, Twee, JSON, or JSONP into objects.
|
|
@@ -109,6 +105,8 @@ Translates output formats such as HTML, Twee, JSON, or JSONP into objects.
|
|
|
109
105
|
- `parseTwine2HTML()`
|
|
110
106
|
- `parseTwine2ArchiveHTML()`
|
|
111
107
|
|
|
108
|
+
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
|
109
|
+
|
|
112
110
|
### Compilers
|
|
113
111
|
|
|
114
112
|
Compiles story, story formats, or other data into an archive or playable format.
|
|
@@ -116,16 +114,31 @@ Compiles story, story formats, or other data into an archive or playable format.
|
|
|
116
114
|
- `compileTwine2HTML()`
|
|
117
115
|
- `compileTwine1HTML()`
|
|
118
116
|
- `compileTwine2ArchiveHTML()`
|
|
117
|
+
- `compileStoryFormat()`
|
|
118
|
+
|
|
119
|
+
To create playable Twine 1 HTML, an `engine.js` file must be supplied. (See [Story Format Archive](https://github.com/videlais/story-formats-archive/tree/main/official/twine1/engine/1.4.2) for available Twine 1 `engine.js` file.)
|
|
120
|
+
|
|
121
|
+
Compilation of a story format adds the necessary function wrapper to convert the JSON output, via `toJSON()`, to JSONP.
|
|
122
|
+
|
|
123
|
+
### Support Functionality
|
|
124
|
+
|
|
125
|
+
Multiple Twine formats support using [an IFID](https://ifdb.org/help-ifid) to identify one work from another.
|
|
119
126
|
|
|
120
|
-
|
|
127
|
+
As part of its API, the Extwee method `generateIFID()` can be used to create a new IFID for a `Story` object or as part of other processes.
|
|
128
|
+
|
|
129
|
+
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
|
121
130
|
|
|
122
131
|
## Documentation
|
|
123
132
|
|
|
124
|
-
Extwee has documentation
|
|
133
|
+
Extwee has [documentation hosted on GitHub Pages](https://videlais.github.io/extwee/#/).
|
|
134
|
+
|
|
135
|
+
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
|
125
136
|
|
|
126
137
|
## Command-Line Usage
|
|
127
138
|
|
|
128
|
-
Extwee supports a command-line interface for four general scenarios
|
|
139
|
+
Extwee supports a command-line interface for four general scenarios.
|
|
140
|
+
|
|
141
|
+
**Notes:** As of Extwee 2.2.5, short and long command-line option flags are separated. Short options use one hyphen followed by one character and all long options begin with two hyphens and a name as word.
|
|
129
142
|
|
|
130
143
|
### Compiling Twee 3 + Twine 2 Story Format into Twine 2 HTML
|
|
131
144
|
|
|
@@ -141,27 +154,38 @@ De-compile Twine 2 HTML into Twee 3:
|
|
|
141
154
|
|
|
142
155
|
### Compiling Twee 3 into Twine 1 HTML
|
|
143
156
|
|
|
144
|
-
Enabling Twine 1 mode requires using the
|
|
157
|
+
Enabling Twine 1 mode requires using the `--twine1` long flag.
|
|
158
|
+
|
|
159
|
+
Because Twine 1 story formats can be split across files, compilation requires the "engine" from Twine 1 named `engine.js`, the name of the story format, and then its `header.html` template code and the optional but often included `code.js` file.
|
|
160
|
+
|
|
161
|
+
(Refer to the [Story Formats Archive](https://github.com/videlais/story-formats-archive) for access to historic `engine.js` and other files.)
|
|
145
162
|
|
|
146
|
-
`extwee
|
|
163
|
+
`extwee --twine1 -c -i <tweeFile> -o <Twine1HTML> --engine <engineJS> --name <storyFormatName> --codejs <CodeJS> --header <header>`
|
|
147
164
|
|
|
148
165
|
### De-compiling Twine 1 HTML into Twee 3
|
|
149
166
|
|
|
150
|
-
Enabling Twine 1 mode requires using the
|
|
167
|
+
Enabling Twine 1 mode requires using the `--twine1` flag.
|
|
151
168
|
|
|
152
|
-
`extwee
|
|
169
|
+
`extwee --twine1 -d -i <twine1HTML> -o <outputTwee>`
|
|
153
170
|
|
|
154
|
-
|
|
171
|
+
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
|
155
172
|
|
|
156
|
-
|
|
173
|
+
## Config File Usage
|
|
157
174
|
|
|
158
|
-
-
|
|
159
|
-
|
|
175
|
+
When invoked from its command-line interface using `npx extwee`, it will look for a `extwee.config.json` file in the local directory. If found, and its fields are valid, processing will use the values found in the file.
|
|
176
|
+
|
|
177
|
+
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
|
160
178
|
|
|
161
179
|
## Tree Shaking Support
|
|
162
180
|
|
|
163
|
-
For [advanced tree shaking](https://developer.mozilla.org/en-US/docs/Glossary/Tree_shaking) patterns, most formats are broke into `compile.js` and `parse.js` files exporting associated `compile()` and `parse()` functions.
|
|
181
|
+
For [advanced tree shaking](https://developer.mozilla.org/en-US/docs/Glossary/Tree_shaking) patterns, most formats are broke into `compile.js` and `parse.js` files exporting associated `compile()` and `parse()` functions.
|
|
182
|
+
|
|
183
|
+
When using the API, it is possible to only import a single function or object to produce smaller and potentially faster code in projects dependent on Extwee functionality.
|
|
184
|
+
|
|
185
|
+
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
|
164
186
|
|
|
165
187
|
## License
|
|
166
188
|
|
|
167
189
|
Distributed under the MIT License. See `LICENSE.txt` for more information.
|
|
190
|
+
|
|
191
|
+
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
package/docs/_sidebar.md
CHANGED
package/docs/install/npm.md
CHANGED
|
@@ -13,8 +13,4 @@ import { Story, Passage } from 'extwee';
|
|
|
13
13
|
const example = new Story( 'Example' );
|
|
14
14
|
// Add a new passage.
|
|
15
15
|
example.addPassage(new Passage( 'Test', 'Some Text') );
|
|
16
|
-
|
|
17
|
-
// Confirm size change.
|
|
18
|
-
// (Should produce 1).
|
|
19
|
-
console.log ( example.size() );
|
|
20
16
|
```
|
package/docs/install/npx.md
CHANGED
|
@@ -7,3 +7,73 @@ Extwee can be used via NPX (node package execution) without being added to a loc
|
|
|
7
7
|
```bash
|
|
8
8
|
npx extwee -c -i <tweeFile> -s <storyFormat> -o <Twine2HTML>
|
|
9
9
|
```
|
|
10
|
+
|
|
11
|
+
## Config File Usage
|
|
12
|
+
|
|
13
|
+
When used via NPX, Extwee will also look for a local file, `extwee.config.json`.
|
|
14
|
+
|
|
15
|
+
The configuration file supports some, but not all, possible actions using command-line arguments.
|
|
16
|
+
|
|
17
|
+
### Defining `mode`
|
|
18
|
+
|
|
19
|
+
The most important option is `mode`. This **MUST BE** either `compile` or `decompile`.
|
|
20
|
+
|
|
21
|
+
```json
|
|
22
|
+
{
|
|
23
|
+
"mode": "decompile"
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Defining `input` and `output`
|
|
28
|
+
|
|
29
|
+
To process files, the `input` and `output` properties **MUST BE** defined using either an absolute or relative path.
|
|
30
|
+
|
|
31
|
+
```json
|
|
32
|
+
{
|
|
33
|
+
"mode": "compile",
|
|
34
|
+
"input": "index.twee",
|
|
35
|
+
"output": "index.html"
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Defining `story-format`
|
|
40
|
+
|
|
41
|
+
If using the `"mode": "compile"` option, the `story-format` property **MUST BE** defined. This should be the name of a directory in the relative `./story-formats` directory.
|
|
42
|
+
|
|
43
|
+
For example, if using Harlowe, the path would be `./story-formats/harlowe` and the key-value pair would be `"story-format": "harlowe"`.
|
|
44
|
+
|
|
45
|
+
```json
|
|
46
|
+
{
|
|
47
|
+
"mode": "compile",
|
|
48
|
+
"input": "index.twee",
|
|
49
|
+
"output": "index.html",
|
|
50
|
+
"story-format": "harlowe"
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
#### Defining optional `story-format-version`
|
|
55
|
+
|
|
56
|
+
The Story Format Archive retrieves story formats based on its version in a sub-directory structure:
|
|
57
|
+
|
|
58
|
+
```file
|
|
59
|
+
story-formats/
|
|
60
|
+
├── harlowe/
|
|
61
|
+
│ ├── 2.3.0/
|
|
62
|
+
│ └── format.js
|
|
63
|
+
│ ├── 2.4.0/
|
|
64
|
+
│ └── format.js
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
This can be specified, such as `3.2.0`, or the default `latest`, can be used.
|
|
68
|
+
|
|
69
|
+
```json
|
|
70
|
+
{
|
|
71
|
+
"mode": "compile",
|
|
72
|
+
"input": "index.twee",
|
|
73
|
+
"output": "index.html",
|
|
74
|
+
"story-format": "harlowe",
|
|
75
|
+
"story-format-version": "3.2.0"
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
If only the story format name is specified, and it can be found in the local `story-formats` directory, it will search for a corresponding `format.js` file.
|
package/extwee.config.md
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Extwee Config File Options
|
|
2
|
+
|
|
3
|
+
The configuration file supports some, but not all, possible actions using command-line arguments.
|
|
4
|
+
|
|
5
|
+
## Defining `mode`
|
|
6
|
+
|
|
7
|
+
The most important option is `mode`. This **MUST BE** either `compile` or `decompile`.
|
|
8
|
+
|
|
9
|
+
```json
|
|
10
|
+
{
|
|
11
|
+
"mode": "decompile"
|
|
12
|
+
}
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Defining `input` and `output`
|
|
16
|
+
|
|
17
|
+
To process files, the `input` and `output` properties **MUST BE** defined using either an absolute or relative path.
|
|
18
|
+
|
|
19
|
+
```json
|
|
20
|
+
{
|
|
21
|
+
"mode": "compile",
|
|
22
|
+
"input": "index.twee",
|
|
23
|
+
"output": "index.html"
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Defining `story-format`
|
|
28
|
+
|
|
29
|
+
If using the `"mode": "compile"` option, the `story-format` property **MUST BE** defined. This should be the name of a directory in the relative `./story-formats` directory.
|
|
30
|
+
|
|
31
|
+
For example, if using Harlowe, the path would be `./story-formats/harlowe` and the key-value pair would be `"story-format": "harlowe"`.
|
|
32
|
+
|
|
33
|
+
```json
|
|
34
|
+
{
|
|
35
|
+
"mode": "compile",
|
|
36
|
+
"input": "index.twee",
|
|
37
|
+
"output": "index.html",
|
|
38
|
+
"story-format": "harlowe"
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Defining optional `story-format-version`
|
|
43
|
+
|
|
44
|
+
The Story Format Archive retrieves story formats based on its version in a sub-directory structure:
|
|
45
|
+
|
|
46
|
+
```file
|
|
47
|
+
story-formats/
|
|
48
|
+
├── harlowe/
|
|
49
|
+
│ ├── 2.3.0/
|
|
50
|
+
│ └── format.js
|
|
51
|
+
│ ├── 2.4.0/
|
|
52
|
+
│ └── format.js
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
This can be specified, such as `3.2.0`, or the default `latest`, can be used.
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"mode": "compile",
|
|
60
|
+
"input": "index.twee",
|
|
61
|
+
"output": "index.html",
|
|
62
|
+
"story-format": "harlowe",
|
|
63
|
+
"story-format-version": "3.2.0"
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
If only the story format name is specified, and it can be found in the local `story-formats` directory, it will search for a corresponding `format.js` file.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "extwee",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.1",
|
|
4
4
|
"description": "A story compiler tool using Twine-compatible formats",
|
|
5
5
|
"author": "Dan Cox",
|
|
6
6
|
"main": "index.js",
|
|
@@ -12,9 +12,8 @@
|
|
|
12
12
|
"lint": "eslint ./src/**/*.js --fix",
|
|
13
13
|
"lint:test": "eslint ./test/**/*.test.js --fix",
|
|
14
14
|
"build:web": "webpack",
|
|
15
|
-
"build:bin": "esbuild ./src/extwee.js --bundle --platform=node --target=node12 --outfile=out.js",
|
|
16
15
|
"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"
|
|
16
|
+
"all": "npm run lint && npm run lint:test && npm run test && npm run build:web && npm run gen-types"
|
|
18
17
|
},
|
|
19
18
|
"keywords": [
|
|
20
19
|
"twine",
|
|
@@ -24,35 +23,36 @@
|
|
|
24
23
|
],
|
|
25
24
|
"license": "MIT",
|
|
26
25
|
"dependencies": {
|
|
27
|
-
"commander": "^
|
|
26
|
+
"commander": "^14.0.0",
|
|
28
27
|
"graphemer": "^1.4.0",
|
|
29
|
-
"html-entities": "^2.
|
|
28
|
+
"html-entities": "^2.6.0",
|
|
30
29
|
"node-html-parser": "^7.0.1",
|
|
31
30
|
"pickleparser": "^0.2.1",
|
|
32
|
-
"semver": "^7.7.
|
|
31
|
+
"semver": "^7.7.2",
|
|
32
|
+
"shelljs": "^0.10.0",
|
|
33
33
|
"uuid": "^11.1.0"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
|
-
"@babel/cli": "^7.
|
|
37
|
-
"@babel/core": "^7.
|
|
38
|
-
"@babel/preset-env": "^7.
|
|
39
|
-
"@eslint/js": "^9.
|
|
40
|
-
"@
|
|
36
|
+
"@babel/cli": "^7.28.0",
|
|
37
|
+
"@babel/core": "^7.28.0",
|
|
38
|
+
"@babel/preset-env": "^7.28.0",
|
|
39
|
+
"@eslint/js": "^9.29.0",
|
|
40
|
+
"@inquirer/prompts": "^7.6.0",
|
|
41
|
+
"@types/semver": "^7.7.0",
|
|
41
42
|
"@types/uuid": "^10.0.0",
|
|
42
43
|
"babel-loader": "^10.0.0",
|
|
43
44
|
"clean-jsdoc-theme": "^4.3.0",
|
|
44
|
-
"core-js": "^3.
|
|
45
|
-
"
|
|
46
|
-
"eslint": "^
|
|
47
|
-
"eslint-plugin-
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"jest": "^
|
|
45
|
+
"core-js": "^3.43.0",
|
|
46
|
+
"eslint": "^9.29.0",
|
|
47
|
+
"eslint-plugin-jest": "^29.0.1",
|
|
48
|
+
"eslint-plugin-jsdoc": "^51.0.1",
|
|
49
|
+
"globals": "^16.3.0",
|
|
50
|
+
"jest": "^30.0.4",
|
|
51
|
+
"jest-environment-jsdom": "^30.0.4",
|
|
51
52
|
"regenerator-runtime": "^0.14.1",
|
|
52
|
-
"
|
|
53
|
-
"typescript": "^
|
|
54
|
-
"
|
|
55
|
-
"webpack": "^5.98.0",
|
|
53
|
+
"typescript": "^5.8.3",
|
|
54
|
+
"typescript-eslint": "^8.34.0",
|
|
55
|
+
"webpack": "^5.99.9",
|
|
56
56
|
"webpack-cli": "^6.0.1"
|
|
57
57
|
},
|
|
58
58
|
"repository": {
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
// Import functions we need.
|
|
2
|
+
import {
|
|
3
|
+
parseTwine2HTML,
|
|
4
|
+
parseTwee,
|
|
5
|
+
parseStoryFormat,
|
|
6
|
+
parseTwine1HTML,
|
|
7
|
+
compileTwine2HTML,
|
|
8
|
+
compileTwine1HTML
|
|
9
|
+
} from '../../index.js';
|
|
10
|
+
|
|
11
|
+
// Import fs.
|
|
12
|
+
import { readFileSync, writeFileSync } from 'node:fs';
|
|
13
|
+
|
|
14
|
+
// Import Commander.
|
|
15
|
+
import { Command, InvalidArgumentError } from 'commander';
|
|
16
|
+
|
|
17
|
+
// Import package.json.
|
|
18
|
+
import Package from '../../package.json' with { type: 'json' };
|
|
19
|
+
|
|
20
|
+
// Import isFile function.
|
|
21
|
+
import { isFile } from './isFile.js';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Process command line arguments.
|
|
25
|
+
* @function CommandLineProcessing
|
|
26
|
+
* @description This function processes the command line arguments passed to the Extwee CLI.
|
|
27
|
+
* @module CLI/commandLineProcessing
|
|
28
|
+
* @param {Array} argv - The command line arguments passed to the CLI.
|
|
29
|
+
*/
|
|
30
|
+
export function CommandLineProcessing(argv) {
|
|
31
|
+
// This is the main function for processing the command line arguments.
|
|
32
|
+
// It uses the Commander library to parse the arguments and then calls the appropriate functions.
|
|
33
|
+
// The function is called when the script is run from the command line.
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
// Create a new Command.
|
|
37
|
+
const program = new Command();
|
|
38
|
+
|
|
39
|
+
program
|
|
40
|
+
.name('extwee')
|
|
41
|
+
.description('CLI for Extwee')
|
|
42
|
+
.option('-v, --version', 'Show version number', () => {
|
|
43
|
+
// Show the version number.
|
|
44
|
+
console.log(`Extwee v${Package.version}`);
|
|
45
|
+
// Exit the process.
|
|
46
|
+
process.exit(0);
|
|
47
|
+
})
|
|
48
|
+
.option('-c, --compile', 'Compile input into output')
|
|
49
|
+
.option('-d, --decompile', 'De-compile input into output')
|
|
50
|
+
.option('--twine1', 'Enable Twine 1 processing')
|
|
51
|
+
.option('--name <storyFormatName>', 'Name of the Twine 1 story format (needed for `code.js` inclusion)')
|
|
52
|
+
.option('--codejs <codeJSFile>', 'Twine 1 code.js file for use with Twine 1 HTML', (value) => {
|
|
53
|
+
// Does the input file exist?
|
|
54
|
+
if (isFile(value) === false) {
|
|
55
|
+
// We cannot do anything without valid input.
|
|
56
|
+
throw new InvalidArgumentError(`Twine 1 code.js ${value} does not exist.`);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return value;
|
|
60
|
+
})
|
|
61
|
+
.option('--engine <engineFile>', 'Twine 1 engine.js file for use with Twine 1 HTML', (value) => {
|
|
62
|
+
// Does the input file exist?
|
|
63
|
+
if (isFile(value) === false) {
|
|
64
|
+
// We cannot do anything without valid input.
|
|
65
|
+
throw new InvalidArgumentError(`Twine 1 engine.js ${value} does not exist.`);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return value;
|
|
69
|
+
})
|
|
70
|
+
.option('--header <headerFile>', 'Twine 1 header.html file for use with Twine 1 HTML', (value) => {
|
|
71
|
+
// Does the input file exist?
|
|
72
|
+
if (isFile(value) === false) {
|
|
73
|
+
// We cannot do anything without valid input.
|
|
74
|
+
throw new InvalidArgumentError(`Twine 1 header.html ${value} does not exist.`);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return value;
|
|
78
|
+
})
|
|
79
|
+
.option('-s <storyformat>, --storyformat <storyformat>', 'Path to story format file for Twine 2', (value) => {
|
|
80
|
+
// Does the input file exist?
|
|
81
|
+
if (isFile(value) === false) {
|
|
82
|
+
// We cannot do anything without valid input.
|
|
83
|
+
throw new InvalidArgumentError(`Story format ${value} does not exist.`);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return value;
|
|
87
|
+
})
|
|
88
|
+
.option('-i <inputFile>, --input <inputFile>', 'Path to input file', (value) => {
|
|
89
|
+
// Does the input file exist?
|
|
90
|
+
if (isFile(value) === false) {
|
|
91
|
+
// We cannot do anything without valid input.
|
|
92
|
+
throw new InvalidArgumentError(`Input file ${value} does not exist.`);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return value;
|
|
96
|
+
})
|
|
97
|
+
.option('-o <outputFile>, --output <outputFile>', 'Path to output file');
|
|
98
|
+
|
|
99
|
+
// Parse the passed arguments.
|
|
100
|
+
program.parse(argv);
|
|
101
|
+
|
|
102
|
+
// Create object of passed arguments parsed by Commander.
|
|
103
|
+
const options = program.opts();
|
|
104
|
+
|
|
105
|
+
/*
|
|
106
|
+
* Prepare some (soon to be) global variables.
|
|
107
|
+
*/
|
|
108
|
+
// Check if Twine 1 is enabled.
|
|
109
|
+
const isTwine1Mode = (options.twine1 === true);
|
|
110
|
+
|
|
111
|
+
// Check if Twine 2 is enabled.
|
|
112
|
+
const isTwine2Mode = (isTwine1Mode === false);
|
|
113
|
+
|
|
114
|
+
// Check if de-compile mode is enabled.
|
|
115
|
+
const isDecompileMode = (options.decompile === true);
|
|
116
|
+
|
|
117
|
+
// Check if compile mode is enabled.
|
|
118
|
+
const isCompileMode = (options.compile === true);
|
|
119
|
+
|
|
120
|
+
// De-compile Twine 2 HTML into Twee 3 branch.
|
|
121
|
+
// If -d is passed, -i and -o are required.
|
|
122
|
+
if (isTwine2Mode === true && isDecompileMode === true) {
|
|
123
|
+
// Read the input HTML file.
|
|
124
|
+
const inputHTML = readFileSync(options.i, 'utf-8');
|
|
125
|
+
|
|
126
|
+
// Parse the input HTML file into Story object.
|
|
127
|
+
const storyObject = parseTwine2HTML(inputHTML);
|
|
128
|
+
|
|
129
|
+
// Write the output file from Story as Twee 3.
|
|
130
|
+
writeFileSync(options.o, storyObject.toTwee());
|
|
131
|
+
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Compile Twee 3 into Twine 2 HTML branch.
|
|
136
|
+
// If -c is passed, -i, -o, and -s are required.
|
|
137
|
+
if (isTwine2Mode === true && isCompileMode === true) {
|
|
138
|
+
// Read the input file.
|
|
139
|
+
const inputTwee = readFileSync(options.i, 'utf-8');
|
|
140
|
+
|
|
141
|
+
// Parse the input file.
|
|
142
|
+
const story = parseTwee(inputTwee);
|
|
143
|
+
|
|
144
|
+
// Read the story format file.
|
|
145
|
+
const inputStoryFormat = readFileSync(options.s, 'utf-8');
|
|
146
|
+
|
|
147
|
+
// Parse the story format file.
|
|
148
|
+
const parsedStoryFormat = parseStoryFormat(inputStoryFormat);
|
|
149
|
+
|
|
150
|
+
// Compile the story.
|
|
151
|
+
const Twine2HTML = compileTwine2HTML(story, parsedStoryFormat);
|
|
152
|
+
|
|
153
|
+
// Write the output file.
|
|
154
|
+
writeFileSync(options.o, Twine2HTML);
|
|
155
|
+
|
|
156
|
+
// Exit the process.
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Compile Twee 3 into Twine 1 HTML branch.
|
|
161
|
+
// Twine 1 compilation is complicated, so we have to check for all the required options.
|
|
162
|
+
// * options.engine (from Twine 1 itself)
|
|
163
|
+
// * options.header (from Twine 1 story format)
|
|
164
|
+
// * options.name (from Twine 1 story format)
|
|
165
|
+
// * options.codejs (from Twine 1 story format)
|
|
166
|
+
if (isTwine1Mode === true && isCompileMode === true) {
|
|
167
|
+
// Read the input file.
|
|
168
|
+
const inputTwee = readFileSync(options.i, 'utf-8');
|
|
169
|
+
|
|
170
|
+
// Parse the input file.
|
|
171
|
+
const story = parseTwee(inputTwee);
|
|
172
|
+
|
|
173
|
+
// Does the engine file exist?
|
|
174
|
+
const Twine1HTML = compileTwine1HTML(story, options.engine, options.header, options.name, options.codejs);
|
|
175
|
+
|
|
176
|
+
// Write the output file.
|
|
177
|
+
writeFileSync(options.o, Twine1HTML);
|
|
178
|
+
|
|
179
|
+
// Exit the process.
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// De-compile Twine 1 HTML into Twee 3 branch.
|
|
184
|
+
if (isTwine1Mode === true && isDecompileMode === true) {
|
|
185
|
+
// Read the input HTML file.
|
|
186
|
+
const inputHTML = readFileSync(options.i, 'utf-8');
|
|
187
|
+
|
|
188
|
+
// Parse the input HTML file into Story object.
|
|
189
|
+
const storyObject = parseTwine1HTML(inputHTML);
|
|
190
|
+
|
|
191
|
+
// Write the output file from Story as Twee 3.
|
|
192
|
+
writeFileSync(options.o, storyObject.toTwee());
|
|
193
|
+
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
}
|