I want to replace some variable tags inside a Word Document using the DocxTemplater library. E.g. I have a loop tag as follows:
{#gid_123}
...content...
{/gid_123}
And I just want to replace the tags with new IDs:
{#gid_999}
...content...
{/gid_999}
I am able to replace expressions that are not loops, but I just cannot get the loop tags to be replaced even tho I am using a custom parser function.
My implementation looks as follows:
let doc = new DocxTemplater(zip, {
paragraphLoop: true,
linebreaks: true,
parser(expression) {
// The default regex is used to match the groups variables.
let variablesRegex = /(?<type>gid)_(?<id>\d+)/g
let variablesMatches = expression.match(variablesRegex) ?? []
// If no group variables are found, the regex is changed to match the rest of the variables.
if (variablesMatches.length === 0) {
variablesRegex.lastIndex = 0
variablesRegex = /(?<type>qid|tax|fee)_(?<id>\d+)(?:_(?<property>description|amount|percentage))?/g
variablesMatches = expression.match(variablesRegex) ?? []
}
return {
get: function (scope, context) {
let newExpression = expression
if (variablesMatches.length === 0)
return `{${newExpression.trim()}}`
for (let match of variablesMatches) {
variablesRegex.lastIndex = 0
let {symbol = null, type, id, property} = variablesRegex.exec(match).groups
let newId = null
let newTag = null
let isTaxOrFee = ['tax', 'fee'].includes(type)
let isGroup = type === 'gid'
let isQuestion = type === 'qid'
// ?: tax, fee, qid (questions) and qid (question groups) are the only available variables to replace.
if (!isTaxOrFee && !isGroup && !isQuestion)
throw new Error(`Invalid variable type ${type}`)
if (isTaxOrFee) {
newId = tax_fee_id_relations.find(rel => rel.old_tax_or_fee_id === Number(id))?.tax_or_fee_id
newTag = `${type}_${newId}_${property}`
} else if (isQuestion) {
newId = question_id_relations.find(rel => rel.old_question_id === Number(id))?.new_question_id
newTag = `${type}_${newId}`
} else if (isGroup) {
let isOpeningTag = context.meta.part.raw.startsWith('#')
newId = group_id_relations.find(rel => rel.old_group_id === Number(id))?.new_group_id
// newTag = `${type}_${newId}`
newTag = isOpeningTag ?
`#${type}_${newId}` :
`/${type}_${newId}`
}
newExpression = newExpression.replaceAll(match, newTag)
}
return `{${newExpression.trim()}}`
},
}
},
})
I have tried implementing a custom parsing method that identifies the tags I want to replace, creates the new tag and returns it inside the get() function, but that is just not working. The resulting document has blank spaces where the new loop tags should be.
I want to get a new document with the new tags for all the loops inside the document.