extwee 2.3.11 → 2.3.13
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/CHANGELOG.md +219 -0
- package/CONTRIBUTING.md +305 -0
- package/README.md +16 -0
- package/build/extwee.core.min.js +1 -1
- package/build/extwee.twine1html.min.js +1 -1
- package/build/extwee.twine2archive.min.js +1 -1
- package/build/extwee.tws.min.js +1 -1
- package/logs/arrays.html +79 -0
- package/logs/arrays.twee +64 -0
- package/logs/example.html +47 -0
- package/logs/fixing.js +23 -0
- package/logs/format-fixed.js +8 -0
- package/logs/format.js +8 -0
- package/logs/test-entities.cjs +40 -0
- package/package.json +19 -16
- package/src/Story.js +2 -2
- package/types/src/Story.d.ts +1 -1
- package/.github/FUNDING.yml +0 -3
- package/.github/codeql-analysis.yml +0 -51
- package/.github/dependabot.yml +0 -11
- package/.github/workflows/dependabot-automerge.yml +0 -23
- package/.github/workflows/nodejs.yml +0 -28
- package/.travis.yml +0 -13
- package/babel.config.json +0 -18
- package/docs/.nojekyll +0 -0
- package/docs/README.md +0 -224
- package/docs/_sidebar.md +0 -19
- package/docs/build/extwee.core.min.js +0 -1
- package/docs/build/extwee.twine1html.min.js +0 -1
- package/docs/build/extwee.twine2archive.min.js +0 -1
- package/docs/build/extwee.tws.min.js +0 -1
- package/docs/demos/compiler/extwee.core.min.js +0 -1
- package/docs/demos/compiler/index.css +0 -105
- package/docs/demos/compiler/index.html +0 -359
- package/docs/demos/decompile/extwee.core.min.js +0 -1
- package/docs/demos/decompile/index.css +0 -584
- package/docs/demos/decompile/index.html +0 -468
- package/docs/examples/dynamicPassages.md +0 -28
- package/docs/examples/jsonToTwee.md +0 -23
- package/docs/examples/twsToTwee.md +0 -25
- package/docs/formats/json.md +0 -17
- package/docs/formats/twee.md +0 -13
- package/docs/formats/twine1HTML.md +0 -13
- package/docs/formats/twine2ArchiveHTML.md +0 -13
- package/docs/formats/twine2HTML.md +0 -13
- package/docs/formats/tws.md +0 -9
- package/docs/index.html +0 -26
- package/docs/install/npm.md +0 -16
- package/docs/install/npx.md +0 -79
- package/docs/objects/passage.md +0 -47
- package/docs/objects/story.md +0 -69
- package/docs/objects/storyformat.md +0 -27
- package/eslint.config.js +0 -28
- package/extwee.config.json +0 -6
- package/extwee.config.md +0 -67
- package/jest.config.json +0 -5
- package/test/CLI/CLI.test.js +0 -49
- package/test/CLI/files/example.json +0 -1
- package/test/CLI/files/example6.twee +0 -22
- package/test/CLI/files/harlowe.js +0 -3
- package/test/CLI/files/input.html +0 -47
- package/test/CLI/files/output/test.twee +0 -0
- package/test/CLI/files/test.twee +0 -18
- package/test/CLI/files/tweeExample.twee +0 -17
- package/test/CLI/files/twine1/LICENSE.txt +0 -32
- package/test/CLI/files/twine1/code.js +0 -5
- package/test/CLI/files/twine1/engine.js +0 -43
- package/test/CLI/files/twine1/header.html +0 -325
- package/test/CLI/files/twine1Test.html +0 -371
- package/test/CLI/files/twineExample.html +0 -16
- package/test/Config/Config.test.js +0 -76
- package/test/Config/files/empty.json +0 -3
- package/test/Config/files/full.json +0 -8
- package/test/Config/files/invalid.json +0 -1
- package/test/Config/files/valid.json +0 -6
- package/test/Config/isDirectory.test.js +0 -50
- package/test/Config/isFile.test.js +0 -53
- package/test/Config/loadStoryFormat.test.js +0 -117
- package/test/Config/readDirectories.test.js +0 -78
- package/test/IFID/IFID.Generate.test.js +0 -10
- package/test/JSON/JSON.Parse.test.js +0 -316
- package/test/Objects/Passage.test.js +0 -274
- package/test/Objects/SnowmanCompatibility.test.js +0 -111
- package/test/Objects/Story.test.js +0 -1075
- package/test/Objects/StoryFormat.test.js +0 -219
- package/test/Roundtrip/Files/Example1.html +0 -64
- package/test/Roundtrip/Files/LICENSE +0 -19
- package/test/Roundtrip/Files/example1.twee +0 -10
- package/test/Roundtrip/Files/example2.twee +0 -27
- package/test/Roundtrip/Files/example4.twee +0 -27
- package/test/Roundtrip/Files/harlowe.js +0 -3
- package/test/Roundtrip/Files/round.html +0 -49
- package/test/Roundtrip/Roundtrip.test.js +0 -54
- package/test/StoryFormat/StoryFormat.Parse.test.js +0 -479
- package/test/TWS/Parse.test.js +0 -56
- package/test/TWS/TWSParser/Example5.tws +0 -414
- package/test/TWS/TWSParser/noscale.tws +0 -0
- package/test/TWS/TWSParser/nostory.tws +0 -0
- package/test/Twee/Twee.Escaping.test.js +0 -200
- package/test/Twee/Twee.Parse.test.js +0 -108
- package/test/Twee/TweeParser/cursed.twee +0 -16
- package/test/Twee/TweeParser/cycling.twee +0 -75
- package/test/Twee/TweeParser/emptytags.twee +0 -2
- package/test/Twee/TweeParser/example.twee +0 -32
- package/test/Twee/TweeParser/malformed.twee +0 -2
- package/test/Twee/TweeParser/missing.twee +0 -19
- package/test/Twee/TweeParser/multipleScriptPassages.twee +0 -19
- package/test/Twee/TweeParser/multipleStyleTag.twee +0 -19
- package/test/Twee/TweeParser/multipletags.twee +0 -10
- package/test/Twee/TweeParser/noTitle.twee +0 -2
- package/test/Twee/TweeParser/notes.twee +0 -16
- package/test/Twee/TweeParser/pasagemetadataerror.twee +0 -2
- package/test/Twee/TweeParser/scriptPassage.twee +0 -16
- package/test/Twee/TweeParser/singletag.twee +0 -13
- package/test/Twee/TweeParser/start.twee +0 -2
- package/test/Twee/TweeParser/startMetadata.twee +0 -14
- package/test/Twee/TweeParser/storydataerror.twee +0 -25
- package/test/Twee/TweeParser/style.twee +0 -16
- package/test/Twee/TweeParser/stylePassage.twee +0 -16
- package/test/Twee/TweeParser/test.twee +0 -25
- package/test/Twine1HTML/Twine1HTML.Compile.test.js +0 -180
- package/test/Twine1HTML/Twine1HTML.Parse.Web.test.js +0 -484
- package/test/Twine1HTML/Twine1HTML.Parse.test.js +0 -183
- package/test/Twine1HTML/Twine1HTMLCompiler/Twine1/LICENSE +0 -674
- package/test/Twine1HTML/Twine1HTMLCompiler/Twine1/engine.js +0 -43
- package/test/Twine1HTML/Twine1HTMLCompiler/Twine1/jquery.js +0 -4
- package/test/Twine1HTML/Twine1HTMLCompiler/Twine1/modernizr.js +0 -4
- package/test/Twine1HTML/Twine1HTMLCompiler/engineTest.html +0 -1
- package/test/Twine1HTML/Twine1HTMLCompiler/jonah-1.4.2/LICENSE +0 -32
- package/test/Twine1HTML/Twine1HTMLCompiler/jonah-1.4.2/code.js +0 -4
- package/test/Twine1HTML/Twine1HTMLCompiler/jonah-1.4.2/header.html +0 -327
- package/test/Twine1HTML/Twine1HTMLCompiler/test.html +0 -0
- package/test/Twine1HTML/Twine1HTMLCompiler/test1.html +0 -6
- package/test/Twine1HTML/Twine1HTMLCompiler/test2.html +0 -6
- package/test/Twine1HTML/Twine1HTMLCompiler/test3.html +0 -43
- package/test/Twine1HTML/Twine1HTMLCompiler/test4.html +0 -372
- package/test/Twine1HTML/Twine1HTMLCompiler/test5.html +0 -372
- package/test/Twine2ArchiveHTML/Twine2ArchiveHTML.Compile.test.js +0 -35
- package/test/Twine2ArchiveHTML/Twine2ArchiveHTML.Parse.Web.test.js +0 -293
- package/test/Twine2ArchiveHTML/Twine2ArchiveHTML.Parse.test.js +0 -42
- package/test/Twine2ArchiveHTML/Twine2ArchiveHTMLCompiler/test1.html +0 -6
- package/test/Twine2ArchiveHTML/Twine2ArchiveHTMLParser/test1.html +0 -3
- package/test/Twine2HTML/Twine2HTML.Compile.test.js +0 -139
- package/test/Twine2HTML/Twine2HTML.Parse.Web.test.js +0 -329
- package/test/Twine2HTML/Twine2HTML.Parse.test.js +0 -192
- package/test/Twine2HTML/Twine2HTMLCompiler/TestTags.html +0 -42
- package/test/Twine2HTML/Twine2HTMLCompiler/creator.html +0 -50
- package/test/Twine2HTML/Twine2HTMLCompiler/example6.twee +0 -16
- package/test/Twine2HTML/Twine2HTMLCompiler/format.js +0 -9
- package/test/Twine2HTML/Twine2HTMLCompiler/missingStoryTitle.twee +0 -29
- package/test/Twine2HTML/Twine2HTMLCompiler/test11.html +0 -121
- package/test/Twine2HTML/Twine2HTMLCompiler/test2.html +0 -58
- package/test/Twine2HTML/Twine2HTMLCompiler/test3.html +0 -49
- package/test/Twine2HTML/Twine2HTMLCompiler/test4.html +0 -50
- package/test/Twine2HTML/Twine2HTMLCompiler/test6.html +0 -49
- package/test/Twine2HTML/Twine2HTMLParser/Example1.html +0 -53
- package/test/Twine2HTML/Twine2HTMLParser/Tags.html +0 -15
- package/test/Twine2HTML/Twine2HTMLParser/lyingStartnode.html +0 -15
- package/test/Twine2HTML/Twine2HTMLParser/lyingTagColors.html +0 -48
- package/test/Twine2HTML/Twine2HTMLParser/missingCreator.html +0 -11
- package/test/Twine2HTML/Twine2HTMLParser/missingCreatorVersion.html +0 -11
- package/test/Twine2HTML/Twine2HTMLParser/missingFormat.html +0 -11
- package/test/Twine2HTML/Twine2HTMLParser/missingFormatVersion.html +0 -11
- package/test/Twine2HTML/Twine2HTMLParser/missingIFID.html +0 -11
- package/test/Twine2HTML/Twine2HTMLParser/missingPassageTags.html +0 -15
- package/test/Twine2HTML/Twine2HTMLParser/missingPosition.html +0 -15
- package/test/Twine2HTML/Twine2HTMLParser/missingScript.html +0 -14
- package/test/Twine2HTML/Twine2HTMLParser/missingSize.html +0 -35
- package/test/Twine2HTML/Twine2HTMLParser/missingStartnode.html +0 -11
- package/test/Twine2HTML/Twine2HTMLParser/missingStyle.html +0 -14
- package/test/Twine2HTML/Twine2HTMLParser/missingZoom.html +0 -11
- package/test/Twine2HTML/Twine2HTMLParser/tagColors.html +0 -31
- package/test/Twine2HTML/Twine2HTMLParser/twineExample.html +0 -23
- package/test/Twine2HTML/Twine2HTMLParser/twineExample2.html +0 -15
- package/test/Twine2HTML/Twine2HTMLParser/twineExample3.html +0 -15
- package/test/Twine2HTML/Twine2HTMLParser/unescaping.html +0 -33
- package/test/Web/web-core-coverage.test.js +0 -175
- package/test/Web/web-core-global.test.js +0 -93
- package/test/Web/web-core.test.js +0 -156
- package/test/Web/web-exports.test.js +0 -136
- package/test/Web/web-twine1html.test.js +0 -105
- package/test/Web/web-twine2archive.test.js +0 -96
- package/test/Web/web-tws.test.js +0 -77
- package/test/Web/window.Extwee.test.js +0 -97
- package/tsconfig.json +0 -21
- package/webpack.config.js +0 -47
|
@@ -1,414 +0,0 @@
|
|
|
1
|
-
(dp0
|
|
2
|
-
S'buildDestination'
|
|
3
|
-
p1
|
|
4
|
-
V\u005c\u005cMac\u005cDropbox\u005cTwineBuild.html
|
|
5
|
-
p2
|
|
6
|
-
sS'saveDestination'
|
|
7
|
-
p3
|
|
8
|
-
V\u005c\u005cMac\u005cDropbox\u005cExample5.tws
|
|
9
|
-
p4
|
|
10
|
-
sS'metadata'
|
|
11
|
-
p5
|
|
12
|
-
(dp6
|
|
13
|
-
S'description'
|
|
14
|
-
p7
|
|
15
|
-
Vtest1
|
|
16
|
-
p8
|
|
17
|
-
sS'identity'
|
|
18
|
-
p9
|
|
19
|
-
Vtest1
|
|
20
|
-
p10
|
|
21
|
-
ssS'target'
|
|
22
|
-
p11
|
|
23
|
-
S'sugarcane'
|
|
24
|
-
p12
|
|
25
|
-
sS'storyPanel'
|
|
26
|
-
p13
|
|
27
|
-
(dp14
|
|
28
|
-
S'widgets'
|
|
29
|
-
p15
|
|
30
|
-
(lp16
|
|
31
|
-
(dp17
|
|
32
|
-
S'selected'
|
|
33
|
-
p18
|
|
34
|
-
I00
|
|
35
|
-
sS'pos'
|
|
36
|
-
p19
|
|
37
|
-
(lp20
|
|
38
|
-
I10
|
|
39
|
-
aI10
|
|
40
|
-
asS'passage'
|
|
41
|
-
p21
|
|
42
|
-
(itiddlywiki
|
|
43
|
-
Tiddler
|
|
44
|
-
p22
|
|
45
|
-
(dp24
|
|
46
|
-
S'text'
|
|
47
|
-
p25
|
|
48
|
-
S'Your story will display this passage first. Edit it by double clicking it.'
|
|
49
|
-
p26
|
|
50
|
-
sS'title'
|
|
51
|
-
p27
|
|
52
|
-
S'Start'
|
|
53
|
-
p28
|
|
54
|
-
sS'modified'
|
|
55
|
-
p29
|
|
56
|
-
ctime
|
|
57
|
-
struct_time
|
|
58
|
-
p30
|
|
59
|
-
((I2023
|
|
60
|
-
I9
|
|
61
|
-
I3
|
|
62
|
-
I14
|
|
63
|
-
I38
|
|
64
|
-
I52
|
|
65
|
-
I6
|
|
66
|
-
I246
|
|
67
|
-
I1
|
|
68
|
-
tp31
|
|
69
|
-
(dp32
|
|
70
|
-
tp33
|
|
71
|
-
Rp34
|
|
72
|
-
sS'tags'
|
|
73
|
-
p35
|
|
74
|
-
(lp36
|
|
75
|
-
sS'created'
|
|
76
|
-
p37
|
|
77
|
-
g34
|
|
78
|
-
sbsa(dp38
|
|
79
|
-
g18
|
|
80
|
-
I00
|
|
81
|
-
sg19
|
|
82
|
-
(lp39
|
|
83
|
-
I10
|
|
84
|
-
aI150
|
|
85
|
-
asg21
|
|
86
|
-
(itiddlywiki
|
|
87
|
-
Tiddler
|
|
88
|
-
p40
|
|
89
|
-
(dp41
|
|
90
|
-
g25
|
|
91
|
-
S'Untitled Story'
|
|
92
|
-
p42
|
|
93
|
-
sg27
|
|
94
|
-
S'StoryTitle'
|
|
95
|
-
p43
|
|
96
|
-
sg29
|
|
97
|
-
g30
|
|
98
|
-
((I2023
|
|
99
|
-
I9
|
|
100
|
-
I3
|
|
101
|
-
I14
|
|
102
|
-
I38
|
|
103
|
-
I52
|
|
104
|
-
I6
|
|
105
|
-
I246
|
|
106
|
-
I1
|
|
107
|
-
tp44
|
|
108
|
-
(dp45
|
|
109
|
-
tp46
|
|
110
|
-
Rp47
|
|
111
|
-
sg35
|
|
112
|
-
(lp48
|
|
113
|
-
sg37
|
|
114
|
-
g47
|
|
115
|
-
sbsa(dp49
|
|
116
|
-
g18
|
|
117
|
-
I00
|
|
118
|
-
sg19
|
|
119
|
-
(lp50
|
|
120
|
-
I10
|
|
121
|
-
aI290
|
|
122
|
-
asg21
|
|
123
|
-
(itiddlywiki
|
|
124
|
-
Tiddler
|
|
125
|
-
p51
|
|
126
|
-
(dp52
|
|
127
|
-
g25
|
|
128
|
-
S'Anonymous'
|
|
129
|
-
p53
|
|
130
|
-
sg27
|
|
131
|
-
S'StoryAuthor'
|
|
132
|
-
p54
|
|
133
|
-
sg29
|
|
134
|
-
g30
|
|
135
|
-
((I2023
|
|
136
|
-
I9
|
|
137
|
-
I3
|
|
138
|
-
I14
|
|
139
|
-
I38
|
|
140
|
-
I52
|
|
141
|
-
I6
|
|
142
|
-
I246
|
|
143
|
-
I1
|
|
144
|
-
tp55
|
|
145
|
-
(dp56
|
|
146
|
-
tp57
|
|
147
|
-
Rp58
|
|
148
|
-
sg35
|
|
149
|
-
(lp59
|
|
150
|
-
sg37
|
|
151
|
-
g58
|
|
152
|
-
sbsa(dp60
|
|
153
|
-
g18
|
|
154
|
-
I01
|
|
155
|
-
sg19
|
|
156
|
-
(lp61
|
|
157
|
-
F262.0
|
|
158
|
-
aF10.0
|
|
159
|
-
asg21
|
|
160
|
-
(itiddlywiki
|
|
161
|
-
Tiddler
|
|
162
|
-
p62
|
|
163
|
-
(dp63
|
|
164
|
-
g25
|
|
165
|
-
V[[Untitled Passage 2]]
|
|
166
|
-
p64
|
|
167
|
-
sg27
|
|
168
|
-
VUntitled Passage 1
|
|
169
|
-
p65
|
|
170
|
-
sg29
|
|
171
|
-
g30
|
|
172
|
-
((I2023
|
|
173
|
-
I9
|
|
174
|
-
I3
|
|
175
|
-
I15
|
|
176
|
-
I47
|
|
177
|
-
I59
|
|
178
|
-
I6
|
|
179
|
-
I246
|
|
180
|
-
I1
|
|
181
|
-
tp66
|
|
182
|
-
(dp67
|
|
183
|
-
tp68
|
|
184
|
-
Rp69
|
|
185
|
-
sg35
|
|
186
|
-
(lp70
|
|
187
|
-
Vtag1
|
|
188
|
-
p71
|
|
189
|
-
aVtag2
|
|
190
|
-
p72
|
|
191
|
-
aVtag3
|
|
192
|
-
p73
|
|
193
|
-
asg37
|
|
194
|
-
g30
|
|
195
|
-
((I2023
|
|
196
|
-
I9
|
|
197
|
-
I3
|
|
198
|
-
I14
|
|
199
|
-
I39
|
|
200
|
-
I28
|
|
201
|
-
I6
|
|
202
|
-
I246
|
|
203
|
-
I1
|
|
204
|
-
tp74
|
|
205
|
-
(dp75
|
|
206
|
-
tp76
|
|
207
|
-
Rp77
|
|
208
|
-
sbsa(dp78
|
|
209
|
-
g18
|
|
210
|
-
I00
|
|
211
|
-
sg19
|
|
212
|
-
(lp79
|
|
213
|
-
F261.0
|
|
214
|
-
aF150.0
|
|
215
|
-
asg21
|
|
216
|
-
(itiddlywiki
|
|
217
|
-
Tiddler
|
|
218
|
-
p80
|
|
219
|
-
(dp81
|
|
220
|
-
g25
|
|
221
|
-
Vdd
|
|
222
|
-
p82
|
|
223
|
-
sg27
|
|
224
|
-
VUntitled Passage 2
|
|
225
|
-
p83
|
|
226
|
-
sg29
|
|
227
|
-
g30
|
|
228
|
-
((I2023
|
|
229
|
-
I9
|
|
230
|
-
I3
|
|
231
|
-
I15
|
|
232
|
-
I42
|
|
233
|
-
I58
|
|
234
|
-
I6
|
|
235
|
-
I246
|
|
236
|
-
I1
|
|
237
|
-
tp84
|
|
238
|
-
(dp85
|
|
239
|
-
tp86
|
|
240
|
-
Rp87
|
|
241
|
-
sg35
|
|
242
|
-
(lp88
|
|
243
|
-
sg37
|
|
244
|
-
g30
|
|
245
|
-
((I2023
|
|
246
|
-
I9
|
|
247
|
-
I3
|
|
248
|
-
I14
|
|
249
|
-
I39
|
|
250
|
-
I30
|
|
251
|
-
I6
|
|
252
|
-
I246
|
|
253
|
-
I1
|
|
254
|
-
tp89
|
|
255
|
-
(dp90
|
|
256
|
-
tp91
|
|
257
|
-
Rp92
|
|
258
|
-
sbsa(dp93
|
|
259
|
-
g18
|
|
260
|
-
I00
|
|
261
|
-
sg19
|
|
262
|
-
(lp94
|
|
263
|
-
F262.0
|
|
264
|
-
aF290.0
|
|
265
|
-
asg21
|
|
266
|
-
(itiddlywiki
|
|
267
|
-
Tiddler
|
|
268
|
-
p95
|
|
269
|
-
(dp96
|
|
270
|
-
g25
|
|
271
|
-
Vdd
|
|
272
|
-
p97
|
|
273
|
-
sg27
|
|
274
|
-
VUntitled Passage 3
|
|
275
|
-
p98
|
|
276
|
-
sg29
|
|
277
|
-
g30
|
|
278
|
-
((I2023
|
|
279
|
-
I9
|
|
280
|
-
I3
|
|
281
|
-
I15
|
|
282
|
-
I44
|
|
283
|
-
I49
|
|
284
|
-
I6
|
|
285
|
-
I246
|
|
286
|
-
I1
|
|
287
|
-
tp99
|
|
288
|
-
(dp100
|
|
289
|
-
tp101
|
|
290
|
-
Rp102
|
|
291
|
-
sg35
|
|
292
|
-
(lp103
|
|
293
|
-
sg37
|
|
294
|
-
g30
|
|
295
|
-
((I2023
|
|
296
|
-
I9
|
|
297
|
-
I3
|
|
298
|
-
I14
|
|
299
|
-
I39
|
|
300
|
-
I31
|
|
301
|
-
I6
|
|
302
|
-
I246
|
|
303
|
-
I1
|
|
304
|
-
tp104
|
|
305
|
-
(dp105
|
|
306
|
-
tp106
|
|
307
|
-
Rp107
|
|
308
|
-
sbsa(dp108
|
|
309
|
-
g18
|
|
310
|
-
I00
|
|
311
|
-
sg19
|
|
312
|
-
(lp109
|
|
313
|
-
F401.0
|
|
314
|
-
aF10.0
|
|
315
|
-
asg21
|
|
316
|
-
(itiddlywiki
|
|
317
|
-
Tiddler
|
|
318
|
-
p110
|
|
319
|
-
(dp111
|
|
320
|
-
g25
|
|
321
|
-
Vdd
|
|
322
|
-
p112
|
|
323
|
-
sg27
|
|
324
|
-
VUntitled Passage 4
|
|
325
|
-
p113
|
|
326
|
-
sg29
|
|
327
|
-
g30
|
|
328
|
-
((I2023
|
|
329
|
-
I9
|
|
330
|
-
I3
|
|
331
|
-
I15
|
|
332
|
-
I43
|
|
333
|
-
I10
|
|
334
|
-
I6
|
|
335
|
-
I246
|
|
336
|
-
I1
|
|
337
|
-
tp114
|
|
338
|
-
(dp115
|
|
339
|
-
tp116
|
|
340
|
-
Rp117
|
|
341
|
-
sg35
|
|
342
|
-
(lp118
|
|
343
|
-
sg37
|
|
344
|
-
g30
|
|
345
|
-
((I2023
|
|
346
|
-
I9
|
|
347
|
-
I3
|
|
348
|
-
I14
|
|
349
|
-
I39
|
|
350
|
-
I31
|
|
351
|
-
I6
|
|
352
|
-
I246
|
|
353
|
-
I1
|
|
354
|
-
tp119
|
|
355
|
-
(dp120
|
|
356
|
-
tp121
|
|
357
|
-
Rp122
|
|
358
|
-
sbsa(dp123
|
|
359
|
-
g18
|
|
360
|
-
I00
|
|
361
|
-
sg19
|
|
362
|
-
(lp124
|
|
363
|
-
F402.0
|
|
364
|
-
aF150.0
|
|
365
|
-
asg21
|
|
366
|
-
(itiddlywiki
|
|
367
|
-
Tiddler
|
|
368
|
-
p125
|
|
369
|
-
(dp126
|
|
370
|
-
g25
|
|
371
|
-
S'jquery:off\nhash:off\nbookmark:on\nmodernizr:off\nundo:on\nobfuscate:off\nexitprompt:off\nblankcss:off\n'
|
|
372
|
-
p127
|
|
373
|
-
sg27
|
|
374
|
-
VStorySettings
|
|
375
|
-
p128
|
|
376
|
-
sg29
|
|
377
|
-
g30
|
|
378
|
-
((I2023
|
|
379
|
-
I9
|
|
380
|
-
I3
|
|
381
|
-
I15
|
|
382
|
-
I20
|
|
383
|
-
I35
|
|
384
|
-
I6
|
|
385
|
-
I246
|
|
386
|
-
I1
|
|
387
|
-
tp129
|
|
388
|
-
(dp130
|
|
389
|
-
tp131
|
|
390
|
-
Rp132
|
|
391
|
-
sg35
|
|
392
|
-
(lp133
|
|
393
|
-
sg37
|
|
394
|
-
g30
|
|
395
|
-
((I2023
|
|
396
|
-
I9
|
|
397
|
-
I3
|
|
398
|
-
I15
|
|
399
|
-
I20
|
|
400
|
-
I35
|
|
401
|
-
I6
|
|
402
|
-
I246
|
|
403
|
-
I1
|
|
404
|
-
tp134
|
|
405
|
-
(dp135
|
|
406
|
-
tp136
|
|
407
|
-
Rp137
|
|
408
|
-
sbsasS'scale'
|
|
409
|
-
p138
|
|
410
|
-
F6.200000000000003
|
|
411
|
-
sS'snapping'
|
|
412
|
-
p139
|
|
413
|
-
I00
|
|
414
|
-
ss.
|
|
Binary file
|
|
Binary file
|
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
import { parse as parseTwee, escapeTweeMetacharacters, unescapeTweeMetacharacters } from '../../src/Twee/parse.js';
|
|
2
|
-
import Passage from '../../src/Passage.js';
|
|
3
|
-
|
|
4
|
-
describe('Twee Escaping', () => {
|
|
5
|
-
describe('unescapeTweeMetacharacters()', () => {
|
|
6
|
-
it('Should unescape square brackets', () => {
|
|
7
|
-
expect(unescapeTweeMetacharacters('Test\\[Name\\]')).toBe('Test[Name]');
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
it('Should unescape curly braces', () => {
|
|
11
|
-
expect(unescapeTweeMetacharacters('Test\\{Name\\}')).toBe('Test{Name}');
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
it('Should unescape backslashes', () => {
|
|
15
|
-
expect(unescapeTweeMetacharacters('Test\\\\Name')).toBe('Test\\Name');
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
it('Should unescape any character after backslash (robust decoding)', () => {
|
|
19
|
-
expect(unescapeTweeMetacharacters('\\q')).toBe('q');
|
|
20
|
-
expect(unescapeTweeMetacharacters('\\x')).toBe('x');
|
|
21
|
-
expect(unescapeTweeMetacharacters('\\5')).toBe('5');
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
it('Should handle complex combinations', () => {
|
|
25
|
-
expect(unescapeTweeMetacharacters('\\[Hello\\] \\{world\\} \\\\\\\\')).toBe('[Hello] {world} \\\\');
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
it('Should handle non-string input gracefully', () => {
|
|
29
|
-
expect(unescapeTweeMetacharacters(null)).toBe(null);
|
|
30
|
-
expect(unescapeTweeMetacharacters(undefined)).toBe(undefined);
|
|
31
|
-
expect(unescapeTweeMetacharacters(123)).toBe(123);
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
it('Should handle empty strings', () => {
|
|
35
|
-
expect(unescapeTweeMetacharacters('')).toBe('');
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
it('Should handle strings without escape sequences', () => {
|
|
39
|
-
expect(unescapeTweeMetacharacters('Normal Text')).toBe('Normal Text');
|
|
40
|
-
});
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
describe('escapeTweeMetacharacters()', () => {
|
|
44
|
-
it('Should escape square brackets', () => {
|
|
45
|
-
expect(escapeTweeMetacharacters('Test[Name]')).toBe('Test\\[Name\\]');
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
it('Should escape curly braces', () => {
|
|
49
|
-
expect(escapeTweeMetacharacters('Test{Name}')).toBe('Test\\{Name\\}');
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
it('Should escape backslashes', () => {
|
|
53
|
-
expect(escapeTweeMetacharacters('Test\\Name')).toBe('Test\\\\Name');
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
it('Should escape complex combinations', () => {
|
|
57
|
-
expect(escapeTweeMetacharacters('[Hello] {world} \\\\')).toBe('\\[Hello\\] \\{world\\} \\\\\\\\');
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
it('Should handle non-string input gracefully', () => {
|
|
61
|
-
expect(escapeTweeMetacharacters(null)).toBe(null);
|
|
62
|
-
expect(escapeTweeMetacharacters(undefined)).toBe(undefined);
|
|
63
|
-
expect(escapeTweeMetacharacters(123)).toBe(123);
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
it('Should handle empty strings', () => {
|
|
67
|
-
expect(escapeTweeMetacharacters('')).toBe('');
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
it('Should handle strings without metacharacters', () => {
|
|
71
|
-
expect(escapeTweeMetacharacters('Normal Text')).toBe('Normal Text');
|
|
72
|
-
});
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
describe('Round-trip escaping', () => {
|
|
76
|
-
it('Should preserve text through escape -> unescape cycle', () => {
|
|
77
|
-
const original = 'Test[Name]{Value}\\Path';
|
|
78
|
-
const escaped = escapeTweeMetacharacters(original);
|
|
79
|
-
const unescaped = unescapeTweeMetacharacters(escaped);
|
|
80
|
-
expect(unescaped).toBe(original);
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
it('Should handle complex nested scenarios', () => {
|
|
84
|
-
const original = '[{\\}]{[\\]}';
|
|
85
|
-
const escaped = escapeTweeMetacharacters(original);
|
|
86
|
-
const unescaped = unescapeTweeMetacharacters(escaped);
|
|
87
|
-
expect(unescaped).toBe(original);
|
|
88
|
-
});
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
describe('Twee parsing with escaping', () => {
|
|
92
|
-
it('Should correctly parse escaped passage names', () => {
|
|
93
|
-
const content = ':: Test\\[Name\\] \\{with\\} \\\\brackets\nContent here';
|
|
94
|
-
const story = parseTwee(content);
|
|
95
|
-
expect(story.passages[0].name).toBe('Test[Name] {with} \\brackets');
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
it('Should correctly parse escaped tags', () => {
|
|
99
|
-
const content = ':: TestPassage [tag\\[1\\] tag\\{2\\}]\nContent here';
|
|
100
|
-
const story = parseTwee(content);
|
|
101
|
-
expect(story.passages[0].tags).toEqual(['tag[1]', 'tag{2}']);
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
it('Should handle mixed escaped and non-escaped content', () => {
|
|
105
|
-
const content = ':: Test\\[Passage [normal escaped\\]tag]\nContent here';
|
|
106
|
-
const story = parseTwee(content);
|
|
107
|
-
expect(story.passages[0].name).toBe('Test[Passage');
|
|
108
|
-
expect(story.passages[0].tags).toEqual(['normal', 'escaped]tag']);
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
it('Should handle the cursed.twee test case correctly', () => {
|
|
112
|
-
const content = `:: StoryData
|
|
113
|
-
{
|
|
114
|
-
"ifid": "22F25A58-7062-4927-95B6-F424DDB2EC65",
|
|
115
|
-
"format": "Harlowe",
|
|
116
|
-
"format-version": "3.3.8",
|
|
117
|
-
"start": "[Hello] {world} \\\\\\\\",
|
|
118
|
-
"zoom": 1
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
:: \\[Hello\\] \\{world\\} \\\\\\\\
|
|
122
|
-
Content here`;
|
|
123
|
-
|
|
124
|
-
const story = parseTwee(content);
|
|
125
|
-
expect(story.start).toBe('[Hello] {world} \\\\');
|
|
126
|
-
|
|
127
|
-
// Find the passage by the unescaped name
|
|
128
|
-
const passage = story.getPassageByName('[Hello] {world} \\\\');
|
|
129
|
-
expect(passage).not.toBeNull();
|
|
130
|
-
expect(passage.name).toBe('[Hello] {world} \\\\');
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
it('Should handle complex metadata with escaped keys (if supported)', () => {
|
|
134
|
-
const content = ':: TestPassage {"position": "100,200", "size": "150,100"}\nContent here';
|
|
135
|
-
const story = parseTwee(content);
|
|
136
|
-
expect(story.passages[0].metadata.position).toBe('100,200');
|
|
137
|
-
expect(story.passages[0].metadata.size).toBe('150,100');
|
|
138
|
-
});
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
describe('Twee generation with escaping', () => {
|
|
142
|
-
it('Should escape passage names when generating Twee', () => {
|
|
143
|
-
const passage = new Passage('Test[Name]', 'Content', [], {});
|
|
144
|
-
const tweeOutput = passage.toTwee();
|
|
145
|
-
expect(tweeOutput).toContain(':: Test\\[Name\\]');
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
it('Should escape tag names when generating Twee', () => {
|
|
149
|
-
const passage = new Passage('TestPassage', 'Content', ['tag[1]', 'tag{2}'], {});
|
|
150
|
-
const tweeOutput = passage.toTwee();
|
|
151
|
-
expect(tweeOutput).toContain('[tag\\[1\\] tag\\{2\\}]');
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
it('Should handle complex escaping scenarios', () => {
|
|
155
|
-
const passage = new Passage('Test[Name]{Value}\\Path', 'Content', ['complex[tag]'], {});
|
|
156
|
-
const tweeOutput = passage.toTwee();
|
|
157
|
-
expect(tweeOutput).toContain(':: Test\\[Name\\]\\{Value\\}\\\\Path');
|
|
158
|
-
expect(tweeOutput).toContain('[complex\\[tag\\]]');
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
it('Should preserve normal names and tags without escaping', () => {
|
|
162
|
-
const passage = new Passage('NormalName', 'Content', ['normaltag'], {});
|
|
163
|
-
const tweeOutput = passage.toTwee();
|
|
164
|
-
expect(tweeOutput).toContain(':: NormalName');
|
|
165
|
-
expect(tweeOutput).toContain('[normaltag]');
|
|
166
|
-
});
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
describe('Edge cases', () => {
|
|
170
|
-
it('Should handle empty passage names gracefully', () => {
|
|
171
|
-
const content = ':: \nContent here';
|
|
172
|
-
expect(() => parseTwee(content)).toThrow('Malformed passage header!');
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
it('Should handle passages with only escaped characters as names', () => {
|
|
176
|
-
const content = ':: \\[\\]\nContent here';
|
|
177
|
-
const story = parseTwee(content);
|
|
178
|
-
expect(story.passages[0].name).toBe('[]');
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
it('Should handle multiple consecutive escapes', () => {
|
|
182
|
-
const content = ':: Test\\\\\\\\Name\nContent here';
|
|
183
|
-
const story = parseTwee(content);
|
|
184
|
-
expect(story.passages[0].name).toBe('Test\\\\Name');
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
it('Should handle tags with only metacharacters', () => {
|
|
188
|
-
const content = ':: TestPassage [\\[\\] \\{\\}]\nContent here';
|
|
189
|
-
const story = parseTwee(content);
|
|
190
|
-
expect(story.passages[0].tags).toEqual(['[]', '{}']);
|
|
191
|
-
});
|
|
192
|
-
|
|
193
|
-
it('Should handle mixed whitespace and escaping', () => {
|
|
194
|
-
const content = ':: Test\\[Name\\] [ tag\\[1\\] tag2 ]\nContent here';
|
|
195
|
-
const story = parseTwee(content);
|
|
196
|
-
expect(story.passages[0].name).toBe('Test[Name]');
|
|
197
|
-
expect(story.passages[0].tags).toEqual(['tag[1]', 'tag2']);
|
|
198
|
-
});
|
|
199
|
-
});
|
|
200
|
-
});
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import { readFileSync } from 'node:fs';
|
|
2
|
-
import { parse as parseTwee } from '../../src/Twee/parse.js';
|
|
3
|
-
|
|
4
|
-
describe('Twee', () => {
|
|
5
|
-
describe('parse()', () => {
|
|
6
|
-
it('Should throw error if non-string is used', () => {
|
|
7
|
-
expect(() => { parseTwee(1); }).toThrow();
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
it('Should throw error if empty string is used', () => {
|
|
11
|
-
expect(() => { parseTwee(); }).toThrow();
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
it('Should throw error if no passages are present', () => {
|
|
15
|
-
expect(() => { parseTwee('()()'); }).toThrow();
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
it('Should ignore malformed passage metadata and create empty object', () => {
|
|
19
|
-
const fr = readFileSync('test/Twee/TweeParser/malformed.twee', 'utf-8');
|
|
20
|
-
const story = parseTwee(fr);
|
|
21
|
-
const metadata = story.getPassageByName('Start').metadata;
|
|
22
|
-
const numberOfMetadataProperties = Object.keys(metadata).length;
|
|
23
|
-
expect(numberOfMetadataProperties).toBe(0);
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
it('Should throw error if it detects malformed passage headers', () => {
|
|
27
|
-
expect(() => { parseTwee('::{}[]\nNo name'); }).toThrow();
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
it('Should cut notes before passages', () => {
|
|
31
|
-
const fr = readFileSync('test/Twee/TweeParser/notes.twee', 'utf-8');
|
|
32
|
-
const story = parseTwee(fr);
|
|
33
|
-
expect(story.name).toBe('twineExample');
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
it('Should be able to parse Twee file for Story Name', () => {
|
|
37
|
-
const fr = readFileSync('test/Twee/TweeParser/example.twee', 'utf-8');
|
|
38
|
-
const story = parseTwee(fr);
|
|
39
|
-
expect(story.name).toBe('twineExample');
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
it('Should parse single tag on Start passage', () => {
|
|
43
|
-
const fr = readFileSync('test/Twee/TweeParser/singletag.twee', 'utf-8');
|
|
44
|
-
const story = parseTwee(fr);
|
|
45
|
-
const start = story.getPassageByName('Start');
|
|
46
|
-
expect(start.tags).toHaveLength(1);
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
it('Should parse multiple tag', () => {
|
|
50
|
-
const fr = readFileSync('test/Twee/TweeParser/multipletags.twee', 'utf-8');
|
|
51
|
-
const story = parseTwee(fr);
|
|
52
|
-
const start = story.getPassageByName('Start');
|
|
53
|
-
expect(start.tags).toHaveLength(2);
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
it('Should parse single script passage', () => {
|
|
57
|
-
const fr = readFileSync('test/Twee/TweeParser/scriptPassage.twee', 'utf-8');
|
|
58
|
-
const story = parseTwee(fr);
|
|
59
|
-
const p = story.getPassageByName('UserScript');
|
|
60
|
-
expect(p).toBe(null);
|
|
61
|
-
expect(story.storyJavaScript.length).toBeGreaterThan(0);
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
it('Should parse single stylesheet passage', () => {
|
|
65
|
-
const fr = readFileSync('test/Twee/TweeParser/stylePassage.twee', 'utf-8');
|
|
66
|
-
const story = parseTwee(fr);
|
|
67
|
-
const p = story.getPassageByName('UserStylesheet');
|
|
68
|
-
expect(p).toBe(null);
|
|
69
|
-
expect(story.storyStylesheet.length).toBeGreaterThan(0);
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
it('Should parse StoryTitle', () => {
|
|
73
|
-
const fr = readFileSync('test/Twee/TweeParser/test.twee', 'utf-8');
|
|
74
|
-
const story = parseTwee(fr);
|
|
75
|
-
expect(story.name).not.toBe(null);
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
it('Should parse StoryAuthor', () => {
|
|
79
|
-
const fr = readFileSync('test/Twee/TweeParser/example.twee', 'utf-8');
|
|
80
|
-
const story = parseTwee(fr);
|
|
81
|
-
const p = story.getPassageByName('StoryAuthor');
|
|
82
|
-
expect(p).not.toBe(null);
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
it('Should parse single and only passage Start', () => {
|
|
86
|
-
const fr = readFileSync('test/Twee/TweeParser/start.twee', 'utf-8');
|
|
87
|
-
const story = parseTwee(fr);
|
|
88
|
-
const p = story.getPassageByName('Start');
|
|
89
|
-
const startingPassage = story.start;
|
|
90
|
-
expect(p).not.toBe(null);
|
|
91
|
-
expect(startingPassage).toBe('Start');
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
it('Should correctly parse "script" tagged passages as story javascript AND remove passages from story', () => {
|
|
95
|
-
const fr = readFileSync('test/Twee/TweeParser/cycling.twee', 'utf-8');
|
|
96
|
-
const story = parseTwee(fr);
|
|
97
|
-
expect(story.storyJavaScript.length).toBeGreaterThan(0);
|
|
98
|
-
expect(story.passages.length).toBe(2);
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
it('Should correctly parse "stylesheet" tagged passages as story stylesheet AND remove passages from story', () => {
|
|
102
|
-
const fr = readFileSync('test/Twee/TweeParser/style.twee', 'utf-8');
|
|
103
|
-
const story = parseTwee(fr);
|
|
104
|
-
expect(story.storyStylesheet.length).toBeGreaterThan(0);
|
|
105
|
-
expect(story.passages.length).toBe(1);
|
|
106
|
-
});
|
|
107
|
-
});
|
|
108
|
-
});
|