extwee 2.0.5 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (215) hide show
  1. package/.eslintrc.json +25 -25
  2. package/.github/FUNDING.yml +3 -0
  3. package/.github/dependabot.yml +11 -0
  4. package/.github/workflows/nodejs.yml +25 -24
  5. package/.travis.yml +13 -13
  6. package/CODE_OF_CONDUCT.md +82 -82
  7. package/LICENSE +21 -21
  8. package/README.md +173 -36
  9. package/SECURITY.md +12 -12
  10. package/babel.config.json +18 -22
  11. package/build/extwee +0 -0
  12. package/build/extwee.exe +0 -0
  13. package/build/extwee.web.min.js +2 -0
  14. package/build/extwee.web.min.js.LICENSE.txt +1 -0
  15. package/docs/.nojekyll +0 -0
  16. package/docs/README.md +167 -0
  17. package/docs/_sidebar.md +19 -0
  18. package/docs/examples/dynamicPassages.md +28 -0
  19. package/docs/examples/jsonToTwee.md +23 -0
  20. package/docs/examples/twsToTwee.md +25 -0
  21. package/docs/formats/json.md +17 -0
  22. package/docs/formats/twee.md +13 -0
  23. package/docs/formats/twine1HTML.md +13 -0
  24. package/docs/formats/twine2ArchiveHTML.md +13 -0
  25. package/docs/formats/twine2HTML.md +13 -0
  26. package/docs/formats/tws.md +9 -0
  27. package/docs/index.html +26 -0
  28. package/docs/install/binaries.md +9 -0
  29. package/docs/install/npm.md +20 -0
  30. package/docs/install/npx.md +9 -0
  31. package/docs/objects/passage.md +47 -0
  32. package/docs/objects/story.md +70 -0
  33. package/docs/objects/storyformat.md +27 -0
  34. package/index.html +22 -0
  35. package/index.js +29 -31
  36. package/package.json +65 -58
  37. package/src/JSON/parse.js +128 -0
  38. package/src/Passage.js +298 -202
  39. package/src/Story.js +650 -489
  40. package/src/StoryFormat/parse.js +134 -0
  41. package/src/StoryFormat.js +259 -300
  42. package/src/TWS/parse.js +86 -0
  43. package/src/Twee/parse.js +157 -0
  44. package/src/Twine1HTML/compile.js +58 -0
  45. package/src/Twine1HTML/parse.js +134 -0
  46. package/src/Twine2ArchiveHTML/compile.js +36 -0
  47. package/src/Twine2ArchiveHTML/parse.js +49 -0
  48. package/src/Twine2HTML/compile.js +35 -0
  49. package/src/Twine2HTML/parse.js +348 -0
  50. package/src/extwee.js +206 -0
  51. package/test/CLI/CLI.test.js +49 -0
  52. package/test/CLI/files/example.json +1 -0
  53. package/test/CLI/files/example6.twee +22 -0
  54. package/test/{Roundtrip → CLI/files}/harlowe.js +2 -2
  55. package/test/CLI/{input.html → files/input.html} +47 -47
  56. package/test/CLI/files/output/test.twee +0 -0
  57. package/test/CLI/{tweeExample.twee → files/tweeExample.twee} +17 -17
  58. package/test/CLI/files/twine1/LICENSE.txt +32 -0
  59. package/test/CLI/files/twine1/code.js +5 -0
  60. package/test/CLI/files/twine1/engine.js +43 -0
  61. package/test/CLI/files/twine1/header.html +325 -0
  62. package/test/CLI/files/twine1Test.html +371 -0
  63. package/test/{HTMLParser → CLI/files}/twineExample.html +16 -15
  64. package/test/JSON/JSON.Parse.test.js +316 -0
  65. package/test/Passage.test.js +175 -104
  66. package/test/Roundtrip/{Example1.html → Files/Example1.html} +63 -63
  67. package/test/Roundtrip/Files/LICENSE +19 -0
  68. package/test/Roundtrip/Files/example1.twee +10 -0
  69. package/test/Roundtrip/{example2.twee → Files/example2.twee} +27 -18
  70. package/test/Roundtrip/Files/example4.twee +27 -0
  71. package/test/{StoryFormatParser → Roundtrip/Files}/harlowe.js +2 -2
  72. package/test/Roundtrip/{round.html → Files/round.html} +6 -7
  73. package/test/Roundtrip/Roundtrip.test.js +54 -0
  74. package/test/Story.test.js +624 -355
  75. package/test/StoryFormat/StoryFormat.Parse.test.js +91 -0
  76. package/test/{StoryFormatParser → StoryFormat/StoryFormatParser}/example.js +3 -3
  77. package/test/{StoryFormatParser → StoryFormat/StoryFormatParser}/example2.js +3 -3
  78. package/test/{CLI → StoryFormat/StoryFormatParser}/harlowe.js +2 -2
  79. package/test/StoryFormat.test.js +152 -152
  80. package/test/TWS/Parse.test.js +78 -0
  81. package/test/TWS/TWSParser/Example1.tws +150 -0
  82. package/test/TWS/TWSParser/Example5.tws +414 -0
  83. package/test/TWS/TWSParser/noscale.tws +0 -0
  84. package/test/TWS/TWSParser/nostory.tws +0 -0
  85. package/test/Twee/Twee.Parse.test.js +76 -0
  86. package/test/{TweeParser → Twee/TweeParser}/emptytags.twee +2 -2
  87. package/test/{TweeParser → Twee/TweeParser}/example.twee +32 -32
  88. package/test/{TweeParser → Twee/TweeParser}/missing.twee +19 -19
  89. package/test/{TweeParser → Twee/TweeParser}/multipleScriptPassages.twee +19 -19
  90. package/test/{TweeParser → Twee/TweeParser}/multipleStyleTag.twee +19 -19
  91. package/test/{TweeParser → Twee/TweeParser}/multipletags.twee +10 -10
  92. package/test/{TweeParser → Twee/TweeParser}/noTitle.twee +2 -2
  93. package/test/{TweeParser → Twee/TweeParser}/notes.twee +16 -16
  94. package/test/{TweeParser → Twee/TweeParser}/pasagemetadataerror.twee +2 -2
  95. package/test/{TweeParser → Twee/TweeParser}/scriptPassage.twee +16 -16
  96. package/test/{TweeParser → Twee/TweeParser}/singletag.twee +13 -13
  97. package/test/{TweeParser → Twee/TweeParser}/startMetadata.twee +14 -14
  98. package/test/{TweeParser → Twee/TweeParser}/storydataerror.twee +25 -25
  99. package/test/{TweeParser → Twee/TweeParser}/stylePassage.twee +16 -16
  100. package/test/{Story → Twee/TweeParser}/test.twee +25 -25
  101. package/test/Twine1HTML/Twine1HTML.Compile.test.js +180 -0
  102. package/test/Twine1HTML/Twine1HTML.Parse.test.js +183 -0
  103. package/test/Twine1HTML/Twine1HTMLCompiler/Twine1/LICENSE +674 -0
  104. package/test/Twine1HTML/Twine1HTMLCompiler/Twine1/engine.js +43 -0
  105. package/test/Twine1HTML/Twine1HTMLCompiler/Twine1/jquery.js +4 -0
  106. package/test/Twine1HTML/Twine1HTMLCompiler/Twine1/modernizr.js +4 -0
  107. package/test/Twine1HTML/Twine1HTMLCompiler/engineTest.html +1 -0
  108. package/test/Twine1HTML/Twine1HTMLCompiler/jonah-1.4.2/LICENSE +32 -0
  109. package/test/Twine1HTML/Twine1HTMLCompiler/jonah-1.4.2/code.js +4 -0
  110. package/test/Twine1HTML/Twine1HTMLCompiler/jonah-1.4.2/header.html +327 -0
  111. package/test/Twine1HTML/Twine1HTMLCompiler/test.html +0 -0
  112. package/test/Twine1HTML/Twine1HTMLCompiler/test1.html +6 -0
  113. package/test/Twine1HTML/Twine1HTMLCompiler/test2.html +6 -0
  114. package/test/Twine1HTML/Twine1HTMLCompiler/test3.html +43 -0
  115. package/test/Twine1HTML/Twine1HTMLCompiler/test4.html +372 -0
  116. package/test/Twine1HTML/Twine1HTMLCompiler/test5.html +372 -0
  117. package/test/Twine2ArchiveHTML/Twine2ArchiveHTML.Compile.test.js +35 -0
  118. package/test/Twine2ArchiveHTML/Twine2ArchiveHTML.Parse.test.js +25 -0
  119. package/test/Twine2ArchiveHTML/Twine2ArchiveHTMLCompiler/test1.html +6 -0
  120. package/test/Twine2ArchiveHTML/Twine2ArchiveHTMLParser/test1.html +3 -0
  121. package/test/Twine2HTML/Twine2HTML.Compile.test.js +224 -0
  122. package/test/Twine2HTML/Twine2HTML.Parse.test.js +172 -0
  123. package/test/{HTMLWriter → Twine2HTML/Twine2HTMLCompiler}/creator.html +4 -5
  124. package/test/{CLI → Twine2HTML/Twine2HTMLCompiler}/example6.twee +15 -15
  125. package/test/{HTMLWriter → Twine2HTML/Twine2HTMLCompiler}/missingStoryTitle.twee +29 -29
  126. package/test/{HTMLWriter → Twine2HTML/Twine2HTMLCompiler}/test11.html +1 -3
  127. package/test/{HTMLWriter → Twine2HTML/Twine2HTMLCompiler}/test2.html +10 -11
  128. package/test/{HTMLWriter → Twine2HTML/Twine2HTMLCompiler}/test3.html +1 -2
  129. package/test/{HTMLWriter → Twine2HTML/Twine2HTMLCompiler}/test4.html +4 -5
  130. package/test/{HTMLWriter → Twine2HTML/Twine2HTMLCompiler}/test6.html +1 -2
  131. package/test/{HTMLParser → Twine2HTML/Twine2HTMLParser}/Example1.html +52 -52
  132. package/test/{HTMLParser → Twine2HTML/Twine2HTMLParser}/Tags.html +15 -15
  133. package/test/{HTMLParser → Twine2HTML/Twine2HTMLParser}/lyingStartnode.html +15 -15
  134. package/test/{HTMLParser → Twine2HTML/Twine2HTMLParser}/lyingTagColors.html +48 -48
  135. package/test/{HTMLParser → Twine2HTML/Twine2HTMLParser}/missingCreator.html +11 -11
  136. package/test/{HTMLParser → Twine2HTML/Twine2HTMLParser}/missingCreatorVersion.html +11 -11
  137. package/test/{HTMLParser → Twine2HTML/Twine2HTMLParser}/missingFormat.html +11 -11
  138. package/test/{HTMLParser → Twine2HTML/Twine2HTMLParser}/missingFormatVersion.html +11 -11
  139. package/test/{HTMLParser → Twine2HTML/Twine2HTMLParser}/missingIFID.html +11 -11
  140. package/test/{HTMLParser → Twine2HTML/Twine2HTMLParser}/missingName.html +33 -33
  141. package/test/{HTMLParser → Twine2HTML/Twine2HTMLParser}/missingPID.html +15 -15
  142. package/test/{HTMLParser → Twine2HTML/Twine2HTMLParser}/missingPassageName.html +15 -15
  143. package/test/{HTMLParser → Twine2HTML/Twine2HTMLParser}/missingPassageTags.html +15 -15
  144. package/test/{HTMLParser → Twine2HTML/Twine2HTMLParser}/missingPosition.html +15 -15
  145. package/test/{HTMLParser → Twine2HTML/Twine2HTMLParser}/missingScript.html +14 -14
  146. package/test/{HTMLParser → Twine2HTML/Twine2HTMLParser}/missingSize.html +35 -35
  147. package/test/{HTMLParser → Twine2HTML/Twine2HTMLParser}/missingStartnode.html +11 -11
  148. package/test/{HTMLParser → Twine2HTML/Twine2HTMLParser}/missingStyle.html +14 -14
  149. package/test/{HTMLParser → Twine2HTML/Twine2HTMLParser}/missingZoom.html +11 -11
  150. package/test/Twine2HTML/Twine2HTMLParser/twineExample.html +23 -0
  151. package/test/{HTMLParser → Twine2HTML/Twine2HTMLParser}/twineExample2.html +15 -15
  152. package/test/{HTMLParser → Twine2HTML/Twine2HTMLParser}/twineExample3.html +15 -15
  153. package/web-index.js +29 -0
  154. package/webpack.config.js +12 -0
  155. package/bin/extwee.js +0 -47
  156. package/src/FileReader.js +0 -33
  157. package/src/HTMLParser.js +0 -343
  158. package/src/HTMLWriter.js +0 -231
  159. package/src/StoryFormatParser.js +0 -142
  160. package/src/TweeParser.js +0 -161
  161. package/src/TweeWriter.js +0 -98
  162. package/story-formats/chapbook-1.2.0/format.js +0 -1
  163. package/story-formats/chapbook-1.2.0/logo.svg +0 -1
  164. package/story-formats/harlowe-1.2.4/format.js +0 -1
  165. package/story-formats/harlowe-1.2.4/icon.svg +0 -78
  166. package/story-formats/harlowe-2.1.0/format.js +0 -2
  167. package/story-formats/harlowe-2.1.0/icon.svg +0 -78
  168. package/story-formats/harlowe-3.1.0/format.js +0 -3
  169. package/story-formats/harlowe-3.1.0/icon.svg +0 -78
  170. package/story-formats/paperthin-1.0.0/format.js +0 -1
  171. package/story-formats/paperthin-1.0.0/icon.svg +0 -5
  172. package/story-formats/snowman-1.4.0/format.js +0 -1
  173. package/story-formats/snowman-1.4.0/icon.svg +0 -436
  174. package/story-formats/snowman-2.0.2/format.js +0 -1
  175. package/story-formats/snowman-2.0.2/icon.svg +0 -436
  176. package/story-formats/sugarcube-1.0.35/LICENSE +0 -23
  177. package/story-formats/sugarcube-1.0.35/format.js +0 -1
  178. package/story-formats/sugarcube-1.0.35/icon.svg +0 -56
  179. package/story-formats/sugarcube-2.31.1/LICENSE +0 -22
  180. package/story-formats/sugarcube-2.31.1/format.js +0 -1
  181. package/story-formats/sugarcube-2.31.1/icon.svg +0 -56
  182. package/test/CLI/test2.html +0 -47
  183. package/test/CLI/twineExample.html +0 -15
  184. package/test/CLI.test.js +0 -30
  185. package/test/FileReader/t1.txt +0 -1
  186. package/test/FileReader.test.js +0 -14
  187. package/test/HTMLParser.test.js +0 -177
  188. package/test/HTMLWriter/example6.twee +0 -16
  189. package/test/HTMLWriter.test.js +0 -289
  190. package/test/Roundtrip/example1.twee +0 -21
  191. package/test/Roundtrip.test.js +0 -48
  192. package/test/Story/startmeta.twee +0 -29
  193. package/test/StoryFormatParser.test.js +0 -91
  194. package/test/TweeParser/test.twee +0 -25
  195. package/test/TweeParser.test.js +0 -79
  196. package/test/TweeWriter/test1.twee +0 -18
  197. package/test/TweeWriter/test3.twee +0 -12
  198. package/test/TweeWriter/test4.twee +0 -14
  199. package/test/TweeWriter/test5.twee +0 -20
  200. package/test/TweeWriter.test.js +0 -85
  201. /package/test/CLI/{test.twee → files/test.twee} +0 -0
  202. /package/test/{StoryFormatParser → StoryFormat/StoryFormatParser}/format.js +0 -0
  203. /package/test/{StoryFormatParser → StoryFormat/StoryFormatParser}/format_doublename.js +0 -0
  204. /package/test/{StoryFormatParser → StoryFormat/StoryFormatParser}/missingAuthor.js +0 -0
  205. /package/test/{StoryFormatParser → StoryFormat/StoryFormatParser}/missingDescription.js +0 -0
  206. /package/test/{StoryFormatParser → StoryFormat/StoryFormatParser}/missingImage.js +0 -0
  207. /package/test/{StoryFormatParser → StoryFormat/StoryFormatParser}/missingLicense.js +0 -0
  208. /package/test/{StoryFormatParser → StoryFormat/StoryFormatParser}/missingName.js +0 -0
  209. /package/test/{StoryFormatParser → StoryFormat/StoryFormatParser}/missingProofing.js +0 -0
  210. /package/test/{StoryFormatParser → StoryFormat/StoryFormatParser}/missingSource.js +0 -0
  211. /package/test/{StoryFormatParser → StoryFormat/StoryFormatParser}/missingURL.js +0 -0
  212. /package/test/{StoryFormatParser → StoryFormat/StoryFormatParser}/missingVersion.js +0 -0
  213. /package/test/{StoryFormatParser → StoryFormat/StoryFormatParser}/versionWrong.js +0 -0
  214. /package/test/{HTMLWriter → Twine2HTML/Twine2HTMLCompiler}/TestTags.html +0 -0
  215. /package/test/{HTMLParser → Twine2HTML/Twine2HTMLParser}/tagColors.html +0 -0
