0
0
mirror of https://github.com/naturalcrit/homebrewery.git synced 2026-01-07 01:12:44 +00:00
This commit is contained in:
Trevor Buckner
2024-02-20 23:00:57 -05:00
parent 7bb1f16946
commit e3bf913a80
3 changed files with 130 additions and 130 deletions

View File

@@ -152,7 +152,7 @@ const BrewRenderer = (props)=>{
renderedPages.length = 0; renderedPages.length = 0;
// Render currently-edited page first so cross-page effects (variables, links) can propagate out first // Render currently-edited page first so cross-page effects (variables, links) can propagate out first
renderedPages[props.currentEditorPage] = renderPage(rawPages[props.currentEditorPage], props.currentEditorPage) renderedPages[props.currentEditorPage] = renderPage(rawPages[props.currentEditorPage], props.currentEditorPage);
_.forEach(rawPages, (page, index)=>{ _.forEach(rawPages, (page, index)=>{
if((isInView(index) || !renderedPages[index]) && typeof window !== 'undefined'){ if((isInView(index) || !renderedPages[index]) && typeof window !== 'undefined'){

View File

@@ -10,34 +10,34 @@ const tokenizer = new Marked.Tokenizer();
//Limit math features to simple items //Limit math features to simple items
const mathParser = new MathParser({ const mathParser = new MathParser({
operators: { operators : {
// These default to true, but are included to be explicit // These default to true, but are included to be explicit
add : true, add : true,
subtract : true, subtract : true,
multiply : true, multiply : true,
divide : true, divide : true,
power : true, power : true,
round : true, round : true,
floor : true, floor : true,
ceil : true, ceil : true,
sin : false, cos : false, tan : false, asin : false, acos : false, sin : false, cos : false, tan : false, asin : false, acos : false,
atan : false, sinh : false, cosh : false, tanh : false, asinh : false, atan : false, sinh : false, cosh : false, tanh : false, asinh : false,
acosh : false, atanh : false, sqrt : false, cbrt : false, log : false, acosh : false, atanh : false, sqrt : false, cbrt : false, log : false,
log2 : false, ln : false, lg : false, log10: false, expm1 : false, log2 : false, ln : false, lg : false, log10 : false, expm1 : false,
log1p : false, abs : false, trunc : false, join : false, sum : false, log1p : false, abs : false, trunc : false, join : false, sum : false,
'-' : false, '+' : false, exp : false, not : false, length: false, '-' : false, '+' : false, exp : false, not : false, length : false,
'!' : false, sign : false, random : false, fac : false, min : false, '!' : false, sign : false, random : false, fac : false, min : false,
max : false, hypot : false, pyt : false, pow : false, atan2 : false, max : false, hypot : false, pyt : false, pow : false, atan2 : false,
'if' : false, gamma : false, roundTo: false, map : false, fold : false, 'if' : false, gamma : false, roundTo : false, map : false, fold : false,
filter: false, indexOf: false, filter : false, indexOf : false,
remainder : false, factorial : false, remainder : false, factorial : false,
comparison : false, concatenate : false, comparison : false, concatenate : false,
logical : false, assignment : false, logical : false, assignment : false,
array : false, fndef : false array : false, fndef : false
} }
}); });
//Processes the markdown within an HTML block if it's just a class-wrapper //Processes the markdown within an HTML block if it's just a class-wrapper
renderer.html = function (html) { renderer.html = function (html) {
@@ -336,14 +336,14 @@ const replaceVar = function(input, hoist=false, allowUnresolved=false) {
const label = match[2]; const label = match[2];
//v=====--------------------< HANDLE MATH >-------------------=====v// //v=====--------------------< HANDLE MATH >-------------------=====v//
let mathRegex = /[a-z]+\(|[+\-*/^()]/g; const mathRegex = /[a-z]+\(|[+\-*/^()]/g;
let matches = label.split(mathRegex) const matches = label.split(mathRegex);
let mathVars = matches.filter(match => isNaN(match))?.map((s)=>s.trim()); // Capture any variable names const mathVars = matches.filter((match)=>isNaN(match))?.map((s)=>s.trim()); // Capture any variable names
let replacedLabel = label; let replacedLabel = label;
if(mathVars?.[0] !== label.trim()) {// If there was mathy stuff not captured, let's do math! if(mathVars?.[0] !== label.trim()) {// If there was mathy stuff not captured, let's do math!
mathVars?.forEach((variable) => { mathVars?.forEach((variable)=>{
const foundVar = lookupVar(variable, globalPageNumber, hoist); const foundVar = lookupVar(variable, globalPageNumber, hoist);
if(foundVar && foundVar.resolved && foundVar.content && !isNaN(foundVar.content)) // Only subsitute math values if fully resolved, not empty strings, and numbers if(foundVar && foundVar.resolved && foundVar.content && !isNaN(foundVar.content)) // Only subsitute math values if fully resolved, not empty strings, and numbers
replacedLabel = replacedLabel.replaceAll(variable, foundVar.content); replacedLabel = replacedLabel.replaceAll(variable, foundVar.content);
@@ -359,22 +359,22 @@ const replaceVar = function(input, hoist=false, allowUnresolved=false) {
const foundVar = lookupVar(label, globalPageNumber, hoist); const foundVar = lookupVar(label, globalPageNumber, hoist);
if(!foundVar || (!foundVar.resolved && !allowUnresolved)) if(!foundVar || (!foundVar.resolved && !allowUnresolved))
return undefined; // Return undefined if not found, or parially-resolved vars are not allowed return undefined; // Return undefined if not found, or parially-resolved vars are not allowed
// url or <url> "title" or 'title' or (title) // url or <url> "title" or 'title' or (title)
const linkRegex = /^([^<\s][^\s]*|<.*?>)(?: ("(?:\\"|[^"])*"|'(?:\\'|[^'])*'|\((?:\\\(|\\\)|[^()])*\)))?$/m; const linkRegex = /^([^<\s][^\s]*|<.*?>)(?: ("(?:\\"|[^"])*"|'(?:\\'|[^'])*'|\((?:\\\(|\\\)|[^()])*\)))?$/m;
const linkMatch = linkRegex.exec(foundVar.content); const linkMatch = linkRegex.exec(foundVar.content);
let href = linkMatch ? linkMatch[1] : null; //TODO: TRIM OFF < > IF PRESENT const href = linkMatch ? linkMatch[1] : null; //TODO: TRIM OFF < > IF PRESENT
let title = linkMatch ? linkMatch[2]?.slice(1, -1) : null; const title = linkMatch ? linkMatch[2]?.slice(1, -1) : null;
if(!prefix[0] && href) // Link if(!prefix[0] && href) // Link
return `[${label}](${href}${title ? ` "${title}"` : ''})`; return `[${label}](${href}${title ? ` "${title}"` : ''})`;
if(prefix[0] == '!' && href) // Image if(prefix[0] == '!' && href) // Image
return `![${label}](${href} ${title ? ` "${title}"` : ''})`; return `![${label}](${href} ${title ? ` "${title}"` : ''})`;
if(prefix[0] == '$') // Variable if(prefix[0] == '$') // Variable
return foundVar.content; return foundVar.content;
}; };
@@ -439,27 +439,27 @@ const processVariableQueue = function() {
const value = replaceVar(item.content, true, finalLoop); // final loop will just use the best value so far const value = replaceVar(item.content, true, finalLoop); // final loop will just use the best value so far
if(value == undefined) if(value == undefined)
continue; continue;
resolvedOne = true; resolvedOne = true;
item.content = value; item.content = value;
item.type = 'text'; item.type = 'text';
} }
} }
varsQueue = varsQueue.filter(item => item.type !== 'resolved'); // Remove any fully-resolved variable definitions varsQueue = varsQueue.filter((item)=>item.type !== 'resolved'); // Remove any fully-resolved variable definitions
if(finalLoop) if(finalLoop)
break; break;
if(!resolvedOne) if(!resolvedOne)
finalLoop = true; finalLoop = true;
} }
varsQueue = varsQueue.filter(item => item.type !== 'varDefBlock'); varsQueue = varsQueue.filter((item)=>item.type !== 'varDefBlock');
}; };
function MarkedVariables() { function MarkedVariables() {
return { return {
hooks: { hooks : {
preprocess(src) { preprocess(src) {
const codeBlockSkip = /^(?: {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+|^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})(?:[^\n]*)(?:\n|$)(?:|(?:[\s\S]*?)(?:\n|$))(?: {0,3}\2[~`]* *(?=\n|$))|`[^`]*?`/; const codeBlockSkip = /^(?: {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+|^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})(?:[^\n]*)(?:\n|$)(?:|(?:[\s\S]*?)(?:\n|$))(?: {0,3}\2[~`]* *(?=\n|$))|`[^`]*?`/;
const blockDefRegex = /^[!$]?\[((?!\s*\])(?:\\.|[^\[\]\\])+)\]:(?!\() *((?:\n? *[^\s].*)+)(?=\n+|$)/; //Matches 3, [4]:5 const blockDefRegex = /^[!$]?\[((?!\s*\])(?:\\.|[^\[\]\\])+)\]:(?!\() *((?:\n? *[^\s].*)+)(?=\n+|$)/; //Matches 3, [4]:5
const blockCallRegex = /^[!$]?\[((?!\s*\])(?:\\.|[^\[\]\\])+)\](?=\n|$)/; //Matches 6, [7] const blockCallRegex = /^[!$]?\[((?!\s*\])(?:\\.|[^\[\]\\])+)\](?=\n|$)/; //Matches 6, [7]
@@ -467,111 +467,111 @@ function MarkedVariables() {
const inlineCallRegex = /[!$]?\[((?!\s*\])(?:\\.|[^\[\]\\])+)\](?!\()/; //Matches 12, [13] const inlineCallRegex = /[!$]?\[((?!\s*\])(?:\\.|[^\[\]\\])+)\](?!\()/; //Matches 12, [13]
// Combine regexes and wrap in parens like so: (regex1)|(regex2)|(regex3)|(regex4) // Combine regexes and wrap in parens like so: (regex1)|(regex2)|(regex3)|(regex4)
let combinedRegex = new RegExp([codeBlockSkip, blockDefRegex, blockCallRegex, inlineDefRegex, inlineCallRegex].map(s => `(${s.source})`).join('|'), 'gm'); const combinedRegex = new RegExp([codeBlockSkip, blockDefRegex, blockCallRegex, inlineDefRegex, inlineCallRegex].map((s)=>`(${s.source})`).join('|'), 'gm');
let lastIndex = 0; let lastIndex = 0;
let match; let match;
while ((match = combinedRegex.exec(src)) !== null) { while ((match = combinedRegex.exec(src)) !== null) {
// Format any matches into tokens and store // Format any matches into tokens and store
if (match.index > lastIndex) { // Any non-variable stuff if(match.index > lastIndex) { // Any non-variable stuff
varsQueue.push( varsQueue.push(
{ type : 'text', { type : 'text',
varName : null, varName : null,
content : src.slice(lastIndex, match.index) content : src.slice(lastIndex, match.index)
}); });
} }
if(match[1]) { if(match[1]) {
varsQueue.push( varsQueue.push(
{ type : 'text', { type : 'text',
varName : null, varName : null,
content : match[0] content : match[0]
}); });
} }
if(match[3]) { // Block Definition if(match[3]) { // Block Definition
const label = match[4] ? match[4].trim().replace(/\s+/g, ' ') : null; // Trim edge spaces and shorten blocks of whitespace to 1 space const label = match[4] ? match[4].trim().replace(/\s+/g, ' ') : null; // Trim edge spaces and shorten blocks of whitespace to 1 space
const content = match[5] ? match[5].trim().replace(/[ \t]+/g, ' ') : null; // Trim edge spaces and shorten blocks of whitespace to 1 space const content = match[5] ? match[5].trim().replace(/[ \t]+/g, ' ') : null; // Trim edge spaces and shorten blocks of whitespace to 1 space
varsQueue.push( varsQueue.push(
{ type : 'varDefBlock', { type : 'varDefBlock',
varName : label, varName : label,
content : content content : content
}); });
} }
if(match[6]) { // Block Call if(match[6]) { // Block Call
const label = match[7] ? match[7].trim().replace(/\s+/g, ' ') : null; // Trim edge spaces and shorten blocks of whitespace to 1 space const label = match[7] ? match[7].trim().replace(/\s+/g, ' ') : null; // Trim edge spaces and shorten blocks of whitespace to 1 space
varsQueue.push( varsQueue.push(
{ type : 'varCallBlock', { type : 'varCallBlock',
varName : label, varName : label,
content : match[0] content : match[0]
}); });
} }
if(match[8]) { // Inline Definition if(match[8]) { // Inline Definition
const label = match[10] ? match[10].trim().replace(/\s+/g, ' ') : null; // Trim edge spaces and shorten blocks of whitespace to 1 space const label = match[10] ? match[10].trim().replace(/\s+/g, ' ') : null; // Trim edge spaces and shorten blocks of whitespace to 1 space
let content = match[11] ? match[11].trim().replace(/\s+/g, ' ') : null; // Trim edge spaces and shorten blocks of whitespace to 1 space let content = match[11] ? match[11].trim().replace(/\s+/g, ' ') : null; // Trim edge spaces and shorten blocks of whitespace to 1 space
// In case of nested (), find the correct matching end ) // In case of nested (), find the correct matching end )
let level = 0; let level = 0;
let i; let i;
for (i = 0; i < content.length; i++) { for (i = 0; i < content.length; i++) {
if (content[i] === '\\') { if(content[i] === '\\') {
i++; i++;
} else if (content[i] === '(') { } else if(content[i] === '(') {
level++; level++;
} else if (content[i] === ')') { } else if(content[i] === ')') {
level--; level--;
if (level < 0) if(level < 0)
break; break;
}
} }
if (i > -1) {
combinedRegex.lastIndex = combinedRegex.lastIndex - (content.length - i);
content = content.slice(0,i).trim().replace(/\s+/g, ' ');
}
varsQueue.push(
{ type : 'varDefBlock',
varName : label,
content : content
});
varsQueue.push(
{ type : 'varCallInline',
varName : label,
content : match[9]
});
} }
if(match[12]) { // Inline Call if(i > -1) {
const label = match[13] ? match[13].trim().replace(/\s+/g, ' ') : null; // Trim edge spaces and shorten blocks of whitespace to 1 space combinedRegex.lastIndex = combinedRegex.lastIndex - (content.length - i);
content = content.slice(0, i).trim().replace(/\s+/g, ' ');
varsQueue.push(
{ type : 'varCallInline',
varName : label,
content : match[0]
});
} }
lastIndex = combinedRegex.lastIndex;
varsQueue.push(
{ type : 'varDefBlock',
varName : label,
content : content
});
varsQueue.push(
{ type : 'varCallInline',
varName : label,
content : match[9]
});
}
if(match[12]) { // Inline Call
const label = match[13] ? match[13].trim().replace(/\s+/g, ' ') : null; // Trim edge spaces and shorten blocks of whitespace to 1 space
varsQueue.push(
{ type : 'varCallInline',
varName : label,
content : match[0]
});
}
lastIndex = combinedRegex.lastIndex;
} }
if (lastIndex < src.length) { if(lastIndex < src.length) {
varsQueue.push( varsQueue.push(
{ type : 'text', { type : 'text',
varName : null, varName : null,
content : src.slice(lastIndex) content : src.slice(lastIndex)
}); });
} }
processVariableQueue(); processVariableQueue();
const output = varsQueue.map(item => item.content).join(''); const output = varsQueue.map((item)=>item.content).join('');
varsQueue = []; // Must clear varsQueue because custom HTML renderer uses Marked.parse which will preprocess again without clearing the array varsQueue = []; // Must clear varsQueue because custom HTML renderer uses Marked.parse which will preprocess again without clearing the array
return output; return output;
} }
} }
}; };
}; };
//^=====--------------------< Variable Handling >-------------------=====^// //^=====--------------------< Variable Handling >-------------------=====^//
Marked.use(MarkedVariables()) Marked.use(MarkedVariables());
Marked.use({ extensions: [mustacheSpans, mustacheDivs, mustacheInjectInline, definitionLists, superSubScripts] }); Marked.use({ extensions: [mustacheSpans, mustacheDivs, mustacheInjectInline, definitionLists, superSubScripts] });
Marked.use(mustacheInjectBlock); Marked.use(mustacheInjectBlock);
Marked.use({ renderer: renderer, tokenizer: tokenizer, mangle: false }); Marked.use({ renderer: renderer, tokenizer: tokenizer, mangle: false });

View File

@@ -11,7 +11,7 @@ String.prototype.trimReturns = function(){
renderAllPages = function(pages){ renderAllPages = function(pages){
const outputs = []; const outputs = [];
pages.forEach((page, index) => { pages.forEach((page, index)=>{
const output = Markdown.render(page, index); const output = Markdown.render(page, index);
outputs.push(output); outputs.push(output);
}); });
@@ -40,7 +40,7 @@ describe('Block-level variables', ()=>{
lines lines
$[var]`; $[var]`;
const rendered = Markdown.render(source).replace(/\s/g,' ').trimReturns(); const rendered = Markdown.render(source).replace(/\s/g, ' ').trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('<p>string across multiple lines</p>'); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('<p>string across multiple lines</p>');
}); });
@@ -71,7 +71,7 @@ describe('Block-level variables', ()=>{
$[var] $[var]
[var]: string`; [var]: string`;
const rendered = Markdown.render(source).replace(/\s/g,' ').trimReturns(); const rendered = Markdown.render(source).replace(/\s/g, ' ').trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('<p>string</p>'); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('<p>string</p>');
}); });
@@ -82,7 +82,7 @@ describe('Block-level variables', ()=>{
[var]: string [var]: string
[var]: new string`; [var]: new string`;
const rendered = Markdown.render(source).replace(/\s/g,' ').trimReturns(); const rendered = Markdown.render(source).replace(/\s/g, ' ').trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('<p>new string</p>'); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('<p>new string</p>');
}); });
@@ -102,7 +102,7 @@ describe('Block-level variables', ()=>{
[lastName]: $[lastName]son [lastName]: $[lastName]son
`; `;
const rendered = Markdown.render(source).replace(/\s/g,' ').trimReturns(); const rendered = Markdown.render(source).replace(/\s/g, ' ').trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('<p>Welcome, Mr. Bob Jacobson!</p>'); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('<p>Welcome, Mr. Bob Jacobson!</p>');
}); });
@@ -136,13 +136,13 @@ describe('Block-level variables', ()=>{
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('<p>two</p><p>one</p><p>two</p>'.trimReturns()); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('<p>two</p><p>one</p><p>two</p>'.trimReturns());
}); });
it("Ignores undefined variables that can't be hoisted", function() { it('Ignores undefined variables that can\'t be hoisted', function() {
const source = dedent` const source = dedent`
$[var](My name is $[first] $[last]) $[var](My name is $[first] $[last])
$[last]: Jones $[last]: Jones
`; `;
const rendered = Markdown.render(source).replace(/\s/g,' ').trimReturns(); const rendered = Markdown.render(source).replace(/\s/g, ' ').trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`<p>My name is $[first] Jones</p>`.trimReturns()); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`<p>My name is $[first] Jones</p>`.trimReturns());
}); });
}); });
@@ -163,7 +163,7 @@ describe('Inline-level variables', ()=>{
$[var](My name is $[name] Jones) $[var](My name is $[name] Jones)
[name]: Bob`; [name]: Bob`;
const rendered = Markdown.render(source).replace(/\s/g,' ').trimReturns(); const rendered = Markdown.render(source).replace(/\s/g, ' ').trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('<p>My name is Bob Jones</p>'); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('<p>My name is Bob Jones</p>');
}); });
@@ -174,7 +174,7 @@ describe('Inline-level variables', ()=>{
$[name](Bob) $[name](Bob)
[name]: Bill`; [name]: Bill`;
const rendered = Markdown.render(source).replace(/\s/g,' ').trimReturns(); const rendered = Markdown.render(source).replace(/\s/g, ' ').trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`<p>My name is Bill Jones</p> <p>Bob</p>`.trimReturns()); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`<p>My name is Bill Jones</p> <p>Bob</p>`.trimReturns());
}); });
@@ -209,28 +209,28 @@ describe('Math', ()=>{
it('Handles round function', function() { it('Handles round function', function() {
const source = dedent` const source = dedent`
$[round(1/4)]`; $[round(1/4)]`;
const rendered = Markdown.render(source).replace(/\s/g,' ').trimReturns(); const rendered = Markdown.render(source).replace(/\s/g, ' ').trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('<p>0</p>'); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('<p>0</p>');
}); });
it('Handles floor function', function() { it('Handles floor function', function() {
const source = dedent` const source = dedent`
$[floor(0.6)]`; $[floor(0.6)]`;
const rendered = Markdown.render(source).replace(/\s/g,' ').trimReturns(); const rendered = Markdown.render(source).replace(/\s/g, ' ').trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('<p>0</p>'); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('<p>0</p>');
}); });
it('Handles ceil function', function() { it('Handles ceil function', function() {
const source = dedent` const source = dedent`
$[ceil(0.2)]`; $[ceil(0.2)]`;
const rendered = Markdown.render(source).replace(/\s/g,' ').trimReturns(); const rendered = Markdown.render(source).replace(/\s/g, ' ').trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('<p>1</p>'); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('<p>1</p>');
}); });
it('Handles nested functions', function() { it('Handles nested functions', function() {
const source = dedent` const source = dedent`
$[ceil(floor(round(0.6)))]`; $[ceil(floor(round(0.6)))]`;
const rendered = Markdown.render(source).replace(/\s/g,' ').trimReturns(); const rendered = Markdown.render(source).replace(/\s/g, ' ').trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('<p>1</p>'); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('<p>1</p>');
}); });
@@ -352,7 +352,7 @@ describe('Cross-page variables', ()=>{
const source0 = `[var]: string`; const source0 = `[var]: string`;
const source1 = `$[var]`; const source1 = `$[var]`;
const rendered = renderAllPages([source0, source1]).join('\n\\page\n').trimReturns(); const rendered = renderAllPages([source0, source1]).join('\n\\page\n').trimReturns();
expect(rendered, `Input:\n${[source0,source1].join('\n\\page\n')}`, { showPrefix: false }).toBe('\\page<p>string</p>'); expect(rendered, `Input:\n${[source0, source1].join('\n\\page\n')}`, { showPrefix: false }).toBe('\\page<p>string</p>');
}); });
it('Handles hoisting across pages', function() { it('Handles hoisting across pages', function() {
@@ -360,7 +360,7 @@ describe('Cross-page variables', ()=>{
const source1 = `[var]: string`; const source1 = `[var]: string`;
renderAllPages([source0, source1]).join('\n\\page\n').trimReturns(); //Requires one full render of document before hoisting is picked up renderAllPages([source0, source1]).join('\n\\page\n').trimReturns(); //Requires one full render of document before hoisting is picked up
const rendered = renderAllPages([source0, source1]).join('\n\\page\n').trimReturns(); const rendered = renderAllPages([source0, source1]).join('\n\\page\n').trimReturns();
expect(rendered, `Input:\n${[source0,source1].join('\n\\page\n')}`, { showPrefix: false }).toBe('<p>string</p>\\page'); expect(rendered, `Input:\n${[source0, source1].join('\n\\page\n')}`, { showPrefix: false }).toBe('<p>string</p>\\page');
}); });
it('Handles reassignment and hoisting across pages', function() { it('Handles reassignment and hoisting across pages', function() {
@@ -368,6 +368,6 @@ describe('Cross-page variables', ()=>{
const source1 = `[var]: two\n\n$[var]`; const source1 = `[var]: two\n\n$[var]`;
renderAllPages([source0, source1]).join('\n\\page\n').trimReturns(); //Requires one full render of document before hoisting is picked up renderAllPages([source0, source1]).join('\n\\page\n').trimReturns(); //Requires one full render of document before hoisting is picked up
const rendered = renderAllPages([source0, source1]).join('\n\\page\n').trimReturns(); const rendered = renderAllPages([source0, source1]).join('\n\\page\n').trimReturns();
expect(rendered, `Input:\n${[source0,source1].join('\n\\page\n')}`, { showPrefix: false }).toBe('<p>two</p><p>one</p>\\page<p>two</p>'); expect(rendered, `Input:\n${[source0, source1].join('\n\\page\n')}`, { showPrefix: false }).toBe('<p>two</p><p>one</p>\\page<p>two</p>');
}); });
}); });