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 = ``; + 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 = ``; + 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 - - - - - - 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 - - - - - -