mirror of
https://github.com/Oreolek/raconteur.git
synced 2024-05-17 00:08:16 +03:00
Fix indentation normalisation algorithm
This commit is contained in:
parent
6ef13e2094
commit
bb6e302857
|
@ -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({
|
||||
|
|
|
@ -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 `<pre>` 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.
|
||||
|
|
|
@ -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
|
||||
<pre> 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 */
|
||||
|
|
Loading…
Reference in a new issue