diff --git a/src/Twine2HTML/parse.js b/src/Twine2HTML/parse.js
index cf8a13fb..3f572229 100644
--- a/src/Twine2HTML/parse.js
+++ b/src/Twine2HTML/parse.js
@@ -26,7 +26,7 @@ function parse (content) {
// Can only parse string values.
if (typeof content !== 'string') {
- throw new TypeError('Content is not a string!');
+ throw new TypeError('TypeError: Content is not a string!');
}
// Set default start node.
@@ -50,7 +50,7 @@ function parse (content) {
// Did we find any elements?
if (storyDataElements.length === 0) {
// If there is not a single `` element, this is not a Twine 2 story!
- throw new Error('TypeError: Not Twine 2 HTML content!');
+ throw new TypeError('TypeError: Not Twine 2 HTML content!');
}
// We only parse the first element found.
@@ -185,15 +185,21 @@ function parse (content) {
* https://github.com/iftechfoundation/twine-specs/blob/master/twine-2-htmloutput-spec.md#passages
*/
// Create a default value
- let name = null;
+ let name = 'Untitled Passage';
// Does name exist?
if (Object.prototype.hasOwnProperty.call(attr, 'name')) {
// Escape the name
name = attr.name;
} else {
- throw new Error('TypeError: Cannot parse passage data without name!');
+ console.warn('Warning: name attribute is missing! Default passage name will be used.');
}
+ /**
+ * tags: (string) Optional.
+ * A space-separated list of tags for the passage.
+ *
+ * https://github.com/iftechfoundation/twine-specs/blob/master/twine-2-htmloutput-spec.md#passages
+ */
// Create empty tag array.
let tags = [];
// Does the tags attribute exist?
@@ -211,6 +217,12 @@ function parse (content) {
tags = tags.filter(tag => tag !== '');
}
+ /**
+ * metadata: (object) Optional.
+ * An object containing additional metadata about the passage.
+ *
+ * Twine 2 HTML does not support metadata, but other formats do.
+ */
// Create metadata for passage.
const metadata = {};
@@ -234,14 +246,14 @@ function parse (content) {
* https://github.com/iftechfoundation/twine-specs/blob/master/twine-2-htmloutput-spec.md#passages
*/
// Create a default PID
- let pid = -1;
+ let pid = 1;
// Does pid exist?
if (Object.prototype.hasOwnProperty.call(attr, 'pid')) {
// Parse string into int
// Update PID
pid = Number.parseInt(attr.pid, 10);
} else {
- throw new Error('Passages are required to have PID!');
+ console.warn('Warning: pid attribute is missing! Default PID will be used.');
}
// Check the current PID against startNode number.
diff --git a/test/Twine2HTML/Twine2HTML.Parse.test.js b/test/Twine2HTML/Twine2HTML.Parse.test.js
index 611df8e9..2ec9b9c2 100644
--- a/test/Twine2HTML/Twine2HTML.Parse.test.js
+++ b/test/Twine2HTML/Twine2HTML.Parse.test.js
@@ -6,7 +6,7 @@ import { parse as parseTwine2HTML } from '../../src/Twine2HTML/parse.js';
const { version } = JSON.parse(readFileSync('package.json', 'utf-8'));
describe('Twine2HTMLParser', () => {
- describe('#parse()', () => {
+ describe('Errors', () => {
it('Should throw error if content is not a string', () => {
expect(() => { parseTwine2HTML({}); }).toThrow();
});
@@ -14,7 +14,9 @@ describe('Twine2HTMLParser', () => {
it('Should throw error if content is not Twine-2 style HTML', () => {
expect(() => { parseTwine2HTML(''); }).toThrow();
});
+ });
+ describe('#parse()', () => {
it('Should be able to parse Twine 2 HTML for story name', () => {
const fr = readFileSync('test/Twine2HTML/Twine2HTMLParser/twineExample.html', 'utf-8');
const story = parseTwine2HTML(fr);
@@ -120,16 +122,6 @@ describe('Twine2HTMLParser', () => {
expect(stylesheetPassages.length).toBe(1);
});
- it('Should throw error if passage name is missing', () => {
- const fr = readFileSync('test/Twine2HTML/Twine2HTMLParser/missingPassageName.html', 'utf-8');
- expect(() => { parseTwine2HTML(fr); }).toThrow();
- });
-
- it('Should throw error if passage PID is missing', () => {
- const fr = readFileSync('test/Twine2HTML/Twine2HTMLParser/missingPID.html', 'utf-8');
- expect(() => { parseTwine2HTML(fr); }).toThrow();
- });
-
it('Should parse HTML without passage start node', () => {
const fr = readFileSync('test/Twine2HTML/Twine2HTMLParser/missingStartnode.html', 'utf-8');
const story = parseTwine2HTML(fr);
@@ -188,5 +180,25 @@ describe('Twine2HTMLParser', () => {
parseTwine2HTML(s);
expect(console.warn).toHaveBeenCalledWith('Warning: The IFID is not in valid UUIDv4 formatting on tw-storydata!');
});
+
+ it('Should generate warning if passage name is missing', () => {
+ const fr = `
+
+
+ Double-click this passage to edit it.
+ `;
+ parseTwine2HTML(fr);
+ expect(console.warn).toHaveBeenCalledWith('Warning: name attribute is missing! Default passage name will be used.');
+ });
+
+ it('Should generate error if passage PID is missing', () => {
+ const fr = `
+
+
+ Double-click this passage to edit it.
+ `;
+ parseTwine2HTML(fr);
+ expect(console.warn).toHaveBeenCalledWith('Warning: pid attribute is missing! Default PID will be used.');
+ });
});
});
diff --git a/test/Twine2HTML/Twine2HTMLParser/missingPID.html b/test/Twine2HTML/Twine2HTMLParser/missingPID.html
deleted file mode 100644
index c66db2da..00000000
--- a/test/Twine2HTML/Twine2HTMLParser/missingPID.html
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
-Tags
-
-
-
-
-
-
- Double-click this passage to edit it.
-
-
-
diff --git a/test/Twine2HTML/Twine2HTMLParser/missingPassageName.html b/test/Twine2HTML/Twine2HTMLParser/missingPassageName.html
deleted file mode 100644
index 7ca507ac..00000000
--- a/test/Twine2HTML/Twine2HTMLParser/missingPassageName.html
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
-Tags
-
-
-
-
-
-
- Double-click this passage to edit it.
-
-
-