diff --git a/devel/js/main.js b/devel/js/main.js index 144156c..69c35f2 100644 --- a/devel/js/main.js +++ b/devel/js/main.js @@ -19,9 +19,15 @@ situation('start', { choices: ['#testing-option'] }); +situation ('return', { + content: 'Choose an option...', + optionText: 'Return', + choices: ['#testing-option'] +}); + situation('functions-as-properties', { - content: (character, system, from) => - ` + content (character, system, from) { + return ` This property of this situation is outputted by a function, which allows us to incorporate variables such as the name of the situation we came from; in this case, "${from}." @@ -30,9 +36,10 @@ situation('functions-as-properties', { functions; the notable exception is optionText. Those functions are passed the character and system objects, in that order, and a third object that is usually either the current situation, or the situation - we just came from.`, + we just came from.`}, tags: ['testing-option'], - optionText: 'Functions as properties' + optionText: 'Functions as properties', + choices: ['return'] }); situation('markdown-features', { @@ -50,7 +57,8 @@ situation('markdown-features', { Additionally, we also support "smart quotes" and -- dashes.`, tags: ['testing-option'], - optionText: 'Markdown support' + optionText: 'Markdown support', + choices: ['return'] }); situation('special-links', { @@ -72,7 +80,8 @@ situation('special-links', { 'inserter-link': "-- like this" }, tags: ['testing-option'], - optionText: 'Special Links' + optionText: 'Special Links', + choices: ['return'] }); situation('custom-actions', { @@ -93,7 +102,8 @@ situation('custom-actions', { } }, tags: ['testing-option'], - optionText: 'Special Actions' + optionText: 'Special Actions', + choices: ['return'] }); situation('randomness', { @@ -108,37 +118,45 @@ situation('randomness', { ${["dog", "cat", "alpaca", "crow"].shuffle(system).join(', ')}. `, tags: ['testing-option'], - optionText: 'Randomness' + optionText: 'Randomness' , + choices: ['return'] }); var myIterators = {}; situation('iterators', { - content: (character, system, from) => - ` - # Iterators + animal: oneOf('cat', 'crow', 'alpaca').cycling(), + content (character, system, from) { + console.log("got here"); + console.log(this); + return ` + # Iterators - Iterators are an useful feature for generating adaptive text. For example, - clicking ${a('this link').writer('iterator')} will output a - new paragraph with a random animal. + Iterators are an useful feature for generating adaptive text. For example, + clicking ${a('this link').writer('iterator')} will output a + new paragraph with a random animal. - Initialising iterators during your init function will make them even more - useful, since it lets you pass the system object on to them to ensure - consistency between saves. For example, ${a('this link') - .writer('consistent')} will produce the same output every - time. + Initialising iterators during your init function will make them even more + useful, since it lets you pass the system object on to them to ensure + consistency between saves. For example, ${a('this link') + .writer('consistent')} will produce the same output every + time. - Other iterators allow you to ${a('cycle').writer('cycler')} through - different content in ${a('various ways').writer('stopper')}. - `, + Other iterators allow you to ${a('cycle').writer('cycler')} through + different content in ${a('various ways').writer('stopper')}. + + And finally, OneOf iterator objects can be used directly in situations: + ${this.animal}. + ` }, writers: { - iterator: oneOf(['Cat', 'Dog', 'Crow', 'Alpaca']).randomly(), + iterator: oneOf('Cat', 'Dog', 'Crow', 'Alpaca').randomly(), consistent: () => myIterators.consistentIterator(), - cycler: oneOf(['Spring', 'Summer', 'Fall', 'Winter']).cycling(), - stopper: oneOf(['First click', 'Second click', 'Another click']).stopping() + cycler: oneOf('Spring', 'Summer', 'Fall', 'Winter').cycling(), + stopper: oneOf('First click', 'Second click', 'Another click').stopping() }, tags: ['testing-option'], - optionText: 'Iterators' + optionText: 'Iterators', + choices: ['return'] }); situation('progress-bar', { @@ -152,7 +170,8 @@ situation('progress-bar', { through Undum's own API. `, tags: ['testing-option'], - optionText: 'Progress bars' + optionText: 'Progress bars', + choices: ['return'] }); qualities({ diff --git a/docs/situation.md b/docs/situation.md index ac37e8d..0cd6d79 100644 --- a/docs/situation.md +++ b/docs/situation.md @@ -92,6 +92,39 @@ The output from the function is taken as a string to be parsed as markdown, and Inside a content function, the value of `this` is bound to the situation object itself, allowing you to refer to properties of the situation. +#### A note about indentation + +Markdown cares about indentation for things such as `
` blocks and nested lists. However, we as programmers care about indentation to keep our code readable. As a compromise between the two, Raconteur will normalise indentation in content strings by doing the following: + +- Finding the smallest level of indentation on a non-empty line; +- Stripping that level of indentation out of every line. + +This means that if you write: + +```javascript +` + Lorem ipsum dolor sit amet. + + var foo = x; +` +``` + +Then Raconteur will normalise that to: + +```markdown +Lorem ipsum dolor sit amet. + + var foo = x; +``` + +So that when this is parsed as markdown, the first line will be a paragraph and the second line will be a code block. If, for some reason, you need an entire situation's content to be a preformatted code block, you can use a fenced code block: + +~~~markdown +``` +This is a fenced code block. +``` +~~~ + ### tags :: Array (from undum.Situation) A list of tags. See Undum documentation. diff --git a/lib/situation.js b/lib/situation.js index 7b9af06..658e13d 100644 --- a/lib/situation.js +++ b/lib/situation.js @@ -12,17 +12,25 @@ var undum = require('undum-commonjs'), ----------------------------------------------------------------------------*/ /* - Normalises the whitespace on a string. So the indentation level of the - first line will become 0. FIXME: This isn't quite ideal. Need to figure out - a better way of preventing strings in source code ending up interpreted as -blocks. + Normalises the whitespace on a string. */ String.prototype.normaliseTabs = function () { - let lines = this.split('\n'); - let indent = lines[0].match(/^\s+/) || lines[1].match(/^\s+/); - if (!indent) return this; - return lines.map( s => s.replace(new RegExp('^' + indent), '')).join('\n'); + var lines = this.split('\n'); + var indents = lines + .filter((l) => l !== '') // Ignore empty lines + .map((l) => l.match(/^\s+/)) + .map(function (m) { + if (m === null) return ''; + return m[0]; + }); + var smallestIndent = indents.reduce(function(max, curr) { + if (curr.length < max.length) return curr; + return max; + }); // Find the "bottom" indentation level + return lines.map(function (l) { + return l.replace(new RegExp('^' + smallestIndent), ''); + }).join('\n'); }; /* Agnostic Call */