diff --git a/README.md b/README.md index dd31c4d..86c2d4d 100644 --- a/README.md +++ b/README.md @@ -100,6 +100,12 @@ YouTube](https://www.youtube.com/playlist?list=PLy3M_6DKN9joOGhUD1chHumc9aS6EZZ_ * [Cards with Covers](doc/cards-with-covers.md): [twee](examples/covers.tw), [html](https://joshuagrams.github.io/tiny-qbn/examples/covers.html). +* [Cards using objects in requirements](doc/dot-notation.md): + [twee](examples/dot-notation.tw), + [html](https://joshuagrams.github.io/tiny-qbn/examples/dot-notation.html) +* [Cards with Covers and objects in requirements](doc/cards-with-covers-dot-notation.md): + [twee](examples/covers-dot-notation.tw), + [html](https://joshuagrams.github.io/tiny-qbn/examples/covers-dot-notation.html). * [Inline Choices](doc/choices.md): [twee](examples/choices.tw), [html](https://joshuagrams.github.io/tiny-qbn/examples/choices.html). diff --git a/doc/cards-with-covers-dot-notation.md b/doc/cards-with-covers-dot-notation.md new file mode 100644 index 0000000..c194bca --- /dev/null +++ b/doc/cards-with-covers-dot-notation.md @@ -0,0 +1,19 @@ +Card Covers with objects using dot notation in requirements +=========== + +This example is identical to [cards with covers](cards-with-covers.md). The only difference is that it uses objects within the card requirements rather than simple variables. Instead of `$strength`, the characters stats are defined as an object in StoryInit: `<>`. + +The individual properties of that object can be used in requirements using dot notation syntax. To access the `strength` property, you'd refer to it as `$pc.strength` (in requirements expressed using comment syntax) or `pc.strength` (in requirements expressed in tag syntax) + +For example: + +`::Card Title [card req-pc.strength-gte-2]` + +or + +``::Card Title\ +/*QBN\ + sticky-card\ + req: $pc.strength gte 2\ + also: $pc.strength gte 3\ +*/`` diff --git a/doc/dot-notation.md b/doc/dot-notation.md new file mode 100644 index 0000000..e5e77fc --- /dev/null +++ b/doc/dot-notation.md @@ -0,0 +1,18 @@ +Using objects in requirements +=========== + +It is possible to use object properties within card requirements. In this example, the player characters stats are defined an object in StoryInit using `<>`. + +The individual properties of that object can be used in requirements using dot notation syntax. To access the `strength` property, you'd refer to it as `$pc.strength` (in requirements expressed using comment syntax) or `pc.strength` (in requirements expressed in tag syntax) + +For example: + +`::Card Title [card req-pc.strength-gte-2]` + +or + +``::Card Title\ +/*QBN\ + sticky-card\ + req: $pc.strength gte 2\ +*/`` diff --git a/examples/choices.html b/examples/choices.html index b33c6bd..735024a 100644 --- a/examples/choices.html +++ b/examples/choices.html @@ -180,7 +180,7 @@ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -State.initPRNG();var QBN={meta:{}};window.QBN=QBN,QBN.parseTagsInto=function(a,b){let c,d=new RegExp("("+["[a-zA-Z0-9-_]+(?:\\s+|$)","[a-zA-Z0-9_]+:[^\\n]*(?:\\n|$)\\s*","[^\\n]+(?:\\n|$)\\s*"].join(")|(")+")","g"),e=!1;for(;null!=(c=d.exec(a));)if(c[1]!==void 0)e?(b[b.length-1]+=c[1],!/\\\n/.test(c[1])&&(e=!1)):b.push(c[1].trim());else if(c[2]!==void 0){let a=c[2].replace(":","- "),d=a.replace("\\\n","");d.length!==a.length&&(e=!0),b.push(d)}else if(c[3]!==void 0){if(e)b[b.length-1]+=c[3];else throw new Error("Invalid metadata: "+JSON.stringify(c[3]));/(^|[^\\])\n/.test(c[3])&&(e=!1)}return b};const commentPattern=/\/\*\s*QBN\s([^*]*)\s\*\//g;Story.lookupWith(function(a){let b,c=a.tags.slice();for(;null!=(b=commentPattern.exec(a.text));){let a=b[1].trim();QBN.parseTagsInto(a,c)}return QBN.meta[a.title]=c,!1}),QBN.tags=function(a){return QBN.meta[a.title]||a.tags};var getVar=State.getVar||Wikifier.getValue,setVar=State.setVar||Wikifier.setValue;setVar("$QBN",{type:{},priority:{}}),$(document).on(":passagestart",function(a){QBN.current=a.passage.title,passageType(a.passage,!1)});function toArgument(a){if("object"==typeof a&&(a=a.title),"string"==typeof a)return JSON.stringify(a);throw new Error("Cards must be referred to by title (got "+typeof a+").")}function toPassage(a){if("object"==typeof a)if(a.link&&a.text)a=a.link;else return a;if("string"!=typeof a)throw new Error("Cards must be referred to by title (got "+typeof a+").");else{if(Story.has(a))return Story.get(a);let b=JSON.parse(a),c=b[0],d=b[1],e=b[2];if(passage()===c){let a=getVar(d);if(null!=a&&null!=a[e])return a[e]}throw new Error("No such passage or choice \""+a+"\".")}}QBN.toPassage=toPassage;function passageType(a,b){var c,d=QBN.tags(a);c=0<=d.indexOf("sticky-card")?"sticky-card":!!(0<=d.indexOf("card"))&&"card";var e=getVar("$QBN").type,f=e[a.title];return void 0===f&&(f=c),void 0!==b&&b!==f&&(null===b?e[a.title]=!1:!1===b?"card"===f&&(e[a.title]=!1):b===c?delete e[a.title]:e[a.title]=b),f}function shuffle(b){for(let a=b.length;0d?1:0};function choose(a,b,c){var d=Math.min;if(null==b||!1===b)return c?a:shuffle(a);b=Math.max(0,d(b,a.length));for(var e=d(b,a.length-b),f=e===b||void 0,g=[],h={},j=0;ja},lte:function(c,a){return c<=a},le:function(c,a){return c<=a},gte:function(c,a){return c>=a},ge:function(c,a){return c>=a},eqvar:function(c,a,b,d){return c==QBN.value(d)},neqvar:function(c,a,b,d){return c==QBN.value(d)},ltvar:function(c,a,b,d){return c==QBN.value(d)},gtvar:function(c,a,b,d){return c==QBN.value(d)},ltevar:function(c,a,b,d){return c==QBN.value(d)},gtevar:function(c,a,b,d){return c==QBN.value(d)},before:function(c,a,b){return QBN.progress(b,c)QBN.progress(b,a)},endingAt:function(c,a,b){return QBN.progress(b,c)<=QBN.progress(b,a)},startingAt:function(c,a,b){return QBN.progress(b,c)>=QBN.progress(b,a)}},operatorNames={eq:"to be",ne:"not to be",lt:"to be less than",le:"to be at most",gt:"to be greater than",ge:"to be at least"};QBN.functions={twinescript:{match:/^\s.*/,action:function(a){try{return Scripting.evalTwineScript(a[0])}catch(b){throw b.message+=" in: "+a[0],b}},description:function(a){return"\"\"\""+a[0]+"\"\"\""}},not:{match:/^not-(.+)/,action:function(a){return!QBN.requirementMet(a[1])},description:function(a){var b=QBN.description(a[1]);return null==b?b:"not "+b}},passage:{match:/^passage-(.+)/,action:function(a){return passage()===a[1]||passage()===a[1].replace(/_/g," ")},description:function(){return null}},tagged:{match:/^tagged-(.+)/,action:function(a){return tags().includes(a[1])},description:function(){return null}},visited:{match:/^visited-([^-]+)/,action:function(a){return 0c){var d="QBN.range: invalid range spec:";throw d+=" must have at least two values",d+=" (got "+JSON.stringify(c)+").",new Error(d)}for(var e,f,g,h,j=0;j>: "+(a.message||a))}setVar("_"+a+"_"+c.substring(1),!0),setVar("_"+c.substring(1)+"_range",a)}}),QBN.value=function(a){var b=State.variables,c=State.temporary;return null==c[a]?b[a]:c[a]},QBN.requirementMet=function(a){var b=null;for(var c in QBN.functions)if(QBN.functions.hasOwnProperty(c)){var d=QBN.functions[c],e=d.match.exec(a);if(e){b=d.action(e);break}}return null===b&&(b=QBN.value(a)),!!b},QBN.description=function(a){var b=null;for(var c in QBN.functions)if(QBN.functions.hasOwnProperty(c)){var d=QBN.functions[c],e=d.match.exec(a);if(e){b=d.description(e);break}}return null===b&&(b=a),b},QBN.tagsMatch=function(a,b){a=toPassage(a);let c=QBN.current;QBN.current=a.title;let d=QBN.tags(a);for(var e=0;e>"),d&&f>"):e.wiki(d))}}}),Macro.add("requirements",{handler:function(){var a=$(this.output),b=toPassage(this.args[0]||QBN.current),c=this.args[1];if(c&&!Macro.has(c))return this.error("No such widget "+JSON.stringify(c)+".");for(var d,e=this.args[2]||"comma",f=QBN.requirements(b),g=0;g>"):a.wiki(d),e&&g>"):a.append(document.createTextNode(e)))}});function addTo(a,b){var c="string"==typeof b?b:b.title,d=!a[c];return d&&(a[c]=!0),d}function firstWord(a){var b=a.indexOf(" ");return a.substring(0,-1==b?a.length:b)}Macro.add("fillhand",{handler:function(){try{var a=this.args[0],b=this.args[1],c=this.args[2];if(!a){a=[];var d=firstWord(this.args.raw).substring(1);if(!setVar(d,a))return this.error("<>: failed to set hand \""+d+"\".")}var e,f={};for(e=0;e>: "+("object"==typeof a?a.message:a))}}}),Macro.add("card",{tags:["contents"],handler:function(){var a=$(this.output);if(getVar("_qbn_cover"))a.wiki(this.payload[0].contents.trim());else for(var b=1;bc.indexOf("card")&&0>c.indexOf("sticky-card")&&c.push("card"),a.push({title:JSON.stringify([passage(),b,a.length]),tags:c})}Macro.add("choices",{tags:["when","offer"],handler:function(){var a=this.args.raw,b=invalidName(a);if(b)return this.error(b);for(var c=[],d=0;d> content must be in sub-tags.");break;case"when":if(partialChoice(c))return this.error("This choice already has a \"when\" clause (section "+d+", "+e.contents.substring(0,30)+").");var f=QBN.parseTagsInto(e.contents.trim(),[]);beginChoice(c,a,f);break;case"offer":partialChoice(c)||beginChoice(c,a,[]),c[c.length-1].text=e.contents.trim(),""!==e.args[0]&&(c[e.args[0]]=c[c.length-1]);}}setVar(a,c)}}),QBN.progress=function(a,b){a=a.replace(/^[$_]/,"");let c=setup[a];if(null==c)throw"No such progress sequence "+JSON.stringify(a)+".";for(let d=0;d<<set $stat_points to 1>> +State.initPRNG();var QBN={meta:{}};window.QBN=QBN,QBN.parseTagsInto=function(a,b){let c,d=new RegExp("("+["[a-zA-Z0-9-_\\.]+(?:\\s+|$)","[a-zA-Z0-9_\\.]+:[^\\n]*(?:\\n|$)\\s*","[^\\n]+(?:\\n|$)\\s*"].join(")|(")+")","g"),e=!1;for(;null!=(c=d.exec(a));)if(c[1]!==void 0)e?(b[b.length-1]+=c[1],!/\\\n/.test(c[1])&&(e=!1)):b.push(c[1].trim());else if(c[2]!==void 0){let a=c[2].replace(":","- "),d=a.replace("\\\n","");d.length!==a.length&&(e=!0),b.push(d)}else if(c[3]!==void 0){if(e)b[b.length-1]+=c[3];else throw new Error("Invalid metadata: "+JSON.stringify(c[3]));/(^|[^\\])\n/.test(c[3])&&(e=!1)}return b};const commentPattern=/\/\*\s*QBN\s([^*]*)\s\*\//g;Story.lookupWith(function(a){let b,c=a.tags.slice();for(;null!=(b=commentPattern.exec(a.text));){let a=b[1].trim();QBN.parseTagsInto(a,c)}return QBN.meta[a.title]=c,!1}),QBN.tags=function(a){return QBN.meta[a.title]||a.tags};var getVar=State.getVar||Wikifier.getValue,setVar=State.setVar||Wikifier.setValue;setVar("$QBN",{type:{},priority:{}}),$(document).on(":passagestart",function(a){QBN.current=a.passage.title,passageType(a.passage,!1)});function toArgument(a){if("object"==typeof a&&(a=a.title),"string"==typeof a)return JSON.stringify(a);throw new Error("Cards must be referred to by title (got "+typeof a+").")}function toPassage(a){if("object"==typeof a)if(a.link&&a.text)a=a.link;else return a;if("string"!=typeof a)throw new Error("Cards must be referred to by title (got "+typeof a+").");else{if(Story.has(a))return Story.get(a);let b=JSON.parse(a),c=b[0],d=b[1],e=b[2];if(passage()===c){let a=getVar(d);if(null!=a&&null!=a[e])return a[e]}throw new Error("No such passage or choice \""+a+"\".")}}QBN.toPassage=toPassage;function passageType(a,b){var c,d=QBN.tags(a);c=0<=d.indexOf("sticky-card")?"sticky-card":!!(0<=d.indexOf("card"))&&"card";var e=getVar("$QBN").type,f=e[a.title];return void 0===f&&(f=c),void 0!==b&&b!==f&&(null===b?e[a.title]=!1:!1===b?"card"===f&&(e[a.title]=!1):b===c?delete e[a.title]:e[a.title]=b),f}function shuffle(b){for(let a=b.length;0d?1:0};function choose(a,b,c){var d=Math.min;if(null==b||!1===b)return c?a:shuffle(a);b=Math.max(0,d(b,a.length));for(var e=d(b,a.length-b),f=e===b||void 0,g=[],h={},j=0;ja},lte:function(c,a){return c<=a},le:function(c,a){return c<=a},gte:function(c,a){return c>=a},ge:function(c,a){return c>=a},eqvar:function(c,a,b,d){return c==QBN.value(d)},neqvar:function(c,a,b,d){return c==QBN.value(d)},ltvar:function(c,a,b,d){return c==QBN.value(d)},gtvar:function(c,a,b,d){return c==QBN.value(d)},ltevar:function(c,a,b,d){return c==QBN.value(d)},gtevar:function(c,a,b,d){return c==QBN.value(d)},before:function(c,a,b){return QBN.progress(b,c)QBN.progress(b,a)},endingAt:function(c,a,b){return QBN.progress(b,c)<=QBN.progress(b,a)},startingAt:function(c,a,b){return QBN.progress(b,c)>=QBN.progress(b,a)}},operatorNames={eq:"to be",ne:"not to be",lt:"to be less than",le:"to be at most",gt:"to be greater than",ge:"to be at least"};QBN.functions={twinescript:{match:/^\s.*/,action:function(a){try{return Scripting.evalTwineScript(a[0])}catch(b){throw b.message+=" in: "+a[0],b}},description:function(a){return"\"\"\""+a[0]+"\"\"\""}},not:{match:/^not-(.+)/,action:function(a){return!QBN.requirementMet(a[1])},description:function(a){var b=QBN.description(a[1]);return null==b?b:"not "+b}},passage:{match:/^passage-(.+)/,action:function(a){return passage()===a[1]||passage()===a[1].replace(/_/g," ")},description:function(){return null}},tagged:{match:/^tagged-(.+)/,action:function(a){return tags().includes(a[1])},description:function(){return null}},visited:{match:/^visited-([^-]+)/,action:function(a){return 0c){var d="QBN.range: invalid range spec:";throw d+=" must have at least two values",d+=" (got "+JSON.stringify(c)+").",new Error(d)}for(var e,f,g,h,j=0;j>: "+(a.message||a))}setVar("_"+a+"_"+c.substring(1),!0),setVar("_"+c.substring(1)+"_range",a)}}),QBN.getProperty=function(a,b){var c,d=a.split("."),e=d.length,f=b||this;for(c=0;c>"),d&&f>"):e.wiki(d))}}}),Macro.add("requirements",{handler:function(){var a=$(this.output),b=toPassage(this.args[0]||QBN.current),c=this.args[1];if(c&&!Macro.has(c))return this.error("No such widget "+JSON.stringify(c)+".");for(var d,e=this.args[2]||"comma",f=QBN.requirements(b),g=0;g>"):a.wiki(d),e&&g>"):a.append(document.createTextNode(e)))}});function addTo(a,b){var c="string"==typeof b?b:b.title,d=!a[c];return d&&(a[c]=!0),d}function firstWord(a){var b=a.indexOf(" ");return a.substring(0,-1==b?a.length:b)}Macro.add("fillhand",{handler:function(){try{var a=this.args[0],b=this.args[1],c=this.args[2];if(!a){a=[];var d=firstWord(this.args.raw).substring(1);if(!setVar(d,a))return this.error("<>: failed to set hand \""+d+"\".")}var e,f={};for(e=0;e>: "+("object"==typeof a?a.message:a))}}}),Macro.add("card",{tags:["contents"],handler:function(){var a=$(this.output);if(getVar("_qbn_cover"))a.wiki(this.payload[0].contents.trim());else for(var b=1;bc.indexOf("card")&&0>c.indexOf("sticky-card")&&c.push("card"),a.push({title:JSON.stringify([passage(),b,a.length]),tags:c})}Macro.add("choices",{tags:["when","offer"],handler:function(){var a=this.args.raw,b=invalidName(a);if(b)return this.error(b);for(var c=[],d=0;d> content must be in sub-tags.");break;case"when":if(partialChoice(c))return this.error("This choice already has a \"when\" clause (section "+d+", "+e.contents.substring(0,30)+").");var f=QBN.parseTagsInto(e.contents.trim(),[]);beginChoice(c,a,f);break;case"offer":partialChoice(c)||beginChoice(c,a,[]),c[c.length-1].text=e.contents.trim(),""!==e.args[0]&&(c[e.args[0]]=c[c.length-1]);}}setVar(a,c)}}),QBN.progress=function(a,b){a=a.replace(/^[$_]/,"");let c=setup[a];if(null==c)throw"No such progress sequence "+JSON.stringify(a)+".";for(let d=0;d<<set $stat_points to 1>> <<set $stealth to 0>> <<set $strength to 0>>Stat Points: $stat_points Stealth: $stealth<<if $stat_points gt 0>> ([[increase->Start][$stealth++; $stat_points--]])<</if>> diff --git a/examples/common/tiny-qbn.js b/examples/common/tiny-qbn.js index 55e7994..507a89b 100644 --- a/examples/common/tiny-qbn.js +++ b/examples/common/tiny-qbn.js @@ -66,4 +66,4 @@ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -State.initPRNG();var QBN={meta:{}};window.QBN=QBN,QBN.parseTagsInto=function(a,b){let c,d=new RegExp("("+["[a-zA-Z0-9-_]+(?:\\s+|$)","[a-zA-Z0-9_]+:[^\\n]*(?:\\n|$)\\s*","[^\\n]+(?:\\n|$)\\s*"].join(")|(")+")","g"),e=!1;for(;null!=(c=d.exec(a));)if(c[1]!==void 0)e?(b[b.length-1]+=c[1],!/\\\n/.test(c[1])&&(e=!1)):b.push(c[1].trim());else if(c[2]!==void 0){let a=c[2].replace(":","- "),d=a.replace("\\\n","");d.length!==a.length&&(e=!0),b.push(d)}else if(c[3]!==void 0){if(e)b[b.length-1]+=c[3];else throw new Error("Invalid metadata: "+JSON.stringify(c[3]));/(^|[^\\])\n/.test(c[3])&&(e=!1)}return b};const commentPattern=/\/\*\s*QBN\s([^*]*)\s\*\//g;Story.lookupWith(function(a){let b,c=a.tags.slice();for(;null!=(b=commentPattern.exec(a.text));){let a=b[1].trim();QBN.parseTagsInto(a,c)}return QBN.meta[a.title]=c,!1}),QBN.tags=function(a){return QBN.meta[a.title]||a.tags};var getVar=State.getVar||Wikifier.getValue,setVar=State.setVar||Wikifier.setValue;setVar("$QBN",{type:{},priority:{}}),$(document).on(":passagestart",function(a){QBN.current=a.passage.title,passageType(a.passage,!1)});function toArgument(a){if("object"==typeof a&&(a=a.title),"string"==typeof a)return JSON.stringify(a);throw new Error("Cards must be referred to by title (got "+typeof a+").")}function toPassage(a){if("object"==typeof a)if(a.link&&a.text)a=a.link;else return a;if("string"!=typeof a)throw new Error("Cards must be referred to by title (got "+typeof a+").");else{if(Story.has(a))return Story.get(a);let b=JSON.parse(a),c=b[0],d=b[1],e=b[2];if(passage()===c){let a=getVar(d);if(null!=a&&null!=a[e])return a[e]}throw new Error("No such passage or choice \""+a+"\".")}}QBN.toPassage=toPassage;function passageType(a,b){var c,d=QBN.tags(a);c=0<=d.indexOf("sticky-card")?"sticky-card":!!(0<=d.indexOf("card"))&&"card";var e=getVar("$QBN").type,f=e[a.title];return void 0===f&&(f=c),void 0!==b&&b!==f&&(null===b?e[a.title]=!1:!1===b?"card"===f&&(e[a.title]=!1):b===c?delete e[a.title]:e[a.title]=b),f}function shuffle(b){for(let a=b.length;0d?1:0};function choose(a,b,c){var d=Math.min;if(null==b||!1===b)return c?a:shuffle(a);b=Math.max(0,d(b,a.length));for(var e=d(b,a.length-b),f=e===b||void 0,g=[],h={},j=0;ja},lte:function(c,a){return c<=a},le:function(c,a){return c<=a},gte:function(c,a){return c>=a},ge:function(c,a){return c>=a},eqvar:function(c,a,b,d){return c==QBN.value(d)},neqvar:function(c,a,b,d){return c==QBN.value(d)},ltvar:function(c,a,b,d){return c==QBN.value(d)},gtvar:function(c,a,b,d){return c==QBN.value(d)},ltevar:function(c,a,b,d){return c==QBN.value(d)},gtevar:function(c,a,b,d){return c==QBN.value(d)},before:function(c,a,b){return QBN.progress(b,c)QBN.progress(b,a)},endingAt:function(c,a,b){return QBN.progress(b,c)<=QBN.progress(b,a)},startingAt:function(c,a,b){return QBN.progress(b,c)>=QBN.progress(b,a)}},operatorNames={eq:"to be",ne:"not to be",lt:"to be less than",le:"to be at most",gt:"to be greater than",ge:"to be at least"};QBN.functions={twinescript:{match:/^\s.*/,action:function(a){try{return Scripting.evalTwineScript(a[0])}catch(b){throw b.message+=" in: "+a[0],b}},description:function(a){return"\"\"\""+a[0]+"\"\"\""}},not:{match:/^not-(.+)/,action:function(a){return!QBN.requirementMet(a[1])},description:function(a){var b=QBN.description(a[1]);return null==b?b:"not "+b}},passage:{match:/^passage-(.+)/,action:function(a){return passage()===a[1]||passage()===a[1].replace(/_/g," ")},description:function(){return null}},tagged:{match:/^tagged-(.+)/,action:function(a){return tags().includes(a[1])},description:function(){return null}},visited:{match:/^visited-([^-]+)/,action:function(a){return 0c){var d="QBN.range: invalid range spec:";throw d+=" must have at least two values",d+=" (got "+JSON.stringify(c)+").",new Error(d)}for(var e,f,g,h,j=0;j>: "+(a.message||a))}setVar("_"+a+"_"+c.substring(1),!0),setVar("_"+c.substring(1)+"_range",a)}}),QBN.value=function(a){var b=State.variables,c=State.temporary;return null==c[a]?b[a]:c[a]},QBN.requirementMet=function(a){var b=null;for(var c in QBN.functions)if(QBN.functions.hasOwnProperty(c)){var d=QBN.functions[c],e=d.match.exec(a);if(e){b=d.action(e);break}}return null===b&&(b=QBN.value(a)),!!b},QBN.description=function(a){var b=null;for(var c in QBN.functions)if(QBN.functions.hasOwnProperty(c)){var d=QBN.functions[c],e=d.match.exec(a);if(e){b=d.description(e);break}}return null===b&&(b=a),b},QBN.tagsMatch=function(a,b){a=toPassage(a);let c=QBN.current;QBN.current=a.title;let d=QBN.tags(a);for(var e=0;e>"),d&&f>"):e.wiki(d))}}}),Macro.add("requirements",{handler:function(){var a=$(this.output),b=toPassage(this.args[0]||QBN.current),c=this.args[1];if(c&&!Macro.has(c))return this.error("No such widget "+JSON.stringify(c)+".");for(var d,e=this.args[2]||"comma",f=QBN.requirements(b),g=0;g>"):a.wiki(d),e&&g>"):a.append(document.createTextNode(e)))}});function addTo(a,b){var c="string"==typeof b?b:b.title,d=!a[c];return d&&(a[c]=!0),d}function firstWord(a){var b=a.indexOf(" ");return a.substring(0,-1==b?a.length:b)}Macro.add("fillhand",{handler:function(){try{var a=this.args[0],b=this.args[1],c=this.args[2];if(!a){a=[];var d=firstWord(this.args.raw).substring(1);if(!setVar(d,a))return this.error("<>: failed to set hand \""+d+"\".")}var e,f={};for(e=0;e>: "+("object"==typeof a?a.message:a))}}}),Macro.add("card",{tags:["contents"],handler:function(){var a=$(this.output);if(getVar("_qbn_cover"))a.wiki(this.payload[0].contents.trim());else for(var b=1;bc.indexOf("card")&&0>c.indexOf("sticky-card")&&c.push("card"),a.push({title:JSON.stringify([passage(),b,a.length]),tags:c})}Macro.add("choices",{tags:["when","offer"],handler:function(){var a=this.args.raw,b=invalidName(a);if(b)return this.error(b);for(var c=[],d=0;d> content must be in sub-tags.");break;case"when":if(partialChoice(c))return this.error("This choice already has a \"when\" clause (section "+d+", "+e.contents.substring(0,30)+").");var f=QBN.parseTagsInto(e.contents.trim(),[]);beginChoice(c,a,f);break;case"offer":partialChoice(c)||beginChoice(c,a,[]),c[c.length-1].text=e.contents.trim(),""!==e.args[0]&&(c[e.args[0]]=c[c.length-1]);}}setVar(a,c)}}),QBN.progress=function(a,b){a=a.replace(/^[$_]/,"");let c=setup[a];if(null==c)throw"No such progress sequence "+JSON.stringify(a)+".";for(let d=0;dd?1:0};function choose(a,b,c){var d=Math.min;if(null==b||!1===b)return c?a:shuffle(a);b=Math.max(0,d(b,a.length));for(var e=d(b,a.length-b),f=e===b||void 0,g=[],h={},j=0;ja},lte:function(c,a){return c<=a},le:function(c,a){return c<=a},gte:function(c,a){return c>=a},ge:function(c,a){return c>=a},eqvar:function(c,a,b,d){return c==QBN.value(d)},neqvar:function(c,a,b,d){return c==QBN.value(d)},ltvar:function(c,a,b,d){return c==QBN.value(d)},gtvar:function(c,a,b,d){return c==QBN.value(d)},ltevar:function(c,a,b,d){return c==QBN.value(d)},gtevar:function(c,a,b,d){return c==QBN.value(d)},before:function(c,a,b){return QBN.progress(b,c)QBN.progress(b,a)},endingAt:function(c,a,b){return QBN.progress(b,c)<=QBN.progress(b,a)},startingAt:function(c,a,b){return QBN.progress(b,c)>=QBN.progress(b,a)}},operatorNames={eq:"to be",ne:"not to be",lt:"to be less than",le:"to be at most",gt:"to be greater than",ge:"to be at least"};QBN.functions={twinescript:{match:/^\s.*/,action:function(a){try{return Scripting.evalTwineScript(a[0])}catch(b){throw b.message+=" in: "+a[0],b}},description:function(a){return"\"\"\""+a[0]+"\"\"\""}},not:{match:/^not-(.+)/,action:function(a){return!QBN.requirementMet(a[1])},description:function(a){var b=QBN.description(a[1]);return null==b?b:"not "+b}},passage:{match:/^passage-(.+)/,action:function(a){return passage()===a[1]||passage()===a[1].replace(/_/g," ")},description:function(){return null}},tagged:{match:/^tagged-(.+)/,action:function(a){return tags().includes(a[1])},description:function(){return null}},visited:{match:/^visited-([^-]+)/,action:function(a){return 0c){var d="QBN.range: invalid range spec:";throw d+=" must have at least two values",d+=" (got "+JSON.stringify(c)+").",new Error(d)}for(var e,f,g,h,j=0;j>: "+(a.message||a))}setVar("_"+a+"_"+c.substring(1),!0),setVar("_"+c.substring(1)+"_range",a)}}),QBN.getProperty=function(a,b){var c,d=a.split("."),e=d.length,f=b||this;for(c=0;c>"),d&&f>"):e.wiki(d))}}}),Macro.add("requirements",{handler:function(){var a=$(this.output),b=toPassage(this.args[0]||QBN.current),c=this.args[1];if(c&&!Macro.has(c))return this.error("No such widget "+JSON.stringify(c)+".");for(var d,e=this.args[2]||"comma",f=QBN.requirements(b),g=0;g>"):a.wiki(d),e&&g>"):a.append(document.createTextNode(e)))}});function addTo(a,b){var c="string"==typeof b?b:b.title,d=!a[c];return d&&(a[c]=!0),d}function firstWord(a){var b=a.indexOf(" ");return a.substring(0,-1==b?a.length:b)}Macro.add("fillhand",{handler:function(){try{var a=this.args[0],b=this.args[1],c=this.args[2];if(!a){a=[];var d=firstWord(this.args.raw).substring(1);if(!setVar(d,a))return this.error("<>: failed to set hand \""+d+"\".")}var e,f={};for(e=0;e>: "+("object"==typeof a?a.message:a))}}}),Macro.add("card",{tags:["contents"],handler:function(){var a=$(this.output);if(getVar("_qbn_cover"))a.wiki(this.payload[0].contents.trim());else for(var b=1;bc.indexOf("card")&&0>c.indexOf("sticky-card")&&c.push("card"),a.push({title:JSON.stringify([passage(),b,a.length]),tags:c})}Macro.add("choices",{tags:["when","offer"],handler:function(){var a=this.args.raw,b=invalidName(a);if(b)return this.error(b);for(var c=[],d=0;d> content must be in sub-tags.");break;case"when":if(partialChoice(c))return this.error("This choice already has a \"when\" clause (section "+d+", "+e.contents.substring(0,30)+").");var f=QBN.parseTagsInto(e.contents.trim(),[]);beginChoice(c,a,f);break;case"offer":partialChoice(c)||beginChoice(c,a,[]),c[c.length-1].text=e.contents.trim(),""!==e.args[0]&&(c[e.args[0]]=c[c.length-1]);}}setVar(a,c)}}),QBN.progress=function(a,b){a=a.replace(/^[$_]/,"");let c=setup[a];if(null==c)throw"No such progress sequence "+JSON.stringify(a)+".";for(let d=0;dd?1:0};function choose(a,b,c){var d=Math.min;if(null==b||!1===b)return c?a:shuffle(a);b=Math.max(0,d(b,a.length));for(var e=d(b,a.length-b),f=e===b||void 0,g=[],h={},j=0;ja},lte:function(c,a){return c<=a},le:function(c,a){return c<=a},gte:function(c,a){return c>=a},ge:function(c,a){return c>=a},eqvar:function(c,a,b,d){return c==QBN.value(d)},neqvar:function(c,a,b,d){return c==QBN.value(d)},ltvar:function(c,a,b,d){return c==QBN.value(d)},gtvar:function(c,a,b,d){return c==QBN.value(d)},ltevar:function(c,a,b,d){return c==QBN.value(d)},gtevar:function(c,a,b,d){return c==QBN.value(d)},before:function(c,a,b){return QBN.progress(b,c)QBN.progress(b,a)},endingAt:function(c,a,b){return QBN.progress(b,c)<=QBN.progress(b,a)},startingAt:function(c,a,b){return QBN.progress(b,c)>=QBN.progress(b,a)}},operatorNames={eq:"to be",ne:"not to be",lt:"to be less than",le:"to be at most",gt:"to be greater than",ge:"to be at least"};QBN.functions={twinescript:{match:/^\s.*/,action:function(a){try{return Scripting.evalTwineScript(a[0])}catch(b){throw b.message+=" in: "+a[0],b}},description:function(a){return"\"\"\""+a[0]+"\"\"\""}},not:{match:/^not-(.+)/,action:function(a){return!QBN.requirementMet(a[1])},description:function(a){var b=QBN.description(a[1]);return null==b?b:"not "+b}},passage:{match:/^passage-(.+)/,action:function(a){return passage()===a[1]||passage()===a[1].replace(/_/g," ")},description:function(){return null}},tagged:{match:/^tagged-(.+)/,action:function(a){return tags().includes(a[1])},description:function(){return null}},visited:{match:/^visited-([^-]+)/,action:function(a){return 0c){var d="QBN.range: invalid range spec:";throw d+=" must have at least two values",d+=" (got "+JSON.stringify(c)+").",new Error(d)}for(var e,f,g,h,j=0;j>: "+(a.message||a))}setVar("_"+a+"_"+c.substring(1),!0),setVar("_"+c.substring(1)+"_range",a)}}),QBN.value=function(a){var b=State.variables,c=State.temporary;return null==c[a]?b[a]:c[a]},QBN.requirementMet=function(a){var b=null;for(var c in QBN.functions)if(QBN.functions.hasOwnProperty(c)){var d=QBN.functions[c],e=d.match.exec(a);if(e){b=d.action(e);break}}return null===b&&(b=QBN.value(a)),!!b},QBN.description=function(a){var b=null;for(var c in QBN.functions)if(QBN.functions.hasOwnProperty(c)){var d=QBN.functions[c],e=d.match.exec(a);if(e){b=d.description(e);break}}return null===b&&(b=a),b},QBN.tagsMatch=function(a,b){a=toPassage(a);let c=QBN.current;QBN.current=a.title;let d=QBN.tags(a);for(var e=0;e>"),d&&f>"):e.wiki(d))}}}),Macro.add("requirements",{handler:function(){var a=$(this.output),b=toPassage(this.args[0]||QBN.current),c=this.args[1];if(c&&!Macro.has(c))return this.error("No such widget "+JSON.stringify(c)+".");for(var d,e=this.args[2]||"comma",f=QBN.requirements(b),g=0;g>"):a.wiki(d),e&&g>"):a.append(document.createTextNode(e)))}});function addTo(a,b){var c="string"==typeof b?b:b.title,d=!a[c];return d&&(a[c]=!0),d}function firstWord(a){var b=a.indexOf(" ");return a.substring(0,-1==b?a.length:b)}Macro.add("fillhand",{handler:function(){try{var a=this.args[0],b=this.args[1],c=this.args[2];if(!a){a=[];var d=firstWord(this.args.raw).substring(1);if(!setVar(d,a))return this.error("<>: failed to set hand \""+d+"\".")}var e,f={};for(e=0;e>: "+("object"==typeof a?a.message:a))}}}),Macro.add("card",{tags:["contents"],handler:function(){var a=$(this.output);if(getVar("_qbn_cover"))a.wiki(this.payload[0].contents.trim());else for(var b=1;bc.indexOf("card")&&0>c.indexOf("sticky-card")&&c.push("card"),a.push({title:JSON.stringify([passage(),b,a.length]),tags:c})}Macro.add("choices",{tags:["when","offer"],handler:function(){var a=this.args.raw,b=invalidName(a);if(b)return this.error(b);for(var c=[],d=0;d> content must be in sub-tags.");break;case"when":if(partialChoice(c))return this.error("This choice already has a \"when\" clause (section "+d+", "+e.contents.substring(0,30)+").");var f=QBN.parseTagsInto(e.contents.trim(),[]);beginChoice(c,a,f);break;case"offer":partialChoice(c)||beginChoice(c,a,[]),c[c.length-1].text=e.contents.trim(),""!==e.args[0]&&(c[e.args[0]]=c[c.length-1]);}}setVar(a,c)}}),QBN.progress=function(a,b){a=a.replace(/^[$_]/,"");let c=setup[a];if(null==c)throw"No such progress sequence "+JSON.stringify(a)+".";for(let d=0;dd?1:0};function choose(a,b,c){var d=Math.min;if(null==b||!1===b)return c?a:shuffle(a);b=Math.max(0,d(b,a.length));for(var e=d(b,a.length-b),f=e===b||void 0,g=[],h={},j=0;ja},lte:function(c,a){return c<=a},le:function(c,a){return c<=a},gte:function(c,a){return c>=a},ge:function(c,a){return c>=a},eqvar:function(c,a,b,d){return c==QBN.value(d)},neqvar:function(c,a,b,d){return c==QBN.value(d)},ltvar:function(c,a,b,d){return c==QBN.value(d)},gtvar:function(c,a,b,d){return c==QBN.value(d)},ltevar:function(c,a,b,d){return c==QBN.value(d)},gtevar:function(c,a,b,d){return c==QBN.value(d)},before:function(c,a,b){return QBN.progress(b,c)QBN.progress(b,a)},endingAt:function(c,a,b){return QBN.progress(b,c)<=QBN.progress(b,a)},startingAt:function(c,a,b){return QBN.progress(b,c)>=QBN.progress(b,a)}},operatorNames={eq:"to be",ne:"not to be",lt:"to be less than",le:"to be at most",gt:"to be greater than",ge:"to be at least"};QBN.functions={twinescript:{match:/^\s.*/,action:function(a){try{return Scripting.evalTwineScript(a[0])}catch(b){throw b.message+=" in: "+a[0],b}},description:function(a){return"\"\"\""+a[0]+"\"\"\""}},not:{match:/^not-(.+)/,action:function(a){return!QBN.requirementMet(a[1])},description:function(a){var b=QBN.description(a[1]);return null==b?b:"not "+b}},passage:{match:/^passage-(.+)/,action:function(a){return passage()===a[1]||passage()===a[1].replace(/_/g," ")},description:function(){return null}},tagged:{match:/^tagged-(.+)/,action:function(a){return tags().includes(a[1])},description:function(){return null}},visited:{match:/^visited-([^-]+)/,action:function(a){return 0c){var d="QBN.range: invalid range spec:";throw d+=" must have at least two values",d+=" (got "+JSON.stringify(c)+").",new Error(d)}for(var e,f,g,h,j=0;j>: "+(a.message||a))}setVar("_"+a+"_"+c.substring(1),!0),setVar("_"+c.substring(1)+"_range",a)}}),QBN.getProperty=function(a,b){var c,d=a.split("."),e=d.length,f=b||this;for(c=0;c>"),d&&f>"):e.wiki(d))}}}),Macro.add("requirements",{handler:function(){var a=$(this.output),b=toPassage(this.args[0]||QBN.current),c=this.args[1];if(c&&!Macro.has(c))return this.error("No such widget "+JSON.stringify(c)+".");for(var d,e=this.args[2]||"comma",f=QBN.requirements(b),g=0;g>"):a.wiki(d),e&&g>"):a.append(document.createTextNode(e)))}});function addTo(a,b){var c="string"==typeof b?b:b.title,d=!a[c];return d&&(a[c]=!0),d}function firstWord(a){var b=a.indexOf(" ");return a.substring(0,-1==b?a.length:b)}Macro.add("fillhand",{handler:function(){try{var a=this.args[0],b=this.args[1],c=this.args[2];if(!a){a=[];var d=firstWord(this.args.raw).substring(1);if(!setVar(d,a))return this.error("<>: failed to set hand \""+d+"\".")}var e,f={};for(e=0;e>: "+("object"==typeof a?a.message:a))}}}),Macro.add("card",{tags:["contents"],handler:function(){var a=$(this.output);if(getVar("_qbn_cover"))a.wiki(this.payload[0].contents.trim());else for(var b=1;bc.indexOf("card")&&0>c.indexOf("sticky-card")&&c.push("card"),a.push({title:JSON.stringify([passage(),b,a.length]),tags:c})}Macro.add("choices",{tags:["when","offer"],handler:function(){var a=this.args.raw,b=invalidName(a);if(b)return this.error(b);for(var c=[],d=0;d> content must be in sub-tags.");break;case"when":if(partialChoice(c))return this.error("This choice already has a \"when\" clause (section "+d+", "+e.contents.substring(0,30)+").");var f=QBN.parseTagsInto(e.contents.trim(),[]);beginChoice(c,a,f);break;case"offer":partialChoice(c)||beginChoice(c,a,[]),c[c.length-1].text=e.contents.trim(),""!==e.args[0]&&(c[e.args[0]]=c[c.length-1]);}}setVar(a,c)}}),QBN.progress=function(a,b){a=a.replace(/^[$_]/,"");let c=setup[a];if(null==c)throw"No such progress sequence "+JSON.stringify(a)+".";for(let d=0;d + + + +Cards with Covers and Objects (dot notation) + + + + + + + + + + + + + + + + +
+
+
Your browser lacks required capabilities. Please upgrade it or switch to another to continue.
+
Loading…
+
+ + + + diff --git a/examples/covers-dot-notation.tw b/examples/covers-dot-notation.tw new file mode 100644 index 0000000..8330483 --- /dev/null +++ b/examples/covers-dot-notation.tw @@ -0,0 +1,50 @@ +::StoryTitle +Cards with Covers and Objects (dot notation) + +::StoryData +{"ifid": "A62F5683-9EF5-4ECE-A911-7EEDCFD6B046"} + +::StoryInit +<> + +::Start +Strength: $pc.strength ([[increase strength->Start][$pc.strength to $pc.strength + 1]]) + +----- + +You round a bend in the trail and come face to...chest with a four-legged monster that has horns like giant spaghetti servers. Or should that be antlers? Whatever they are, it shakes them angrily at you. + +<> + +::Back away slowly [sticky-card] +<><><>\ +Moving slowly so as not to incite its hunting instincts, you tiptoe backwards until you can no longer see the beast. + +<> +<> + +::Play dead [sticky-card] +<>\ +<>\ +<>\ +The better part of valor is discretion, in the which better part I have sav'd my life. +--Falstaff + +You curl into a ball on the ground and lie motionless. The beast snuffles you, but after a terrifying eternity, it wanders away, leaving you miraculously un-gored and un-trampled. + +<> +<> + +::Very Strong +/*QBN + sticky-card + req: $pc.strength gte 2 + also: $pc.strength gte 3 +*/\ +<>\ +<> (requires <>)\ +<>\ +You leap at the beast, screaming wildly, and grab its antlers. Or horns? Whatever. You wrench them to the side, driving it to its knees, and sit on its head. It attempts to get up, but doesn't have the leverage. When it seems properly cowed, you release it, and it saunters off into the brush, trying to pretend that it meant to do that all along. + +<> +<> diff --git a/examples/covers.html b/examples/covers.html index a6986d1..81239b3 100644 --- a/examples/covers.html +++ b/examples/covers.html @@ -180,7 +180,7 @@ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -State.initPRNG();var QBN={meta:{}};window.QBN=QBN,QBN.parseTagsInto=function(a,b){let c,d=new RegExp("("+["[a-zA-Z0-9-_]+(?:\\s+|$)","[a-zA-Z0-9_]+:[^\\n]*(?:\\n|$)\\s*","[^\\n]+(?:\\n|$)\\s*"].join(")|(")+")","g"),e=!1;for(;null!=(c=d.exec(a));)if(c[1]!==void 0)e?(b[b.length-1]+=c[1],!/\\\n/.test(c[1])&&(e=!1)):b.push(c[1].trim());else if(c[2]!==void 0){let a=c[2].replace(":","- "),d=a.replace("\\\n","");d.length!==a.length&&(e=!0),b.push(d)}else if(c[3]!==void 0){if(e)b[b.length-1]+=c[3];else throw new Error("Invalid metadata: "+JSON.stringify(c[3]));/(^|[^\\])\n/.test(c[3])&&(e=!1)}return b};const commentPattern=/\/\*\s*QBN\s([^*]*)\s\*\//g;Story.lookupWith(function(a){let b,c=a.tags.slice();for(;null!=(b=commentPattern.exec(a.text));){let a=b[1].trim();QBN.parseTagsInto(a,c)}return QBN.meta[a.title]=c,!1}),QBN.tags=function(a){return QBN.meta[a.title]||a.tags};var getVar=State.getVar||Wikifier.getValue,setVar=State.setVar||Wikifier.setValue;setVar("$QBN",{type:{},priority:{}}),$(document).on(":passagestart",function(a){QBN.current=a.passage.title,passageType(a.passage,!1)});function toArgument(a){if("object"==typeof a&&(a=a.title),"string"==typeof a)return JSON.stringify(a);throw new Error("Cards must be referred to by title (got "+typeof a+").")}function toPassage(a){if("object"==typeof a)if(a.link&&a.text)a=a.link;else return a;if("string"!=typeof a)throw new Error("Cards must be referred to by title (got "+typeof a+").");else{if(Story.has(a))return Story.get(a);let b=JSON.parse(a),c=b[0],d=b[1],e=b[2];if(passage()===c){let a=getVar(d);if(null!=a&&null!=a[e])return a[e]}throw new Error("No such passage or choice \""+a+"\".")}}QBN.toPassage=toPassage;function passageType(a,b){var c,d=QBN.tags(a);c=0<=d.indexOf("sticky-card")?"sticky-card":!!(0<=d.indexOf("card"))&&"card";var e=getVar("$QBN").type,f=e[a.title];return void 0===f&&(f=c),void 0!==b&&b!==f&&(null===b?e[a.title]=!1:!1===b?"card"===f&&(e[a.title]=!1):b===c?delete e[a.title]:e[a.title]=b),f}function shuffle(b){for(let a=b.length;0d?1:0};function choose(a,b,c){var d=Math.min;if(null==b||!1===b)return c?a:shuffle(a);b=Math.max(0,d(b,a.length));for(var e=d(b,a.length-b),f=e===b||void 0,g=[],h={},j=0;ja},lte:function(c,a){return c<=a},le:function(c,a){return c<=a},gte:function(c,a){return c>=a},ge:function(c,a){return c>=a},eqvar:function(c,a,b,d){return c==QBN.value(d)},neqvar:function(c,a,b,d){return c==QBN.value(d)},ltvar:function(c,a,b,d){return c==QBN.value(d)},gtvar:function(c,a,b,d){return c==QBN.value(d)},ltevar:function(c,a,b,d){return c==QBN.value(d)},gtevar:function(c,a,b,d){return c==QBN.value(d)},before:function(c,a,b){return QBN.progress(b,c)QBN.progress(b,a)},endingAt:function(c,a,b){return QBN.progress(b,c)<=QBN.progress(b,a)},startingAt:function(c,a,b){return QBN.progress(b,c)>=QBN.progress(b,a)}},operatorNames={eq:"to be",ne:"not to be",lt:"to be less than",le:"to be at most",gt:"to be greater than",ge:"to be at least"};QBN.functions={twinescript:{match:/^\s.*/,action:function(a){try{return Scripting.evalTwineScript(a[0])}catch(b){throw b.message+=" in: "+a[0],b}},description:function(a){return"\"\"\""+a[0]+"\"\"\""}},not:{match:/^not-(.+)/,action:function(a){return!QBN.requirementMet(a[1])},description:function(a){var b=QBN.description(a[1]);return null==b?b:"not "+b}},passage:{match:/^passage-(.+)/,action:function(a){return passage()===a[1]||passage()===a[1].replace(/_/g," ")},description:function(){return null}},tagged:{match:/^tagged-(.+)/,action:function(a){return tags().includes(a[1])},description:function(){return null}},visited:{match:/^visited-([^-]+)/,action:function(a){return 0c){var d="QBN.range: invalid range spec:";throw d+=" must have at least two values",d+=" (got "+JSON.stringify(c)+").",new Error(d)}for(var e,f,g,h,j=0;j>: "+(a.message||a))}setVar("_"+a+"_"+c.substring(1),!0),setVar("_"+c.substring(1)+"_range",a)}}),QBN.value=function(a){var b=State.variables,c=State.temporary;return null==c[a]?b[a]:c[a]},QBN.requirementMet=function(a){var b=null;for(var c in QBN.functions)if(QBN.functions.hasOwnProperty(c)){var d=QBN.functions[c],e=d.match.exec(a);if(e){b=d.action(e);break}}return null===b&&(b=QBN.value(a)),!!b},QBN.description=function(a){var b=null;for(var c in QBN.functions)if(QBN.functions.hasOwnProperty(c)){var d=QBN.functions[c],e=d.match.exec(a);if(e){b=d.description(e);break}}return null===b&&(b=a),b},QBN.tagsMatch=function(a,b){a=toPassage(a);let c=QBN.current;QBN.current=a.title;let d=QBN.tags(a);for(var e=0;e>"),d&&f>"):e.wiki(d))}}}),Macro.add("requirements",{handler:function(){var a=$(this.output),b=toPassage(this.args[0]||QBN.current),c=this.args[1];if(c&&!Macro.has(c))return this.error("No such widget "+JSON.stringify(c)+".");for(var d,e=this.args[2]||"comma",f=QBN.requirements(b),g=0;g>"):a.wiki(d),e&&g>"):a.append(document.createTextNode(e)))}});function addTo(a,b){var c="string"==typeof b?b:b.title,d=!a[c];return d&&(a[c]=!0),d}function firstWord(a){var b=a.indexOf(" ");return a.substring(0,-1==b?a.length:b)}Macro.add("fillhand",{handler:function(){try{var a=this.args[0],b=this.args[1],c=this.args[2];if(!a){a=[];var d=firstWord(this.args.raw).substring(1);if(!setVar(d,a))return this.error("<>: failed to set hand \""+d+"\".")}var e,f={};for(e=0;e>: "+("object"==typeof a?a.message:a))}}}),Macro.add("card",{tags:["contents"],handler:function(){var a=$(this.output);if(getVar("_qbn_cover"))a.wiki(this.payload[0].contents.trim());else for(var b=1;bc.indexOf("card")&&0>c.indexOf("sticky-card")&&c.push("card"),a.push({title:JSON.stringify([passage(),b,a.length]),tags:c})}Macro.add("choices",{tags:["when","offer"],handler:function(){var a=this.args.raw,b=invalidName(a);if(b)return this.error(b);for(var c=[],d=0;d> content must be in sub-tags.");break;case"when":if(partialChoice(c))return this.error("This choice already has a \"when\" clause (section "+d+", "+e.contents.substring(0,30)+").");var f=QBN.parseTagsInto(e.contents.trim(),[]);beginChoice(c,a,f);break;case"offer":partialChoice(c)||beginChoice(c,a,[]),c[c.length-1].text=e.contents.trim(),""!==e.args[0]&&(c[e.args[0]]=c[c.length-1]);}}setVar(a,c)}}),QBN.progress=function(a,b){a=a.replace(/^[$_]/,"");let c=setup[a];if(null==c)throw"No such progress sequence "+JSON.stringify(a)+".";for(let d=0;d<<set $strength to 1>>Strength: $strength ([[increase strength->Start][$strength to $strength + 1]]) +State.initPRNG();var QBN={meta:{}};window.QBN=QBN,QBN.parseTagsInto=function(a,b){let c,d=new RegExp("("+["[a-zA-Z0-9-_\\.]+(?:\\s+|$)","[a-zA-Z0-9_\\.]+:[^\\n]*(?:\\n|$)\\s*","[^\\n]+(?:\\n|$)\\s*"].join(")|(")+")","g"),e=!1;for(;null!=(c=d.exec(a));)if(c[1]!==void 0)e?(b[b.length-1]+=c[1],!/\\\n/.test(c[1])&&(e=!1)):b.push(c[1].trim());else if(c[2]!==void 0){let a=c[2].replace(":","- "),d=a.replace("\\\n","");d.length!==a.length&&(e=!0),b.push(d)}else if(c[3]!==void 0){if(e)b[b.length-1]+=c[3];else throw new Error("Invalid metadata: "+JSON.stringify(c[3]));/(^|[^\\])\n/.test(c[3])&&(e=!1)}return b};const commentPattern=/\/\*\s*QBN\s([^*]*)\s\*\//g;Story.lookupWith(function(a){let b,c=a.tags.slice();for(;null!=(b=commentPattern.exec(a.text));){let a=b[1].trim();QBN.parseTagsInto(a,c)}return QBN.meta[a.title]=c,!1}),QBN.tags=function(a){return QBN.meta[a.title]||a.tags};var getVar=State.getVar||Wikifier.getValue,setVar=State.setVar||Wikifier.setValue;setVar("$QBN",{type:{},priority:{}}),$(document).on(":passagestart",function(a){QBN.current=a.passage.title,passageType(a.passage,!1)});function toArgument(a){if("object"==typeof a&&(a=a.title),"string"==typeof a)return JSON.stringify(a);throw new Error("Cards must be referred to by title (got "+typeof a+").")}function toPassage(a){if("object"==typeof a)if(a.link&&a.text)a=a.link;else return a;if("string"!=typeof a)throw new Error("Cards must be referred to by title (got "+typeof a+").");else{if(Story.has(a))return Story.get(a);let b=JSON.parse(a),c=b[0],d=b[1],e=b[2];if(passage()===c){let a=getVar(d);if(null!=a&&null!=a[e])return a[e]}throw new Error("No such passage or choice \""+a+"\".")}}QBN.toPassage=toPassage;function passageType(a,b){var c,d=QBN.tags(a);c=0<=d.indexOf("sticky-card")?"sticky-card":!!(0<=d.indexOf("card"))&&"card";var e=getVar("$QBN").type,f=e[a.title];return void 0===f&&(f=c),void 0!==b&&b!==f&&(null===b?e[a.title]=!1:!1===b?"card"===f&&(e[a.title]=!1):b===c?delete e[a.title]:e[a.title]=b),f}function shuffle(b){for(let a=b.length;0d?1:0};function choose(a,b,c){var d=Math.min;if(null==b||!1===b)return c?a:shuffle(a);b=Math.max(0,d(b,a.length));for(var e=d(b,a.length-b),f=e===b||void 0,g=[],h={},j=0;ja},lte:function(c,a){return c<=a},le:function(c,a){return c<=a},gte:function(c,a){return c>=a},ge:function(c,a){return c>=a},eqvar:function(c,a,b,d){return c==QBN.value(d)},neqvar:function(c,a,b,d){return c==QBN.value(d)},ltvar:function(c,a,b,d){return c==QBN.value(d)},gtvar:function(c,a,b,d){return c==QBN.value(d)},ltevar:function(c,a,b,d){return c==QBN.value(d)},gtevar:function(c,a,b,d){return c==QBN.value(d)},before:function(c,a,b){return QBN.progress(b,c)QBN.progress(b,a)},endingAt:function(c,a,b){return QBN.progress(b,c)<=QBN.progress(b,a)},startingAt:function(c,a,b){return QBN.progress(b,c)>=QBN.progress(b,a)}},operatorNames={eq:"to be",ne:"not to be",lt:"to be less than",le:"to be at most",gt:"to be greater than",ge:"to be at least"};QBN.functions={twinescript:{match:/^\s.*/,action:function(a){try{return Scripting.evalTwineScript(a[0])}catch(b){throw b.message+=" in: "+a[0],b}},description:function(a){return"\"\"\""+a[0]+"\"\"\""}},not:{match:/^not-(.+)/,action:function(a){return!QBN.requirementMet(a[1])},description:function(a){var b=QBN.description(a[1]);return null==b?b:"not "+b}},passage:{match:/^passage-(.+)/,action:function(a){return passage()===a[1]||passage()===a[1].replace(/_/g," ")},description:function(){return null}},tagged:{match:/^tagged-(.+)/,action:function(a){return tags().includes(a[1])},description:function(){return null}},visited:{match:/^visited-([^-]+)/,action:function(a){return 0c){var d="QBN.range: invalid range spec:";throw d+=" must have at least two values",d+=" (got "+JSON.stringify(c)+").",new Error(d)}for(var e,f,g,h,j=0;j>: "+(a.message||a))}setVar("_"+a+"_"+c.substring(1),!0),setVar("_"+c.substring(1)+"_range",a)}}),QBN.getProperty=function(a,b){var c,d=a.split("."),e=d.length,f=b||this;for(c=0;c>"),d&&f>"):e.wiki(d))}}}),Macro.add("requirements",{handler:function(){var a=$(this.output),b=toPassage(this.args[0]||QBN.current),c=this.args[1];if(c&&!Macro.has(c))return this.error("No such widget "+JSON.stringify(c)+".");for(var d,e=this.args[2]||"comma",f=QBN.requirements(b),g=0;g>"):a.wiki(d),e&&g>"):a.append(document.createTextNode(e)))}});function addTo(a,b){var c="string"==typeof b?b:b.title,d=!a[c];return d&&(a[c]=!0),d}function firstWord(a){var b=a.indexOf(" ");return a.substring(0,-1==b?a.length:b)}Macro.add("fillhand",{handler:function(){try{var a=this.args[0],b=this.args[1],c=this.args[2];if(!a){a=[];var d=firstWord(this.args.raw).substring(1);if(!setVar(d,a))return this.error("<>: failed to set hand \""+d+"\".")}var e,f={};for(e=0;e>: "+("object"==typeof a?a.message:a))}}}),Macro.add("card",{tags:["contents"],handler:function(){var a=$(this.output);if(getVar("_qbn_cover"))a.wiki(this.payload[0].contents.trim());else for(var b=1;bc.indexOf("card")&&0>c.indexOf("sticky-card")&&c.push("card"),a.push({title:JSON.stringify([passage(),b,a.length]),tags:c})}Macro.add("choices",{tags:["when","offer"],handler:function(){var a=this.args.raw,b=invalidName(a);if(b)return this.error(b);for(var c=[],d=0;d> content must be in sub-tags.");break;case"when":if(partialChoice(c))return this.error("This choice already has a \"when\" clause (section "+d+", "+e.contents.substring(0,30)+").");var f=QBN.parseTagsInto(e.contents.trim(),[]);beginChoice(c,a,f);break;case"offer":partialChoice(c)||beginChoice(c,a,[]),c[c.length-1].text=e.contents.trim(),""!==e.args[0]&&(c[e.args[0]]=c[c.length-1]);}}setVar(a,c)}}),QBN.progress=function(a,b){a=a.replace(/^[$_]/,"");let c=setup[a];if(null==c)throw"No such progress sequence "+JSON.stringify(a)+".";for(let d=0;d<<set $strength to 1>>Strength: $strength ([[increase strength->Start][$strength to $strength + 1]]) ----- diff --git a/examples/dice-rolls.html b/examples/dice-rolls.html index e22c552..1983f6f 100644 --- a/examples/dice-rolls.html +++ b/examples/dice-rolls.html @@ -180,7 +180,7 @@ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -State.initPRNG();var QBN={meta:{}};window.QBN=QBN,QBN.parseTagsInto=function(a,b){let c,d=new RegExp("("+["[a-zA-Z0-9-_]+(?:\\s+|$)","[a-zA-Z0-9_]+:[^\\n]*(?:\\n|$)\\s*","[^\\n]+(?:\\n|$)\\s*"].join(")|(")+")","g"),e=!1;for(;null!=(c=d.exec(a));)if(c[1]!==void 0)e?(b[b.length-1]+=c[1],!/\\\n/.test(c[1])&&(e=!1)):b.push(c[1].trim());else if(c[2]!==void 0){let a=c[2].replace(":","- "),d=a.replace("\\\n","");d.length!==a.length&&(e=!0),b.push(d)}else if(c[3]!==void 0){if(e)b[b.length-1]+=c[3];else throw new Error("Invalid metadata: "+JSON.stringify(c[3]));/(^|[^\\])\n/.test(c[3])&&(e=!1)}return b};const commentPattern=/\/\*\s*QBN\s([^*]*)\s\*\//g;Story.lookupWith(function(a){let b,c=a.tags.slice();for(;null!=(b=commentPattern.exec(a.text));){let a=b[1].trim();QBN.parseTagsInto(a,c)}return QBN.meta[a.title]=c,!1}),QBN.tags=function(a){return QBN.meta[a.title]||a.tags};var getVar=State.getVar||Wikifier.getValue,setVar=State.setVar||Wikifier.setValue;setVar("$QBN",{type:{},priority:{}}),$(document).on(":passagestart",function(a){QBN.current=a.passage.title,passageType(a.passage,!1)});function toArgument(a){if("object"==typeof a&&(a=a.title),"string"==typeof a)return JSON.stringify(a);throw new Error("Cards must be referred to by title (got "+typeof a+").")}function toPassage(a){if("object"==typeof a)if(a.link&&a.text)a=a.link;else return a;if("string"!=typeof a)throw new Error("Cards must be referred to by title (got "+typeof a+").");else{if(Story.has(a))return Story.get(a);let b=JSON.parse(a),c=b[0],d=b[1],e=b[2];if(passage()===c){let a=getVar(d);if(null!=a&&null!=a[e])return a[e]}throw new Error("No such passage or choice \""+a+"\".")}}QBN.toPassage=toPassage;function passageType(a,b){var c,d=QBN.tags(a);c=0<=d.indexOf("sticky-card")?"sticky-card":!!(0<=d.indexOf("card"))&&"card";var e=getVar("$QBN").type,f=e[a.title];return void 0===f&&(f=c),void 0!==b&&b!==f&&(null===b?e[a.title]=!1:!1===b?"card"===f&&(e[a.title]=!1):b===c?delete e[a.title]:e[a.title]=b),f}function shuffle(b){for(let a=b.length;0d?1:0};function choose(a,b,c){var d=Math.min;if(null==b||!1===b)return c?a:shuffle(a);b=Math.max(0,d(b,a.length));for(var e=d(b,a.length-b),f=e===b||void 0,g=[],h={},j=0;ja},lte:function(c,a){return c<=a},le:function(c,a){return c<=a},gte:function(c,a){return c>=a},ge:function(c,a){return c>=a},eqvar:function(c,a,b,d){return c==QBN.value(d)},neqvar:function(c,a,b,d){return c==QBN.value(d)},ltvar:function(c,a,b,d){return c==QBN.value(d)},gtvar:function(c,a,b,d){return c==QBN.value(d)},ltevar:function(c,a,b,d){return c==QBN.value(d)},gtevar:function(c,a,b,d){return c==QBN.value(d)},before:function(c,a,b){return QBN.progress(b,c)QBN.progress(b,a)},endingAt:function(c,a,b){return QBN.progress(b,c)<=QBN.progress(b,a)},startingAt:function(c,a,b){return QBN.progress(b,c)>=QBN.progress(b,a)}},operatorNames={eq:"to be",ne:"not to be",lt:"to be less than",le:"to be at most",gt:"to be greater than",ge:"to be at least"};QBN.functions={twinescript:{match:/^\s.*/,action:function(a){try{return Scripting.evalTwineScript(a[0])}catch(b){throw b.message+=" in: "+a[0],b}},description:function(a){return"\"\"\""+a[0]+"\"\"\""}},not:{match:/^not-(.+)/,action:function(a){return!QBN.requirementMet(a[1])},description:function(a){var b=QBN.description(a[1]);return null==b?b:"not "+b}},passage:{match:/^passage-(.+)/,action:function(a){return passage()===a[1]||passage()===a[1].replace(/_/g," ")},description:function(){return null}},tagged:{match:/^tagged-(.+)/,action:function(a){return tags().includes(a[1])},description:function(){return null}},visited:{match:/^visited-([^-]+)/,action:function(a){return 0c){var d="QBN.range: invalid range spec:";throw d+=" must have at least two values",d+=" (got "+JSON.stringify(c)+").",new Error(d)}for(var e,f,g,h,j=0;j>: "+(a.message||a))}setVar("_"+a+"_"+c.substring(1),!0),setVar("_"+c.substring(1)+"_range",a)}}),QBN.value=function(a){var b=State.variables,c=State.temporary;return null==c[a]?b[a]:c[a]},QBN.requirementMet=function(a){var b=null;for(var c in QBN.functions)if(QBN.functions.hasOwnProperty(c)){var d=QBN.functions[c],e=d.match.exec(a);if(e){b=d.action(e);break}}return null===b&&(b=QBN.value(a)),!!b},QBN.description=function(a){var b=null;for(var c in QBN.functions)if(QBN.functions.hasOwnProperty(c)){var d=QBN.functions[c],e=d.match.exec(a);if(e){b=d.description(e);break}}return null===b&&(b=a),b},QBN.tagsMatch=function(a,b){a=toPassage(a);let c=QBN.current;QBN.current=a.title;let d=QBN.tags(a);for(var e=0;e>"),d&&f>"):e.wiki(d))}}}),Macro.add("requirements",{handler:function(){var a=$(this.output),b=toPassage(this.args[0]||QBN.current),c=this.args[1];if(c&&!Macro.has(c))return this.error("No such widget "+JSON.stringify(c)+".");for(var d,e=this.args[2]||"comma",f=QBN.requirements(b),g=0;g>"):a.wiki(d),e&&g>"):a.append(document.createTextNode(e)))}});function addTo(a,b){var c="string"==typeof b?b:b.title,d=!a[c];return d&&(a[c]=!0),d}function firstWord(a){var b=a.indexOf(" ");return a.substring(0,-1==b?a.length:b)}Macro.add("fillhand",{handler:function(){try{var a=this.args[0],b=this.args[1],c=this.args[2];if(!a){a=[];var d=firstWord(this.args.raw).substring(1);if(!setVar(d,a))return this.error("<>: failed to set hand \""+d+"\".")}var e,f={};for(e=0;e>: "+("object"==typeof a?a.message:a))}}}),Macro.add("card",{tags:["contents"],handler:function(){var a=$(this.output);if(getVar("_qbn_cover"))a.wiki(this.payload[0].contents.trim());else for(var b=1;bc.indexOf("card")&&0>c.indexOf("sticky-card")&&c.push("card"),a.push({title:JSON.stringify([passage(),b,a.length]),tags:c})}Macro.add("choices",{tags:["when","offer"],handler:function(){var a=this.args.raw,b=invalidName(a);if(b)return this.error(b);for(var c=[],d=0;d> content must be in sub-tags.");break;case"when":if(partialChoice(c))return this.error("This choice already has a \"when\" clause (section "+d+", "+e.contents.substring(0,30)+").");var f=QBN.parseTagsInto(e.contents.trim(),[]);beginChoice(c,a,f);break;case"offer":partialChoice(c)||beginChoice(c,a,[]),c[c.length-1].text=e.contents.trim(),""!==e.args[0]&&(c[e.args[0]]=c[c.length-1]);}}setVar(a,c)}}),QBN.progress=function(a,b){a=a.replace(/^[$_]/,"");let c=setup[a];if(null==c)throw"No such progress sequence "+JSON.stringify(a)+".";for(let d=0;d/% Just put the player stats in plain variables? %/ +State.initPRNG();var QBN={meta:{}};window.QBN=QBN,QBN.parseTagsInto=function(a,b){let c,d=new RegExp("("+["[a-zA-Z0-9-_\\.]+(?:\\s+|$)","[a-zA-Z0-9_\\.]+:[^\\n]*(?:\\n|$)\\s*","[^\\n]+(?:\\n|$)\\s*"].join(")|(")+")","g"),e=!1;for(;null!=(c=d.exec(a));)if(c[1]!==void 0)e?(b[b.length-1]+=c[1],!/\\\n/.test(c[1])&&(e=!1)):b.push(c[1].trim());else if(c[2]!==void 0){let a=c[2].replace(":","- "),d=a.replace("\\\n","");d.length!==a.length&&(e=!0),b.push(d)}else if(c[3]!==void 0){if(e)b[b.length-1]+=c[3];else throw new Error("Invalid metadata: "+JSON.stringify(c[3]));/(^|[^\\])\n/.test(c[3])&&(e=!1)}return b};const commentPattern=/\/\*\s*QBN\s([^*]*)\s\*\//g;Story.lookupWith(function(a){let b,c=a.tags.slice();for(;null!=(b=commentPattern.exec(a.text));){let a=b[1].trim();QBN.parseTagsInto(a,c)}return QBN.meta[a.title]=c,!1}),QBN.tags=function(a){return QBN.meta[a.title]||a.tags};var getVar=State.getVar||Wikifier.getValue,setVar=State.setVar||Wikifier.setValue;setVar("$QBN",{type:{},priority:{}}),$(document).on(":passagestart",function(a){QBN.current=a.passage.title,passageType(a.passage,!1)});function toArgument(a){if("object"==typeof a&&(a=a.title),"string"==typeof a)return JSON.stringify(a);throw new Error("Cards must be referred to by title (got "+typeof a+").")}function toPassage(a){if("object"==typeof a)if(a.link&&a.text)a=a.link;else return a;if("string"!=typeof a)throw new Error("Cards must be referred to by title (got "+typeof a+").");else{if(Story.has(a))return Story.get(a);let b=JSON.parse(a),c=b[0],d=b[1],e=b[2];if(passage()===c){let a=getVar(d);if(null!=a&&null!=a[e])return a[e]}throw new Error("No such passage or choice \""+a+"\".")}}QBN.toPassage=toPassage;function passageType(a,b){var c,d=QBN.tags(a);c=0<=d.indexOf("sticky-card")?"sticky-card":!!(0<=d.indexOf("card"))&&"card";var e=getVar("$QBN").type,f=e[a.title];return void 0===f&&(f=c),void 0!==b&&b!==f&&(null===b?e[a.title]=!1:!1===b?"card"===f&&(e[a.title]=!1):b===c?delete e[a.title]:e[a.title]=b),f}function shuffle(b){for(let a=b.length;0d?1:0};function choose(a,b,c){var d=Math.min;if(null==b||!1===b)return c?a:shuffle(a);b=Math.max(0,d(b,a.length));for(var e=d(b,a.length-b),f=e===b||void 0,g=[],h={},j=0;ja},lte:function(c,a){return c<=a},le:function(c,a){return c<=a},gte:function(c,a){return c>=a},ge:function(c,a){return c>=a},eqvar:function(c,a,b,d){return c==QBN.value(d)},neqvar:function(c,a,b,d){return c==QBN.value(d)},ltvar:function(c,a,b,d){return c==QBN.value(d)},gtvar:function(c,a,b,d){return c==QBN.value(d)},ltevar:function(c,a,b,d){return c==QBN.value(d)},gtevar:function(c,a,b,d){return c==QBN.value(d)},before:function(c,a,b){return QBN.progress(b,c)QBN.progress(b,a)},endingAt:function(c,a,b){return QBN.progress(b,c)<=QBN.progress(b,a)},startingAt:function(c,a,b){return QBN.progress(b,c)>=QBN.progress(b,a)}},operatorNames={eq:"to be",ne:"not to be",lt:"to be less than",le:"to be at most",gt:"to be greater than",ge:"to be at least"};QBN.functions={twinescript:{match:/^\s.*/,action:function(a){try{return Scripting.evalTwineScript(a[0])}catch(b){throw b.message+=" in: "+a[0],b}},description:function(a){return"\"\"\""+a[0]+"\"\"\""}},not:{match:/^not-(.+)/,action:function(a){return!QBN.requirementMet(a[1])},description:function(a){var b=QBN.description(a[1]);return null==b?b:"not "+b}},passage:{match:/^passage-(.+)/,action:function(a){return passage()===a[1]||passage()===a[1].replace(/_/g," ")},description:function(){return null}},tagged:{match:/^tagged-(.+)/,action:function(a){return tags().includes(a[1])},description:function(){return null}},visited:{match:/^visited-([^-]+)/,action:function(a){return 0c){var d="QBN.range: invalid range spec:";throw d+=" must have at least two values",d+=" (got "+JSON.stringify(c)+").",new Error(d)}for(var e,f,g,h,j=0;j>: "+(a.message||a))}setVar("_"+a+"_"+c.substring(1),!0),setVar("_"+c.substring(1)+"_range",a)}}),QBN.getProperty=function(a,b){var c,d=a.split("."),e=d.length,f=b||this;for(c=0;c>"),d&&f>"):e.wiki(d))}}}),Macro.add("requirements",{handler:function(){var a=$(this.output),b=toPassage(this.args[0]||QBN.current),c=this.args[1];if(c&&!Macro.has(c))return this.error("No such widget "+JSON.stringify(c)+".");for(var d,e=this.args[2]||"comma",f=QBN.requirements(b),g=0;g>"):a.wiki(d),e&&g>"):a.append(document.createTextNode(e)))}});function addTo(a,b){var c="string"==typeof b?b:b.title,d=!a[c];return d&&(a[c]=!0),d}function firstWord(a){var b=a.indexOf(" ");return a.substring(0,-1==b?a.length:b)}Macro.add("fillhand",{handler:function(){try{var a=this.args[0],b=this.args[1],c=this.args[2];if(!a){a=[];var d=firstWord(this.args.raw).substring(1);if(!setVar(d,a))return this.error("<>: failed to set hand \""+d+"\".")}var e,f={};for(e=0;e>: "+("object"==typeof a?a.message:a))}}}),Macro.add("card",{tags:["contents"],handler:function(){var a=$(this.output);if(getVar("_qbn_cover"))a.wiki(this.payload[0].contents.trim());else for(var b=1;bc.indexOf("card")&&0>c.indexOf("sticky-card")&&c.push("card"),a.push({title:JSON.stringify([passage(),b,a.length]),tags:c})}Macro.add("choices",{tags:["when","offer"],handler:function(){var a=this.args.raw,b=invalidName(a);if(b)return this.error(b);for(var c=[],d=0;d> content must be in sub-tags.");break;case"when":if(partialChoice(c))return this.error("This choice already has a \"when\" clause (section "+d+", "+e.contents.substring(0,30)+").");var f=QBN.parseTagsInto(e.contents.trim(),[]);beginChoice(c,a,f);break;case"offer":partialChoice(c)||beginChoice(c,a,[]),c[c.length-1].text=e.contents.trim(),""!==e.args[0]&&(c[e.args[0]]=c[c.length-1]);}}setVar(a,c)}}),QBN.progress=function(a,b){a=a.replace(/^[$_]/,"");let c=setup[a];if(null==c)throw"No such progress sequence "+JSON.stringify(a)+".";for(let d=0;d/% Just put the player stats in plain variables? %/ <<set $Stat to 1>> /% Declare a countdown clock and initialize it to the first value (an empty string) %/ diff --git a/examples/dot-notation.html b/examples/dot-notation.html new file mode 100644 index 0000000..ba170b0 --- /dev/null +++ b/examples/dot-notation.html @@ -0,0 +1,288 @@ + + + + +Objects (dot notation) + + + + + + + + + + + + + + + + +
+
+
Your browser lacks required capabilities. Please upgrade it or switch to another to continue.
+
Loading…
+
+ + + + diff --git a/examples/dot-notation.tw b/examples/dot-notation.tw new file mode 100644 index 0000000..9b776df --- /dev/null +++ b/examples/dot-notation.tw @@ -0,0 +1,44 @@ +:: StoryTitle +Objects (dot notation) + + +:: StoryData +{ + "ifid": "2F0032CE-E4AF-4CDE-89BC-0BC33A71ECE7" +} + +::StoryInit +<> +<> + +::Start +Unused character points: $character_points +Strength: $pc.strength ([[Increase strength->Start][$pc.strength++; ; $character_points--]]) +Stealth: $pc.stealth ([[Increase stealth->Start][$pc.stealth++; $character_points--]]) + +----- + +You round a bend in the trail and come face to...chest with a four-legged monster that has horns like giant spaghetti servers. Or should that be antlers? Whatever they are, it shakes them angrily at you. + +<>\ + +::Back away slowly [sticky-card] +Moving slowly so as not to incite its hunting instincts, you tiptoe backwards until you can no longer see the beast. + +<> + +::Play dead and hope it doesn't eat you [sticky-card] +The better part of valor is discretion, in the which better part I have sav'd my life. +--Falstaff + +You curl into a ball on the ground and lie motionless. The beast snuffles you, but after a terrifying eternity, it wanders away, leaving you miraculously un-gored and un-trampled. + +<> + +::Use brute force [sticky-card req-pc.strength-gte-2] + +You leap at the beast, screaming wildly, and grab its antlers. Or horns? Whatever. You wrench them to the side, driving it to its knees, and sit on its head. It attempts to get up, but doesn't have the leverage. When it seems properly cowed, you release it, and it saunters off into the brush, trying to pretend that it meant to do that all along. + +::Sneak past the beast [sticky-card req-pc.stealth-gte-2] + +You back away from the beast until it is out of sight. Looking to your left, you see a barely noticeable gap in the scrub. You crouch down and inch your way through the bushes back towards the beast. It fails to notice as you creep past it. Once you round a further bend, you emerge from the bush and congratulate yourself on your stealthy escape. diff --git a/examples/localvore.html b/examples/localvore.html index 265e6f9..4358a63 100644 --- a/examples/localvore.html +++ b/examples/localvore.html @@ -180,7 +180,7 @@ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -State.initPRNG();var QBN={meta:{}};window.QBN=QBN,QBN.parseTagsInto=function(a,b){let c,d=new RegExp("("+["[a-zA-Z0-9-_]+(?:\\s+|$)","[a-zA-Z0-9_]+:[^\\n]*(?:\\n|$)\\s*","[^\\n]+(?:\\n|$)\\s*"].join(")|(")+")","g"),e=!1;for(;null!=(c=d.exec(a));)if(c[1]!==void 0)e?(b[b.length-1]+=c[1],!/\\\n/.test(c[1])&&(e=!1)):b.push(c[1].trim());else if(c[2]!==void 0){let a=c[2].replace(":","- "),d=a.replace("\\\n","");d.length!==a.length&&(e=!0),b.push(d)}else if(c[3]!==void 0){if(e)b[b.length-1]+=c[3];else throw new Error("Invalid metadata: "+JSON.stringify(c[3]));/(^|[^\\])\n/.test(c[3])&&(e=!1)}return b};const commentPattern=/\/\*\s*QBN\s([^*]*)\s\*\//g;Story.lookupWith(function(a){let b,c=a.tags.slice();for(;null!=(b=commentPattern.exec(a.text));){let a=b[1].trim();QBN.parseTagsInto(a,c)}return QBN.meta[a.title]=c,!1}),QBN.tags=function(a){return QBN.meta[a.title]||a.tags};var getVar=State.getVar||Wikifier.getValue,setVar=State.setVar||Wikifier.setValue;setVar("$QBN",{type:{},priority:{}}),$(document).on(":passagestart",function(a){QBN.current=a.passage.title,passageType(a.passage,!1)});function toArgument(a){if("object"==typeof a&&(a=a.title),"string"==typeof a)return JSON.stringify(a);throw new Error("Cards must be referred to by title (got "+typeof a+").")}function toPassage(a){if("object"==typeof a)if(a.link&&a.text)a=a.link;else return a;if("string"!=typeof a)throw new Error("Cards must be referred to by title (got "+typeof a+").");else{if(Story.has(a))return Story.get(a);let b=JSON.parse(a),c=b[0],d=b[1],e=b[2];if(passage()===c){let a=getVar(d);if(null!=a&&null!=a[e])return a[e]}throw new Error("No such passage or choice \""+a+"\".")}}QBN.toPassage=toPassage;function passageType(a,b){var c,d=QBN.tags(a);c=0<=d.indexOf("sticky-card")?"sticky-card":!!(0<=d.indexOf("card"))&&"card";var e=getVar("$QBN").type,f=e[a.title];return void 0===f&&(f=c),void 0!==b&&b!==f&&(null===b?e[a.title]=!1:!1===b?"card"===f&&(e[a.title]=!1):b===c?delete e[a.title]:e[a.title]=b),f}function shuffle(b){for(let a=b.length;0d?1:0};function choose(a,b,c){var d=Math.min;if(null==b||!1===b)return c?a:shuffle(a);b=Math.max(0,d(b,a.length));for(var e=d(b,a.length-b),f=e===b||void 0,g=[],h={},j=0;ja},lte:function(c,a){return c<=a},le:function(c,a){return c<=a},gte:function(c,a){return c>=a},ge:function(c,a){return c>=a},eqvar:function(c,a,b,d){return c==QBN.value(d)},neqvar:function(c,a,b,d){return c==QBN.value(d)},ltvar:function(c,a,b,d){return c==QBN.value(d)},gtvar:function(c,a,b,d){return c==QBN.value(d)},ltevar:function(c,a,b,d){return c==QBN.value(d)},gtevar:function(c,a,b,d){return c==QBN.value(d)},before:function(c,a,b){return QBN.progress(b,c)QBN.progress(b,a)},endingAt:function(c,a,b){return QBN.progress(b,c)<=QBN.progress(b,a)},startingAt:function(c,a,b){return QBN.progress(b,c)>=QBN.progress(b,a)}},operatorNames={eq:"to be",ne:"not to be",lt:"to be less than",le:"to be at most",gt:"to be greater than",ge:"to be at least"};QBN.functions={twinescript:{match:/^\s.*/,action:function(a){try{return Scripting.evalTwineScript(a[0])}catch(b){throw b.message+=" in: "+a[0],b}},description:function(a){return"\"\"\""+a[0]+"\"\"\""}},not:{match:/^not-(.+)/,action:function(a){return!QBN.requirementMet(a[1])},description:function(a){var b=QBN.description(a[1]);return null==b?b:"not "+b}},passage:{match:/^passage-(.+)/,action:function(a){return passage()===a[1]||passage()===a[1].replace(/_/g," ")},description:function(){return null}},tagged:{match:/^tagged-(.+)/,action:function(a){return tags().includes(a[1])},description:function(){return null}},visited:{match:/^visited-([^-]+)/,action:function(a){return 0c){var d="QBN.range: invalid range spec:";throw d+=" must have at least two values",d+=" (got "+JSON.stringify(c)+").",new Error(d)}for(var e,f,g,h,j=0;j>: "+(a.message||a))}setVar("_"+a+"_"+c.substring(1),!0),setVar("_"+c.substring(1)+"_range",a)}}),QBN.value=function(a){var b=State.variables,c=State.temporary;return null==c[a]?b[a]:c[a]},QBN.requirementMet=function(a){var b=null;for(var c in QBN.functions)if(QBN.functions.hasOwnProperty(c)){var d=QBN.functions[c],e=d.match.exec(a);if(e){b=d.action(e);break}}return null===b&&(b=QBN.value(a)),!!b},QBN.description=function(a){var b=null;for(var c in QBN.functions)if(QBN.functions.hasOwnProperty(c)){var d=QBN.functions[c],e=d.match.exec(a);if(e){b=d.description(e);break}}return null===b&&(b=a),b},QBN.tagsMatch=function(a,b){a=toPassage(a);let c=QBN.current;QBN.current=a.title;let d=QBN.tags(a);for(var e=0;e>"),d&&f>"):e.wiki(d))}}}),Macro.add("requirements",{handler:function(){var a=$(this.output),b=toPassage(this.args[0]||QBN.current),c=this.args[1];if(c&&!Macro.has(c))return this.error("No such widget "+JSON.stringify(c)+".");for(var d,e=this.args[2]||"comma",f=QBN.requirements(b),g=0;g>"):a.wiki(d),e&&g>"):a.append(document.createTextNode(e)))}});function addTo(a,b){var c="string"==typeof b?b:b.title,d=!a[c];return d&&(a[c]=!0),d}function firstWord(a){var b=a.indexOf(" ");return a.substring(0,-1==b?a.length:b)}Macro.add("fillhand",{handler:function(){try{var a=this.args[0],b=this.args[1],c=this.args[2];if(!a){a=[];var d=firstWord(this.args.raw).substring(1);if(!setVar(d,a))return this.error("<>: failed to set hand \""+d+"\".")}var e,f={};for(e=0;e>: "+("object"==typeof a?a.message:a))}}}),Macro.add("card",{tags:["contents"],handler:function(){var a=$(this.output);if(getVar("_qbn_cover"))a.wiki(this.payload[0].contents.trim());else for(var b=1;bc.indexOf("card")&&0>c.indexOf("sticky-card")&&c.push("card"),a.push({title:JSON.stringify([passage(),b,a.length]),tags:c})}Macro.add("choices",{tags:["when","offer"],handler:function(){var a=this.args.raw,b=invalidName(a);if(b)return this.error(b);for(var c=[],d=0;d> content must be in sub-tags.");break;case"when":if(partialChoice(c))return this.error("This choice already has a \"when\" clause (section "+d+", "+e.contents.substring(0,30)+").");var f=QBN.parseTagsInto(e.contents.trim(),[]);beginChoice(c,a,f);break;case"offer":partialChoice(c)||beginChoice(c,a,[]),c[c.length-1].text=e.contents.trim(),""!==e.args[0]&&(c[e.args[0]]=c[c.length-1]);}}setVar(a,c)}}),QBN.progress=function(a,b){a=a.replace(/^[$_]/,"");let c=setup[a];if(null==c)throw"No such progress sequence "+JSON.stringify(a)+".";for(let d=0;d<<set $month to 1>> +State.initPRNG();var QBN={meta:{}};window.QBN=QBN,QBN.parseTagsInto=function(a,b){let c,d=new RegExp("("+["[a-zA-Z0-9-_\\.]+(?:\\s+|$)","[a-zA-Z0-9_\\.]+:[^\\n]*(?:\\n|$)\\s*","[^\\n]+(?:\\n|$)\\s*"].join(")|(")+")","g"),e=!1;for(;null!=(c=d.exec(a));)if(c[1]!==void 0)e?(b[b.length-1]+=c[1],!/\\\n/.test(c[1])&&(e=!1)):b.push(c[1].trim());else if(c[2]!==void 0){let a=c[2].replace(":","- "),d=a.replace("\\\n","");d.length!==a.length&&(e=!0),b.push(d)}else if(c[3]!==void 0){if(e)b[b.length-1]+=c[3];else throw new Error("Invalid metadata: "+JSON.stringify(c[3]));/(^|[^\\])\n/.test(c[3])&&(e=!1)}return b};const commentPattern=/\/\*\s*QBN\s([^*]*)\s\*\//g;Story.lookupWith(function(a){let b,c=a.tags.slice();for(;null!=(b=commentPattern.exec(a.text));){let a=b[1].trim();QBN.parseTagsInto(a,c)}return QBN.meta[a.title]=c,!1}),QBN.tags=function(a){return QBN.meta[a.title]||a.tags};var getVar=State.getVar||Wikifier.getValue,setVar=State.setVar||Wikifier.setValue;setVar("$QBN",{type:{},priority:{}}),$(document).on(":passagestart",function(a){QBN.current=a.passage.title,passageType(a.passage,!1)});function toArgument(a){if("object"==typeof a&&(a=a.title),"string"==typeof a)return JSON.stringify(a);throw new Error("Cards must be referred to by title (got "+typeof a+").")}function toPassage(a){if("object"==typeof a)if(a.link&&a.text)a=a.link;else return a;if("string"!=typeof a)throw new Error("Cards must be referred to by title (got "+typeof a+").");else{if(Story.has(a))return Story.get(a);let b=JSON.parse(a),c=b[0],d=b[1],e=b[2];if(passage()===c){let a=getVar(d);if(null!=a&&null!=a[e])return a[e]}throw new Error("No such passage or choice \""+a+"\".")}}QBN.toPassage=toPassage;function passageType(a,b){var c,d=QBN.tags(a);c=0<=d.indexOf("sticky-card")?"sticky-card":!!(0<=d.indexOf("card"))&&"card";var e=getVar("$QBN").type,f=e[a.title];return void 0===f&&(f=c),void 0!==b&&b!==f&&(null===b?e[a.title]=!1:!1===b?"card"===f&&(e[a.title]=!1):b===c?delete e[a.title]:e[a.title]=b),f}function shuffle(b){for(let a=b.length;0d?1:0};function choose(a,b,c){var d=Math.min;if(null==b||!1===b)return c?a:shuffle(a);b=Math.max(0,d(b,a.length));for(var e=d(b,a.length-b),f=e===b||void 0,g=[],h={},j=0;ja},lte:function(c,a){return c<=a},le:function(c,a){return c<=a},gte:function(c,a){return c>=a},ge:function(c,a){return c>=a},eqvar:function(c,a,b,d){return c==QBN.value(d)},neqvar:function(c,a,b,d){return c==QBN.value(d)},ltvar:function(c,a,b,d){return c==QBN.value(d)},gtvar:function(c,a,b,d){return c==QBN.value(d)},ltevar:function(c,a,b,d){return c==QBN.value(d)},gtevar:function(c,a,b,d){return c==QBN.value(d)},before:function(c,a,b){return QBN.progress(b,c)QBN.progress(b,a)},endingAt:function(c,a,b){return QBN.progress(b,c)<=QBN.progress(b,a)},startingAt:function(c,a,b){return QBN.progress(b,c)>=QBN.progress(b,a)}},operatorNames={eq:"to be",ne:"not to be",lt:"to be less than",le:"to be at most",gt:"to be greater than",ge:"to be at least"};QBN.functions={twinescript:{match:/^\s.*/,action:function(a){try{return Scripting.evalTwineScript(a[0])}catch(b){throw b.message+=" in: "+a[0],b}},description:function(a){return"\"\"\""+a[0]+"\"\"\""}},not:{match:/^not-(.+)/,action:function(a){return!QBN.requirementMet(a[1])},description:function(a){var b=QBN.description(a[1]);return null==b?b:"not "+b}},passage:{match:/^passage-(.+)/,action:function(a){return passage()===a[1]||passage()===a[1].replace(/_/g," ")},description:function(){return null}},tagged:{match:/^tagged-(.+)/,action:function(a){return tags().includes(a[1])},description:function(){return null}},visited:{match:/^visited-([^-]+)/,action:function(a){return 0c){var d="QBN.range: invalid range spec:";throw d+=" must have at least two values",d+=" (got "+JSON.stringify(c)+").",new Error(d)}for(var e,f,g,h,j=0;j>: "+(a.message||a))}setVar("_"+a+"_"+c.substring(1),!0),setVar("_"+c.substring(1)+"_range",a)}}),QBN.getProperty=function(a,b){var c,d=a.split("."),e=d.length,f=b||this;for(c=0;c>"),d&&f>"):e.wiki(d))}}}),Macro.add("requirements",{handler:function(){var a=$(this.output),b=toPassage(this.args[0]||QBN.current),c=this.args[1];if(c&&!Macro.has(c))return this.error("No such widget "+JSON.stringify(c)+".");for(var d,e=this.args[2]||"comma",f=QBN.requirements(b),g=0;g>"):a.wiki(d),e&&g>"):a.append(document.createTextNode(e)))}});function addTo(a,b){var c="string"==typeof b?b:b.title,d=!a[c];return d&&(a[c]=!0),d}function firstWord(a){var b=a.indexOf(" ");return a.substring(0,-1==b?a.length:b)}Macro.add("fillhand",{handler:function(){try{var a=this.args[0],b=this.args[1],c=this.args[2];if(!a){a=[];var d=firstWord(this.args.raw).substring(1);if(!setVar(d,a))return this.error("<>: failed to set hand \""+d+"\".")}var e,f={};for(e=0;e>: "+("object"==typeof a?a.message:a))}}}),Macro.add("card",{tags:["contents"],handler:function(){var a=$(this.output);if(getVar("_qbn_cover"))a.wiki(this.payload[0].contents.trim());else for(var b=1;bc.indexOf("card")&&0>c.indexOf("sticky-card")&&c.push("card"),a.push({title:JSON.stringify([passage(),b,a.length]),tags:c})}Macro.add("choices",{tags:["when","offer"],handler:function(){var a=this.args.raw,b=invalidName(a);if(b)return this.error(b);for(var c=[],d=0;d> content must be in sub-tags.");break;case"when":if(partialChoice(c))return this.error("This choice already has a \"when\" clause (section "+d+", "+e.contents.substring(0,30)+").");var f=QBN.parseTagsInto(e.contents.trim(),[]);beginChoice(c,a,f);break;case"offer":partialChoice(c)||beginChoice(c,a,[]),c[c.length-1].text=e.contents.trim(),""!==e.args[0]&&(c[e.args[0]]=c[c.length-1]);}}setVar(a,c)}}),QBN.progress=function(a,b){a=a.replace(/^[$_]/,"");let c=setup[a];if(null==c)throw"No such progress sequence "+JSON.stringify(a)+".";for(let d=0;d<<set $month to 1>> <<set setup.monthnames to ["", "January", "February", "March", "April", "May", "June", "July", "August", diff --git a/examples/priority.html b/examples/priority.html index d16ed5f..96b2d4c 100644 --- a/examples/priority.html +++ b/examples/priority.html @@ -180,7 +180,7 @@ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -State.initPRNG();var QBN={meta:{}};window.QBN=QBN,QBN.parseTagsInto=function(a,b){let c,d=new RegExp("("+["[a-zA-Z0-9-_]+(?:\\s+|$)","[a-zA-Z0-9_]+:[^\\n]*(?:\\n|$)\\s*","[^\\n]+(?:\\n|$)\\s*"].join(")|(")+")","g"),e=!1;for(;null!=(c=d.exec(a));)if(c[1]!==void 0)e?(b[b.length-1]+=c[1],!/\\\n/.test(c[1])&&(e=!1)):b.push(c[1].trim());else if(c[2]!==void 0){let a=c[2].replace(":","- "),d=a.replace("\\\n","");d.length!==a.length&&(e=!0),b.push(d)}else if(c[3]!==void 0){if(e)b[b.length-1]+=c[3];else throw new Error("Invalid metadata: "+JSON.stringify(c[3]));/(^|[^\\])\n/.test(c[3])&&(e=!1)}return b};const commentPattern=/\/\*\s*QBN\s([^*]*)\s\*\//g;Story.lookupWith(function(a){let b,c=a.tags.slice();for(;null!=(b=commentPattern.exec(a.text));){let a=b[1].trim();QBN.parseTagsInto(a,c)}return QBN.meta[a.title]=c,!1}),QBN.tags=function(a){return QBN.meta[a.title]||a.tags};var getVar=State.getVar||Wikifier.getValue,setVar=State.setVar||Wikifier.setValue;setVar("$QBN",{type:{},priority:{}}),$(document).on(":passagestart",function(a){QBN.current=a.passage.title,passageType(a.passage,!1)});function toArgument(a){if("object"==typeof a&&(a=a.title),"string"==typeof a)return JSON.stringify(a);throw new Error("Cards must be referred to by title (got "+typeof a+").")}function toPassage(a){if("object"==typeof a)if(a.link&&a.text)a=a.link;else return a;if("string"!=typeof a)throw new Error("Cards must be referred to by title (got "+typeof a+").");else{if(Story.has(a))return Story.get(a);let b=JSON.parse(a),c=b[0],d=b[1],e=b[2];if(passage()===c){let a=getVar(d);if(null!=a&&null!=a[e])return a[e]}throw new Error("No such passage or choice \""+a+"\".")}}QBN.toPassage=toPassage;function passageType(a,b){var c,d=QBN.tags(a);c=0<=d.indexOf("sticky-card")?"sticky-card":!!(0<=d.indexOf("card"))&&"card";var e=getVar("$QBN").type,f=e[a.title];return void 0===f&&(f=c),void 0!==b&&b!==f&&(null===b?e[a.title]=!1:!1===b?"card"===f&&(e[a.title]=!1):b===c?delete e[a.title]:e[a.title]=b),f}function shuffle(b){for(let a=b.length;0d?1:0};function choose(a,b,c){var d=Math.min;if(null==b||!1===b)return c?a:shuffle(a);b=Math.max(0,d(b,a.length));for(var e=d(b,a.length-b),f=e===b||void 0,g=[],h={},j=0;ja},lte:function(c,a){return c<=a},le:function(c,a){return c<=a},gte:function(c,a){return c>=a},ge:function(c,a){return c>=a},eqvar:function(c,a,b,d){return c==QBN.value(d)},neqvar:function(c,a,b,d){return c==QBN.value(d)},ltvar:function(c,a,b,d){return c==QBN.value(d)},gtvar:function(c,a,b,d){return c==QBN.value(d)},ltevar:function(c,a,b,d){return c==QBN.value(d)},gtevar:function(c,a,b,d){return c==QBN.value(d)},before:function(c,a,b){return QBN.progress(b,c)QBN.progress(b,a)},endingAt:function(c,a,b){return QBN.progress(b,c)<=QBN.progress(b,a)},startingAt:function(c,a,b){return QBN.progress(b,c)>=QBN.progress(b,a)}},operatorNames={eq:"to be",ne:"not to be",lt:"to be less than",le:"to be at most",gt:"to be greater than",ge:"to be at least"};QBN.functions={twinescript:{match:/^\s.*/,action:function(a){try{return Scripting.evalTwineScript(a[0])}catch(b){throw b.message+=" in: "+a[0],b}},description:function(a){return"\"\"\""+a[0]+"\"\"\""}},not:{match:/^not-(.+)/,action:function(a){return!QBN.requirementMet(a[1])},description:function(a){var b=QBN.description(a[1]);return null==b?b:"not "+b}},passage:{match:/^passage-(.+)/,action:function(a){return passage()===a[1]||passage()===a[1].replace(/_/g," ")},description:function(){return null}},tagged:{match:/^tagged-(.+)/,action:function(a){return tags().includes(a[1])},description:function(){return null}},visited:{match:/^visited-([^-]+)/,action:function(a){return 0c){var d="QBN.range: invalid range spec:";throw d+=" must have at least two values",d+=" (got "+JSON.stringify(c)+").",new Error(d)}for(var e,f,g,h,j=0;j>: "+(a.message||a))}setVar("_"+a+"_"+c.substring(1),!0),setVar("_"+c.substring(1)+"_range",a)}}),QBN.value=function(a){var b=State.variables,c=State.temporary;return null==c[a]?b[a]:c[a]},QBN.requirementMet=function(a){var b=null;for(var c in QBN.functions)if(QBN.functions.hasOwnProperty(c)){var d=QBN.functions[c],e=d.match.exec(a);if(e){b=d.action(e);break}}return null===b&&(b=QBN.value(a)),!!b},QBN.description=function(a){var b=null;for(var c in QBN.functions)if(QBN.functions.hasOwnProperty(c)){var d=QBN.functions[c],e=d.match.exec(a);if(e){b=d.description(e);break}}return null===b&&(b=a),b},QBN.tagsMatch=function(a,b){a=toPassage(a);let c=QBN.current;QBN.current=a.title;let d=QBN.tags(a);for(var e=0;e>"),d&&f>"):e.wiki(d))}}}),Macro.add("requirements",{handler:function(){var a=$(this.output),b=toPassage(this.args[0]||QBN.current),c=this.args[1];if(c&&!Macro.has(c))return this.error("No such widget "+JSON.stringify(c)+".");for(var d,e=this.args[2]||"comma",f=QBN.requirements(b),g=0;g>"):a.wiki(d),e&&g>"):a.append(document.createTextNode(e)))}});function addTo(a,b){var c="string"==typeof b?b:b.title,d=!a[c];return d&&(a[c]=!0),d}function firstWord(a){var b=a.indexOf(" ");return a.substring(0,-1==b?a.length:b)}Macro.add("fillhand",{handler:function(){try{var a=this.args[0],b=this.args[1],c=this.args[2];if(!a){a=[];var d=firstWord(this.args.raw).substring(1);if(!setVar(d,a))return this.error("<>: failed to set hand \""+d+"\".")}var e,f={};for(e=0;e>: "+("object"==typeof a?a.message:a))}}}),Macro.add("card",{tags:["contents"],handler:function(){var a=$(this.output);if(getVar("_qbn_cover"))a.wiki(this.payload[0].contents.trim());else for(var b=1;bc.indexOf("card")&&0>c.indexOf("sticky-card")&&c.push("card"),a.push({title:JSON.stringify([passage(),b,a.length]),tags:c})}Macro.add("choices",{tags:["when","offer"],handler:function(){var a=this.args.raw,b=invalidName(a);if(b)return this.error(b);for(var c=[],d=0;d> content must be in sub-tags.");break;case"when":if(partialChoice(c))return this.error("This choice already has a \"when\" clause (section "+d+", "+e.contents.substring(0,30)+").");var f=QBN.parseTagsInto(e.contents.trim(),[]);beginChoice(c,a,f);break;case"offer":partialChoice(c)||beginChoice(c,a,[]),c[c.length-1].text=e.contents.trim(),""!==e.args[0]&&(c[e.args[0]]=c[c.length-1]);}}setVar(a,c)}}),QBN.progress=function(a,b){a=a.replace(/^[$_]/,"");let c=setup[a];if(null==c)throw"No such progress sequence "+JSON.stringify(a)+".";for(let d=0;d<<set $limit to false>> +State.initPRNG();var QBN={meta:{}};window.QBN=QBN,QBN.parseTagsInto=function(a,b){let c,d=new RegExp("("+["[a-zA-Z0-9-_\\.]+(?:\\s+|$)","[a-zA-Z0-9_\\.]+:[^\\n]*(?:\\n|$)\\s*","[^\\n]+(?:\\n|$)\\s*"].join(")|(")+")","g"),e=!1;for(;null!=(c=d.exec(a));)if(c[1]!==void 0)e?(b[b.length-1]+=c[1],!/\\\n/.test(c[1])&&(e=!1)):b.push(c[1].trim());else if(c[2]!==void 0){let a=c[2].replace(":","- "),d=a.replace("\\\n","");d.length!==a.length&&(e=!0),b.push(d)}else if(c[3]!==void 0){if(e)b[b.length-1]+=c[3];else throw new Error("Invalid metadata: "+JSON.stringify(c[3]));/(^|[^\\])\n/.test(c[3])&&(e=!1)}return b};const commentPattern=/\/\*\s*QBN\s([^*]*)\s\*\//g;Story.lookupWith(function(a){let b,c=a.tags.slice();for(;null!=(b=commentPattern.exec(a.text));){let a=b[1].trim();QBN.parseTagsInto(a,c)}return QBN.meta[a.title]=c,!1}),QBN.tags=function(a){return QBN.meta[a.title]||a.tags};var getVar=State.getVar||Wikifier.getValue,setVar=State.setVar||Wikifier.setValue;setVar("$QBN",{type:{},priority:{}}),$(document).on(":passagestart",function(a){QBN.current=a.passage.title,passageType(a.passage,!1)});function toArgument(a){if("object"==typeof a&&(a=a.title),"string"==typeof a)return JSON.stringify(a);throw new Error("Cards must be referred to by title (got "+typeof a+").")}function toPassage(a){if("object"==typeof a)if(a.link&&a.text)a=a.link;else return a;if("string"!=typeof a)throw new Error("Cards must be referred to by title (got "+typeof a+").");else{if(Story.has(a))return Story.get(a);let b=JSON.parse(a),c=b[0],d=b[1],e=b[2];if(passage()===c){let a=getVar(d);if(null!=a&&null!=a[e])return a[e]}throw new Error("No such passage or choice \""+a+"\".")}}QBN.toPassage=toPassage;function passageType(a,b){var c,d=QBN.tags(a);c=0<=d.indexOf("sticky-card")?"sticky-card":!!(0<=d.indexOf("card"))&&"card";var e=getVar("$QBN").type,f=e[a.title];return void 0===f&&(f=c),void 0!==b&&b!==f&&(null===b?e[a.title]=!1:!1===b?"card"===f&&(e[a.title]=!1):b===c?delete e[a.title]:e[a.title]=b),f}function shuffle(b){for(let a=b.length;0d?1:0};function choose(a,b,c){var d=Math.min;if(null==b||!1===b)return c?a:shuffle(a);b=Math.max(0,d(b,a.length));for(var e=d(b,a.length-b),f=e===b||void 0,g=[],h={},j=0;ja},lte:function(c,a){return c<=a},le:function(c,a){return c<=a},gte:function(c,a){return c>=a},ge:function(c,a){return c>=a},eqvar:function(c,a,b,d){return c==QBN.value(d)},neqvar:function(c,a,b,d){return c==QBN.value(d)},ltvar:function(c,a,b,d){return c==QBN.value(d)},gtvar:function(c,a,b,d){return c==QBN.value(d)},ltevar:function(c,a,b,d){return c==QBN.value(d)},gtevar:function(c,a,b,d){return c==QBN.value(d)},before:function(c,a,b){return QBN.progress(b,c)QBN.progress(b,a)},endingAt:function(c,a,b){return QBN.progress(b,c)<=QBN.progress(b,a)},startingAt:function(c,a,b){return QBN.progress(b,c)>=QBN.progress(b,a)}},operatorNames={eq:"to be",ne:"not to be",lt:"to be less than",le:"to be at most",gt:"to be greater than",ge:"to be at least"};QBN.functions={twinescript:{match:/^\s.*/,action:function(a){try{return Scripting.evalTwineScript(a[0])}catch(b){throw b.message+=" in: "+a[0],b}},description:function(a){return"\"\"\""+a[0]+"\"\"\""}},not:{match:/^not-(.+)/,action:function(a){return!QBN.requirementMet(a[1])},description:function(a){var b=QBN.description(a[1]);return null==b?b:"not "+b}},passage:{match:/^passage-(.+)/,action:function(a){return passage()===a[1]||passage()===a[1].replace(/_/g," ")},description:function(){return null}},tagged:{match:/^tagged-(.+)/,action:function(a){return tags().includes(a[1])},description:function(){return null}},visited:{match:/^visited-([^-]+)/,action:function(a){return 0c){var d="QBN.range: invalid range spec:";throw d+=" must have at least two values",d+=" (got "+JSON.stringify(c)+").",new Error(d)}for(var e,f,g,h,j=0;j>: "+(a.message||a))}setVar("_"+a+"_"+c.substring(1),!0),setVar("_"+c.substring(1)+"_range",a)}}),QBN.getProperty=function(a,b){var c,d=a.split("."),e=d.length,f=b||this;for(c=0;c>"),d&&f>"):e.wiki(d))}}}),Macro.add("requirements",{handler:function(){var a=$(this.output),b=toPassage(this.args[0]||QBN.current),c=this.args[1];if(c&&!Macro.has(c))return this.error("No such widget "+JSON.stringify(c)+".");for(var d,e=this.args[2]||"comma",f=QBN.requirements(b),g=0;g>"):a.wiki(d),e&&g>"):a.append(document.createTextNode(e)))}});function addTo(a,b){var c="string"==typeof b?b:b.title,d=!a[c];return d&&(a[c]=!0),d}function firstWord(a){var b=a.indexOf(" ");return a.substring(0,-1==b?a.length:b)}Macro.add("fillhand",{handler:function(){try{var a=this.args[0],b=this.args[1],c=this.args[2];if(!a){a=[];var d=firstWord(this.args.raw).substring(1);if(!setVar(d,a))return this.error("<>: failed to set hand \""+d+"\".")}var e,f={};for(e=0;e>: "+("object"==typeof a?a.message:a))}}}),Macro.add("card",{tags:["contents"],handler:function(){var a=$(this.output);if(getVar("_qbn_cover"))a.wiki(this.payload[0].contents.trim());else for(var b=1;bc.indexOf("card")&&0>c.indexOf("sticky-card")&&c.push("card"),a.push({title:JSON.stringify([passage(),b,a.length]),tags:c})}Macro.add("choices",{tags:["when","offer"],handler:function(){var a=this.args.raw,b=invalidName(a);if(b)return this.error(b);for(var c=[],d=0;d> content must be in sub-tags.");break;case"when":if(partialChoice(c))return this.error("This choice already has a \"when\" clause (section "+d+", "+e.contents.substring(0,30)+").");var f=QBN.parseTagsInto(e.contents.trim(),[]);beginChoice(c,a,f);break;case"offer":partialChoice(c)||beginChoice(c,a,[]),c[c.length-1].text=e.contents.trim(),""!==e.args[0]&&(c[e.args[0]]=c[c.length-1]);}}setVar(a,c)}}),QBN.progress=function(a,b){a=a.replace(/^[$_]/,"");let c=setup[a];if(null==c)throw"No such progress sequence "+JSON.stringify(a)+".";for(let d=0;d<<set $limit to false>> <<set $carrots to false>> <<set $milk to true>><<listbox "$limit" autoselect>> <<option "Show the full list" false>> diff --git a/examples/progress.html b/examples/progress.html index 9a8ce2d..e6e7d57 100644 --- a/examples/progress.html +++ b/examples/progress.html @@ -180,7 +180,7 @@ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -State.initPRNG();var QBN={meta:{}};window.QBN=QBN,QBN.parseTagsInto=function(a,b){let c,d=new RegExp("("+["[a-zA-Z0-9-_]+(?:\\s+|$)","[a-zA-Z0-9_]+:[^\\n]*(?:\\n|$)\\s*","[^\\n]+(?:\\n|$)\\s*"].join(")|(")+")","g"),e=!1;for(;null!=(c=d.exec(a));)if(c[1]!==void 0)e?(b[b.length-1]+=c[1],!/\\\n/.test(c[1])&&(e=!1)):b.push(c[1].trim());else if(c[2]!==void 0){let a=c[2].replace(":","- "),d=a.replace("\\\n","");d.length!==a.length&&(e=!0),b.push(d)}else if(c[3]!==void 0){if(e)b[b.length-1]+=c[3];else throw new Error("Invalid metadata: "+JSON.stringify(c[3]));/(^|[^\\])\n/.test(c[3])&&(e=!1)}return b};const commentPattern=/\/\*\s*QBN\s([^*]*)\s\*\//g;Story.lookupWith(function(a){let b,c=a.tags.slice();for(;null!=(b=commentPattern.exec(a.text));){let a=b[1].trim();QBN.parseTagsInto(a,c)}return QBN.meta[a.title]=c,!1}),QBN.tags=function(a){return QBN.meta[a.title]||a.tags};var getVar=State.getVar||Wikifier.getValue,setVar=State.setVar||Wikifier.setValue;setVar("$QBN",{type:{},priority:{}}),$(document).on(":passagestart",function(a){QBN.current=a.passage.title,passageType(a.passage,!1)});function toArgument(a){if("object"==typeof a&&(a=a.title),"string"==typeof a)return JSON.stringify(a);throw new Error("Cards must be referred to by title (got "+typeof a+").")}function toPassage(a){if("object"==typeof a)if(a.link&&a.text)a=a.link;else return a;if("string"!=typeof a)throw new Error("Cards must be referred to by title (got "+typeof a+").");else{if(Story.has(a))return Story.get(a);let b=JSON.parse(a),c=b[0],d=b[1],e=b[2];if(passage()===c){let a=getVar(d);if(null!=a&&null!=a[e])return a[e]}throw new Error("No such passage or choice \""+a+"\".")}}QBN.toPassage=toPassage;function passageType(a,b){var c,d=QBN.tags(a);c=0<=d.indexOf("sticky-card")?"sticky-card":!!(0<=d.indexOf("card"))&&"card";var e=getVar("$QBN").type,f=e[a.title];return void 0===f&&(f=c),void 0!==b&&b!==f&&(null===b?e[a.title]=!1:!1===b?"card"===f&&(e[a.title]=!1):b===c?delete e[a.title]:e[a.title]=b),f}function shuffle(b){for(let a=b.length;0d?1:0};function choose(a,b,c){var d=Math.min;if(null==b||!1===b)return c?a:shuffle(a);b=Math.max(0,d(b,a.length));for(var e=d(b,a.length-b),f=e===b||void 0,g=[],h={},j=0;ja},lte:function(c,a){return c<=a},le:function(c,a){return c<=a},gte:function(c,a){return c>=a},ge:function(c,a){return c>=a},eqvar:function(c,a,b,d){return c==QBN.value(d)},neqvar:function(c,a,b,d){return c==QBN.value(d)},ltvar:function(c,a,b,d){return c==QBN.value(d)},gtvar:function(c,a,b,d){return c==QBN.value(d)},ltevar:function(c,a,b,d){return c==QBN.value(d)},gtevar:function(c,a,b,d){return c==QBN.value(d)},before:function(c,a,b){return QBN.progress(b,c)QBN.progress(b,a)},endingAt:function(c,a,b){return QBN.progress(b,c)<=QBN.progress(b,a)},startingAt:function(c,a,b){return QBN.progress(b,c)>=QBN.progress(b,a)}},operatorNames={eq:"to be",ne:"not to be",lt:"to be less than",le:"to be at most",gt:"to be greater than",ge:"to be at least"};QBN.functions={twinescript:{match:/^\s.*/,action:function(a){try{return Scripting.evalTwineScript(a[0])}catch(b){throw b.message+=" in: "+a[0],b}},description:function(a){return"\"\"\""+a[0]+"\"\"\""}},not:{match:/^not-(.+)/,action:function(a){return!QBN.requirementMet(a[1])},description:function(a){var b=QBN.description(a[1]);return null==b?b:"not "+b}},passage:{match:/^passage-(.+)/,action:function(a){return passage()===a[1]||passage()===a[1].replace(/_/g," ")},description:function(){return null}},tagged:{match:/^tagged-(.+)/,action:function(a){return tags().includes(a[1])},description:function(){return null}},visited:{match:/^visited-([^-]+)/,action:function(a){return 0c){var d="QBN.range: invalid range spec:";throw d+=" must have at least two values",d+=" (got "+JSON.stringify(c)+").",new Error(d)}for(var e,f,g,h,j=0;j>: "+(a.message||a))}setVar("_"+a+"_"+c.substring(1),!0),setVar("_"+c.substring(1)+"_range",a)}}),QBN.value=function(a){var b=State.variables,c=State.temporary;return null==c[a]?b[a]:c[a]},QBN.requirementMet=function(a){var b=null;for(var c in QBN.functions)if(QBN.functions.hasOwnProperty(c)){var d=QBN.functions[c],e=d.match.exec(a);if(e){b=d.action(e);break}}return null===b&&(b=QBN.value(a)),!!b},QBN.description=function(a){var b=null;for(var c in QBN.functions)if(QBN.functions.hasOwnProperty(c)){var d=QBN.functions[c],e=d.match.exec(a);if(e){b=d.description(e);break}}return null===b&&(b=a),b},QBN.tagsMatch=function(a,b){a=toPassage(a);let c=QBN.current;QBN.current=a.title;let d=QBN.tags(a);for(var e=0;e>"),d&&f>"):e.wiki(d))}}}),Macro.add("requirements",{handler:function(){var a=$(this.output),b=toPassage(this.args[0]||QBN.current),c=this.args[1];if(c&&!Macro.has(c))return this.error("No such widget "+JSON.stringify(c)+".");for(var d,e=this.args[2]||"comma",f=QBN.requirements(b),g=0;g>"):a.wiki(d),e&&g>"):a.append(document.createTextNode(e)))}});function addTo(a,b){var c="string"==typeof b?b:b.title,d=!a[c];return d&&(a[c]=!0),d}function firstWord(a){var b=a.indexOf(" ");return a.substring(0,-1==b?a.length:b)}Macro.add("fillhand",{handler:function(){try{var a=this.args[0],b=this.args[1],c=this.args[2];if(!a){a=[];var d=firstWord(this.args.raw).substring(1);if(!setVar(d,a))return this.error("<>: failed to set hand \""+d+"\".")}var e,f={};for(e=0;e>: "+("object"==typeof a?a.message:a))}}}),Macro.add("card",{tags:["contents"],handler:function(){var a=$(this.output);if(getVar("_qbn_cover"))a.wiki(this.payload[0].contents.trim());else for(var b=1;bc.indexOf("card")&&0>c.indexOf("sticky-card")&&c.push("card"),a.push({title:JSON.stringify([passage(),b,a.length]),tags:c})}Macro.add("choices",{tags:["when","offer"],handler:function(){var a=this.args.raw,b=invalidName(a);if(b)return this.error(b);for(var c=[],d=0;d> content must be in sub-tags.");break;case"when":if(partialChoice(c))return this.error("This choice already has a \"when\" clause (section "+d+", "+e.contents.substring(0,30)+").");var f=QBN.parseTagsInto(e.contents.trim(),[]);beginChoice(c,a,f);break;case"offer":partialChoice(c)||beginChoice(c,a,[]),c[c.length-1].text=e.contents.trim(),""!==e.args[0]&&(c[e.args[0]]=c[c.length-1]);}}setVar(a,c)}}),QBN.progress=function(a,b){a=a.replace(/^[$_]/,"");let c=setup[a];if(null==c)throw"No such progress sequence "+JSON.stringify(a)+".";for(let d=0;d<<progress "$schedule" "daydream" "early_midmorning_nap" "dawdle_and_delay" +State.initPRNG();var QBN={meta:{}};window.QBN=QBN,QBN.parseTagsInto=function(a,b){let c,d=new RegExp("("+["[a-zA-Z0-9-_\\.]+(?:\\s+|$)","[a-zA-Z0-9_\\.]+:[^\\n]*(?:\\n|$)\\s*","[^\\n]+(?:\\n|$)\\s*"].join(")|(")+")","g"),e=!1;for(;null!=(c=d.exec(a));)if(c[1]!==void 0)e?(b[b.length-1]+=c[1],!/\\\n/.test(c[1])&&(e=!1)):b.push(c[1].trim());else if(c[2]!==void 0){let a=c[2].replace(":","- "),d=a.replace("\\\n","");d.length!==a.length&&(e=!0),b.push(d)}else if(c[3]!==void 0){if(e)b[b.length-1]+=c[3];else throw new Error("Invalid metadata: "+JSON.stringify(c[3]));/(^|[^\\])\n/.test(c[3])&&(e=!1)}return b};const commentPattern=/\/\*\s*QBN\s([^*]*)\s\*\//g;Story.lookupWith(function(a){let b,c=a.tags.slice();for(;null!=(b=commentPattern.exec(a.text));){let a=b[1].trim();QBN.parseTagsInto(a,c)}return QBN.meta[a.title]=c,!1}),QBN.tags=function(a){return QBN.meta[a.title]||a.tags};var getVar=State.getVar||Wikifier.getValue,setVar=State.setVar||Wikifier.setValue;setVar("$QBN",{type:{},priority:{}}),$(document).on(":passagestart",function(a){QBN.current=a.passage.title,passageType(a.passage,!1)});function toArgument(a){if("object"==typeof a&&(a=a.title),"string"==typeof a)return JSON.stringify(a);throw new Error("Cards must be referred to by title (got "+typeof a+").")}function toPassage(a){if("object"==typeof a)if(a.link&&a.text)a=a.link;else return a;if("string"!=typeof a)throw new Error("Cards must be referred to by title (got "+typeof a+").");else{if(Story.has(a))return Story.get(a);let b=JSON.parse(a),c=b[0],d=b[1],e=b[2];if(passage()===c){let a=getVar(d);if(null!=a&&null!=a[e])return a[e]}throw new Error("No such passage or choice \""+a+"\".")}}QBN.toPassage=toPassage;function passageType(a,b){var c,d=QBN.tags(a);c=0<=d.indexOf("sticky-card")?"sticky-card":!!(0<=d.indexOf("card"))&&"card";var e=getVar("$QBN").type,f=e[a.title];return void 0===f&&(f=c),void 0!==b&&b!==f&&(null===b?e[a.title]=!1:!1===b?"card"===f&&(e[a.title]=!1):b===c?delete e[a.title]:e[a.title]=b),f}function shuffle(b){for(let a=b.length;0d?1:0};function choose(a,b,c){var d=Math.min;if(null==b||!1===b)return c?a:shuffle(a);b=Math.max(0,d(b,a.length));for(var e=d(b,a.length-b),f=e===b||void 0,g=[],h={},j=0;ja},lte:function(c,a){return c<=a},le:function(c,a){return c<=a},gte:function(c,a){return c>=a},ge:function(c,a){return c>=a},eqvar:function(c,a,b,d){return c==QBN.value(d)},neqvar:function(c,a,b,d){return c==QBN.value(d)},ltvar:function(c,a,b,d){return c==QBN.value(d)},gtvar:function(c,a,b,d){return c==QBN.value(d)},ltevar:function(c,a,b,d){return c==QBN.value(d)},gtevar:function(c,a,b,d){return c==QBN.value(d)},before:function(c,a,b){return QBN.progress(b,c)QBN.progress(b,a)},endingAt:function(c,a,b){return QBN.progress(b,c)<=QBN.progress(b,a)},startingAt:function(c,a,b){return QBN.progress(b,c)>=QBN.progress(b,a)}},operatorNames={eq:"to be",ne:"not to be",lt:"to be less than",le:"to be at most",gt:"to be greater than",ge:"to be at least"};QBN.functions={twinescript:{match:/^\s.*/,action:function(a){try{return Scripting.evalTwineScript(a[0])}catch(b){throw b.message+=" in: "+a[0],b}},description:function(a){return"\"\"\""+a[0]+"\"\"\""}},not:{match:/^not-(.+)/,action:function(a){return!QBN.requirementMet(a[1])},description:function(a){var b=QBN.description(a[1]);return null==b?b:"not "+b}},passage:{match:/^passage-(.+)/,action:function(a){return passage()===a[1]||passage()===a[1].replace(/_/g," ")},description:function(){return null}},tagged:{match:/^tagged-(.+)/,action:function(a){return tags().includes(a[1])},description:function(){return null}},visited:{match:/^visited-([^-]+)/,action:function(a){return 0c){var d="QBN.range: invalid range spec:";throw d+=" must have at least two values",d+=" (got "+JSON.stringify(c)+").",new Error(d)}for(var e,f,g,h,j=0;j>: "+(a.message||a))}setVar("_"+a+"_"+c.substring(1),!0),setVar("_"+c.substring(1)+"_range",a)}}),QBN.getProperty=function(a,b){var c,d=a.split("."),e=d.length,f=b||this;for(c=0;c>"),d&&f>"):e.wiki(d))}}}),Macro.add("requirements",{handler:function(){var a=$(this.output),b=toPassage(this.args[0]||QBN.current),c=this.args[1];if(c&&!Macro.has(c))return this.error("No such widget "+JSON.stringify(c)+".");for(var d,e=this.args[2]||"comma",f=QBN.requirements(b),g=0;g>"):a.wiki(d),e&&g>"):a.append(document.createTextNode(e)))}});function addTo(a,b){var c="string"==typeof b?b:b.title,d=!a[c];return d&&(a[c]=!0),d}function firstWord(a){var b=a.indexOf(" ");return a.substring(0,-1==b?a.length:b)}Macro.add("fillhand",{handler:function(){try{var a=this.args[0],b=this.args[1],c=this.args[2];if(!a){a=[];var d=firstWord(this.args.raw).substring(1);if(!setVar(d,a))return this.error("<>: failed to set hand \""+d+"\".")}var e,f={};for(e=0;e>: "+("object"==typeof a?a.message:a))}}}),Macro.add("card",{tags:["contents"],handler:function(){var a=$(this.output);if(getVar("_qbn_cover"))a.wiki(this.payload[0].contents.trim());else for(var b=1;bc.indexOf("card")&&0>c.indexOf("sticky-card")&&c.push("card"),a.push({title:JSON.stringify([passage(),b,a.length]),tags:c})}Macro.add("choices",{tags:["when","offer"],handler:function(){var a=this.args.raw,b=invalidName(a);if(b)return this.error(b);for(var c=[],d=0;d> content must be in sub-tags.");break;case"when":if(partialChoice(c))return this.error("This choice already has a \"when\" clause (section "+d+", "+e.contents.substring(0,30)+").");var f=QBN.parseTagsInto(e.contents.trim(),[]);beginChoice(c,a,f);break;case"offer":partialChoice(c)||beginChoice(c,a,[]),c[c.length-1].text=e.contents.trim(),""!==e.args[0]&&(c[e.args[0]]=c[c.length-1]);}}setVar(a,c)}}),QBN.progress=function(a,b){a=a.replace(/^[$_]/,"");let c=setup[a];if(null==c)throw"No such progress sequence "+JSON.stringify(a)+".";for(let d=0;d<<progress "$schedule" "daydream" "early_midmorning_nap" "dawdle_and_delay" "late_early_morning_nap" "bide_our_time" "eat_lunch" "linger_and_loiter" "early_afternoon_nap" "put_off_for_tomorrow_what_we_could_have_done_today" diff --git a/examples/sprawl.html b/examples/sprawl.html index 33186cd..968ce42 100644 --- a/examples/sprawl.html +++ b/examples/sprawl.html @@ -202,7 +202,7 @@ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -State.initPRNG();var QBN={meta:{}};window.QBN=QBN,QBN.parseTagsInto=function(a,b){let c,d=new RegExp("("+["[a-zA-Z0-9-_]+(?:\\s+|$)","[a-zA-Z0-9_]+:[^\\n]*(?:\\n|$)\\s*","[^\\n]+(?:\\n|$)\\s*"].join(")|(")+")","g"),e=!1;for(;null!=(c=d.exec(a));)if(c[1]!==void 0)e?(b[b.length-1]+=c[1],!/\\\n/.test(c[1])&&(e=!1)):b.push(c[1].trim());else if(c[2]!==void 0){let a=c[2].replace(":","- "),d=a.replace("\\\n","");d.length!==a.length&&(e=!0),b.push(d)}else if(c[3]!==void 0){if(e)b[b.length-1]+=c[3];else throw new Error("Invalid metadata: "+JSON.stringify(c[3]));/(^|[^\\])\n/.test(c[3])&&(e=!1)}return b};const commentPattern=/\/\*\s*QBN\s([^*]*)\s\*\//g;Story.lookupWith(function(a){let b,c=a.tags.slice();for(;null!=(b=commentPattern.exec(a.text));){let a=b[1].trim();QBN.parseTagsInto(a,c)}return QBN.meta[a.title]=c,!1}),QBN.tags=function(a){return QBN.meta[a.title]||a.tags};var getVar=State.getVar||Wikifier.getValue,setVar=State.setVar||Wikifier.setValue;setVar("$QBN",{type:{},priority:{}}),$(document).on(":passagestart",function(a){QBN.current=a.passage.title,passageType(a.passage,!1)});function toArgument(a){if("object"==typeof a&&(a=a.title),"string"==typeof a)return JSON.stringify(a);throw new Error("Cards must be referred to by title (got "+typeof a+").")}function toPassage(a){if("object"==typeof a)if(a.link&&a.text)a=a.link;else return a;if("string"!=typeof a)throw new Error("Cards must be referred to by title (got "+typeof a+").");else{if(Story.has(a))return Story.get(a);let b=JSON.parse(a),c=b[0],d=b[1],e=b[2];if(passage()===c){let a=getVar(d);if(null!=a&&null!=a[e])return a[e]}throw new Error("No such passage or choice \""+a+"\".")}}QBN.toPassage=toPassage;function passageType(a,b){var c,d=QBN.tags(a);c=0<=d.indexOf("sticky-card")?"sticky-card":!!(0<=d.indexOf("card"))&&"card";var e=getVar("$QBN").type,f=e[a.title];return void 0===f&&(f=c),void 0!==b&&b!==f&&(null===b?e[a.title]=!1:!1===b?"card"===f&&(e[a.title]=!1):b===c?delete e[a.title]:e[a.title]=b),f}function shuffle(b){for(let a=b.length;0d?1:0};function choose(a,b,c){var d=Math.min;if(null==b||!1===b)return c?a:shuffle(a);b=Math.max(0,d(b,a.length));for(var e=d(b,a.length-b),f=e===b||void 0,g=[],h={},j=0;ja},lte:function(c,a){return c<=a},le:function(c,a){return c<=a},gte:function(c,a){return c>=a},ge:function(c,a){return c>=a},eqvar:function(c,a,b,d){return c==QBN.value(d)},neqvar:function(c,a,b,d){return c==QBN.value(d)},ltvar:function(c,a,b,d){return c==QBN.value(d)},gtvar:function(c,a,b,d){return c==QBN.value(d)},ltevar:function(c,a,b,d){return c==QBN.value(d)},gtevar:function(c,a,b,d){return c==QBN.value(d)},before:function(c,a,b){return QBN.progress(b,c)QBN.progress(b,a)},endingAt:function(c,a,b){return QBN.progress(b,c)<=QBN.progress(b,a)},startingAt:function(c,a,b){return QBN.progress(b,c)>=QBN.progress(b,a)}},operatorNames={eq:"to be",ne:"not to be",lt:"to be less than",le:"to be at most",gt:"to be greater than",ge:"to be at least"};QBN.functions={twinescript:{match:/^\s.*/,action:function(a){try{return Scripting.evalTwineScript(a[0])}catch(b){throw b.message+=" in: "+a[0],b}},description:function(a){return"\"\"\""+a[0]+"\"\"\""}},not:{match:/^not-(.+)/,action:function(a){return!QBN.requirementMet(a[1])},description:function(a){var b=QBN.description(a[1]);return null==b?b:"not "+b}},passage:{match:/^passage-(.+)/,action:function(a){return passage()===a[1]||passage()===a[1].replace(/_/g," ")},description:function(){return null}},tagged:{match:/^tagged-(.+)/,action:function(a){return tags().includes(a[1])},description:function(){return null}},visited:{match:/^visited-([^-]+)/,action:function(a){return 0c){var d="QBN.range: invalid range spec:";throw d+=" must have at least two values",d+=" (got "+JSON.stringify(c)+").",new Error(d)}for(var e,f,g,h,j=0;j>: "+(a.message||a))}setVar("_"+a+"_"+c.substring(1),!0),setVar("_"+c.substring(1)+"_range",a)}}),QBN.value=function(a){var b=State.variables,c=State.temporary;return null==c[a]?b[a]:c[a]},QBN.requirementMet=function(a){var b=null;for(var c in QBN.functions)if(QBN.functions.hasOwnProperty(c)){var d=QBN.functions[c],e=d.match.exec(a);if(e){b=d.action(e);break}}return null===b&&(b=QBN.value(a)),!!b},QBN.description=function(a){var b=null;for(var c in QBN.functions)if(QBN.functions.hasOwnProperty(c)){var d=QBN.functions[c],e=d.match.exec(a);if(e){b=d.description(e);break}}return null===b&&(b=a),b},QBN.tagsMatch=function(a,b){a=toPassage(a);let c=QBN.current;QBN.current=a.title;let d=QBN.tags(a);for(var e=0;e>"),d&&f>"):e.wiki(d))}}}),Macro.add("requirements",{handler:function(){var a=$(this.output),b=toPassage(this.args[0]||QBN.current),c=this.args[1];if(c&&!Macro.has(c))return this.error("No such widget "+JSON.stringify(c)+".");for(var d,e=this.args[2]||"comma",f=QBN.requirements(b),g=0;g>"):a.wiki(d),e&&g>"):a.append(document.createTextNode(e)))}});function addTo(a,b){var c="string"==typeof b?b:b.title,d=!a[c];return d&&(a[c]=!0),d}function firstWord(a){var b=a.indexOf(" ");return a.substring(0,-1==b?a.length:b)}Macro.add("fillhand",{handler:function(){try{var a=this.args[0],b=this.args[1],c=this.args[2];if(!a){a=[];var d=firstWord(this.args.raw).substring(1);if(!setVar(d,a))return this.error("<>: failed to set hand \""+d+"\".")}var e,f={};for(e=0;e>: "+("object"==typeof a?a.message:a))}}}),Macro.add("card",{tags:["contents"],handler:function(){var a=$(this.output);if(getVar("_qbn_cover"))a.wiki(this.payload[0].contents.trim());else for(var b=1;bc.indexOf("card")&&0>c.indexOf("sticky-card")&&c.push("card"),a.push({title:JSON.stringify([passage(),b,a.length]),tags:c})}Macro.add("choices",{tags:["when","offer"],handler:function(){var a=this.args.raw,b=invalidName(a);if(b)return this.error(b);for(var c=[],d=0;d> content must be in sub-tags.");break;case"when":if(partialChoice(c))return this.error("This choice already has a \"when\" clause (section "+d+", "+e.contents.substring(0,30)+").");var f=QBN.parseTagsInto(e.contents.trim(),[]);beginChoice(c,a,f);break;case"offer":partialChoice(c)||beginChoice(c,a,[]),c[c.length-1].text=e.contents.trim(),""!==e.args[0]&&(c[e.args[0]]=c[c.length-1]);}}setVar(a,c)}}),QBN.progress=function(a,b){a=a.replace(/^[$_]/,"");let c=setup[a];if(null==c)throw"No such progress sequence "+JSON.stringify(a)+".";for(let d=0;d<<widget "coveritem">><li><<cover $args[0]>></li><</widget>> +State.initPRNG();var QBN={meta:{}};window.QBN=QBN,QBN.parseTagsInto=function(a,b){let c,d=new RegExp("("+["[a-zA-Z0-9-_\\.]+(?:\\s+|$)","[a-zA-Z0-9_\\.]+:[^\\n]*(?:\\n|$)\\s*","[^\\n]+(?:\\n|$)\\s*"].join(")|(")+")","g"),e=!1;for(;null!=(c=d.exec(a));)if(c[1]!==void 0)e?(b[b.length-1]+=c[1],!/\\\n/.test(c[1])&&(e=!1)):b.push(c[1].trim());else if(c[2]!==void 0){let a=c[2].replace(":","- "),d=a.replace("\\\n","");d.length!==a.length&&(e=!0),b.push(d)}else if(c[3]!==void 0){if(e)b[b.length-1]+=c[3];else throw new Error("Invalid metadata: "+JSON.stringify(c[3]));/(^|[^\\])\n/.test(c[3])&&(e=!1)}return b};const commentPattern=/\/\*\s*QBN\s([^*]*)\s\*\//g;Story.lookupWith(function(a){let b,c=a.tags.slice();for(;null!=(b=commentPattern.exec(a.text));){let a=b[1].trim();QBN.parseTagsInto(a,c)}return QBN.meta[a.title]=c,!1}),QBN.tags=function(a){return QBN.meta[a.title]||a.tags};var getVar=State.getVar||Wikifier.getValue,setVar=State.setVar||Wikifier.setValue;setVar("$QBN",{type:{},priority:{}}),$(document).on(":passagestart",function(a){QBN.current=a.passage.title,passageType(a.passage,!1)});function toArgument(a){if("object"==typeof a&&(a=a.title),"string"==typeof a)return JSON.stringify(a);throw new Error("Cards must be referred to by title (got "+typeof a+").")}function toPassage(a){if("object"==typeof a)if(a.link&&a.text)a=a.link;else return a;if("string"!=typeof a)throw new Error("Cards must be referred to by title (got "+typeof a+").");else{if(Story.has(a))return Story.get(a);let b=JSON.parse(a),c=b[0],d=b[1],e=b[2];if(passage()===c){let a=getVar(d);if(null!=a&&null!=a[e])return a[e]}throw new Error("No such passage or choice \""+a+"\".")}}QBN.toPassage=toPassage;function passageType(a,b){var c,d=QBN.tags(a);c=0<=d.indexOf("sticky-card")?"sticky-card":!!(0<=d.indexOf("card"))&&"card";var e=getVar("$QBN").type,f=e[a.title];return void 0===f&&(f=c),void 0!==b&&b!==f&&(null===b?e[a.title]=!1:!1===b?"card"===f&&(e[a.title]=!1):b===c?delete e[a.title]:e[a.title]=b),f}function shuffle(b){for(let a=b.length;0d?1:0};function choose(a,b,c){var d=Math.min;if(null==b||!1===b)return c?a:shuffle(a);b=Math.max(0,d(b,a.length));for(var e=d(b,a.length-b),f=e===b||void 0,g=[],h={},j=0;ja},lte:function(c,a){return c<=a},le:function(c,a){return c<=a},gte:function(c,a){return c>=a},ge:function(c,a){return c>=a},eqvar:function(c,a,b,d){return c==QBN.value(d)},neqvar:function(c,a,b,d){return c==QBN.value(d)},ltvar:function(c,a,b,d){return c==QBN.value(d)},gtvar:function(c,a,b,d){return c==QBN.value(d)},ltevar:function(c,a,b,d){return c==QBN.value(d)},gtevar:function(c,a,b,d){return c==QBN.value(d)},before:function(c,a,b){return QBN.progress(b,c)QBN.progress(b,a)},endingAt:function(c,a,b){return QBN.progress(b,c)<=QBN.progress(b,a)},startingAt:function(c,a,b){return QBN.progress(b,c)>=QBN.progress(b,a)}},operatorNames={eq:"to be",ne:"not to be",lt:"to be less than",le:"to be at most",gt:"to be greater than",ge:"to be at least"};QBN.functions={twinescript:{match:/^\s.*/,action:function(a){try{return Scripting.evalTwineScript(a[0])}catch(b){throw b.message+=" in: "+a[0],b}},description:function(a){return"\"\"\""+a[0]+"\"\"\""}},not:{match:/^not-(.+)/,action:function(a){return!QBN.requirementMet(a[1])},description:function(a){var b=QBN.description(a[1]);return null==b?b:"not "+b}},passage:{match:/^passage-(.+)/,action:function(a){return passage()===a[1]||passage()===a[1].replace(/_/g," ")},description:function(){return null}},tagged:{match:/^tagged-(.+)/,action:function(a){return tags().includes(a[1])},description:function(){return null}},visited:{match:/^visited-([^-]+)/,action:function(a){return 0c){var d="QBN.range: invalid range spec:";throw d+=" must have at least two values",d+=" (got "+JSON.stringify(c)+").",new Error(d)}for(var e,f,g,h,j=0;j>: "+(a.message||a))}setVar("_"+a+"_"+c.substring(1),!0),setVar("_"+c.substring(1)+"_range",a)}}),QBN.getProperty=function(a,b){var c,d=a.split("."),e=d.length,f=b||this;for(c=0;c>"),d&&f>"):e.wiki(d))}}}),Macro.add("requirements",{handler:function(){var a=$(this.output),b=toPassage(this.args[0]||QBN.current),c=this.args[1];if(c&&!Macro.has(c))return this.error("No such widget "+JSON.stringify(c)+".");for(var d,e=this.args[2]||"comma",f=QBN.requirements(b),g=0;g>"):a.wiki(d),e&&g>"):a.append(document.createTextNode(e)))}});function addTo(a,b){var c="string"==typeof b?b:b.title,d=!a[c];return d&&(a[c]=!0),d}function firstWord(a){var b=a.indexOf(" ");return a.substring(0,-1==b?a.length:b)}Macro.add("fillhand",{handler:function(){try{var a=this.args[0],b=this.args[1],c=this.args[2];if(!a){a=[];var d=firstWord(this.args.raw).substring(1);if(!setVar(d,a))return this.error("<>: failed to set hand \""+d+"\".")}var e,f={};for(e=0;e>: "+("object"==typeof a?a.message:a))}}}),Macro.add("card",{tags:["contents"],handler:function(){var a=$(this.output);if(getVar("_qbn_cover"))a.wiki(this.payload[0].contents.trim());else for(var b=1;bc.indexOf("card")&&0>c.indexOf("sticky-card")&&c.push("card"),a.push({title:JSON.stringify([passage(),b,a.length]),tags:c})}Macro.add("choices",{tags:["when","offer"],handler:function(){var a=this.args.raw,b=invalidName(a);if(b)return this.error(b);for(var c=[],d=0;d> content must be in sub-tags.");break;case"when":if(partialChoice(c))return this.error("This choice already has a \"when\" clause (section "+d+", "+e.contents.substring(0,30)+").");var f=QBN.parseTagsInto(e.contents.trim(),[]);beginChoice(c,a,f);break;case"offer":partialChoice(c)||beginChoice(c,a,[]),c[c.length-1].text=e.contents.trim(),""!==e.args[0]&&(c[e.args[0]]=c[c.length-1]);}}setVar(a,c)}}),QBN.progress=function(a,b){a=a.replace(/^[$_]/,"");let c=setup[a];if(null==c)throw"No such progress sequence "+JSON.stringify(a)+".";for(let d=0;d<<widget "coveritem">><li><<cover $args[0]>></li><</widget>> <<progress "$mission" "assemble_team" "legwork" diff --git a/examples/tutorial-1.html b/examples/tutorial-1.html index 612db41..2991c51 100644 --- a/examples/tutorial-1.html +++ b/examples/tutorial-1.html @@ -180,7 +180,7 @@ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -State.initPRNG();var QBN={meta:{}};window.QBN=QBN,QBN.parseTagsInto=function(a,b){let c,d=new RegExp("("+["[a-zA-Z0-9-_]+(?:\\s+|$)","[a-zA-Z0-9_]+:[^\\n]*(?:\\n|$)\\s*","[^\\n]+(?:\\n|$)\\s*"].join(")|(")+")","g"),e=!1;for(;null!=(c=d.exec(a));)if(c[1]!==void 0)e?(b[b.length-1]+=c[1],!/\\\n/.test(c[1])&&(e=!1)):b.push(c[1].trim());else if(c[2]!==void 0){let a=c[2].replace(":","- "),d=a.replace("\\\n","");d.length!==a.length&&(e=!0),b.push(d)}else if(c[3]!==void 0){if(e)b[b.length-1]+=c[3];else throw new Error("Invalid metadata: "+JSON.stringify(c[3]));/(^|[^\\])\n/.test(c[3])&&(e=!1)}return b};const commentPattern=/\/\*\s*QBN\s([^*]*)\s\*\//g;Story.lookupWith(function(a){let b,c=a.tags.slice();for(;null!=(b=commentPattern.exec(a.text));){let a=b[1].trim();QBN.parseTagsInto(a,c)}return QBN.meta[a.title]=c,!1}),QBN.tags=function(a){return QBN.meta[a.title]||a.tags};var getVar=State.getVar||Wikifier.getValue,setVar=State.setVar||Wikifier.setValue;setVar("$QBN",{type:{},priority:{}}),$(document).on(":passagestart",function(a){QBN.current=a.passage.title,passageType(a.passage,!1)});function toArgument(a){if("object"==typeof a&&(a=a.title),"string"==typeof a)return JSON.stringify(a);throw new Error("Cards must be referred to by title (got "+typeof a+").")}function toPassage(a){if("object"==typeof a)if(a.link&&a.text)a=a.link;else return a;if("string"!=typeof a)throw new Error("Cards must be referred to by title (got "+typeof a+").");else{if(Story.has(a))return Story.get(a);let b=JSON.parse(a),c=b[0],d=b[1],e=b[2];if(passage()===c){let a=getVar(d);if(null!=a&&null!=a[e])return a[e]}throw new Error("No such passage or choice \""+a+"\".")}}QBN.toPassage=toPassage;function passageType(a,b){var c,d=QBN.tags(a);c=0<=d.indexOf("sticky-card")?"sticky-card":!!(0<=d.indexOf("card"))&&"card";var e=getVar("$QBN").type,f=e[a.title];return void 0===f&&(f=c),void 0!==b&&b!==f&&(null===b?e[a.title]=!1:!1===b?"card"===f&&(e[a.title]=!1):b===c?delete e[a.title]:e[a.title]=b),f}function shuffle(b){for(let a=b.length;0d?1:0};function choose(a,b,c){var d=Math.min;if(null==b||!1===b)return c?a:shuffle(a);b=Math.max(0,d(b,a.length));for(var e=d(b,a.length-b),f=e===b||void 0,g=[],h={},j=0;ja},lte:function(c,a){return c<=a},le:function(c,a){return c<=a},gte:function(c,a){return c>=a},ge:function(c,a){return c>=a},eqvar:function(c,a,b,d){return c==QBN.value(d)},neqvar:function(c,a,b,d){return c==QBN.value(d)},ltvar:function(c,a,b,d){return c==QBN.value(d)},gtvar:function(c,a,b,d){return c==QBN.value(d)},ltevar:function(c,a,b,d){return c==QBN.value(d)},gtevar:function(c,a,b,d){return c==QBN.value(d)},before:function(c,a,b){return QBN.progress(b,c)QBN.progress(b,a)},endingAt:function(c,a,b){return QBN.progress(b,c)<=QBN.progress(b,a)},startingAt:function(c,a,b){return QBN.progress(b,c)>=QBN.progress(b,a)}},operatorNames={eq:"to be",ne:"not to be",lt:"to be less than",le:"to be at most",gt:"to be greater than",ge:"to be at least"};QBN.functions={twinescript:{match:/^\s.*/,action:function(a){try{return Scripting.evalTwineScript(a[0])}catch(b){throw b.message+=" in: "+a[0],b}},description:function(a){return"\"\"\""+a[0]+"\"\"\""}},not:{match:/^not-(.+)/,action:function(a){return!QBN.requirementMet(a[1])},description:function(a){var b=QBN.description(a[1]);return null==b?b:"not "+b}},passage:{match:/^passage-(.+)/,action:function(a){return passage()===a[1]||passage()===a[1].replace(/_/g," ")},description:function(){return null}},tagged:{match:/^tagged-(.+)/,action:function(a){return tags().includes(a[1])},description:function(){return null}},visited:{match:/^visited-([^-]+)/,action:function(a){return 0c){var d="QBN.range: invalid range spec:";throw d+=" must have at least two values",d+=" (got "+JSON.stringify(c)+").",new Error(d)}for(var e,f,g,h,j=0;j>: "+(a.message||a))}setVar("_"+a+"_"+c.substring(1),!0),setVar("_"+c.substring(1)+"_range",a)}}),QBN.value=function(a){var b=State.variables,c=State.temporary;return null==c[a]?b[a]:c[a]},QBN.requirementMet=function(a){var b=null;for(var c in QBN.functions)if(QBN.functions.hasOwnProperty(c)){var d=QBN.functions[c],e=d.match.exec(a);if(e){b=d.action(e);break}}return null===b&&(b=QBN.value(a)),!!b},QBN.description=function(a){var b=null;for(var c in QBN.functions)if(QBN.functions.hasOwnProperty(c)){var d=QBN.functions[c],e=d.match.exec(a);if(e){b=d.description(e);break}}return null===b&&(b=a),b},QBN.tagsMatch=function(a,b){a=toPassage(a);let c=QBN.current;QBN.current=a.title;let d=QBN.tags(a);for(var e=0;e>"),d&&f>"):e.wiki(d))}}}),Macro.add("requirements",{handler:function(){var a=$(this.output),b=toPassage(this.args[0]||QBN.current),c=this.args[1];if(c&&!Macro.has(c))return this.error("No such widget "+JSON.stringify(c)+".");for(var d,e=this.args[2]||"comma",f=QBN.requirements(b),g=0;g>"):a.wiki(d),e&&g>"):a.append(document.createTextNode(e)))}});function addTo(a,b){var c="string"==typeof b?b:b.title,d=!a[c];return d&&(a[c]=!0),d}function firstWord(a){var b=a.indexOf(" ");return a.substring(0,-1==b?a.length:b)}Macro.add("fillhand",{handler:function(){try{var a=this.args[0],b=this.args[1],c=this.args[2];if(!a){a=[];var d=firstWord(this.args.raw).substring(1);if(!setVar(d,a))return this.error("<>: failed to set hand \""+d+"\".")}var e,f={};for(e=0;e>: "+("object"==typeof a?a.message:a))}}}),Macro.add("card",{tags:["contents"],handler:function(){var a=$(this.output);if(getVar("_qbn_cover"))a.wiki(this.payload[0].contents.trim());else for(var b=1;bc.indexOf("card")&&0>c.indexOf("sticky-card")&&c.push("card"),a.push({title:JSON.stringify([passage(),b,a.length]),tags:c})}Macro.add("choices",{tags:["when","offer"],handler:function(){var a=this.args.raw,b=invalidName(a);if(b)return this.error(b);for(var c=[],d=0;d> content must be in sub-tags.");break;case"when":if(partialChoice(c))return this.error("This choice already has a \"when\" clause (section "+d+", "+e.contents.substring(0,30)+").");var f=QBN.parseTagsInto(e.contents.trim(),[]);beginChoice(c,a,f);break;case"offer":partialChoice(c)||beginChoice(c,a,[]),c[c.length-1].text=e.contents.trim(),""!==e.args[0]&&(c[e.args[0]]=c[c.length-1]);}}setVar(a,c)}}),QBN.progress=function(a,b){a=a.replace(/^[$_]/,"");let c=setup[a];if(null==c)throw"No such progress sequence "+JSON.stringify(a)+".";for(let d=0;d!Home +State.initPRNG();var QBN={meta:{}};window.QBN=QBN,QBN.parseTagsInto=function(a,b){let c,d=new RegExp("("+["[a-zA-Z0-9-_\\.]+(?:\\s+|$)","[a-zA-Z0-9_\\.]+:[^\\n]*(?:\\n|$)\\s*","[^\\n]+(?:\\n|$)\\s*"].join(")|(")+")","g"),e=!1;for(;null!=(c=d.exec(a));)if(c[1]!==void 0)e?(b[b.length-1]+=c[1],!/\\\n/.test(c[1])&&(e=!1)):b.push(c[1].trim());else if(c[2]!==void 0){let a=c[2].replace(":","- "),d=a.replace("\\\n","");d.length!==a.length&&(e=!0),b.push(d)}else if(c[3]!==void 0){if(e)b[b.length-1]+=c[3];else throw new Error("Invalid metadata: "+JSON.stringify(c[3]));/(^|[^\\])\n/.test(c[3])&&(e=!1)}return b};const commentPattern=/\/\*\s*QBN\s([^*]*)\s\*\//g;Story.lookupWith(function(a){let b,c=a.tags.slice();for(;null!=(b=commentPattern.exec(a.text));){let a=b[1].trim();QBN.parseTagsInto(a,c)}return QBN.meta[a.title]=c,!1}),QBN.tags=function(a){return QBN.meta[a.title]||a.tags};var getVar=State.getVar||Wikifier.getValue,setVar=State.setVar||Wikifier.setValue;setVar("$QBN",{type:{},priority:{}}),$(document).on(":passagestart",function(a){QBN.current=a.passage.title,passageType(a.passage,!1)});function toArgument(a){if("object"==typeof a&&(a=a.title),"string"==typeof a)return JSON.stringify(a);throw new Error("Cards must be referred to by title (got "+typeof a+").")}function toPassage(a){if("object"==typeof a)if(a.link&&a.text)a=a.link;else return a;if("string"!=typeof a)throw new Error("Cards must be referred to by title (got "+typeof a+").");else{if(Story.has(a))return Story.get(a);let b=JSON.parse(a),c=b[0],d=b[1],e=b[2];if(passage()===c){let a=getVar(d);if(null!=a&&null!=a[e])return a[e]}throw new Error("No such passage or choice \""+a+"\".")}}QBN.toPassage=toPassage;function passageType(a,b){var c,d=QBN.tags(a);c=0<=d.indexOf("sticky-card")?"sticky-card":!!(0<=d.indexOf("card"))&&"card";var e=getVar("$QBN").type,f=e[a.title];return void 0===f&&(f=c),void 0!==b&&b!==f&&(null===b?e[a.title]=!1:!1===b?"card"===f&&(e[a.title]=!1):b===c?delete e[a.title]:e[a.title]=b),f}function shuffle(b){for(let a=b.length;0d?1:0};function choose(a,b,c){var d=Math.min;if(null==b||!1===b)return c?a:shuffle(a);b=Math.max(0,d(b,a.length));for(var e=d(b,a.length-b),f=e===b||void 0,g=[],h={},j=0;ja},lte:function(c,a){return c<=a},le:function(c,a){return c<=a},gte:function(c,a){return c>=a},ge:function(c,a){return c>=a},eqvar:function(c,a,b,d){return c==QBN.value(d)},neqvar:function(c,a,b,d){return c==QBN.value(d)},ltvar:function(c,a,b,d){return c==QBN.value(d)},gtvar:function(c,a,b,d){return c==QBN.value(d)},ltevar:function(c,a,b,d){return c==QBN.value(d)},gtevar:function(c,a,b,d){return c==QBN.value(d)},before:function(c,a,b){return QBN.progress(b,c)QBN.progress(b,a)},endingAt:function(c,a,b){return QBN.progress(b,c)<=QBN.progress(b,a)},startingAt:function(c,a,b){return QBN.progress(b,c)>=QBN.progress(b,a)}},operatorNames={eq:"to be",ne:"not to be",lt:"to be less than",le:"to be at most",gt:"to be greater than",ge:"to be at least"};QBN.functions={twinescript:{match:/^\s.*/,action:function(a){try{return Scripting.evalTwineScript(a[0])}catch(b){throw b.message+=" in: "+a[0],b}},description:function(a){return"\"\"\""+a[0]+"\"\"\""}},not:{match:/^not-(.+)/,action:function(a){return!QBN.requirementMet(a[1])},description:function(a){var b=QBN.description(a[1]);return null==b?b:"not "+b}},passage:{match:/^passage-(.+)/,action:function(a){return passage()===a[1]||passage()===a[1].replace(/_/g," ")},description:function(){return null}},tagged:{match:/^tagged-(.+)/,action:function(a){return tags().includes(a[1])},description:function(){return null}},visited:{match:/^visited-([^-]+)/,action:function(a){return 0c){var d="QBN.range: invalid range spec:";throw d+=" must have at least two values",d+=" (got "+JSON.stringify(c)+").",new Error(d)}for(var e,f,g,h,j=0;j>: "+(a.message||a))}setVar("_"+a+"_"+c.substring(1),!0),setVar("_"+c.substring(1)+"_range",a)}}),QBN.getProperty=function(a,b){var c,d=a.split("."),e=d.length,f=b||this;for(c=0;c>"),d&&f>"):e.wiki(d))}}}),Macro.add("requirements",{handler:function(){var a=$(this.output),b=toPassage(this.args[0]||QBN.current),c=this.args[1];if(c&&!Macro.has(c))return this.error("No such widget "+JSON.stringify(c)+".");for(var d,e=this.args[2]||"comma",f=QBN.requirements(b),g=0;g>"):a.wiki(d),e&&g>"):a.append(document.createTextNode(e)))}});function addTo(a,b){var c="string"==typeof b?b:b.title,d=!a[c];return d&&(a[c]=!0),d}function firstWord(a){var b=a.indexOf(" ");return a.substring(0,-1==b?a.length:b)}Macro.add("fillhand",{handler:function(){try{var a=this.args[0],b=this.args[1],c=this.args[2];if(!a){a=[];var d=firstWord(this.args.raw).substring(1);if(!setVar(d,a))return this.error("<>: failed to set hand \""+d+"\".")}var e,f={};for(e=0;e>: "+("object"==typeof a?a.message:a))}}}),Macro.add("card",{tags:["contents"],handler:function(){var a=$(this.output);if(getVar("_qbn_cover"))a.wiki(this.payload[0].contents.trim());else for(var b=1;bc.indexOf("card")&&0>c.indexOf("sticky-card")&&c.push("card"),a.push({title:JSON.stringify([passage(),b,a.length]),tags:c})}Macro.add("choices",{tags:["when","offer"],handler:function(){var a=this.args.raw,b=invalidName(a);if(b)return this.error(b);for(var c=[],d=0;d> content must be in sub-tags.");break;case"when":if(partialChoice(c))return this.error("This choice already has a \"when\" clause (section "+d+", "+e.contents.substring(0,30)+").");var f=QBN.parseTagsInto(e.contents.trim(),[]);beginChoice(c,a,f);break;case"offer":partialChoice(c)||beginChoice(c,a,[]),c[c.length-1].text=e.contents.trim(),""!==e.args[0]&&(c[e.args[0]]=c[c.length-1]);}}setVar(a,c)}}),QBN.progress=function(a,b){a=a.replace(/^[$_]/,"");let c=setup[a];if(null==c)throw"No such progress sequence "+JSON.stringify(a)+".";for(let d=0;d!Home /*QBN sticky-card req: _driving req: $location neq QBN.current diff --git a/examples/tutorial-2.html b/examples/tutorial-2.html index d322856..123156b 100644 --- a/examples/tutorial-2.html +++ b/examples/tutorial-2.html @@ -180,7 +180,7 @@ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -State.initPRNG();var QBN={meta:{}};window.QBN=QBN,QBN.parseTagsInto=function(a,b){let c,d=new RegExp("("+["[a-zA-Z0-9-_]+(?:\\s+|$)","[a-zA-Z0-9_]+:[^\\n]*(?:\\n|$)\\s*","[^\\n]+(?:\\n|$)\\s*"].join(")|(")+")","g"),e=!1;for(;null!=(c=d.exec(a));)if(c[1]!==void 0)e?(b[b.length-1]+=c[1],!/\\\n/.test(c[1])&&(e=!1)):b.push(c[1].trim());else if(c[2]!==void 0){let a=c[2].replace(":","- "),d=a.replace("\\\n","");d.length!==a.length&&(e=!0),b.push(d)}else if(c[3]!==void 0){if(e)b[b.length-1]+=c[3];else throw new Error("Invalid metadata: "+JSON.stringify(c[3]));/(^|[^\\])\n/.test(c[3])&&(e=!1)}return b};const commentPattern=/\/\*\s*QBN\s([^*]*)\s\*\//g;Story.lookupWith(function(a){let b,c=a.tags.slice();for(;null!=(b=commentPattern.exec(a.text));){let a=b[1].trim();QBN.parseTagsInto(a,c)}return QBN.meta[a.title]=c,!1}),QBN.tags=function(a){return QBN.meta[a.title]||a.tags};var getVar=State.getVar||Wikifier.getValue,setVar=State.setVar||Wikifier.setValue;setVar("$QBN",{type:{},priority:{}}),$(document).on(":passagestart",function(a){QBN.current=a.passage.title,passageType(a.passage,!1)});function toArgument(a){if("object"==typeof a&&(a=a.title),"string"==typeof a)return JSON.stringify(a);throw new Error("Cards must be referred to by title (got "+typeof a+").")}function toPassage(a){if("object"==typeof a)if(a.link&&a.text)a=a.link;else return a;if("string"!=typeof a)throw new Error("Cards must be referred to by title (got "+typeof a+").");else{if(Story.has(a))return Story.get(a);let b=JSON.parse(a),c=b[0],d=b[1],e=b[2];if(passage()===c){let a=getVar(d);if(null!=a&&null!=a[e])return a[e]}throw new Error("No such passage or choice \""+a+"\".")}}QBN.toPassage=toPassage;function passageType(a,b){var c,d=QBN.tags(a);c=0<=d.indexOf("sticky-card")?"sticky-card":!!(0<=d.indexOf("card"))&&"card";var e=getVar("$QBN").type,f=e[a.title];return void 0===f&&(f=c),void 0!==b&&b!==f&&(null===b?e[a.title]=!1:!1===b?"card"===f&&(e[a.title]=!1):b===c?delete e[a.title]:e[a.title]=b),f}function shuffle(b){for(let a=b.length;0d?1:0};function choose(a,b,c){var d=Math.min;if(null==b||!1===b)return c?a:shuffle(a);b=Math.max(0,d(b,a.length));for(var e=d(b,a.length-b),f=e===b||void 0,g=[],h={},j=0;ja},lte:function(c,a){return c<=a},le:function(c,a){return c<=a},gte:function(c,a){return c>=a},ge:function(c,a){return c>=a},eqvar:function(c,a,b,d){return c==QBN.value(d)},neqvar:function(c,a,b,d){return c==QBN.value(d)},ltvar:function(c,a,b,d){return c==QBN.value(d)},gtvar:function(c,a,b,d){return c==QBN.value(d)},ltevar:function(c,a,b,d){return c==QBN.value(d)},gtevar:function(c,a,b,d){return c==QBN.value(d)},before:function(c,a,b){return QBN.progress(b,c)QBN.progress(b,a)},endingAt:function(c,a,b){return QBN.progress(b,c)<=QBN.progress(b,a)},startingAt:function(c,a,b){return QBN.progress(b,c)>=QBN.progress(b,a)}},operatorNames={eq:"to be",ne:"not to be",lt:"to be less than",le:"to be at most",gt:"to be greater than",ge:"to be at least"};QBN.functions={twinescript:{match:/^\s.*/,action:function(a){try{return Scripting.evalTwineScript(a[0])}catch(b){throw b.message+=" in: "+a[0],b}},description:function(a){return"\"\"\""+a[0]+"\"\"\""}},not:{match:/^not-(.+)/,action:function(a){return!QBN.requirementMet(a[1])},description:function(a){var b=QBN.description(a[1]);return null==b?b:"not "+b}},passage:{match:/^passage-(.+)/,action:function(a){return passage()===a[1]||passage()===a[1].replace(/_/g," ")},description:function(){return null}},tagged:{match:/^tagged-(.+)/,action:function(a){return tags().includes(a[1])},description:function(){return null}},visited:{match:/^visited-([^-]+)/,action:function(a){return 0c){var d="QBN.range: invalid range spec:";throw d+=" must have at least two values",d+=" (got "+JSON.stringify(c)+").",new Error(d)}for(var e,f,g,h,j=0;j>: "+(a.message||a))}setVar("_"+a+"_"+c.substring(1),!0),setVar("_"+c.substring(1)+"_range",a)}}),QBN.value=function(a){var b=State.variables,c=State.temporary;return null==c[a]?b[a]:c[a]},QBN.requirementMet=function(a){var b=null;for(var c in QBN.functions)if(QBN.functions.hasOwnProperty(c)){var d=QBN.functions[c],e=d.match.exec(a);if(e){b=d.action(e);break}}return null===b&&(b=QBN.value(a)),!!b},QBN.description=function(a){var b=null;for(var c in QBN.functions)if(QBN.functions.hasOwnProperty(c)){var d=QBN.functions[c],e=d.match.exec(a);if(e){b=d.description(e);break}}return null===b&&(b=a),b},QBN.tagsMatch=function(a,b){a=toPassage(a);let c=QBN.current;QBN.current=a.title;let d=QBN.tags(a);for(var e=0;e>"),d&&f>"):e.wiki(d))}}}),Macro.add("requirements",{handler:function(){var a=$(this.output),b=toPassage(this.args[0]||QBN.current),c=this.args[1];if(c&&!Macro.has(c))return this.error("No such widget "+JSON.stringify(c)+".");for(var d,e=this.args[2]||"comma",f=QBN.requirements(b),g=0;g>"):a.wiki(d),e&&g>"):a.append(document.createTextNode(e)))}});function addTo(a,b){var c="string"==typeof b?b:b.title,d=!a[c];return d&&(a[c]=!0),d}function firstWord(a){var b=a.indexOf(" ");return a.substring(0,-1==b?a.length:b)}Macro.add("fillhand",{handler:function(){try{var a=this.args[0],b=this.args[1],c=this.args[2];if(!a){a=[];var d=firstWord(this.args.raw).substring(1);if(!setVar(d,a))return this.error("<>: failed to set hand \""+d+"\".")}var e,f={};for(e=0;e>: "+("object"==typeof a?a.message:a))}}}),Macro.add("card",{tags:["contents"],handler:function(){var a=$(this.output);if(getVar("_qbn_cover"))a.wiki(this.payload[0].contents.trim());else for(var b=1;bc.indexOf("card")&&0>c.indexOf("sticky-card")&&c.push("card"),a.push({title:JSON.stringify([passage(),b,a.length]),tags:c})}Macro.add("choices",{tags:["when","offer"],handler:function(){var a=this.args.raw,b=invalidName(a);if(b)return this.error(b);for(var c=[],d=0;d> content must be in sub-tags.");break;case"when":if(partialChoice(c))return this.error("This choice already has a \"when\" clause (section "+d+", "+e.contents.substring(0,30)+").");var f=QBN.parseTagsInto(e.contents.trim(),[]);beginChoice(c,a,f);break;case"offer":partialChoice(c)||beginChoice(c,a,[]),c[c.length-1].text=e.contents.trim(),""!==e.args[0]&&(c[e.args[0]]=c[c.length-1]);}}setVar(a,c)}}),QBN.progress=function(a,b){a=a.replace(/^[$_]/,"");let c=setup[a];if(null==c)throw"No such progress sequence "+JSON.stringify(a)+".";for(let d=0;d<<set $month to 1>> +State.initPRNG();var QBN={meta:{}};window.QBN=QBN,QBN.parseTagsInto=function(a,b){let c,d=new RegExp("("+["[a-zA-Z0-9-_\\.]+(?:\\s+|$)","[a-zA-Z0-9_\\.]+:[^\\n]*(?:\\n|$)\\s*","[^\\n]+(?:\\n|$)\\s*"].join(")|(")+")","g"),e=!1;for(;null!=(c=d.exec(a));)if(c[1]!==void 0)e?(b[b.length-1]+=c[1],!/\\\n/.test(c[1])&&(e=!1)):b.push(c[1].trim());else if(c[2]!==void 0){let a=c[2].replace(":","- "),d=a.replace("\\\n","");d.length!==a.length&&(e=!0),b.push(d)}else if(c[3]!==void 0){if(e)b[b.length-1]+=c[3];else throw new Error("Invalid metadata: "+JSON.stringify(c[3]));/(^|[^\\])\n/.test(c[3])&&(e=!1)}return b};const commentPattern=/\/\*\s*QBN\s([^*]*)\s\*\//g;Story.lookupWith(function(a){let b,c=a.tags.slice();for(;null!=(b=commentPattern.exec(a.text));){let a=b[1].trim();QBN.parseTagsInto(a,c)}return QBN.meta[a.title]=c,!1}),QBN.tags=function(a){return QBN.meta[a.title]||a.tags};var getVar=State.getVar||Wikifier.getValue,setVar=State.setVar||Wikifier.setValue;setVar("$QBN",{type:{},priority:{}}),$(document).on(":passagestart",function(a){QBN.current=a.passage.title,passageType(a.passage,!1)});function toArgument(a){if("object"==typeof a&&(a=a.title),"string"==typeof a)return JSON.stringify(a);throw new Error("Cards must be referred to by title (got "+typeof a+").")}function toPassage(a){if("object"==typeof a)if(a.link&&a.text)a=a.link;else return a;if("string"!=typeof a)throw new Error("Cards must be referred to by title (got "+typeof a+").");else{if(Story.has(a))return Story.get(a);let b=JSON.parse(a),c=b[0],d=b[1],e=b[2];if(passage()===c){let a=getVar(d);if(null!=a&&null!=a[e])return a[e]}throw new Error("No such passage or choice \""+a+"\".")}}QBN.toPassage=toPassage;function passageType(a,b){var c,d=QBN.tags(a);c=0<=d.indexOf("sticky-card")?"sticky-card":!!(0<=d.indexOf("card"))&&"card";var e=getVar("$QBN").type,f=e[a.title];return void 0===f&&(f=c),void 0!==b&&b!==f&&(null===b?e[a.title]=!1:!1===b?"card"===f&&(e[a.title]=!1):b===c?delete e[a.title]:e[a.title]=b),f}function shuffle(b){for(let a=b.length;0d?1:0};function choose(a,b,c){var d=Math.min;if(null==b||!1===b)return c?a:shuffle(a);b=Math.max(0,d(b,a.length));for(var e=d(b,a.length-b),f=e===b||void 0,g=[],h={},j=0;ja},lte:function(c,a){return c<=a},le:function(c,a){return c<=a},gte:function(c,a){return c>=a},ge:function(c,a){return c>=a},eqvar:function(c,a,b,d){return c==QBN.value(d)},neqvar:function(c,a,b,d){return c==QBN.value(d)},ltvar:function(c,a,b,d){return c==QBN.value(d)},gtvar:function(c,a,b,d){return c==QBN.value(d)},ltevar:function(c,a,b,d){return c==QBN.value(d)},gtevar:function(c,a,b,d){return c==QBN.value(d)},before:function(c,a,b){return QBN.progress(b,c)QBN.progress(b,a)},endingAt:function(c,a,b){return QBN.progress(b,c)<=QBN.progress(b,a)},startingAt:function(c,a,b){return QBN.progress(b,c)>=QBN.progress(b,a)}},operatorNames={eq:"to be",ne:"not to be",lt:"to be less than",le:"to be at most",gt:"to be greater than",ge:"to be at least"};QBN.functions={twinescript:{match:/^\s.*/,action:function(a){try{return Scripting.evalTwineScript(a[0])}catch(b){throw b.message+=" in: "+a[0],b}},description:function(a){return"\"\"\""+a[0]+"\"\"\""}},not:{match:/^not-(.+)/,action:function(a){return!QBN.requirementMet(a[1])},description:function(a){var b=QBN.description(a[1]);return null==b?b:"not "+b}},passage:{match:/^passage-(.+)/,action:function(a){return passage()===a[1]||passage()===a[1].replace(/_/g," ")},description:function(){return null}},tagged:{match:/^tagged-(.+)/,action:function(a){return tags().includes(a[1])},description:function(){return null}},visited:{match:/^visited-([^-]+)/,action:function(a){return 0c){var d="QBN.range: invalid range spec:";throw d+=" must have at least two values",d+=" (got "+JSON.stringify(c)+").",new Error(d)}for(var e,f,g,h,j=0;j>: "+(a.message||a))}setVar("_"+a+"_"+c.substring(1),!0),setVar("_"+c.substring(1)+"_range",a)}}),QBN.getProperty=function(a,b){var c,d=a.split("."),e=d.length,f=b||this;for(c=0;c>"),d&&f>"):e.wiki(d))}}}),Macro.add("requirements",{handler:function(){var a=$(this.output),b=toPassage(this.args[0]||QBN.current),c=this.args[1];if(c&&!Macro.has(c))return this.error("No such widget "+JSON.stringify(c)+".");for(var d,e=this.args[2]||"comma",f=QBN.requirements(b),g=0;g>"):a.wiki(d),e&&g>"):a.append(document.createTextNode(e)))}});function addTo(a,b){var c="string"==typeof b?b:b.title,d=!a[c];return d&&(a[c]=!0),d}function firstWord(a){var b=a.indexOf(" ");return a.substring(0,-1==b?a.length:b)}Macro.add("fillhand",{handler:function(){try{var a=this.args[0],b=this.args[1],c=this.args[2];if(!a){a=[];var d=firstWord(this.args.raw).substring(1);if(!setVar(d,a))return this.error("<>: failed to set hand \""+d+"\".")}var e,f={};for(e=0;e>: "+("object"==typeof a?a.message:a))}}}),Macro.add("card",{tags:["contents"],handler:function(){var a=$(this.output);if(getVar("_qbn_cover"))a.wiki(this.payload[0].contents.trim());else for(var b=1;bc.indexOf("card")&&0>c.indexOf("sticky-card")&&c.push("card"),a.push({title:JSON.stringify([passage(),b,a.length]),tags:c})}Macro.add("choices",{tags:["when","offer"],handler:function(){var a=this.args.raw,b=invalidName(a);if(b)return this.error(b);for(var c=[],d=0;d> content must be in sub-tags.");break;case"when":if(partialChoice(c))return this.error("This choice already has a \"when\" clause (section "+d+", "+e.contents.substring(0,30)+").");var f=QBN.parseTagsInto(e.contents.trim(),[]);beginChoice(c,a,f);break;case"offer":partialChoice(c)||beginChoice(c,a,[]),c[c.length-1].text=e.contents.trim(),""!==e.args[0]&&(c[e.args[0]]=c[c.length-1]);}}setVar(a,c)}}),QBN.progress=function(a,b){a=a.replace(/^[$_]/,"");let c=setup[a];if(null==c)throw"No such progress sequence "+JSON.stringify(a)+".";for(let d=0;d<<set $month to 1>> <<set setup.monthnames to ["", "January", "February", "March", "April", "May", "June", "July", "August", diff --git a/package.json b/package.json index cb731f9..7b6be77 100644 --- a/package.json +++ b/package.json @@ -14,12 +14,14 @@ "ex-localvore2": "cd examples && tweego -o tutorial-2.html tutorial-2.tw common", "ex-localvore": "cd examples && tweego -o localvore.html localvore.tw common", "ex-covers": "cd examples && tweego -o covers.html covers.tw common", + "ex-covers-dot-notation": "cd examples && tweego -o covers-dot-notation.html covers-dot-notation.tw common", "ex-choices": "cd examples && tweego -o choices.html choices.tw common", + "ex-dot-notation": "cd examples && tweego -o dot-notation.html dot-notation.tw common", "ex-priority": "cd examples && tweego -o priority.html priority.tw common", "ex-progress": "cd examples && tweego -o progress.html progress.tw common", "ex-sprawl": "cd examples && tweego -o sprawl.html sprawl.tw sprawl.css common", "ex-dice-rolls": "cd examples && tweego -o dice-rolls.html dice-rolls.tw common", - "examples": "npm run copy-common && npm run ex-localvore1 && npm run ex-localvore2 && npm run ex-localvore && npm run ex-covers && npm run ex-choices && npm run ex-priority && npm run ex-progress && npm run ex-sprawl && npm run ex-dice-rolls" + "examples": "npm run copy-common && npm run ex-localvore1 && npm run ex-localvore2 && npm run ex-localvore && npm run ex-covers && npm run ex-covers-dot-notation && npm run ex-choices && npm run ex-dot-notation && npm run ex-priority && npm run ex-progress && npm run ex-sprawl && npm run ex-dice-rolls" }, "author": "Josh Grams ", "license": "ISC", diff --git a/story-javascript.js b/story-javascript.js index c5c0f16..ed5d0ff 100644 --- a/story-javascript.js +++ b/story-javascript.js @@ -16,8 +16,8 @@ window.QBN = QBN QBN.parseTagsInto = function(text, tags) { let patterns = [ - "[a-zA-Z0-9-_]+(?:\\s+|$)", // tag - "[a-zA-Z0-9_]+:[^\\n]*(?:\\n|$)\\s*", // tag with TwineScript expression + "[a-zA-Z0-9-_\\.]+(?:\\s+|$)", // tag + "[a-zA-Z0-9_\\.]+:[^\\n]*(?:\\n|$)\\s*", // tag with TwineScript expression "[^\\n]+(?:\\n|$)\\s*" // continue expression or error ] let tokenPattern = new RegExp('(' + patterns.join(')|(') + ')', 'g') @@ -426,9 +426,25 @@ Macro.add('range', { } }) +QBN.getProperty = function(propertyName, object) { + var parts = propertyName.split("."), + length = parts.length, + i, + property = object || this; + for (i = 0; i < length; i++) { + if (parts[i] in property) { + property = property[parts[i]]; + } else { + i = length + property = undefined + } + } + return property; +} + QBN.value = function(name) { - var v = State.variables, t = State.temporary - return t[name] != null ? t[name] : v[name] + var v = QBN.getProperty(name, State.variables), t = QBN.getProperty(name, State.temporary) + return t != null ? t : v } QBN.requirementMet = function(req) { diff --git a/story-javascript.min.js b/story-javascript.min.js index 55e7994..507a89b 100644 --- a/story-javascript.min.js +++ b/story-javascript.min.js @@ -66,4 +66,4 @@ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -State.initPRNG();var QBN={meta:{}};window.QBN=QBN,QBN.parseTagsInto=function(a,b){let c,d=new RegExp("("+["[a-zA-Z0-9-_]+(?:\\s+|$)","[a-zA-Z0-9_]+:[^\\n]*(?:\\n|$)\\s*","[^\\n]+(?:\\n|$)\\s*"].join(")|(")+")","g"),e=!1;for(;null!=(c=d.exec(a));)if(c[1]!==void 0)e?(b[b.length-1]+=c[1],!/\\\n/.test(c[1])&&(e=!1)):b.push(c[1].trim());else if(c[2]!==void 0){let a=c[2].replace(":","- "),d=a.replace("\\\n","");d.length!==a.length&&(e=!0),b.push(d)}else if(c[3]!==void 0){if(e)b[b.length-1]+=c[3];else throw new Error("Invalid metadata: "+JSON.stringify(c[3]));/(^|[^\\])\n/.test(c[3])&&(e=!1)}return b};const commentPattern=/\/\*\s*QBN\s([^*]*)\s\*\//g;Story.lookupWith(function(a){let b,c=a.tags.slice();for(;null!=(b=commentPattern.exec(a.text));){let a=b[1].trim();QBN.parseTagsInto(a,c)}return QBN.meta[a.title]=c,!1}),QBN.tags=function(a){return QBN.meta[a.title]||a.tags};var getVar=State.getVar||Wikifier.getValue,setVar=State.setVar||Wikifier.setValue;setVar("$QBN",{type:{},priority:{}}),$(document).on(":passagestart",function(a){QBN.current=a.passage.title,passageType(a.passage,!1)});function toArgument(a){if("object"==typeof a&&(a=a.title),"string"==typeof a)return JSON.stringify(a);throw new Error("Cards must be referred to by title (got "+typeof a+").")}function toPassage(a){if("object"==typeof a)if(a.link&&a.text)a=a.link;else return a;if("string"!=typeof a)throw new Error("Cards must be referred to by title (got "+typeof a+").");else{if(Story.has(a))return Story.get(a);let b=JSON.parse(a),c=b[0],d=b[1],e=b[2];if(passage()===c){let a=getVar(d);if(null!=a&&null!=a[e])return a[e]}throw new Error("No such passage or choice \""+a+"\".")}}QBN.toPassage=toPassage;function passageType(a,b){var c,d=QBN.tags(a);c=0<=d.indexOf("sticky-card")?"sticky-card":!!(0<=d.indexOf("card"))&&"card";var e=getVar("$QBN").type,f=e[a.title];return void 0===f&&(f=c),void 0!==b&&b!==f&&(null===b?e[a.title]=!1:!1===b?"card"===f&&(e[a.title]=!1):b===c?delete e[a.title]:e[a.title]=b),f}function shuffle(b){for(let a=b.length;0d?1:0};function choose(a,b,c){var d=Math.min;if(null==b||!1===b)return c?a:shuffle(a);b=Math.max(0,d(b,a.length));for(var e=d(b,a.length-b),f=e===b||void 0,g=[],h={},j=0;ja},lte:function(c,a){return c<=a},le:function(c,a){return c<=a},gte:function(c,a){return c>=a},ge:function(c,a){return c>=a},eqvar:function(c,a,b,d){return c==QBN.value(d)},neqvar:function(c,a,b,d){return c==QBN.value(d)},ltvar:function(c,a,b,d){return c==QBN.value(d)},gtvar:function(c,a,b,d){return c==QBN.value(d)},ltevar:function(c,a,b,d){return c==QBN.value(d)},gtevar:function(c,a,b,d){return c==QBN.value(d)},before:function(c,a,b){return QBN.progress(b,c)QBN.progress(b,a)},endingAt:function(c,a,b){return QBN.progress(b,c)<=QBN.progress(b,a)},startingAt:function(c,a,b){return QBN.progress(b,c)>=QBN.progress(b,a)}},operatorNames={eq:"to be",ne:"not to be",lt:"to be less than",le:"to be at most",gt:"to be greater than",ge:"to be at least"};QBN.functions={twinescript:{match:/^\s.*/,action:function(a){try{return Scripting.evalTwineScript(a[0])}catch(b){throw b.message+=" in: "+a[0],b}},description:function(a){return"\"\"\""+a[0]+"\"\"\""}},not:{match:/^not-(.+)/,action:function(a){return!QBN.requirementMet(a[1])},description:function(a){var b=QBN.description(a[1]);return null==b?b:"not "+b}},passage:{match:/^passage-(.+)/,action:function(a){return passage()===a[1]||passage()===a[1].replace(/_/g," ")},description:function(){return null}},tagged:{match:/^tagged-(.+)/,action:function(a){return tags().includes(a[1])},description:function(){return null}},visited:{match:/^visited-([^-]+)/,action:function(a){return 0c){var d="QBN.range: invalid range spec:";throw d+=" must have at least two values",d+=" (got "+JSON.stringify(c)+").",new Error(d)}for(var e,f,g,h,j=0;j>: "+(a.message||a))}setVar("_"+a+"_"+c.substring(1),!0),setVar("_"+c.substring(1)+"_range",a)}}),QBN.value=function(a){var b=State.variables,c=State.temporary;return null==c[a]?b[a]:c[a]},QBN.requirementMet=function(a){var b=null;for(var c in QBN.functions)if(QBN.functions.hasOwnProperty(c)){var d=QBN.functions[c],e=d.match.exec(a);if(e){b=d.action(e);break}}return null===b&&(b=QBN.value(a)),!!b},QBN.description=function(a){var b=null;for(var c in QBN.functions)if(QBN.functions.hasOwnProperty(c)){var d=QBN.functions[c],e=d.match.exec(a);if(e){b=d.description(e);break}}return null===b&&(b=a),b},QBN.tagsMatch=function(a,b){a=toPassage(a);let c=QBN.current;QBN.current=a.title;let d=QBN.tags(a);for(var e=0;e>"),d&&f>"):e.wiki(d))}}}),Macro.add("requirements",{handler:function(){var a=$(this.output),b=toPassage(this.args[0]||QBN.current),c=this.args[1];if(c&&!Macro.has(c))return this.error("No such widget "+JSON.stringify(c)+".");for(var d,e=this.args[2]||"comma",f=QBN.requirements(b),g=0;g>"):a.wiki(d),e&&g>"):a.append(document.createTextNode(e)))}});function addTo(a,b){var c="string"==typeof b?b:b.title,d=!a[c];return d&&(a[c]=!0),d}function firstWord(a){var b=a.indexOf(" ");return a.substring(0,-1==b?a.length:b)}Macro.add("fillhand",{handler:function(){try{var a=this.args[0],b=this.args[1],c=this.args[2];if(!a){a=[];var d=firstWord(this.args.raw).substring(1);if(!setVar(d,a))return this.error("<>: failed to set hand \""+d+"\".")}var e,f={};for(e=0;e>: "+("object"==typeof a?a.message:a))}}}),Macro.add("card",{tags:["contents"],handler:function(){var a=$(this.output);if(getVar("_qbn_cover"))a.wiki(this.payload[0].contents.trim());else for(var b=1;bc.indexOf("card")&&0>c.indexOf("sticky-card")&&c.push("card"),a.push({title:JSON.stringify([passage(),b,a.length]),tags:c})}Macro.add("choices",{tags:["when","offer"],handler:function(){var a=this.args.raw,b=invalidName(a);if(b)return this.error(b);for(var c=[],d=0;d> content must be in sub-tags.");break;case"when":if(partialChoice(c))return this.error("This choice already has a \"when\" clause (section "+d+", "+e.contents.substring(0,30)+").");var f=QBN.parseTagsInto(e.contents.trim(),[]);beginChoice(c,a,f);break;case"offer":partialChoice(c)||beginChoice(c,a,[]),c[c.length-1].text=e.contents.trim(),""!==e.args[0]&&(c[e.args[0]]=c[c.length-1]);}}setVar(a,c)}}),QBN.progress=function(a,b){a=a.replace(/^[$_]/,"");let c=setup[a];if(null==c)throw"No such progress sequence "+JSON.stringify(a)+".";for(let d=0;dd?1:0};function choose(a,b,c){var d=Math.min;if(null==b||!1===b)return c?a:shuffle(a);b=Math.max(0,d(b,a.length));for(var e=d(b,a.length-b),f=e===b||void 0,g=[],h={},j=0;ja},lte:function(c,a){return c<=a},le:function(c,a){return c<=a},gte:function(c,a){return c>=a},ge:function(c,a){return c>=a},eqvar:function(c,a,b,d){return c==QBN.value(d)},neqvar:function(c,a,b,d){return c==QBN.value(d)},ltvar:function(c,a,b,d){return c==QBN.value(d)},gtvar:function(c,a,b,d){return c==QBN.value(d)},ltevar:function(c,a,b,d){return c==QBN.value(d)},gtevar:function(c,a,b,d){return c==QBN.value(d)},before:function(c,a,b){return QBN.progress(b,c)QBN.progress(b,a)},endingAt:function(c,a,b){return QBN.progress(b,c)<=QBN.progress(b,a)},startingAt:function(c,a,b){return QBN.progress(b,c)>=QBN.progress(b,a)}},operatorNames={eq:"to be",ne:"not to be",lt:"to be less than",le:"to be at most",gt:"to be greater than",ge:"to be at least"};QBN.functions={twinescript:{match:/^\s.*/,action:function(a){try{return Scripting.evalTwineScript(a[0])}catch(b){throw b.message+=" in: "+a[0],b}},description:function(a){return"\"\"\""+a[0]+"\"\"\""}},not:{match:/^not-(.+)/,action:function(a){return!QBN.requirementMet(a[1])},description:function(a){var b=QBN.description(a[1]);return null==b?b:"not "+b}},passage:{match:/^passage-(.+)/,action:function(a){return passage()===a[1]||passage()===a[1].replace(/_/g," ")},description:function(){return null}},tagged:{match:/^tagged-(.+)/,action:function(a){return tags().includes(a[1])},description:function(){return null}},visited:{match:/^visited-([^-]+)/,action:function(a){return 0c){var d="QBN.range: invalid range spec:";throw d+=" must have at least two values",d+=" (got "+JSON.stringify(c)+").",new Error(d)}for(var e,f,g,h,j=0;j>: "+(a.message||a))}setVar("_"+a+"_"+c.substring(1),!0),setVar("_"+c.substring(1)+"_range",a)}}),QBN.getProperty=function(a,b){var c,d=a.split("."),e=d.length,f=b||this;for(c=0;c>"),d&&f>"):e.wiki(d))}}}),Macro.add("requirements",{handler:function(){var a=$(this.output),b=toPassage(this.args[0]||QBN.current),c=this.args[1];if(c&&!Macro.has(c))return this.error("No such widget "+JSON.stringify(c)+".");for(var d,e=this.args[2]||"comma",f=QBN.requirements(b),g=0;g>"):a.wiki(d),e&&g>"):a.append(document.createTextNode(e)))}});function addTo(a,b){var c="string"==typeof b?b:b.title,d=!a[c];return d&&(a[c]=!0),d}function firstWord(a){var b=a.indexOf(" ");return a.substring(0,-1==b?a.length:b)}Macro.add("fillhand",{handler:function(){try{var a=this.args[0],b=this.args[1],c=this.args[2];if(!a){a=[];var d=firstWord(this.args.raw).substring(1);if(!setVar(d,a))return this.error("<>: failed to set hand \""+d+"\".")}var e,f={};for(e=0;e>: "+("object"==typeof a?a.message:a))}}}),Macro.add("card",{tags:["contents"],handler:function(){var a=$(this.output);if(getVar("_qbn_cover"))a.wiki(this.payload[0].contents.trim());else for(var b=1;bc.indexOf("card")&&0>c.indexOf("sticky-card")&&c.push("card"),a.push({title:JSON.stringify([passage(),b,a.length]),tags:c})}Macro.add("choices",{tags:["when","offer"],handler:function(){var a=this.args.raw,b=invalidName(a);if(b)return this.error(b);for(var c=[],d=0;d> content must be in sub-tags.");break;case"when":if(partialChoice(c))return this.error("This choice already has a \"when\" clause (section "+d+", "+e.contents.substring(0,30)+").");var f=QBN.parseTagsInto(e.contents.trim(),[]);beginChoice(c,a,f);break;case"offer":partialChoice(c)||beginChoice(c,a,[]),c[c.length-1].text=e.contents.trim(),""!==e.args[0]&&(c[e.args[0]]=c[c.length-1]);}}setVar(a,c)}}),QBN.progress=function(a,b){a=a.replace(/^[$_]/,"");let c=setup[a];if(null==c)throw"No such progress sequence "+JSON.stringify(a)+".";for(let d=0;d