open-xml-templating / docxtemplater

Generate docx, pptx, and xlsx from templates (Word, Powerpoint and Excel documents), from Node.js or the browser. Demo: https://www.docxtemplater.com/demo. #docx #office #generator #templating #report #json #generate #generation #template #create #pptx #docx #xlsx #react #vuejs #angularjs #browser #typescript #image #html #table #chart
https://www.docxtemplater.com
Other
3.03k stars 349 forks source link

ignore unopened tags error #720

Closed SZaidAhmed closed 1 year ago

SZaidAhmed commented 1 year ago

my full code is below what i want to do is either i can define two delimeters or i want to ignore the unopened tag error because my input file contains some words that end with "}" but starts with "$}" as i defined in delimeter

const PizZip = require("pizzip");
const Docxtemplater = require("docxtemplater");

const fs = require("fs");
const path = require("path");

// Load the docx file as binary content
const content = fs.readFileSync(
  path.resolve(__dirname, "deneme.docx"),
  "binary"
);

const zip = new PizZip(content);

function nullGetter(part, scopeManager) {
  if (!part.module) {
      return `$`+`{${part.value}}`;
  }
  if (part.module === "rawxml") {
      return "";
  }
  return "";
}

function customTagParser(tag) {
  console.log(tag)

  return {
    get:function(scope){
      return ;
    }
  } // Ignore unrecognized tags
}

const doc = new Docxtemplater(zip, {
  parser:customTagParser,
  paragraphLoop: true,
  linebreaks: true,
  nullGetter,
  delimiters:{ start: "${", end: "}" },
});

// Render the document (Replace {first_name} by John, {last_name} by Doe, ...)
doc.render({
  pafta: "test",
  ada: "test3"
});

const buf = doc.getZip().generate({
  type: "nodebuffer",
  // compression: DEFLATE adds a compression step.
  // For a 50MB output document, expect 500ms additional CPU time
  compression: "DEFLATE",
});

// buf is a nodejs Buffer, you can either write it to a
// file or res.send it with express for example.
fs.writeFileSync(path.resolve(__dirname, "output.docx"), buf);
edi9999 commented 1 year ago

Hello @SZaidAhmed ,

What I would do would be to use "${{" and "}}" for the delimiters.

This way you could use : "}" in your template without any issue.

edi9999 commented 1 year ago

I will not add an option to ignore some kind of errors in the template, docxtemplater is quite strict, and by changing the delimiters, it will make it possible to use "}" in your template.

However, if a person writes : "Hello user}", then I want to warn users that the template is most probably invalid, I'm not going to add an option for it.

I don't want to add an obscure option to docxtemplater to handle this case.

If you really need this, you can fork docxtemplater and use following patch, it seems that it works for basic cases but I can't guarantee anything :

diff --git a/es6/lexer.js b/es6/lexer.js
index 44088bcf..a8714fe0 100644
--- a/es6/lexer.js
+++ b/es6/lexer.js
@@ -244,10 +244,13 @@ function getAllDelimiterIndexes(fullText, delimiters) {
            case DELIMITER_NONE:
                return indexes;
            case DELIMITER_END:
-               insideTag = false;
                offset = endOffset;
                position = "end";
                len = end.length;
+               if (!insideTag) {
+                   continue;
+               }
+               insideTag = false;
                break;
            case DELIMITER_START:
                insideTag = true;