if in a single text node works
This commit is contained in:
parent
b982700d80
commit
ca5aa1c0bf
@ -293,6 +293,15 @@ function fillEachBlock(startNode, iterableExpression, itemExpression, endNode, c
|
|||||||
const IF = 'IF'
|
const IF = 'IF'
|
||||||
const EACH = 'EACH'
|
const EACH = 'EACH'
|
||||||
|
|
||||||
|
// the regexps below are shared, so they shoudn't have state (no 'g' flag)
|
||||||
|
const ifStartRegex = /{#if\s+([^}]+?)\s*}/;
|
||||||
|
const elseMarker = '{:else}'
|
||||||
|
const closingIfMarker = '{/if}'
|
||||||
|
|
||||||
|
const eachStartMarkerRegex = /{#each\s+([^}]+?)\s+as\s+([^}]+?)\s*}/;
|
||||||
|
const eachClosingBlockString = '{/each}'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -334,8 +343,7 @@ function fillTemplatedOdtElement(rootElement, compartment){
|
|||||||
/**
|
/**
|
||||||
* looking for {#each x as y}
|
* looking for {#each x as y}
|
||||||
*/
|
*/
|
||||||
const eachStartRegex = /{#each\s+([^}]+?)\s+as\s+([^}]+?)\s*}/;
|
const eachStartMatch = text.match(eachStartMarkerRegex);
|
||||||
const eachStartMatch = text.match(eachStartRegex);
|
|
||||||
|
|
||||||
if(eachStartMatch){
|
if(eachStartMatch){
|
||||||
//console.log('startMatch', startMatch)
|
//console.log('startMatch', startMatch)
|
||||||
@ -358,7 +366,6 @@ function fillTemplatedOdtElement(rootElement, compartment){
|
|||||||
/**
|
/**
|
||||||
* Looking for {/each}
|
* Looking for {/each}
|
||||||
*/
|
*/
|
||||||
const eachClosingBlockString = '{/each}'
|
|
||||||
const isEachClosingBlock = text.includes(eachClosingBlockString)
|
const isEachClosingBlock = text.includes(eachClosingBlockString)
|
||||||
|
|
||||||
if(isEachClosingBlock){
|
if(isEachClosingBlock){
|
||||||
@ -394,7 +401,6 @@ function fillTemplatedOdtElement(rootElement, compartment){
|
|||||||
/**
|
/**
|
||||||
* Looking for {#if ...}
|
* Looking for {#if ...}
|
||||||
*/
|
*/
|
||||||
const ifStartRegex = /{#if\s+([^}]+?)\s*}/;
|
|
||||||
const ifStartMatch = text.match(ifStartRegex);
|
const ifStartMatch = text.match(ifStartRegex);
|
||||||
|
|
||||||
if(ifStartMatch){
|
if(ifStartMatch){
|
||||||
@ -415,7 +421,6 @@ function fillTemplatedOdtElement(rootElement, compartment){
|
|||||||
/**
|
/**
|
||||||
* Looking for {:else}
|
* Looking for {:else}
|
||||||
*/
|
*/
|
||||||
const elseMarker = '{:else}'
|
|
||||||
const hasElseMarker = text.includes(elseMarker);
|
const hasElseMarker = text.includes(elseMarker);
|
||||||
|
|
||||||
if(hasElseMarker){
|
if(hasElseMarker){
|
||||||
@ -438,7 +443,6 @@ function fillTemplatedOdtElement(rootElement, compartment){
|
|||||||
/**
|
/**
|
||||||
* Looking for {/if}
|
* Looking for {/if}
|
||||||
*/
|
*/
|
||||||
const closingIfMarker = '{/if}'
|
|
||||||
const hasClosingMarker = text.includes(closingIfMarker);
|
const hasClosingMarker = text.includes(closingIfMarker);
|
||||||
|
|
||||||
if(hasClosingMarker){
|
if(hasClosingMarker){
|
||||||
@ -529,28 +533,42 @@ function fillTemplatedOdtDocument(document, compartment){
|
|||||||
let remainingText = currentNode.textContent || ''
|
let remainingText = currentNode.textContent || ''
|
||||||
|
|
||||||
while(remainingText.length >= 1){
|
while(remainingText.length >= 1){
|
||||||
let match;
|
let matchText;
|
||||||
|
let matchIndex;
|
||||||
|
|
||||||
// looking for opening {#each ...} block
|
// looking for a block marker
|
||||||
const eachBlockOpeningRegex = /{#each\s+([^}]+?)\s+as\s+([^}]+?)\s*}/;
|
for(const marker of [ifStartRegex, elseMarker, closingIfMarker, eachStartMarkerRegex, eachClosingBlockString]){
|
||||||
const eachBlockClosingRegex = /{\/each}/;
|
if(typeof marker === 'string'){
|
||||||
|
const index = remainingText.indexOf(marker)
|
||||||
|
|
||||||
for(const regexp of [eachBlockOpeningRegex, eachBlockClosingRegex]){
|
if(index !== -1){
|
||||||
let thisMatch = remainingText.match(regexp)
|
matchText = marker
|
||||||
|
matchIndex = index
|
||||||
|
|
||||||
// trying to find only the first match in remainingText string
|
// found the first match
|
||||||
// @ts-ignore
|
break; // get out of loop
|
||||||
if(thisMatch && (!match || match.index > thisMatch.index)){
|
}
|
||||||
match = thisMatch
|
}
|
||||||
|
else{
|
||||||
|
// marker is a RegExp
|
||||||
|
const match = remainingText.match(marker)
|
||||||
|
|
||||||
|
if(match){
|
||||||
|
matchText = match[0]
|
||||||
|
matchIndex = match.index
|
||||||
|
|
||||||
|
// found the first match
|
||||||
|
break; // get out of loop
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(match){
|
if(matchText){
|
||||||
// split 3-way : before-match, match and after-match
|
// split 3-way : before-match, match and after-match
|
||||||
|
|
||||||
if(match[0].length < remainingText.length){
|
if(matchText.length < remainingText.length){
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
let afterMatchTextNode = currentNode.splitText(match.index + match[0].length)
|
let afterMatchTextNode = currentNode.splitText(matchIndex + matchText.length)
|
||||||
if(afterMatchTextNode.textContent && afterMatchTextNode.textContent.length >= 1){
|
if(afterMatchTextNode.textContent && afterMatchTextNode.textContent.length >= 1){
|
||||||
remainingText = afterMatchTextNode.textContent
|
remainingText = afterMatchTextNode.textContent
|
||||||
}
|
}
|
||||||
@ -561,9 +579,9 @@ function fillTemplatedOdtDocument(document, compartment){
|
|||||||
// per spec, currentNode now contains before-match and match text
|
// per spec, currentNode now contains before-match and match text
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
if(match.index > 0){
|
if(matchIndex > 0){
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
currentNode.splitText(match.index)
|
currentNode.splitText(matchIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
if(afterMatchTextNode){
|
if(afterMatchTextNode){
|
||||||
|
|||||||
@ -247,33 +247,6 @@ Hiver
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
test('template filling {#each ...}{/each} within a single text node', async t => {
|
|
||||||
const templatePath = join(import.meta.dirname, '../fixtures/liste-nombres.odt')
|
|
||||||
const templateContent = `Liste de nombres
|
|
||||||
|
|
||||||
Les nombres : {#each nombres as n}{n} {/each} !!
|
|
||||||
`
|
|
||||||
|
|
||||||
const data = {
|
|
||||||
nombres : [1,1,2,3,5,8,13,21]
|
|
||||||
}
|
|
||||||
|
|
||||||
const odtTemplate = await getOdtTemplate(templatePath)
|
|
||||||
|
|
||||||
const templateTextContent = await getOdtTextContent(odtTemplate)
|
|
||||||
t.deepEqual(templateTextContent, templateContent, 'reconnaissance du template')
|
|
||||||
|
|
||||||
const odtResult = await fillOdtTemplate(odtTemplate, data)
|
|
||||||
|
|
||||||
const odtResultTextContent = await getOdtTextContent(odtResult)
|
|
||||||
t.deepEqual(odtResultTextContent, `Liste de nombres
|
|
||||||
|
|
||||||
Les nombres : 1 1 2 3 5 8 13 21 !!
|
|
||||||
`)
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
test('template filling of a table', async t => {
|
test('template filling of a table', async t => {
|
||||||
const templatePath = join(import.meta.dirname, '../fixtures/tableau-simple.odt')
|
const templatePath = join(import.meta.dirname, '../fixtures/tableau-simple.odt')
|
||||||
const templateContent = `Évolution énergie en kWh par personne en France
|
const templateContent = `Évolution énergie en kWh par personne en France
|
||||||
|
|||||||
65
tests/fill-odt-template/in-text-node.js
Normal file
65
tests/fill-odt-template/in-text-node.js
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
import test from 'ava';
|
||||||
|
import {join} from 'node:path';
|
||||||
|
|
||||||
|
import {getOdtTemplate} from '../../scripts/odf/odtTemplate-forNode.js'
|
||||||
|
|
||||||
|
import {fillOdtTemplate, getOdtTextContent} from '../../exports.js'
|
||||||
|
|
||||||
|
|
||||||
|
test('template filling {#if ...}{/if} within a single text node', async t => {
|
||||||
|
const templatePath = join(import.meta.dirname, '../fixtures/inline-if-nombres.odt')
|
||||||
|
const templateContent = `Taille de nombre
|
||||||
|
|
||||||
|
Le nombre {n} est {#if n<5}petit{:else}grand{/if}.
|
||||||
|
`
|
||||||
|
|
||||||
|
const odtTemplate = await getOdtTemplate(templatePath)
|
||||||
|
|
||||||
|
const templateTextContent = await getOdtTextContent(odtTemplate)
|
||||||
|
t.deepEqual(templateTextContent, templateContent, 'reconnaissance du template')
|
||||||
|
|
||||||
|
const odtResult3 = await fillOdtTemplate(odtTemplate, {n : 3})
|
||||||
|
|
||||||
|
const odtResult3TextContent = await getOdtTextContent(odtResult3)
|
||||||
|
t.deepEqual(odtResult3TextContent, `Taille de nombre
|
||||||
|
|
||||||
|
Le nombre 3 est petit.
|
||||||
|
`)
|
||||||
|
|
||||||
|
const odtResult9 = await fillOdtTemplate(odtTemplate, {n : 9})
|
||||||
|
|
||||||
|
const odtResult9TextContent = await getOdtTextContent(odtResult9)
|
||||||
|
t.deepEqual(odtResult9TextContent, `Taille de nombre
|
||||||
|
|
||||||
|
Le nombre 9 est grand.
|
||||||
|
`)
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
test('template filling {#each ...}{/each} within a single text node', async t => {
|
||||||
|
const templatePath = join(import.meta.dirname, '../fixtures/liste-nombres.odt')
|
||||||
|
const templateContent = `Liste de nombres
|
||||||
|
|
||||||
|
Les nombres : {#each nombres as n}{n} {/each} !!
|
||||||
|
`
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
nombres : [1,1,2,3,5,8,13,21]
|
||||||
|
}
|
||||||
|
|
||||||
|
const odtTemplate = await getOdtTemplate(templatePath)
|
||||||
|
|
||||||
|
const templateTextContent = await getOdtTextContent(odtTemplate)
|
||||||
|
t.deepEqual(templateTextContent, templateContent, 'reconnaissance du template')
|
||||||
|
|
||||||
|
const odtResult = await fillOdtTemplate(odtTemplate, data)
|
||||||
|
|
||||||
|
const odtResultTextContent = await getOdtTextContent(odtResult)
|
||||||
|
t.deepEqual(odtResultTextContent, `Liste de nombres
|
||||||
|
|
||||||
|
Les nombres : 1 1 2 3 5 8 13 21 !!
|
||||||
|
`)
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
BIN
tests/fixtures/inline-if-nombres.odt
vendored
Normal file
BIN
tests/fixtures/inline-if-nombres.odt
vendored
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user