From 25053d71a1da73e4db0448a60d6cc3e751393501 Mon Sep 17 00:00:00 2001 From: Archis Gore Date: Sun, 21 Feb 2016 12:26:50 -0800 Subject: [PATCH 1/7] Added a JSON parser --- fountain.js | 633 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 391 insertions(+), 242 deletions(-) diff --git a/fountain.js b/fountain.js index b614e1d..6fdafe8 100644 --- a/fountain.js +++ b/fountain.js @@ -6,279 +6,428 @@ 'use strict'; var regex = { - title_page: /^((?:title|credit|author[s]?|source|notes|draft date|date|contact|copyright)\:)/gim, - - scene_heading: /^((?:\*{0,3}_?)?(?:(?:int|ext|est|i\/e)[. ]).+)|^(?:\.(?!\.+))(.+)/i, - scene_number: /( *#(.+)# *)/, - - transition: /^((?:FADE (?:TO BLACK|OUT)|CUT TO BLACK)\.|.+ TO\:)|^(?:> *)(.+)/, - - dialogue: /^([A-Z*_]+[0-9A-Z (._\-')]*)(\^?)?(?:\n(?!\n+))([\s\S]+)/, - parenthetical: /^(\(.+\))$/, - - action: /^(.+)/g, - centered: /^(?:> *)(.+)(?: *<)(\n.+)*/g, - - section: /^(#+)(?: *)(.*)/, - synopsis: /^(?:\=(?!\=+) *)(.*)/, - - note: /^(?:\[{2}(?!\[+))(.+)(?:\]{2}(?!\[+))$/, - note_inline: /(?:\[{2}(?!\[+))([\s\S]+?)(?:\]{2}(?!\[+))/g, - boneyard: /(^\/\*|^\*\/)$/g, - - page_break: /^\={3,}$/, - line_break: /^ {2}$/, - - emphasis: /(_|\*{1,3}|_\*{1,3}|\*{1,3}_)(.+)(_|\*{1,3}|_\*{1,3}|\*{1,3}_)/g, - bold_italic_underline: /(_{1}\*{3}(?=.+\*{3}_{1})|\*{3}_{1}(?=.+_{1}\*{3}))(.+?)(\*{3}_{1}|_{1}\*{3})/g, - bold_underline: /(_{1}\*{2}(?=.+\*{2}_{1})|\*{2}_{1}(?=.+_{1}\*{2}))(.+?)(\*{2}_{1}|_{1}\*{2})/g, - italic_underline: /(?:_{1}\*{1}(?=.+\*{1}_{1})|\*{1}_{1}(?=.+_{1}\*{1}))(.+?)(\*{1}_{1}|_{1}\*{1})/g, - bold_italic: /(\*{3}(?=.+\*{3}))(.+?)(\*{3})/g, - bold: /(\*{2}(?=.+\*{2}))(.+?)(\*{2})/g, - italic: /(\*{1}(?=.+\*{1}))(.+?)(\*{1})/g, - underline: /(_{1}(?=.+_{1}))(.+?)(_{1})/g, - - splitter: /\n{2,}/g, - cleaner: /^\n+|\n+$/, - standardizer: /\r\n|\r/g, - whitespacer: /^\t+|^ {3,}/gm + title_page: /^((?:title|credit|author[s]?|source|notes|draft date|date|contact|copyright)\:)/gim, + + scene_heading: /^((?:\*{0,3}_?)?(?:(?:int|ext|est|i\/e)[. ]).+)|^(?:\.(?!\.+))(.+)/i, + scene_number: /( *#(.+)# *)/, + + transition: /^((?:FADE (?:TO BLACK|OUT)|CUT TO BLACK)\.|.+ TO\:)|^(?:> *)(.+)/, + + dialogue: /^([A-Z*_]+[0-9A-Z (._\-')]*)(\^?)?(?:\n(?!\n+))([\s\S]+)/, + parenthetical: /^(\(.+\))$/, + + action: /^(.+)/g, + centered: /^(?:> *)(.+)(?: *<)(\n.+)*/g, + + section: /^(#+)(?: *)(.*)/, + synopsis: /^(?:\=(?!\=+) *)(.*)/, + + note: /^(?:\[{2}(?!\[+))(.+)(?:\]{2}(?!\[+))$/, + note_inline: /(?:\[{2}(?!\[+))([\s\S]+?)(?:\]{2}(?!\[+))/g, + boneyard: /(^\/\*|^\*\/)$/g, + + page_break: /^\={3,}$/, + line_break: /^ {2}$/, + + emphasis: /(_|\*{1,3}|_\*{1,3}|\*{1,3}_)(.+)(_|\*{1,3}|_\*{1,3}|\*{1,3}_)/g, + bold_italic_underline: /(_{1}\*{3}(?=.+\*{3}_{1})|\*{3}_{1}(?=.+_{1}\*{3}))(.+?)(\*{3}_{1}|_{1}\*{3})/g, + bold_underline: /(_{1}\*{2}(?=.+\*{2}_{1})|\*{2}_{1}(?=.+_{1}\*{2}))(.+?)(\*{2}_{1}|_{1}\*{2})/g, + italic_underline: /(?:_{1}\*{1}(?=.+\*{1}_{1})|\*{1}_{1}(?=.+_{1}\*{1}))(.+?)(\*{1}_{1}|_{1}\*{1})/g, + bold_italic: /(\*{3}(?=.+\*{3}))(.+?)(\*{3})/g, + bold: /(\*{2}(?=.+\*{2}))(.+?)(\*{2})/g, + italic: /(\*{1}(?=.+\*{1}))(.+?)(\*{1})/g, + underline: /(_{1}(?=.+_{1}))(.+?)(_{1})/g, + + splitter: /\n{2,}/g, + cleaner: /^\n+|\n+$/, + standardizer: /\r\n|\r/g, + whitespacer: /^\t+|^ {3,}/gm }; var lexer = function (script) { - return script.replace(regex.boneyard, '\n$1\n') - .replace(regex.standardizer, '\n') - .replace(regex.cleaner, '') - .replace(regex.whitespacer, ''); + return script.replace(regex.boneyard, '\n$1\n') + .replace(regex.standardizer, '\n') + .replace(regex.cleaner, '') + .replace(regex.whitespacer, ''); }; - + var tokenize = function (script) { - var src = lexer(script).split(regex.splitter) - , i = src.length, line, match, parts, text, meta, x, xlen, dual - , tokens = []; - - while (i--) { - line = src[i]; - - // title page - if (regex.title_page.test(line)) { - match = line.replace(regex.title_page, '\n$1').split(regex.splitter).reverse(); - for (x = 0, xlen = match.length; x < xlen; x++) { - parts = match[x].replace(regex.cleaner, '').split(/\:\n*/); - tokens.push({ type: parts[0].trim().toLowerCase().replace(' ', '_'), text: parts[1].trim() }); - } - continue; - } - - // scene headings - if (match = line.match(regex.scene_heading)) { - text = match[1] || match[2]; - - if (text.indexOf(' ') !== text.length - 2) { - if (meta = text.match(regex.scene_number)) { - meta = meta[2]; - text = text.replace(regex.scene_number, ''); - } - tokens.push({ type: 'scene_heading', text: text, scene_number: meta || undefined }); - } - continue; - } - - // centered - if (match = line.match(regex.centered)) { - tokens.push({ type: 'centered', text: match[0].replace(/>| 0) { - tokens.push({ type: regex.parenthetical.test(text) ? 'parenthetical' : 'dialogue', text: text }); - } - } - - tokens.push({ type: 'character', text: match[1].trim() }); - tokens.push({ type: 'dialogue_begin', dual: match[2] ? 'right' : dual ? 'left' : undefined }); - - if (dual) { - tokens.push({ type: 'dual_dialogue_begin' }); - } - - dual = match[2] ? true : false; - continue; - } - } - - // section - if (match = line.match(regex.section)) { - tokens.push({ type: 'section', text: match[2], depth: match[1].length }); - continue; - } - - // synopsis - if (match = line.match(regex.synopsis)) { - tokens.push({ type: 'synopsis', text: match[1] }); - continue; - } - - // notes - if (match = line.match(regex.note)) { - tokens.push({ type: 'note', text: match[1]}); - continue; - } - - // boneyard - if (match = line.match(regex.boneyard)) { - tokens.push({ type: match[0][0] === '/' ? 'boneyard_begin' : 'boneyard_end' }); - continue; - } - - // page breaks - if (regex.page_break.test(line)) { - tokens.push({ type: 'page_break' }); - continue; - } - - // line breaks - if (regex.line_break.test(line)) { - tokens.push({ type: 'line_break' }); - continue; - } - - tokens.push({ type: 'action', text: line }); - } - - return tokens; + var src = lexer(script).split(regex.splitter) + , i = src.length, line, match, parts, text, meta, x, xlen, dual + , tokens = []; + + while (i--) { + line = src[i]; + + // title page + if (regex.title_page.test(line)) { + match = line.replace(regex.title_page, '\n$1').split(regex.splitter).reverse(); + for (x = 0, xlen = match.length; x < xlen; x++) { + parts = match[x].replace(regex.cleaner, '').split(/\:\n*/); + tokens.push({ type: parts[0].trim().toLowerCase().replace(' ', '_'), text: parts[1].trim() }); + } + continue; + } + + // scene headings + if (match = line.match(regex.scene_heading)) { + text = match[1] || match[2]; + + if (text.indexOf(' ') !== text.length - 2) { + if (meta = text.match(regex.scene_number)) { + meta = meta[2]; + text = text.replace(regex.scene_number, ''); + } + tokens.push({ type: 'scene_heading', text: text, scene_number: meta || undefined }); + } + continue; + } + + // centered + if (match = line.match(regex.centered)) { + tokens.push({ type: 'centered', text: match[0].replace(/>| 0) { + tokens.push({ type: regex.parenthetical.test(text) ? 'parenthetical' : 'dialogue', text: text }); + } + } + + tokens.push({ type: 'character', text: match[1].trim() }); + tokens.push({ type: 'dialogue_begin', dual: match[2] ? 'right' : dual ? 'left' : undefined }); + + if (dual) { + tokens.push({ type: 'dual_dialogue_begin' }); + } + + dual = match[2] ? true : false; + continue; + } + } + + // section + if (match = line.match(regex.section)) { + tokens.push({ type: 'section', text: match[2], depth: match[1].length }); + continue; + } + + // synopsis + if (match = line.match(regex.synopsis)) { + tokens.push({ type: 'synopsis', text: match[1] }); + continue; + } + + // notes + if (match = line.match(regex.note)) { + tokens.push({ type: 'note', text: match[1]}); + continue; + } + + // boneyard + if (match = line.match(regex.boneyard)) { + tokens.push({ type: match[0][0] === '/' ? 'boneyard_begin' : 'boneyard_end' }); + continue; + } + + // page breaks + if (regex.page_break.test(line)) { + tokens.push({ type: 'page_break' }); + continue; + } + + // line breaks + if (regex.line_break.test(line)) { + tokens.push({ type: 'line_break' }); + continue; + } + + tokens.push({ type: 'action', text: line }); + } + + return tokens; }; var inline = { - note: '', + note: '', - line_break: '
', + line_break: '
', - bold_italic_underline: '$2', - bold_underline: '$2', - italic_underline: '$2', - bold_italic: '$2', - bold: '$2', - italic: '$2', - underline: '$2' + bold_italic_underline: '$2', + bold_underline: '$2', + italic_underline: '$2', + bold_italic: '$2', + bold: '$2', + italic: '$2', + underline: '$2' }; inline.lexer = function (s) { - if (!s) { - return; - } + if (!s) { + return; + } - var styles = [ 'underline', 'italic', 'bold', 'bold_italic', 'italic_underline', 'bold_underline', 'bold_italic_underline' ] - , i = styles.length, style, match; + var styles = [ 'underline', 'italic', 'bold', 'bold_italic', 'italic_underline', 'bold_underline', 'bold_italic_underline' ] + , i = styles.length, style, match; - s = s.replace(regex.note_inline, inline.note).replace(/\\\*/g, '[star]').replace(/\\_/g, '[underline]').replace(/\n/g, inline.line_break); + s = s.replace(regex.note_inline, inline.note).replace(/\\\*/g, '[star]').replace(/\\_/g, '[underline]').replace(/\n/g, inline.line_break); // if (regex.emphasis.test(s)) { // this was causing only every other occurence of an emphasis syntax to be parsed - while (i--) { - style = styles[i]; - match = regex[style]; + while (i--) { + style = styles[i]; + match = regex[style]; - if (match.test(s)) { - s = s.replace(match, inline[style]); - } - } + if (match.test(s)) { + s = s.replace(match, inline[style]); + } + } // } - return s.replace(/\[star\]/g, '*').replace(/\[underline\]/g, '_').trim(); + return s.replace(/\[star\]/g, '*').replace(/\[underline\]/g, '_').trim(); }; + var pushToArray = function(maybeArray, stuffToPush) { + if (typeof maybeArray == 'undefined') { + maybeArray = [] + } + + if (Array.isArray(maybeArray)) { + maybeArray.push(stuffToPush); + } else { + throw "First parameter to this function must be a proper array. Instead got: " + JSON.stringify(maybeArray); + } + + return maybeArray; + } + var parse = function (script, toks, callback) { - if (callback === undefined && typeof toks === 'function') { - callback = toks; - toks = undefined; - } - - var tokens = tokenize(script) - , i = tokens.length, token - , title, title_page = [], html = [], output; - - while (i--) { - token = tokens[i]; - token.text = inline.lexer(token.text); - - switch (token.type) { - case 'title': title_page.push('

' + token.text + '

'); title = token.text.replace('
', ' ').replace(/<(?:.|\n)*?>/g, ''); break; - case 'credit': title_page.push('

' + token.text + '

'); break; - case 'author': title_page.push('

' + token.text + '

'); break; - case 'authors': title_page.push('

' + token.text + '

'); break; - case 'source': title_page.push('

' + token.text + '

'); break; - case 'notes': title_page.push('

' + token.text + '

'); break; - case 'draft_date': title_page.push('

' + token.text + '

'); break; - case 'date': title_page.push('

' + token.text + '

'); break; - case 'contact': title_page.push('

' + token.text + '

'); break; - case 'copyright': title_page.push('

' + token.text + '

'); break; - - case 'scene_heading': html.push('' : '>') + token.text + ''); break; - case 'transition': html.push('

' + token.text + '

'); break; - - case 'dual_dialogue_begin': html.push('
'); break; - case 'dialogue_begin': html.push('
'); break; - case 'character': html.push('

' + token.text + '

'); break; - case 'parenthetical': html.push('

' + token.text + '

'); break; - case 'dialogue': html.push('

' + token.text + '

'); break; - case 'dialogue_end': html.push('
'); break; - case 'dual_dialogue_end': html.push('
'); break; - - case 'section': html.push('

' + token.text + '

'); break; - case 'synopsis': html.push('

' + token.text + '

'); break; - - case 'note': html.push(''); break; - case 'boneyard_begin': html.push(''); break; - - case 'action': html.push('

' + token.text + '

'); break; - case 'centered': html.push('

' + token.text + '

'); break; - - case 'page_break': html.push('
'); break; - case 'line_break': html.push('
'); break; - } - } - - output = { title: title, html: { title_page: title_page.join(''), script: html.join('') }, tokens: toks ? tokens.reverse() : undefined }; - - if (typeof callback === 'function') { - return callback(output); - } - - return output; + if (callback === undefined && typeof toks === 'function') { + callback = toks; + toks = undefined; + } + + var tokens = tokenize(script) + , i = tokens.length, token + , title, output = {}; + + output.title_page = {}; + output.script = []; //script is an array of scenes + + output.tokens = toks ? tokens.reverse() : undefined; + + var scene = {}; //the current running scene + var dialogue = {}; //the current running dialogue + var character = {}; //the current running character + + while (i--) { + token = tokens[i]; + token.text = inline.lexer(token.text); + + switch (token.type) { + case 'title': + output.title = token.text.replace('
', ' ').replace(/<(?:.|\n)*?>/g, ''); + output.title_page.title = pushToArray(output.title_page.title, output.title); + break; + case 'credit': + output.title_page.credit = pushToArray(output.title_page.credit, token.text); + break; + case 'author': + case 'authors': + output.title_page.authors = pushToArray(output.title_page.authors, token.text); + break; + case 'source': + output.title_page.source = pushToArray(output.title_page.source, token.text); + break; + case 'notes': + output.title_page.notes = pushToArray(output.title_page.notes, token.text); + break; + case 'draft_date': + output.title_page.draftdate = pushToArray(output.title_page.draftdate, token.text); + break; + case 'date': + output.title_page.date = pushToArray(output.title_page.date, token.text); + break; + case 'contact': + output.title_page.contact = pushToArray(output.title_page.contact, token.text); + break; + case 'copyright': + output.title_page.copyright = pushToArray(output.title_page.copyright, token.text); + break; + + case 'scene_heading': + output.script.scenes = pushToArray(output.script.scenes, scene); + scene = {}; + scene.headings = pushToArray(scene.heading, + {"scene_number": token.scene_number, "heading": token.text}); + break; + + case 'transition': + //push the current running scene onto the list, and begin a new one + scene.dialogue = pushToArray(token.text, {type: "transition", text: token.text}); + break; + + + case 'dual_dialogue_begin': + dialogue.characters = pushToArray(dialogue.characters, character); + scene.dialogue = pushToArray(scene.dialog, dialogue); + dialogue = {type: "dual"}; + break; + case 'dialogue_begin': + dialogue.characters = pushToArray(dialogue.characters, character); + scene.dialogue = pushToArray(scene.dialog, dialogue); + dialogue = {type: (token.dual ? "dual" : '')}; + break; + case 'character': + dialogue.characters = pushToArray(dialogue.characters, character); + character = {type: "character", name: token.text}; + break; + case 'parenthetical': + character.dialogue = pushToArray(character.dialogue, {type: "parenthetical", text: token.text}); + break; + case 'dialogue': + character.dialogue = pushToArray(character.dialogue, {type: "dialogue", text: token.text}); + break; + case 'dialogue_end': + case 'dual_dialogue_end': + dialogue.characters = pushToArray(dialogue.characters, character); + scene.dialogue = pushToArray(scene.dialog, dialogue); + dialogue = {}; + break; + + case 'section': + scene.sections = pushToArray(scene.sections, token.text); + html.push('

' + token.text + '

'); + break; + case 'synopsis': + scene.synopses = pushToArray(scene.synopses, token.text); + html.push('

' + token.text + '

'); + break; + + case 'note': + case 'boneyard_begin': + case 'boneyard_end': + //NO OP + break; + + case 'action': + case 'centered': + scene.actions = pushToArray(scene.actions, token.text); + break; + + case 'page_break': + case 'line_break': + + //NO OP + break; + } + } + + //ensure we track any dangling state: + dialogue.characters = pushToArray(dialogue.characters, character); + scene.dialogue = pushToArray(scene.dialog, dialogue); + output.script = pushToArray(output.script, scene); + + if (typeof callback === 'function') { + return callback(output); + } + + return output; + }; + + + var parseToHtml = function (script, toks, callback) { + if (callback === undefined && typeof toks === 'function') { + callback = toks; + toks = undefined; + } + + var tokens = tokenize(script) + , i = tokens.length, token + , title, title_page = [], html = [], output = {}; + + while (i--) { + token = tokens[i]; + token.text = inline.lexer(token.text); + + switch (token.type) { + case 'title': title_page.push('

' + token.text + '

'); title = token.text.replace('
', ' ').replace(/<(?:.|\n)*?>/g, ''); break; + case 'credit': title_page.push('

' + token.text + '

'); break; + case 'author': title_page.push('

' + token.text + '

'); break; + case 'authors': title_page.push('

' + token.text + '

'); break; + case 'source': title_page.push('

' + token.text + '

'); break; + case 'notes': title_page.push('

' + token.text + '

'); break; + case 'draft_date': title_page.push('

' + token.text + '

'); break; + case 'date': title_page.push('

' + token.text + '

'); break; + case 'contact': title_page.push('

' + token.text + '

'); break; + case 'copyright': title_page.push('

' + token.text + '

'); break; + + case 'scene_heading': html.push('' : '>') + token.text + ''); break; + case 'transition': html.push('

' + token.text + '

'); break; + + case 'dual_dialogue_begin': html.push('
'); break; + case 'dialogue_begin': html.push('
'); break; + case 'character': html.push('

' + token.text + '

'); break; + case 'parenthetical': html.push('

' + token.text + '

'); break; + case 'dialogue': html.push('

' + token.text + '

'); break; + case 'dialogue_end': html.push('
'); break; + case 'dual_dialogue_end': html.push('
'); break; + + case 'section': html.push('

' + token.text + '

'); break; + case 'synopsis': html.push('

' + token.text + '

'); break; + + case 'note': html.push(''); break; + case 'boneyard_begin': html.push(''); break; + + case 'action': html.push('

' + token.text + '

'); break; + case 'centered': html.push('

' + token.text + '

'); break; + + case 'page_break': html.push('
'); break; + case 'line_break': html.push('
'); break; + } + } + + output = { title: title, html: { title_page: title_page.join(''), script: html.join('') }, tokens: toks ? tokens.reverse() : undefined}; + + if (typeof callback === 'function') { + return callback(output); + } + + return output; }; var fountain = function (script, callback) { - return fountain.parse(script, callback); + return fountain.parse(script, callback); }; - + fountain.parse = function (script, tokens, callback) { - return parse(script, tokens, callback); + return parse(script, tokens, callback); }; if (typeof module !== 'undefined') { - module.exports = fountain; + module.exports = fountain; } else { - this.fountain = fountain; + this.fountain = fountain; } }).call(this); From c4504c0c7e6386afbf64be9914aef25e324cc611 Mon Sep 17 00:00:00 2001 From: Archis Gore Date: Sun, 21 Feb 2016 12:32:44 -0800 Subject: [PATCH 2/7] Renamed the JSON object-parser to parseToJson --- fountain.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fountain.js b/fountain.js index 6fdafe8..1d1f88a 100644 --- a/fountain.js +++ b/fountain.js @@ -221,7 +221,7 @@ return maybeArray; } - var parse = function (script, toks, callback) { + var parseToJson = function (script, toks, callback) { if (callback === undefined && typeof toks === 'function') { callback = toks; toks = undefined; From f221b4bdee6b0cc5bebfd17cc44be80857dde6eb Mon Sep 17 00:00:00 2001 From: Archis Gore Date: Sun, 21 Feb 2016 12:45:20 -0800 Subject: [PATCH 3/7] Fixed the exports --- fountain.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/fountain.js b/fountain.js index 1d1f88a..4394437 100644 --- a/fountain.js +++ b/fountain.js @@ -211,7 +211,7 @@ if (typeof maybeArray == 'undefined') { maybeArray = [] } - + if (Array.isArray(maybeArray)) { maybeArray.push(stuffToPush); } else { @@ -418,12 +418,12 @@ }; var fountain = function (script, callback) { - return fountain.parse(script, callback); + return fountain.parseToJson(script, callback); }; - fountain.parse = function (script, tokens, callback) { - return parse(script, tokens, callback); - }; + fountain.parseToJson = parseToJson; + + fountain.parseToHtml = parseToHtml; if (typeof module !== 'undefined') { module.exports = fountain; From 88ee153b75a9da62cdbc419fa85fa4e43dcc605a Mon Sep 17 00:00:00 2001 From: Archis Gore Date: Sun, 21 Feb 2016 12:52:15 -0800 Subject: [PATCH 4/7] Fixed it. --- fountain.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fountain.js b/fountain.js index 4394437..49815df 100644 --- a/fountain.js +++ b/fountain.js @@ -211,10 +211,11 @@ if (typeof maybeArray == 'undefined') { maybeArray = [] } - + if (Array.isArray(maybeArray)) { maybeArray.push(stuffToPush); } else { + console.trace(); throw "First parameter to this function must be a proper array. Instead got: " + JSON.stringify(maybeArray); } @@ -284,7 +285,7 @@ case 'transition': //push the current running scene onto the list, and begin a new one - scene.dialogue = pushToArray(token.text, {type: "transition", text: token.text}); + scene.dialogue = pushToArray(scene.dialogue, {type: "transition", text: token.text}); break; From 0b2d8d4f5b7345ad095fa1ddfc3af8cb56d6ef0b Mon Sep 17 00:00:00 2001 From: Archis Gore Date: Sun, 21 Feb 2016 20:27:54 -0800 Subject: [PATCH 5/7] Fixed a couple of parser issues --- fountain.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fountain.js b/fountain.js index 49815df..d6d9cee 100644 --- a/fountain.js +++ b/fountain.js @@ -233,7 +233,7 @@ , title, output = {}; output.title_page = {}; - output.script = []; //script is an array of scenes + output.script = {}; //script is an array of scenes output.tokens = toks ? tokens.reverse() : undefined; @@ -347,7 +347,7 @@ //ensure we track any dangling state: dialogue.characters = pushToArray(dialogue.characters, character); scene.dialogue = pushToArray(scene.dialog, dialogue); - output.script = pushToArray(output.script, scene); + output.script.scenes = pushToArray(output.script.scenes, scene); if (typeof callback === 'function') { return callback(output); From baca3d41bbadf9a8941bf363db8d2dd64a0cb44b Mon Sep 17 00:00:00 2001 From: Archis Gore Date: Sun, 21 Feb 2016 21:40:55 -0800 Subject: [PATCH 6/7] Made scene an array --- fountain.js | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/fountain.js b/fountain.js index d6d9cee..953b8aa 100644 --- a/fountain.js +++ b/fountain.js @@ -237,9 +237,9 @@ output.tokens = toks ? tokens.reverse() : undefined; - var scene = {}; //the current running scene - var dialogue = {}; //the current running dialogue - var character = {}; //the current running character + var scene = []; //the current running scene + var dialogue = {type: "unknown"}; //the current running dialogue + var character = {type: "unknown"}; //the current running character while (i--) { token = tokens[i]; @@ -278,51 +278,51 @@ case 'scene_heading': output.script.scenes = pushToArray(output.script.scenes, scene); - scene = {}; - scene.headings = pushToArray(scene.heading, - {"scene_number": token.scene_number, "heading": token.text}); + scene = []; + scene = pushToArray(scene, + {type: "heading", "scene_number": token.scene_number, "heading": token.text}); break; case 'transition': //push the current running scene onto the list, and begin a new one - scene.dialogue = pushToArray(scene.dialogue, {type: "transition", text: token.text}); + scene = pushToArray(scene, {type: "transition", text: token.text}); break; case 'dual_dialogue_begin': dialogue.characters = pushToArray(dialogue.characters, character); - scene.dialogue = pushToArray(scene.dialog, dialogue); - dialogue = {type: "dual"}; + character = {type: "unkown"}; + scene = pushToArray(scene, dialogue); + dialogue = {type: "dialogue-dual"}; break; case 'dialogue_begin': dialogue.characters = pushToArray(dialogue.characters, character); - scene.dialogue = pushToArray(scene.dialog, dialogue); - dialogue = {type: (token.dual ? "dual" : '')}; + character = {type: "unkown"}; + scene = pushToArray(scene, dialogue); + dialogue = {type: (token.dual ? "dialogue-dual" : 'dialogue-single')}; break; case 'character': dialogue.characters = pushToArray(dialogue.characters, character); character = {type: "character", name: token.text}; break; case 'parenthetical': - character.dialogue = pushToArray(character.dialogue, {type: "parenthetical", text: token.text}); + character.lines = pushToArray(character.lines, {type: "parenthetical", text: token.text}); break; case 'dialogue': - character.dialogue = pushToArray(character.dialogue, {type: "dialogue", text: token.text}); + character.lines = pushToArray(character.lines, {type: "line", text: token.text}); break; case 'dialogue_end': case 'dual_dialogue_end': dialogue.characters = pushToArray(dialogue.characters, character); - scene.dialogue = pushToArray(scene.dialog, dialogue); - dialogue = {}; + scene = pushToArray(scene, dialogue); + dialogue = {type: "dialogue-single"}; break; case 'section': - scene.sections = pushToArray(scene.sections, token.text); - html.push('

' + token.text + '

'); + scene = pushToArray(scene, {type: "section", name: token.text}); break; case 'synopsis': - scene.synopses = pushToArray(scene.synopses, token.text); - html.push('

' + token.text + '

'); + scene = pushToArray(scene, {type: "synopsis", text: token.text}); break; case 'note': @@ -333,7 +333,7 @@ case 'action': case 'centered': - scene.actions = pushToArray(scene.actions, token.text); + scene.actions = pushToArray(scene.actions, {type: "action", text: token.text}); break; case 'page_break': @@ -346,7 +346,7 @@ //ensure we track any dangling state: dialogue.characters = pushToArray(dialogue.characters, character); - scene.dialogue = pushToArray(scene.dialog, dialogue); + scene = pushToArray(scene, dialogue); output.script.scenes = pushToArray(output.script.scenes, scene); if (typeof callback === 'function') { From 2018d9aae7c52490dbd7a309847e618a48490b3a Mon Sep 17 00:00:00 2001 From: Archis Gore Date: Sun, 21 Feb 2016 21:45:46 -0800 Subject: [PATCH 7/7] actions was missing --- fountain.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fountain.js b/fountain.js index 953b8aa..658b162 100644 --- a/fountain.js +++ b/fountain.js @@ -333,7 +333,7 @@ case 'action': case 'centered': - scene.actions = pushToArray(scene.actions, {type: "action", text: token.text}); + scene = pushToArray(scene, {type: "action", text: token.text}); break; case 'page_break':