diff --git a/.gitignore b/.gitignore index 08d407f..5bd2365 100644 --- a/.gitignore +++ b/.gitignore @@ -3,5 +3,7 @@ node_modules/ build/* .~lock* +**/*(Copie)* +**/*(Copy)* stats.html \ No newline at end of file diff --git a/scripts/odf/templating/fillOdtElementTemplate.js b/scripts/odf/templating/fillOdtElementTemplate.js index 723398e..b864d41 100644 --- a/scripts/odf/templating/fillOdtElementTemplate.js +++ b/scripts/odf/templating/fillOdtElementTemplate.js @@ -85,7 +85,8 @@ function findPlacesToFillInString(str, compartment) { * @returns {{startChild: Node, endChild:Node, content: DocumentFragment}} */ function extractBlockContent(blockStartNode, blockEndNode) { - //console.log('[extractBlockContent] blockEndNode', blockEndNode.textContent) + console.log('[extractBlockContent] blockStartNode', blockStartNode.textContent) + console.log('[extractBlockContent] blockEndNode', blockEndNode.textContent) // find common ancestor of blockStartNode and blockEndNode let commonAncestor @@ -93,6 +94,7 @@ function extractBlockContent(blockStartNode, blockEndNode) { let startAncestor = blockStartNode let endAncestor = blockEndNode + // ancestries in order of deepest first, closest to root last const startAncestry = new Set([startAncestor]) const endAncestry = new Set([endAncestor]) @@ -117,10 +119,12 @@ function extractBlockContent(blockStartNode, blockEndNode) { const startAncestryToCommonAncestor = [...startAncestry].slice(0, [...startAncestry].indexOf(commonAncestor)) const endAncestryToCommonAncestor = [...endAncestry].slice(0, [...endAncestry].indexOf(commonAncestor)) + // direct children of commonAncestor in the branch or blockStartNode and blockEndNode respectively const startChild = startAncestryToCommonAncestor.at(-1) const endChild = endAncestryToCommonAncestor.at(-1) - //console.log('[extractBlockContent] endChild', endChild.textContent) + console.log('[extractBlockContent] startChild', startChild.textContent) + console.log('[extractBlockContent] endChild', endChild.textContent) // Extract DOM content in a documentFragment /** @type {DocumentFragment} */ @@ -128,6 +132,21 @@ function extractBlockContent(blockStartNode, blockEndNode) { /** @type {Element[]} */ const repeatedPatternArray = [] + + // get start branch "right" content + for(const startAncestor of startAncestry){ + if(startAncestor === startChild) + break; + + let sibling = startAncestor.nextSibling + + while(sibling) { + repeatedPatternArray.push(sibling) + sibling = sibling.nextSibling; + } + } + + let sibling = startChild.nextSibling while(sibling !== endChild) { @@ -135,12 +154,39 @@ function extractBlockContent(blockStartNode, blockEndNode) { sibling = sibling.nextSibling; } + + // get end branch "left" content + for(const endAncestor of [...endAncestry].reverse()){ + if(endAncestor === endChild) + continue; // already taken care of + + let sibling = endAncestor.previousSibling + + const reversedRepeatedPatternArrayContribution = [] + + while(sibling) { + reversedRepeatedPatternArrayContribution.push(sibling) + sibling = sibling.previousSibling; + } + + const repeatedPatternArrayContribution = reversedRepeatedPatternArrayContribution.reverse() + + repeatedPatternArray.push(...repeatedPatternArrayContribution) + + if(endAncestor === blockEndNode) + break; + } + + + console.log('repeatedPatternArray', repeatedPatternArray.map(n => n.textContent)) + + for(const sibling of repeatedPatternArray) { sibling.parentNode?.removeChild(sibling) contentFragment.appendChild(sibling) } - //console.log('extractBlockContent contentFragment', contentFragment.textContent) + console.log('extractBlockContent contentFragment', contentFragment.textContent) return { startChild, @@ -206,6 +252,8 @@ function fillIfBlock(ifOpeningMarkerNode, ifElseMarkerNode, ifClosingMarkerNode, .add(startIfThenChild).add(endIfThenChild) } + console.log('chosen fragment', chosenFragment?.textContent) + if(chosenFragment) { fillOdtElementTemplate( diff --git a/scripts/odf/templating/prepareTemplateDOMTree.js b/scripts/odf/templating/prepareTemplateDOMTree.js index 698e823..1bb9dc3 100644 --- a/scripts/odf/templating/prepareTemplateDOMTree.js +++ b/scripts/odf/templating/prepareTemplateDOMTree.js @@ -3,6 +3,7 @@ import {traverse, Node} from "../../DOMUtils.js"; import {closingIfMarker, eachClosingMarker, eachStartMarkerRegex, elseMarker, ifStartMarkerRegex, variableRegex} from './markers.js' + /** * * @param {string} text @@ -165,9 +166,9 @@ function consolidateMarkers(document){ ...Array.from(document.getElementsByTagName('text:h')) ] - for(const potentialMarkersContainer of potentialMarkersContainers) { - const consolidatedMarkers = [] + const consolidatedMarkers = [] + for(const potentialMarkersContainer of potentialMarkersContainers) { /** @type {Text[]} */ let containerTextNodesInTreeOrder = []; @@ -199,8 +200,8 @@ function consolidateMarkers(document){ ]; - //if(positionedMarkers.length >= 1) - // console.log('positionedMarkers', positionedMarkers) + if(positionedMarkers.length >= 1) + console.log('positionedMarkers', positionedMarkers) while(consolidatedMarkers.length < positionedMarkers.length) { @@ -322,6 +323,8 @@ function consolidateMarkers(document){ } } } + + console.log('consolidatedMarkers', consolidatedMarkers) } /** @@ -548,8 +551,22 @@ export default function prepareTemplateDOMTree(document){ // after consolidateMarkers, each marker is in at most one text node // (formatting with markers is removed) + console.log('document text after consolidateMarkers', document.documentElement.textContent) + /*traverse(document, (node) => { + if(node.nodeType === Node.TEXT_NODE || node.nodeName.startsWith('text')){ + console.log('node', node.nodeName, node.textContent) + } + })*/ + + isolateMarkerText(document) // after isolateMarkerText, each marker is in exactly one text node // (markers are separated from text that was before or after in the same text node) + console.log('document text after isolateMarkerText', document.documentElement.textContent) + /*traverse(document, (node) => { + if(node.nodeType === Node.TEXT_NODE || node.nodeName.startsWith('text')){ + console.log('node', node.nodeName, node.textContent) + } + })*/ } \ No newline at end of file diff --git a/tests/fill-odt-template/if.js b/tests/fill-odt-template/if.js index 729f0ca..6cf30c8 100644 --- a/tests/fill-odt-template/if.js +++ b/tests/fill-odt-template/if.js @@ -6,7 +6,7 @@ import {getOdtTemplate} from '../../scripts/odf/odtTemplate-forNode.js' import {fillOdtTemplate, getOdtTextContent} from '../../exports.js' -test('basic template filling with {#if}', async t => { +test.skip('basic template filling with {#if}', async t => { const templatePath = join(import.meta.dirname, '../fixtures/description-nombre.odt') const templateContent = `Description du nombre {n} @@ -40,3 +40,30 @@ n est un grand nombre }); + +test('weird bug', async t => { + const templatePath = join(import.meta.dirname, '../fixtures/weird-if-bug.odt') + const templateContent = `Utilisation de sources lumineuses : {#if scientifique.source_lumineuses}Oui{:else}Non{/if} +{#if scientifique.source_lumineuses && scientifique.modalités_source_lumineuses } +Modalités d’utilisation de sources lumineuses : {scientifique.modalités_source_lumineuses} +{/if} +` + + const data = { + scientifique: { + source_lumineuses: false, + //modalités_source_lumineuses: 'lampes torches' + } + } + + + const odtTemplate = await getOdtTemplate(templatePath) + const templateTextContent = await getOdtTextContent(odtTemplate) + t.deepEqual(templateTextContent.trim(), templateContent.trim(), 'reconnaissance du template') + + const odtResult = await fillOdtTemplate(odtTemplate, data) + const odtResultTextContent = await getOdtTextContent(odtResult) + t.deepEqual(odtResultTextContent.trim(), `Utilisation de sources lumineuses : Non`) + +}); + diff --git a/tests/fixtures/weird-if-bug.odt b/tests/fixtures/weird-if-bug.odt new file mode 100644 index 0000000..0630676 Binary files /dev/null and b/tests/fixtures/weird-if-bug.odt differ