extwee 1.6.2 → 2.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.json +25 -24
- package/.github/workflows/nodejs.yml +24 -24
- package/.travis.yml +13 -13
- package/CODE_OF_CONDUCT.md +82 -0
- package/LICENSE +21 -21
- package/README.md +36 -205
- package/SECURITY.md +12 -0
- package/babel.config.json +22 -0
- package/bin/extwee.js +49 -0
- package/index.js +31 -26
- package/package.json +59 -45
- package/src/FileReader.js +33 -35
- package/src/HTMLParser.js +343 -206
- package/src/HTMLWriter.js +231 -172
- package/src/Passage.js +202 -24
- package/src/Story.js +490 -122
- package/src/StoryFormat.js +300 -28
- package/src/StoryFormatParser.js +142 -59
- package/src/TweeParser.js +161 -207
- package/src/TweeWriter.js +98 -96
- package/story-formats/chapbook-1.2.0/format.js +1 -0
- package/story-formats/chapbook-1.2.0/logo.svg +1 -0
- package/story-formats/harlowe-1.2.4/format.js +1 -0
- package/story-formats/harlowe-1.2.4/icon.svg +78 -0
- package/story-formats/harlowe-2.1.0/format.js +2 -0
- package/story-formats/harlowe-2.1.0/icon.svg +78 -0
- package/story-formats/harlowe-3.1.0/format.js +3 -0
- package/story-formats/harlowe-3.1.0/icon.svg +78 -0
- package/story-formats/paperthin-1.0.0/format.js +1 -0
- package/story-formats/paperthin-1.0.0/icon.svg +5 -0
- package/story-formats/snowman-1.4.0/format.js +1 -0
- package/story-formats/snowman-1.4.0/icon.svg +436 -0
- package/story-formats/snowman-2.0.2/format.js +1 -0
- package/story-formats/snowman-2.0.2/icon.svg +436 -0
- package/story-formats/sugarcube-1.0.35/LICENSE +23 -0
- package/story-formats/sugarcube-1.0.35/format.js +1 -0
- package/story-formats/sugarcube-1.0.35/icon.svg +56 -0
- package/story-formats/sugarcube-2.31.1/LICENSE +22 -0
- package/story-formats/sugarcube-2.31.1/format.js +1 -0
- package/story-formats/sugarcube-2.31.1/icon.svg +56 -0
- package/test/{HTMLWriter/example7.twee → CLI/example6.twee} +16 -16
- package/test/CLI/harlowe.js +3 -0
- package/test/CLI/input.html +47 -0
- package/test/CLI/test.twee +18 -0
- package/test/CLI/test2.html +47 -0
- package/test/CLI/tweeExample.twee +17 -0
- package/test/CLI/twineExample.html +15 -0
- package/test/CLI.test.js +30 -0
- package/test/FileReader.test.js +14 -0
- package/test/HTMLParser/Example1.html +53 -0
- package/test/HTMLParser/Tags.html +15 -0
- package/test/HTMLParser/lyingStartnode.html +15 -0
- package/test/HTMLParser/lyingTagColors.html +48 -0
- package/test/HTMLParser/missingCreator.html +11 -0
- package/test/HTMLParser/missingCreatorVersion.html +11 -0
- package/test/HTMLParser/missingFormat.html +11 -0
- package/test/HTMLParser/missingFormatVersion.html +11 -0
- package/test/HTMLParser/missingIFID.html +11 -0
- package/test/HTMLParser/missingName.html +33 -0
- package/test/HTMLParser/missingPID.html +15 -0
- package/test/HTMLParser/missingPassageName.html +15 -0
- package/test/HTMLParser/missingPassageTags.html +15 -0
- package/test/HTMLParser/missingPosition.html +15 -0
- package/test/HTMLParser/missingScript.html +14 -0
- package/test/HTMLParser/missingSize.html +35 -0
- package/test/HTMLParser/missingStartnode.html +11 -0
- package/test/HTMLParser/missingStyle.html +14 -0
- package/test/HTMLParser/missingZoom.html +11 -0
- package/test/HTMLParser/tagColors.html +31 -0
- package/test/HTMLParser/twineExample.html +15 -46
- package/test/HTMLParser/twineExample2.html +15 -0
- package/test/HTMLParser/twineExample3.html +15 -0
- package/test/HTMLParser.test.js +177 -0
- package/test/HTMLWriter/TestTags.html +42 -0
- package/test/HTMLWriter/{test10.html → creator.html} +8 -5
- package/test/HTMLWriter/example6.twee +16 -16
- package/test/HTMLWriter/{example.twee → missingStoryTitle.twee} +29 -29
- package/test/HTMLWriter/test11.html +123 -0
- package/test/HTMLWriter/test2.html +14 -11
- package/test/HTMLWriter/test3.html +7 -13
- package/test/HTMLWriter/test4.html +8 -5
- package/test/HTMLWriter/test6.html +7 -5
- package/test/HTMLWriter.test.js +289 -0
- package/test/Passage.test.js +104 -0
- package/test/Roundtrip/Example1.html +64 -0
- package/test/Roundtrip/example1.twee +21 -0
- package/test/Roundtrip/example2.twee +18 -0
- package/test/Roundtrip/harlowe.js +3 -0
- package/test/Roundtrip/round.html +50 -0
- package/test/Roundtrip.test.js +48 -0
- package/test/Story/startmeta.twee +29 -29
- package/test/Story/test.twee +25 -25
- package/test/Story.test.js +369 -0
- package/test/StoryFormat.test.js +152 -0
- package/test/StoryFormatParser/example.js +3 -0
- package/test/StoryFormatParser/{test2.js → example2.js} +3 -3
- package/test/StoryFormatParser/format_doublename.js +1 -0
- package/test/StoryFormatParser/harlowe.js +2 -2
- package/test/StoryFormatParser/missingAuthor.js +1 -0
- package/test/StoryFormatParser/missingDescription.js +1 -0
- package/test/StoryFormatParser/missingImage.js +1 -0
- package/test/StoryFormatParser/missingLicense.js +1 -0
- package/test/StoryFormatParser/missingName.js +1 -0
- package/test/StoryFormatParser/missingProofing.js +1 -0
- package/test/StoryFormatParser/missingSource.js +1 -0
- package/test/StoryFormatParser/missingURL.js +1 -0
- package/test/StoryFormatParser/missingVersion.js +1 -0
- package/test/StoryFormatParser/versionWrong.js +1 -0
- package/test/StoryFormatParser.test.js +91 -0
- package/test/TweeParser/emptytags.twee +2 -2
- package/test/TweeParser/example.twee +32 -29
- package/test/TweeParser/missing.twee +19 -0
- package/test/{HTMLWriter/example5.twee → TweeParser/multipleScriptPassages.twee} +19 -13
- package/test/{HTMLWriter/example4.twee → TweeParser/multipleStyleTag.twee} +19 -13
- package/test/TweeParser/multipletags.twee +10 -2
- package/test/TweeParser/noTitle.twee +2 -0
- package/test/TweeParser/notes.twee +16 -32
- package/test/TweeParser/pasagemetadataerror.twee +2 -2
- package/test/{HTMLWriter/example2.twee → TweeParser/scriptPassage.twee} +16 -13
- package/test/TweeParser/singletag.twee +13 -2
- package/test/TweeParser/startMetadata.twee +14 -0
- package/test/TweeParser/storydataerror.twee +25 -25
- package/test/{HTMLWriter/example3.twee → TweeParser/stylePassage.twee} +16 -13
- package/test/TweeParser/test.twee +25 -25
- package/test/TweeParser.test.js +79 -0
- package/test/TweeWriter/test1.twee +14 -9
- package/test/TweeWriter/test3.twee +7 -10
- package/test/TweeWriter/test4.twee +14 -0
- package/test/TweeWriter/test5.twee +20 -0
- package/test/TweeWriter.test.js +85 -0
- package/main.js +0 -106
- package/src/DirectoryReader.js +0 -114
- package/src/DirectoryWatcher.js +0 -87
- package/test/DirectoryReader/css/test.css +0 -3
- package/test/DirectoryReader1/js/Site.js +0 -1
- package/test/DirectoryReader2/error.js +0 -1
- package/test/DirectoryReader2/example.css +0 -3
- package/test/DirectoryReader2/index.twee +0 -6
- package/test/DirectoryReader3/twee/index.twee +0 -6
- package/test/DirectoryWatcher/example.txt +0 -0
- package/test/DirectoryWatcher/test.txt +0 -0
- package/test/DirectoryWatcher/test1.txt +0 -0
- package/test/HTMLWriter/test5.html +0 -48
- package/test/HTMLWriter/test7.html +0 -48
- package/test/HTMLWriter/test8.html +0 -48
- package/test/HTMLWriter/test9.html +0 -48
- package/test/StoryFormatParser/test.js +0 -2
- package/test/TweeParser/test.twee3 +0 -11
- package/test/TweeWriter/metatest.twee +0 -12
- package/test/TweeWriter/test2.twee +0 -15
- package/test/test.js +0 -736
|
@@ -9,18 +9,21 @@
|
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
11
|
<tw-story tags></tw-story>
|
|
12
|
-
<tw-storydata name="twineExample" startnode="1" creator="
|
|
13
|
-
<style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"
|
|
14
|
-
<script role="script" id="twine-user-script" type="text/twine-javascript"
|
|
15
|
-
<tw-passagedata pid="1" name="
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
<tw-passagedata pid="2" name="Another passage" tags position="100,100" size="100,100" >[[A fourth passage]]
|
|
19
|
-
|
|
12
|
+
<tw-storydata name="twineExample" startnode="1" creator="Twine" creator-version="2.2.1" ifid="2B68ECD6-348F-4CF5-96F8-549A512A8128" zoom="1" format="Snowman" format-version="2.0.0" options hidden>
|
|
13
|
+
<style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css">html{font-size: 1.2em;}</style>
|
|
14
|
+
<script role="script" id="twine-user-script" type="text/twine-javascript">window.test = {};</script>
|
|
15
|
+
<tw-passagedata pid="1" name="StoryTitle">twineExample</tw-passagedata>
|
|
16
|
+
<tw-passagedata pid="1" name="Start" position="102,104" size="100,100" >[[Another passage]]
|
|
17
|
+
|
|
20
18
|
[[A third passage]]</tw-passagedata>
|
|
21
|
-
<tw-passagedata pid="
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
<tw-passagedata pid="2" name="Another passage" position="353,60" size="100,100" >[[A fourth passage]]
|
|
20
|
+
|
|
21
|
+
[[A third passage]] </tw-passagedata>
|
|
22
|
+
<tw-passagedata pid="3" name="A third passage" position="350,288" size="100,100" >[[Start]]</tw-passagedata>
|
|
23
|
+
<tw-passagedata pid="4" name="A fourth passage" position="587,197" size="100,100" >[[A fifth passage]]</tw-passagedata>
|
|
24
|
+
<tw-passagedata pid="5" name="A fifth passage" position="800,306" size="100,100" >Double-click this passage to edit it.</tw-passagedata>
|
|
25
|
+
<tw-passagedata pid="2" name="UserStylesheet" tags="stylesheet" >html{font-size: 1.2em;}</tw-passagedata>
|
|
26
|
+
<tw-passagedata pid="3" name="UserScript" tags="script" >window.test = {};</tw-passagedata>
|
|
24
27
|
</tw-storydata>
|
|
25
28
|
<script>
|
|
26
29
|
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
2
|
<html>
|
|
3
3
|
<head>
|
|
4
|
-
<title>
|
|
4
|
+
<title>TestTags</title>
|
|
5
5
|
<meta charset="utf-8">
|
|
6
6
|
<style>
|
|
7
7
|
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}[hidden],template{display:none}body{font:18px Helvetica Neue,Helvetica,Arial,sans-serif;color:#222;margin-left:2em}tw-story{max-width:38em;margin:0 auto;line-height:145%}tw-passage{display:block}a{color:#222;text-decoration-color:#bbb}a:hover{color:#cc8929}a:active,a:hover{text-decoration-color:#cc8929}a:active{color:#ffb040}tw-storydata{display:none}@media screen and (max-device-width:480px){#passage{font-size:70%}}
|
|
@@ -9,18 +9,12 @@
|
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
11
|
<tw-story tags></tw-story>
|
|
12
|
-
<tw-storydata name="
|
|
13
|
-
<style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style>
|
|
14
|
-
<script role="script" id="twine-user-script" type="text/twine-javascript"></script>
|
|
15
|
-
<tw-passagedata pid="1" name="
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
<tw-passagedata pid="2" name="Another passage" tags position="100,100" size="100,100" >[[A fourth passage]]
|
|
19
|
-
|
|
20
|
-
[[A third passage]]</tw-passagedata>
|
|
21
|
-
<tw-passagedata pid="3" name="A third passage" tags position="100,100" size="100,100" >[[Start]]</tw-passagedata>
|
|
22
|
-
<tw-passagedata pid="4" name="A fourth passage" tags position="100,100" size="100,100" >[[A fifth passage]]</tw-passagedata>
|
|
23
|
-
<tw-passagedata pid="5" name="A fifth passage" tags position="100,100" size="100,100" >Double-click this passage to edit it.</tw-passagedata>
|
|
12
|
+
<tw-storydata name="TestTags" startnode="1" creator="Twine" creator-version="2.3.9" ifid="5B4E374F-E8B0-4FBB-A78E-A4150401BF24" zoom="1" format="Snowman" format-version="2.0.0" options hidden>
|
|
13
|
+
<style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style>
|
|
14
|
+
<script role="script" id="twine-user-script" type="text/twine-javascript"></script>
|
|
15
|
+
<tw-passagedata pid="1" name="StoryTitle">TestTags</tw-passagedata>
|
|
16
|
+
<tw-passagedata pid="1" name="Untitled Passage" tags="one" position="199,100" size="100,100" >[[Another]]</tw-passagedata>
|
|
17
|
+
<tw-passagedata pid="2" name="Another" tags="two three" position="399,99" size="100,100" >Double-click this passage to edit it.</tw-passagedata>
|
|
24
18
|
</tw-storydata>
|
|
25
19
|
<script>
|
|
26
20
|
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
2
|
<html>
|
|
3
3
|
<head>
|
|
4
|
-
<title>
|
|
4
|
+
<title>Title</title>
|
|
5
5
|
<meta charset="utf-8">
|
|
6
6
|
<style>
|
|
7
7
|
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}[hidden],template{display:none}body{font:18px Helvetica Neue,Helvetica,Arial,sans-serif;color:#222;margin-left:2em}tw-story{max-width:38em;margin:0 auto;line-height:145%}tw-passage{display:block}a{color:#222;text-decoration-color:#bbb}a:hover{color:#cc8929}a:active,a:hover{text-decoration-color:#cc8929}a:active{color:#ffb040}tw-storydata{display:none}@media screen and (max-device-width:480px){#passage{font-size:70%}}
|
|
@@ -9,10 +9,13 @@
|
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
11
|
<tw-story tags></tw-story>
|
|
12
|
-
<tw-storydata name="
|
|
13
|
-
<style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style>
|
|
14
|
-
<script role="script" id="twine-user-script" type="text/twine-javascript"></script>
|
|
15
|
-
<tw-passagedata pid="1" name="
|
|
12
|
+
<tw-storydata name="Title" startnode="4" creator="extwee" creator-version="2.0.3" ifid="A1EFB550-B470-44EA-816C-73683E385FF2" zoom="0" format="Snowman" format-version="2.0.0" options hidden>
|
|
13
|
+
<style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style>
|
|
14
|
+
<script role="script" id="twine-user-script" type="text/twine-javascript"></script>
|
|
15
|
+
<tw-passagedata pid="1" name="A"></tw-passagedata>
|
|
16
|
+
<tw-passagedata pid="2" name="B"></tw-passagedata>
|
|
17
|
+
<tw-passagedata pid="3" name="StoryTitle">Title</tw-passagedata>
|
|
18
|
+
<tw-passagedata pid="4" name="Start">Content</tw-passagedata>
|
|
16
19
|
</tw-storydata>
|
|
17
20
|
<script>
|
|
18
21
|
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
2
|
<html>
|
|
3
3
|
<head>
|
|
4
|
-
<title>
|
|
4
|
+
<title>Name</title>
|
|
5
5
|
<meta charset="utf-8">
|
|
6
6
|
<style>
|
|
7
7
|
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}[hidden],template{display:none}body{font:18px Helvetica Neue,Helvetica,Arial,sans-serif;color:#222;margin-left:2em}tw-story{max-width:38em;margin:0 auto;line-height:145%}tw-passage{display:block}a{color:#222;text-decoration-color:#bbb}a:hover{color:#cc8929}a:active,a:hover{text-decoration-color:#cc8929}a:active{color:#ffb040}tw-storydata{display:none}@media screen and (max-device-width:480px){#passage{font-size:70%}}
|
|
@@ -9,10 +9,12 @@
|
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
11
|
<tw-story tags></tw-story>
|
|
12
|
-
<tw-storydata name="
|
|
13
|
-
<style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style>
|
|
14
|
-
<script role="script" id="twine-user-script" type="text/twine-javascript"></script>
|
|
15
|
-
<tw-passagedata pid="1" name="
|
|
12
|
+
<tw-storydata name="Name" startnode="3" creator="extwee" creator-version="2.0.3" ifid="16D0AFBA-80AF-4C7F-9C85-983D043624E4" zoom="0" format="Snowman" format-version="2.0.0" options hidden>
|
|
13
|
+
<style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style>
|
|
14
|
+
<script role="script" id="twine-user-script" type="text/twine-javascript"></script>
|
|
15
|
+
<tw-passagedata pid="1" name="A"></tw-passagedata>
|
|
16
|
+
<tw-passagedata pid="2" name="StoryTitle">Name</tw-passagedata>
|
|
17
|
+
<tw-passagedata pid="3" name="Start">Content</tw-passagedata>
|
|
16
18
|
</tw-storydata>
|
|
17
19
|
<script>
|
|
18
20
|
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
|
|
@@ -0,0 +1,289 @@
|
|
|
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('<script>alert("Hi!");</script>');
|
|
287
|
+
});
|
|
288
|
+
});
|
|
289
|
+
});
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import Passage from '../src/Passage.js';
|
|
2
|
+
|
|
3
|
+
describe('Passage', () => {
|
|
4
|
+
describe('#constructor()', () => {
|
|
5
|
+
test('Set default values', () => {
|
|
6
|
+
const p = new Passage();
|
|
7
|
+
expect(p.name).toBe('');
|
|
8
|
+
expect(p.tags).toHaveLength(0);
|
|
9
|
+
expect(p.text).toBe('');
|
|
10
|
+
expect(typeof p.metadata).toBe('object');
|
|
11
|
+
expect(p.pid).toBe(-1);
|
|
12
|
+
});
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
describe('name', () => {
|
|
16
|
+
test('Set name', () => {
|
|
17
|
+
const p = new Passage();
|
|
18
|
+
p.name = 'New';
|
|
19
|
+
expect(p.name).toBe('New');
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
test('Throw error if name is not String', () => {
|
|
23
|
+
const p = new Passage();
|
|
24
|
+
expect(() => {
|
|
25
|
+
p.name = 1;
|
|
26
|
+
}).toThrow();
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
describe('tags', () => {
|
|
31
|
+
test('Set tags', () => {
|
|
32
|
+
const p = new Passage();
|
|
33
|
+
p.tags = ['tag'];
|
|
34
|
+
expect(p.tags).toHaveLength(1);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test('Throw error if tags is not Array', () => {
|
|
38
|
+
const p = new Passage();
|
|
39
|
+
expect(() => {
|
|
40
|
+
p.tags = 1;
|
|
41
|
+
}).toThrow();
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
describe('metadata', () => {
|
|
46
|
+
test('Set metadata', () => {
|
|
47
|
+
const p = new Passage();
|
|
48
|
+
p.metadata = { position: '100,100' };
|
|
49
|
+
expect(p.metadata).toEqual({ position: '100,100' });
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test('Throw error if metadata is not an Object', () => {
|
|
53
|
+
const p = new Passage();
|
|
54
|
+
expect(() => {
|
|
55
|
+
p.metadata = 1;
|
|
56
|
+
}).toThrow();
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
describe('text', () => {
|
|
61
|
+
test('Set text', () => {
|
|
62
|
+
const p = new Passage();
|
|
63
|
+
p.text = 'New';
|
|
64
|
+
expect(p.text).toBe('New');
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test('Throw error if text is not a String', () => {
|
|
68
|
+
const p = new Passage();
|
|
69
|
+
expect(() => {
|
|
70
|
+
p.text = 1;
|
|
71
|
+
}).toThrow();
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
describe('pid', () => {
|
|
76
|
+
test('Set PID', () => {
|
|
77
|
+
const p = new Passage();
|
|
78
|
+
p.pid = 12;
|
|
79
|
+
expect(p.pid).toBe(12);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
test('Throw error if pid is not a Number', () => {
|
|
83
|
+
const p = new Passage();
|
|
84
|
+
expect(() => {
|
|
85
|
+
p.pid = [];
|
|
86
|
+
}).toThrow();
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
describe('toString()', () => {
|
|
91
|
+
test('Create name string', () => {
|
|
92
|
+
const p = new Passage('Name', 'Test');
|
|
93
|
+
expect(p.toString()).toBe(':: Name\nTest\n\n');
|
|
94
|
+
});
|
|
95
|
+
test('Create tags string', () => {
|
|
96
|
+
const p = new Passage('Name', 'Test', ['tags', 'another']);
|
|
97
|
+
expect(p.toString()).toBe(':: Name [tags another]\nTest\n\n');
|
|
98
|
+
});
|
|
99
|
+
test('Create metadata string', () => {
|
|
100
|
+
const p = new Passage('Name', 'Test', ['tags', 'another'], { position: '100,100' });
|
|
101
|
+
expect(p.toString()).toBe(':: Name [tags another] {"position":"100,100"}\nTest\n\n');
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
});
|