@@ -1,15 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8">
5
- <title>twineExample</title>
6
- </head>
7
- <body>
8
- <tw-story></tw-story>
9
- <tw-storydata name="twineExample" startnode="1" creator="Twine" creator-version="2.2.1" ifid="2B68ECD6-348F-4CF5-96F8-549A512A8128" zoom="1" format="Harlowe" format-version="2.1.0" options="" 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="Start" tags="" position="102,104" size="100,100">[[Another passage]]
10
-
11
- [[A third passage]]</tw-passagedata><tw-passagedata pid="2" name="Another passage" tags="" position="353,60" size="100,100">[[A fourth passage]]
12
-
13
- [[A third passage]] </tw-passagedata><tw-passagedata pid="3" name="A third passage" tags="" position="350,288" size="100,100">[[Start]]</tw-passagedata><tw-passagedata pid="4" name="A fourth passage" tags="" position="587,197" size="100,100">[[A fifth passage]]</tw-passagedata><tw-passagedata pid="5" name="A fifth passage" tags="" position="800,306" size="100,100">Double-click this passage to edit it.</tw-passagedata></tw-storydata>
14
- </body>
15
- </html>
package/test/CLI.test.js DELETED
@@ -1,30 +0,0 @@
1
- import shell from 'shelljs';
2
-
3
- // We could get this from process,
4
- // but since we are using shelljs,
5
- // we ask for the pwd() instead of cwd().
6
- const currentPath = shell.pwd().stdout;
7
- const testFilePath = currentPath + '/test/CLI';
8
-
9
- describe('CLI', function () {
10
- // Remove the test files, if they exist
11
- beforeAll(function () {
12
- shell.rm(`${testFilePath}/test.*`);
13
- });
14
-
15
- // Test generating Twee files
16
- describe('Decompile', function () {
17
- test('Decompile: HTML into Twee', function () {
18
- shell.exec(`node ${currentPath}/bin/extwee.js -d -i ${testFilePath}/input.html -o ${testFilePath}/test.twee`);
19
- expect(shell.test('-e', `${testFilePath}/test.twee`)).toBe(true);
20
- });
21
- });
22
-
23
- // Test generating HTML files
24
- describe('Compile', function () {
25
- test('Compile: Twee + StoryFormat into Twee', function () {
26
- shell.exec(`node ${currentPath}/bin/extwee.js -c -i ${testFilePath}/example6.twee -s ${testFilePath}/harlowe.js -o ${testFilePath}/test2.html`);
27
- expect(shell.test('-e', `${testFilePath}/test2.html`)).toBe(true);
28
- });
29
- });
30
- });
@@ -1 +0,0 @@
1
- Gibberish
@@ -1,14 +0,0 @@
1
- import FileReader from '../src/FileReader.js';
2
-
3
- describe('FileReader', function () {
4
- describe('#readFile()', function () {
5
- test('Should throw error if file not found', function () {
6
- expect(() => { FileReader.read('test/FileReader/t2.txt'); }).toThrow();
7
- });
8
-
9
- test('Should read the contents of a file', function () {
10
- const fr = FileReader.read('test/FileReader/t1.txt');
11
- expect(fr).toBe('Gibberish');
12
- });
13
- });
14
- });
@@ -1,177 +0,0 @@
1
- import FileReader from '../src/FileReader.js';
2
- import HTMLParser from '../src/HTMLParser.js';
3
-
4
- // Pull the name and version of this project from package.json.
5
- // These are used as the 'creator' and 'creator-version'.
6
- const { version } = JSON.parse(FileReader.read('package.json'));
7
-
8
- describe('HTMLParser', function () {
9
- describe('#parse()', function () {
10
- test('Should throw error if content is not Twine-2 style HTML', function () {
11
- expect(() => { HTMLParser.parse(''); }).toThrow();
12
- });
13
-
14
- test('Should be able to parse Twine 2 HTML for story name', function () {
15
- const fr = FileReader.read('test/HTMLParser/twineExample.html');
16
- const story = HTMLParser.parse(fr);
17
- const storyTitle = story.getPassageByName('StoryTitle');
18
- expect(storyTitle.text).toBe('twineExample');
19
- });
20
-
21
- test('Should be able to parse Twine 2 HTML for correct number of passages', function () {
22
- const fr = FileReader.read('test/HTMLParser/twineExample.html');
23
- const tp = HTMLParser.parse(fr);
24
- expect(tp.size()).toBe(6);
25
- });
26
-
27
- test('Should be able to correctly parse passage tags', function () {
28
- const fr = FileReader.read('test/HTMLParser/Tags.html');
29
- const story = HTMLParser.parse(fr);
30
- const p = story.getPassageByName('Untitled Passage');
31
- expect(p.tags).toHaveLength(2);
32
- });
33
-
34
- test('Should set a missing name to Untitled', function () {
35
- const fr = FileReader.read('test/HTMLParser/missingName.html');
36
- const story = HTMLParser.parse(fr);
37
- const p = story.getPassageByName('StoryTitle');
38
- expect(p.text).toBe('Untitled');
39
- });
40
-
41
- test('Should set a missing IFID to an empty string', function () {
42
- const fr = FileReader.read('test/HTMLParser/missingIFID.html');
43
- const tp = HTMLParser.parse(fr);
44
- expect(tp.IFID).toBe('');
45
- });
46
-
47
- test('Should have Extwee for creator when missing', function () {
48
- const fr = FileReader.read('test/HTMLParser/missingCreator.html');
49
- const tp = HTMLParser.parse(fr);
50
- expect(tp.creator).toBe('extwee');
51
- });
52
-
53
- test('Should have correct for creatorVersion when missing', function () {
54
- const fr = FileReader.read('test/HTMLParser/missingCreatorVersion.html');
55
- const tp = HTMLParser.parse(fr);
56
- expect(tp.creatorVersion).toBe(version);
57
- });
58
-
59
- test('Should have empty string as format when missing', function () {
60
- const fr = FileReader.read('test/HTMLParser/missingFormat.html');
61
- const tp = HTMLParser.parse(fr);
62
- expect(tp.format).toBe('');
63
- });
64
-
65
- test('Should have empty string as formatVersion when missing', function () {
66
- const fr = FileReader.read('test/HTMLParser/missingFormatVersion.html');
67
- const tp = HTMLParser.parse(fr);
68
- expect(tp.formatVersion).toBe('');
69
- });
70
-
71
- test('Should have empty string as zoom when missing', function () {
72
- const fr = FileReader.read('test/HTMLParser/missingZoom.html');
73
- const tp = HTMLParser.parse(fr);
74
- expect(tp.zoom).toBe(0);
75
- });
76
-
77
- test('Should not have position if passage does not', function () {
78
- const fr = FileReader.read('test/HTMLParser/missingPosition.html');
79
- const story = HTMLParser.parse(fr);
80
- const p = story.getPassageByName('Untitled Passage');
81
- expect(Object.prototype.hasOwnProperty.call(p.metadata, 'position')).toBe(false);
82
- });
83
-
84
- test('Should not have size if passage does not', function () {
85
- const fr = FileReader.read('test/HTMLParser/missingSize.html');
86
- const story = HTMLParser.parse(fr);
87
- const p = story.getPassageByName('Untitled Passage');
88
- expect(Object.prototype.hasOwnProperty.call(p.metadata, 'size')).toBe(false);
89
- });
90
-
91
- test('Should have empty array as tags if tags is missing', function () {
92
- const fr = FileReader.read('test/HTMLParser/missingPassageTags.html');
93
- const story = HTMLParser.parse(fr);
94
- const p = story.getPassageByName('Untitled Passage');
95
- expect(p.tags).toHaveLength(0);
96
- });
97
-
98
- test('Should not have stylesheet tag if no passages exist with it', function () {
99
- const fr = FileReader.read('test/HTMLParser/missingStyle.html');
100
- const story = HTMLParser.parse(fr);
101
- const passages = story.getPassagesByTag('stylesheet');
102
- expect(passages.length).toBe(0);
103
- });
104
-
105
- test('Should not have script tag if no passages exist with it', function () {
106
- const fr = FileReader.read('test/HTMLParser/missingScript.html');
107
- const story = HTMLParser.parse(fr);
108
- const passages = story.getPassagesByTag('script');
109
- expect(passages.length).toBe(0);
110
- });
111
-
112
- test('Should have script and style tags normally', function () {
113
- const fr = FileReader.read('test/HTMLParser/Example1.html');
114
- const story = HTMLParser.parse(fr);
115
- const scriptPassages = story.getPassagesByTag('script');
116
- const stylesheetPassages = story.getPassagesByTag('stylesheet');
117
- expect(scriptPassages.length).toBe(1);
118
- expect(stylesheetPassages.length).toBe(1);
119
- });
120
-
121
- test('Should not have start property if startNode does not exist when parsed', function () {
122
- const fr = FileReader.read('test/HTMLParser/missingStartnode.html');
123
- const story = HTMLParser.parse(fr);
124
- expect(story.start).toBe('');
125
- });
126
-
127
- test('Should not add passages without names', function () {
128
- const fr = FileReader.read('test/HTMLParser/missingPassageName.html');
129
- const story = HTMLParser.parse(fr);
130
- // There is only one passage, StoryTitle
131
- expect(story.size()).toBe(1);
132
- });
133
-
134
- test('Should not add passages without PID', function () {
135
- const fr = FileReader.read('test/HTMLParser/missingPID.html');
136
- const story = HTMLParser.parse(fr);
137
- // There is only one passage, StoryTitle
138
- expect(story.size()).toBe(1);
139
- });
140
-
141
- test('Parse tag colors', function () {
142
- const fr = FileReader.read('test/HTMLParser/tagColors.html');
143
- const story = HTMLParser.parse(fr);
144
- // Test for tag colors
145
- const tagColors = story.tagColors;
146
- expect(tagColors.a).toBe('red');
147
- });
148
-
149
- test('Will not set start if startnode is missing', function () {
150
- const fr = FileReader.read('test/HTMLParser/missingStartnode.html');
151
- const story = HTMLParser.parse(fr);
152
- // Test for default start
153
- expect(story.start).toBe('');
154
- });
155
-
156
- test('Throw error when startnode has PID that does not exist', function () {
157
- const fr = FileReader.read('test/HTMLParser/lyingStartnode.html');
158
- expect(() => {
159
- HTMLParser.parse(fr);
160
- }).toThrow();
161
- });
162
-
163
- test('Do not update name and color if those attributes do not exist', function () {
164
- const fr = FileReader.read('test/HTMLParser/lyingTagColors.html');
165
- const story = HTMLParser.parse(fr);
166
- const tagColorProperties = Object.keys(story.tagColors).length;
167
- expect(tagColorProperties).toBe(0);
168
- });
169
- });
170
-
171
- describe('#escapeMetacharacters()', function () {
172
- test('Should escape metacharacters', function () {
173
- /* eslint no-useless-escape: "off" */
174
- expect(HTMLParser.escapeMetacharacters('\\\{\\\}\\\[\\\]\\\\')).toBe('\\\\{\\\\}\\\\[\\\\]\\\\');
175
- });
176
- });
177
- });
@@ -1,16 +0,0 @@
1
- :: StoryTitle
2
- twineExample
3
-
4
- :: Start [tag tags] {"position": "200,200", "size": "100,100"}
5
- Content
6
-
7
- :: Style1 [stylesheet]
8
- body {background-color: green;}
9
-
10
- :: StoryData
11
- {
12
- "ifid": "2B68ECD6-348F-4CF5-96F8-549A512A8128",
13
- "format": "Harlowe",
14
- "formatVersion": "2.1.0",
15
- "zoom": "1"
16
- }
@@ -1,289 +0,0 @@
1
- import FileReader from '../src/FileReader.js';
2
- import StoryFormatParser from '../src/StoryFormatParser.js';
3
- import HTMLParser from '../src/HTMLParser.js';
4
- import TweeParser from '../src/TweeParser.js';
5
- import HTMLWriter from '../src/HTMLWriter.js';
6
- import Story from '../src/Story.js';
7
- import Passage from '../src/Passage.js';
8
-
9
- describe('HTMLWriter', () => {
10
- describe('#write()', () => {
11
- it('story should be instanceof Story', () => {
12
- expect(() => { HTMLWriter.write('test/HTMLWriter/test.html', {}); }).toThrow();
13
- });
14
-
15
- it('storyFormat should be instanceof StoryFormat', () => {
16
- const s = new Story();
17
- expect(() => { HTMLWriter.write('test/HTMLWriter/test.html', s, {}); }).toThrow();
18
- });
19
-
20
- it('Read, write, and read HTML', () => {
21
- // Read HTML.
22
- const fr = FileReader.read('test/HTMLParser/twineExample3.html');
23
- // Parse HTML.
24
- const story = HTMLParser.parse(fr);
25
-
26
- const s1Title = story.getPassageByName('StoryTitle').text;
27
-
28
- // Read StoryFormat.
29
- const fr2 = FileReader.read('test/StoryFormatParser/format.js');
30
- // Parse StoryFormat.
31
- const storyFormat = StoryFormatParser.parse(fr2);
32
-
33
- // Write HTML.
34
- HTMLWriter.write('test/HTMLWriter/test2.html', story, storyFormat);
35
-
36
- // Read HTML.
37
- const fr3 = FileReader.read('test/HTMLWriter/test2.html');
38
- // Parse HTML.
39
- const story2 = HTMLParser.parse(fr3);
40
-
41
- const s2Title = story2.getPassageByName('StoryTitle').text;
42
-
43
- // Test both names to be the same.
44
- expect(s1Title).toBe(s2Title);
45
- });
46
-
47
- it('Should write one and two-tag passages', () => {
48
- // Read HTML.
49
- const fr = FileReader.read('test/HTMLWriter/TestTags.html');
50
- // Parse HTML.
51
- const story = HTMLParser.parse(fr);
52
-
53
- // Read StoryFormat.
54
- const fr2 = FileReader.read('test/StoryFormatParser/format.js');
55
- // Parse StoryFormat.
56
- const storyFormat = StoryFormatParser.parse(fr2);
57
-
58
- // Write HTML.
59
- HTMLWriter.write('test/HTMLWriter/test3.html', story, storyFormat);
60
-
61
- // Read HTML.
62
- const fr3 = FileReader.read('test/HTMLWriter/test3.html');
63
- // Parse HTML.
64
- const story2 = HTMLParser.parse(fr3);
65
-
66
- let tags = '';
67
- let tags2 = '';
68
-
69
- // Combine contents of tags.
70
- story.forEach((p) => {
71
- tags += p.tags.join('');
72
- });
73
-
74
- // Combine contents of tags.
75
- story2.forEach((p) => {
76
- tags2 += p.tags.join('');
77
- });
78
-
79
- // Test combination tags.
80
- // They should be the same.
81
- expect(tags).toBe(tags2);
82
- });
83
-
84
- it('Should throw error if file path invalid', () => {
85
- // Read HTML.
86
- const fr = FileReader.read('test/HTMLParser/twineExample3.html');
87
- // Parse HTML.
88
- const story = HTMLParser.parse(fr);
89
-
90
- // Read StoryFormat.
91
- const fr2 = FileReader.read('test/StoryFormatParser/format.js');
92
- // Parse StoryFormat.
93
- const storyFormat = StoryFormatParser.parse(fr2);
94
-
95
- // Throw error if path is invalid.
96
- expect(() => {
97
- HTMLWriter.write('test2/HTMLWriter/test2.html', story, storyFormat);
98
- }).toThrow();
99
- });
100
-
101
- it('Should not add optional position to passages', () => {
102
- // Create Story.
103
- const story = new Story();
104
- // Add passage.
105
- story.addPassage(new Passage('A'));
106
- // Add passage.
107
- story.addPassage(new Passage('B'));
108
- // Add StoryTitle
109
- story.addPassage(new Passage('StoryTitle', 'Title'));
110
- // Add Start
111
- story.addPassage(new Passage('Start', 'Content'));
112
-
113
- // Read StoryFormat.
114
- const fr2 = FileReader.read('test/StoryFormatParser/format.js');
115
- // Parse StoryFormat.
116
- const storyFormat = StoryFormatParser.parse(fr2);
117
-
118
- // Write out HTML with story and storyFormat.
119
- // (Will add position to passages without them.)
120
- HTMLWriter.write('test/HTMLWriter/test4.html', story, storyFormat);
121
-
122
- // Read new HTML file.
123
- const fr3 = FileReader.read('test/HTMLWriter/test4.html');
124
- // Parse new HTML file.
125
- const story2 = HTMLParser.parse(fr3);
126
-
127
- // Verify none of the directly created passages have position.
128
- story.forEach((passage) => {
129
- expect(Object.prototype.hasOwnProperty.call(passage.metadata, 'position')).toBe(false);
130
- });
131
-
132
- // Verify none parsed passages have position.
133
- story2.forEach((passage) => {
134
- expect(Object.prototype.hasOwnProperty.call(passage.metadata, 'position')).toBe(false);
135
- });
136
- });
137
-
138
- it("Don't write creator if missing originally", () => {
139
- // Create a new story.
140
- const story = new Story();
141
-
142
- // Create a passage.
143
- story.addPassage(new Passage('A'));
144
-
145
- // Create another passage.
146
- story.addPassage(new Passage('B'));
147
-
148
- // Create another passage.
149
- story.addPassage(new Passage('StoryTitle', 'Title'));
150
-
151
- // Add Start
152
- story.addPassage(new Passage('Start', 'Content'));
153
-
154
- // Read StoryFormat.
155
- const fr2 = FileReader.read('test/StoryFormatParser/format.js');
156
- // Parse StoryFormat.
157
- const storyFormat = StoryFormatParser.parse(fr2);
158
-
159
- // Write the HTML.
160
- HTMLWriter.write('test/HTMLWriter/creator.html', story, storyFormat);
161
-
162
- // Read HTML.
163
- const fr3 = FileReader.read('test/HTMLWriter/creator.html');
164
- // Parse HTML.
165
- const story2 = HTMLParser.parse(fr3);
166
-
167
- // Test creator (should be default)
168
- expect(story.creator).toBe('extwee');
169
-
170
- // Test parsed creator (should be default)
171
- expect(story2.creator).toBe('extwee');
172
-
173
- // Creator should be the same
174
- expect(story.creator).toBe(story2.creator);
175
- });
176
-
177
- it('Throw error if StoryTitle does not exist', () => {
178
- // Create a new story.
179
- const story = new Story();
180
-
181
- // Create a passage.
182
- story.addPassage(new Passage('A'));
183
-
184
- // Read StoryFormat.
185
- const fr2 = FileReader.read('test/StoryFormatParser/format.js');
186
- // Parse StoryFormat.
187
- const storyFormat = StoryFormatParser.parse(fr2);
188
-
189
- expect(() => {
190
- HTMLWriter.write('test', story, storyFormat);
191
- }).toThrow();
192
- });
193
-
194
- it('Throw error if no start or Start exists', () => {
195
- // Create a new story.
196
- const story = new Story();
197
-
198
- // Create a passage.
199
- story.addPassage(new Passage('A'));
200
-
201
- // Create StoryTitle
202
- story.addPassage(new Passage('StoryTitle', 'Name'));
203
-
204
- // Read StoryFormat.
205
- const fr2 = FileReader.read('test/StoryFormatParser/format.js');
206
- // Parse StoryFormat.
207
- const storyFormat = StoryFormatParser.parse(fr2);
208
-
209
- // Throws error
210
- expect(() => {
211
- HTMLWriter.write('test/HTMLWriter/test6.html', story, storyFormat);
212
- }).toThrow();
213
- });
214
-
215
- it('Write with Start without start', () => {
216
- // Create a new story.
217
- const story = new Story();
218
-
219
- // Create a passage.
220
- story.addPassage(new Passage('A'));
221
-
222
- // Create StoryTitle
223
- story.addPassage(new Passage('StoryTitle', 'Name'));
224
-
225
- // Create Start
226
- story.addPassage(new Passage('Start', 'Content'));
227
-
228
- // Read StoryFormat.
229
- const fr2 = FileReader.read('test/StoryFormatParser/format.js');
230
- // Parse StoryFormat.
231
- const storyFormat = StoryFormatParser.parse(fr2);
232
-
233
- // Write file
234
- HTMLWriter.write('test/HTMLWriter/test6.html', story, storyFormat);
235
-
236
- // Read new HTML file.
237
- const fr3 = FileReader.read('test/HTMLWriter/test6.html');
238
- // Parse new HTML file.
239
- const story2 = HTMLParser.parse(fr3);
240
-
241
- // Should not be start
242
- expect(story2.start).toBe('Start');
243
- });
244
-
245
- it('Throw error if starting passage property does not exist', () => {
246
- // Create a new story.
247
- const story = new Story();
248
-
249
- // Create a passage.
250
- story.addPassage(new Passage('A'));
251
-
252
- // Create StoryTitle
253
- story.addPassage(new Passage('StoryTitle', 'Name'));
254
-
255
- // Set a passage that doesn't exist
256
- story.start = 'Nope';
257
-
258
- // Read StoryFormat.
259
- const fr2 = FileReader.read('test/StoryFormatParser/format.js');
260
- // Parse StoryFormat.
261
- const storyFormat = StoryFormatParser.parse(fr2);
262
-
263
- // Throws error
264
- expect(() => {
265
- HTMLWriter.write('test/HTMLWriter/test7.html', story, storyFormat);
266
- }).toThrow();
267
- });
268
-
269
- it('Should correctly replace all instances of STORY_NAME', () => {
270
- const fr = FileReader.read('test/HTMLWriter/example6.twee');
271
- const story = TweeParser.parse(fr);
272
- const storyFormatFile = FileReader.read('test/StoryFormatParser/format_doublename.js');
273
- const sfp = StoryFormatParser.parse(storyFormatFile);
274
- HTMLWriter.write('test/HTMLWriter/test11.html', story, sfp);
275
- const frh = FileReader.read('test/HTMLWriter/test11.html');
276
- expect(frh.indexOf('STORY_NAME')).toBe(-1);
277
- });
278
- });
279
-
280
- describe('escape()', () => {
281
- it('Should throw error if argument is not string', () => {
282
- expect(() => { HTMLWriter.escape(1); }).toThrow();
283
- });
284
-
285
- it('Should escape HTML sequences', () => {
286
- expect(HTMLWriter.escape('<script>alert("Hi!");</script>')).toBe('&lt;script&gt;alert(&quot;Hi!&quot;);&lt;/script&gt;');
287
- });
288
- });
289
- });
@@ -1,21 +0,0 @@
1
- :: StoryData
2
- {
3
- "ifid": "E70FC479-01D9-4E44-AC6A-AFF9F5E1C475",
4
- "format": "Chapbook",
5
- "format-version": "1.1.0",
6
- "zoom": 1,
7
- "start": "StoryTitle"
8
- }
9
-
10
- :: StoryTitle
11
- Example1
12
-
13
- :: Untitled Passage {"position":"200,102","size":"100,100"}
14
- [[Another passage]]
15
-
16
- :: Another passage {"position":"200,252","size":"100,100"}
17
- [[A third]]
18
-
19
- :: A third {"position":"200,402","size":"100,100"}
20
- Double-click this passage to edit it.
21
-
@@ -1,48 +0,0 @@
1
- import TweeWriter from '../src/TweeWriter.js';
2
- import FileReader from '../src/FileReader.js';
3
- import TweeParser from '../src/TweeParser.js';
4
- import HTMLParser from '../src/HTMLParser.js';
5
- import StoryFormatParser from '../src/StoryFormatParser.js';
6
- import HTMLWriter from '../src/HTMLWriter.js';
7
-
8
- describe('Round-trip testing', () => {
9
- test('Should round-trip HTML-to-Twee', () => {
10
- // Read HTML
11
- const fr = FileReader.read('test/Roundtrip/Example1.html');
12
- // Parse HTML
13
- const s = HTMLParser.parse(fr);
14
- // Write Story into Twee
15
- TweeWriter.write(s, 'test/Roundtrip/example1.twee');
16
- // Read new Twee file
17
- const fr2 = FileReader.read('test/Roundtrip/example1.twee');
18
- // Parse the new Twee
19
- const s2 = TweeParser.parse(fr2);
20
- // Number of passages should be the same, too
21
- expect(s2.size()).toBe(s.size());
22
- // IFID should be the same
23
- expect(s.ifid).toBe(s2.ifid);
24
- });
25
-
26
- test('Should round-trip Twee-to-HTML', () => {
27
- // Read StoryFormat
28
- const storyFormat = FileReader.read('test/Roundtrip/harlowe.js');
29
- // Parse StoryFormat
30
- const sfp = StoryFormatParser.parse(storyFormat);
31
- // Read Twee
32
- const fr = FileReader.read('test/Roundtrip/example2.twee');
33
- // Parse Twee
34
- const story = TweeParser.parse(fr);
35
- // Write HTML
36
- HTMLWriter.write('test/Roundtrip/round.html', story, sfp);
37
- // Read HTML
38
- const fr2 = FileReader.read('test/Roundtrip/round.html');
39
- // Parse HTML
40
- const story2 = HTMLParser.parse(fr2);
41
- // Number of passages should be the same, too
42
- expect(story2.size()).toBe(story.size());
43
- // IFID should be the same
44
- expect(story.ifid).toBe(story2.ifid);
45
- // Should have same 'start' name
46
- expect(story.start).toBe(story2.start);
47
- });
48
- });
@@ -1,29 +0,0 @@
1
- :: StoryTitle
2
- twineExample
3
-
4
- :: Another
5
- This should be the start passage!
6
-
7
- :: Start
8
- Some content.
9
-
10
- :: StoryData
11
- {
12
- "ifid": "2B68ECD6-348F-4CF5-96F8-549A512A8128",
13
- "format": "Harlowe",
14
- "formatVersion": "2.1.0",
15
- "zoom": "1",
16
- "start": "Another"
17
- }
18
-
19
- :: Script1 [script]
20
- // Some code
21
-
22
- :: Script2 [script]
23
- //More code here!
24
-
25
- :: Style1 [stylesheet]
26
- body {font-size: 1.2em}
27
-
28
- :: Style2 [stylesheet]
29
- p {font-style: italic;}