Skip to content

Commit ac999eb

Browse files
committed
Fix two bugs with nested evaluation
* Fix bug causing the active mode to not be passed down into recursively rendered text. * Fix bug causing named choices executed inside recursively rendered text to not propagate upward.
1 parent b478598 commit ac999eb

File tree

3 files changed

+32
-7
lines changed

3 files changed

+32
-7
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
# Changelog
22

33
### 0.0.17
4+
* Fix bug causing the active mode to not be passed down into
5+
recursively rendered text.
6+
* Fix bug causing named choices executed inside recursively rendered
7+
text to not propagate upward.
48
* tbd...
59

610
### 0.0.16

src/renderer.js

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,14 @@ function resolveBackReference(choiceResultMap, backReference) {
7474
*
7575
* @returns {String} the rendered text.
7676
*/
77-
function renderText(string, startIndex, evalBlock,
78-
modes, renderDefaultSettings, isTopLevel) {
77+
function renderText(string, startIndex, evalBlock, modes, activeMode,
78+
renderDefaultSettings, choiceResultMap, isTopLevel) {
7979
// TODO this function is way too complex and badly needs refactor
80-
let activeMode = null;
80+
// TODO replace isTopLevel with incrementing depth tracker
81+
choiceResultMap = choiceResultMap || new Map();
82+
activeMode = activeMode || null;
8183
let isEscaped = false;
8284
let inLiteralBlock = false;
83-
let choiceResultMap = new Map();
8485
let out = '';
8586
let index = startIndex;
8687
let currentRule = null;
@@ -151,7 +152,7 @@ function renderText(string, startIndex, evalBlock,
151152
// To handle nested choices and to run rules over chosen text,
152153
// we recursively render the chosen text.
153154
renderedReplacement = renderText(
154-
replacement, 0, null, modes, activeMode, settings, false);
155+
replacement, 0, null, modes, activeMode, settings, choiceResultMap, false);
155156
}
156157
if (!(replacer && replacer.isSilent)) {
157158
out += renderedReplacement;
@@ -196,7 +197,7 @@ function renderText(string, startIndex, evalBlock,
196197
// To handle nested choices and to run rules over replaced text,
197198
// we recursively render the chosen text.
198199
let renderedReplacement = renderText(
199-
replacement, 0, null, modes, activeMode, settings, false);
200+
replacement, 0, null, modes, activeMode, settings, choiceResultMap, false);
200201
out += renderedReplacement;
201202
}
202203
index += currentMatch[0].length;
@@ -260,7 +261,7 @@ function render(bmlDocumentString, renderSettings, defaultDocumentSettings) {
260261
evalBlock = null;
261262
}
262263
return renderText(
263-
bmlDocumentString, preludeEndIndex, evalBlock, modes, defaultDocumentSettings, true);
264+
bmlDocumentString, preludeEndIndex, evalBlock, modes, null, defaultDocumentSettings, null, true);
264265
}
265266

266267
exports.renderText = renderText;

test/endToEnd.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,18 @@ describe('bml', function() {
4444
}
4545
});
4646

47+
it('respects the active mode on recursively rendered text', function() {
48+
let testString =
49+
`mode test {
50+
(foo) as (bar) 100
51+
}
52+
{use test}
53+
{(foo)}
54+
`;
55+
let result = bml(testString).trim();
56+
expect(result).to.equal('bar');
57+
});
58+
4759
it('can process recursive inline choices', function() {
4860
let testString = 'hello {(simple), ({(very ), ()}recursive)} world!';
4961
let result = bml(testString);
@@ -106,6 +118,14 @@ describe('bml', function() {
106118
assert.fail(`Unexpected output: ${result}`);
107119
}
108120
});
121+
122+
it('tracks named choices made inside recursively rendered text', function() {
123+
let testString = `
124+
{({TestChoice: (foo)})} {@TestChoice}
125+
`;
126+
let result = bml(testString).trim();
127+
expect(result).to.equal('foo foo');
128+
});
109129

110130
it('produces the exact same document when using a fixed random seed', function() {
111131
const testString = '' + fs.readFileSync(require.resolve('./randomSmokeTest.bml'));

0 commit comments

Comments
 (0)