in progress
This commit is contained in:
parent
2c20c65375
commit
ad1138e307
@ -90,6 +90,22 @@ function findPlacesToFillInString(str, compartment) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Node} ifOpeningMarkerNode
|
||||||
|
* @param {Node | undefined} ifElseMarkerNode
|
||||||
|
* @param {Node} ifClosingMarkerNode
|
||||||
|
* @param {string} ifBlockConditionExpression
|
||||||
|
* @param {Compartment} compartment
|
||||||
|
*/
|
||||||
|
function fillIfBlock(ifOpeningMarkerNode, ifElseMarkerNode, ifClosingMarkerNode, ifBlockConditionExpression, compartment){
|
||||||
|
throw `PPP
|
||||||
|
- executer l'expression
|
||||||
|
- selon la valeur, choisir le bon block à extraire/remplir
|
||||||
|
-
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -280,50 +296,62 @@ function fillTemplatedOdtElement(rootElement, compartment){
|
|||||||
// now, each Node contains at most one block marker
|
// now, each Node contains at most one block marker
|
||||||
|
|
||||||
|
|
||||||
|
let currentlyOpenBlocks = []
|
||||||
|
|
||||||
|
|
||||||
/** @type {Node | undefined} */
|
/** @type {Node | undefined} */
|
||||||
let eachBlockOpeningNode
|
let eachOpeningMarkerNode
|
||||||
/** @type {Node | undefined} */
|
/** @type {Node | undefined} */
|
||||||
let eachBlockClosingNode
|
let eachClosingMarkerNode
|
||||||
|
|
||||||
let currentlyUnclosedBlocks = []
|
|
||||||
|
|
||||||
let eachBlockIterableExpression, eachBlockItemExpression;
|
let eachBlockIterableExpression, eachBlockItemExpression;
|
||||||
|
|
||||||
|
|
||||||
|
/** @type {Node | undefined} */
|
||||||
|
let ifOpeningMarkerNode
|
||||||
|
/** @type {Node | undefined} */
|
||||||
|
let ifElseMarkerNode
|
||||||
|
/** @type {Node | undefined} */
|
||||||
|
let ifClosingMarkerNode
|
||||||
|
|
||||||
|
let ifBlockConditionExpression
|
||||||
// Traverse "in document order"
|
// Traverse "in document order"
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
traverse(rootElement, currentNode => {
|
traverse(rootElement, currentNode => {
|
||||||
//console.log('currentlyUnclosedBlocks', currentlyUnclosedBlocks)
|
//console.log('currentlyUnclosedBlocks', currentlyUnclosedBlocks)
|
||||||
const insideAnOpenBlock = currentlyUnclosedBlocks.length >= 1
|
const insideAnOpenBlock = currentlyOpenBlocks.length >= 1
|
||||||
|
|
||||||
if(currentNode.nodeType === Node.TEXT_NODE){
|
if(currentNode.nodeType === Node.TEXT_NODE){
|
||||||
const text = currentNode.textContent || ''
|
const text = currentNode.textContent || ''
|
||||||
|
|
||||||
// looking for {#each x as y}
|
/**
|
||||||
|
* looking for {#each x as y}
|
||||||
|
*/
|
||||||
const eachStartRegex = /{#each\s+([^}]+?)\s+as\s+([^}]+?)\s*}/;
|
const eachStartRegex = /{#each\s+([^}]+?)\s+as\s+([^}]+?)\s*}/;
|
||||||
const startMatch = text.match(eachStartRegex);
|
const eachStartMatch = text.match(eachStartRegex);
|
||||||
|
|
||||||
//console.log('text, match', )
|
if(eachStartMatch){
|
||||||
|
|
||||||
if(startMatch){
|
|
||||||
//console.log('startMatch', startMatch)
|
//console.log('startMatch', startMatch)
|
||||||
|
|
||||||
currentlyUnclosedBlocks.push(EACH)
|
currentlyOpenBlocks.push(EACH)
|
||||||
|
|
||||||
if(insideAnOpenBlock){
|
if(insideAnOpenBlock){
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
let [_, _iterableExpression, _itemExpression] = startMatch
|
let [_, _iterableExpression, _itemExpression] = eachStartMatch
|
||||||
|
|
||||||
eachBlockIterableExpression = _iterableExpression
|
eachBlockIterableExpression = _iterableExpression
|
||||||
eachBlockItemExpression = _itemExpression
|
eachBlockItemExpression = _itemExpression
|
||||||
eachBlockOpeningNode = currentNode
|
eachOpeningMarkerNode = currentNode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// trying to find an {/each}
|
|
||||||
|
/**
|
||||||
|
* Looking for {/each}
|
||||||
|
*/
|
||||||
const eachClosingBlockString = '{/each}'
|
const eachClosingBlockString = '{/each}'
|
||||||
const isEachClosingBlock = text.includes(eachClosingBlockString)
|
const isEachClosingBlock = text.includes(eachClosingBlockString)
|
||||||
|
|
||||||
@ -331,33 +359,111 @@ function fillTemplatedOdtElement(rootElement, compartment){
|
|||||||
|
|
||||||
//console.log('isEachClosingBlock', isEachClosingBlock)
|
//console.log('isEachClosingBlock', isEachClosingBlock)
|
||||||
|
|
||||||
if(!eachBlockOpeningNode)
|
if(!eachOpeningMarkerNode)
|
||||||
throw new Error(`{/each} found without corresponding opening {#each x as y}`)
|
throw new Error(`{/each} found without corresponding opening {#each x as y}`)
|
||||||
|
|
||||||
if(currentlyUnclosedBlocks.at(-1) !== EACH)
|
if(currentlyOpenBlocks.at(-1) !== EACH)
|
||||||
throw new Error(`{/each} found while the last opened block was not an opening {#each x as y}`)
|
throw new Error(`{/each} found while the last opened block was not an opening {#each x as y}`)
|
||||||
|
|
||||||
if(currentlyUnclosedBlocks.filter(x => x === EACH).length > 1){
|
if(currentlyOpenBlocks.length === 1){
|
||||||
// ignore because it will be treated as part of the outer {#each}
|
eachClosingMarkerNode = currentNode
|
||||||
}
|
|
||||||
else{
|
|
||||||
eachBlockClosingNode = currentNode
|
|
||||||
|
|
||||||
// found an #each and its corresponding /each
|
// found an {#each} and its corresponding {/each}
|
||||||
// execute replacement loop
|
// execute replacement loop
|
||||||
fillEachBlock(eachBlockOpeningNode, eachBlockIterableExpression, eachBlockItemExpression, eachBlockClosingNode, compartment)
|
fillEachBlock(eachOpeningMarkerNode, eachBlockIterableExpression, eachBlockItemExpression, eachClosingMarkerNode, compartment)
|
||||||
|
|
||||||
eachBlockOpeningNode = undefined
|
eachOpeningMarkerNode = undefined
|
||||||
eachBlockIterableExpression = undefined
|
eachBlockIterableExpression = undefined
|
||||||
eachBlockItemExpression = undefined
|
eachBlockItemExpression = undefined
|
||||||
eachBlockClosingNode = undefined
|
eachClosingMarkerNode = undefined
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
// ignore because it will be treated as part of the outer {#each}
|
||||||
}
|
}
|
||||||
|
|
||||||
currentlyUnclosedBlocks.pop()
|
currentlyOpenBlocks.pop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Looking for variables for substitutions
|
/**
|
||||||
|
* Looking for {#if ...}
|
||||||
|
*/
|
||||||
|
const ifStartRegex = /{#if\s+([^}]+?)\s*}/;
|
||||||
|
const ifStartMatch = text.match(ifStartRegex);
|
||||||
|
|
||||||
|
if(ifStartMatch){
|
||||||
|
currentlyOpenBlocks.push(IF)
|
||||||
|
|
||||||
|
if(insideAnOpenBlock){
|
||||||
|
// do nothing because the marker is too deep
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
let [_, _ifBlockConditionExpression] = ifStartMatch
|
||||||
|
|
||||||
|
ifBlockConditionExpression = _ifBlockConditionExpression
|
||||||
|
ifOpeningMarkerNode = currentNode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Looking for {:else}
|
||||||
|
*/
|
||||||
|
const elseMarker = '{:else}'
|
||||||
|
const hasElseMarker = text.includes(elseMarker);
|
||||||
|
|
||||||
|
if(hasElseMarker){
|
||||||
|
if(!insideAnOpenBlock)
|
||||||
|
throw new Error('{:else} without a corresponding {#if}')
|
||||||
|
|
||||||
|
if(currentlyOpenBlocks.length === 1){
|
||||||
|
if(currentlyOpenBlocks[0] === IF){
|
||||||
|
ifElseMarkerNode = currentNode
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new Error('{:else} inside an {#each} but without a corresponding {#if}')
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
// do nothing because the marker is too deep
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Looking for {/if}
|
||||||
|
*/
|
||||||
|
const closingIfMarker = '{/if}'
|
||||||
|
const hasClosingMarker = text.includes(closingIfMarker);
|
||||||
|
|
||||||
|
if(hasClosingMarker){
|
||||||
|
if(!insideAnOpenBlock)
|
||||||
|
throw new Error('{/if} without a corresponding {#if}')
|
||||||
|
|
||||||
|
if(currentlyOpenBlocks.length === 1){
|
||||||
|
if(currentlyOpenBlocks[0] === IF){
|
||||||
|
ifClosingMarkerNode = currentNode
|
||||||
|
|
||||||
|
// found an {#if} and its corresponding {/if}
|
||||||
|
// execute replacement loop
|
||||||
|
fillIfBlock(ifOpeningMarkerNode, ifElseMarkerNode, ifClosingMarkerNode, ifBlockConditionExpression, compartment)
|
||||||
|
|
||||||
|
ifOpeningMarkerNode = undefined
|
||||||
|
ifElseMarkerNode = undefined
|
||||||
|
ifClosingMarkerNode = undefined
|
||||||
|
ifBlockConditionExpression = undefined
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new Error('{/if} inside an {#each} but without a corresponding {#if}')
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
// do nothing because the marker is too deep
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Looking for variables for substitutions
|
||||||
|
*/
|
||||||
if(!insideAnOpenBlock){
|
if(!insideAnOpenBlock){
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
if (currentNode.data) {
|
if (currentNode.data) {
|
||||||
@ -374,7 +480,7 @@ function fillTemplatedOdtElement(rootElement, compartment){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
// ignore because it will be treated as part of the {#each} block
|
// ignore because it will be treated as part of the outer {#each} block
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user