javascriptnode.jspdfkit

PDF kit reverse numbers in Arabic fonts


I'm using pdfkit package for node js application to generate PDFs, but I faced a problem when I attempted to generate Arabic text. It always reverses the numbers in Arabic texts.

if I want to write: ساڵی 1992 (The year 1992), it always changes to (ساڵی ٢٩٩١), This issue persists even when I use Unicode custom fonts.

This is an example in image:

This is an example in image

Here are my codes:

function generatePDFForRuleAndRegulation(data) {
  const fileNamePDF = `${data.name}.pdf`;
  const doc = new PDFDocument();

  // Pipe the PDF document to a writable stream (file in this case)
  const stream = fs.createWriteStream(fileNamePDF);

  doc.pipe(stream);

  doc
    .font(`${path.join(__dirname, "../../assets/fonts/NRT-Reg.ttf")}`)
    .fontSize(12)
    .text(`${data.name}`, {
      align: "center",
    });
  doc.moveDown(); // Move cursor down

  doc
    .font(`${path.join(__dirname, "../../assets/fonts/Rabar_021.ttf")}`)
    .fontSize(10)
    .text(data.text, { align: "right", features: ["rtla"] });

  // Finalize the PDF document
  doc.end();

  // Inform when the file has been created
  stream.on("finish", () => {
    console.log(`PDF created: ${fileNamePDF}`);
  });
}

Is there any solution or workaround you can suggest? Alternatively, do you know of another package to generate PDFs that also supports Arabic fonts?


Solution

  • Finally, I used custom RTL instead of pdfkit plugin.

    // Function to check if text contains Hebrew characters
    const isHebrew = (text) => {
      // Regular expression to check for any Hebrew characters in the input text
      return text.search(/[\u0590-\u05FF]/) >= 0;
    };
    
    // Function to check if text contains Arabic characters
    const isArabic = (text) => {
      // Regular expression to check for any Arabic characters in the input text
      return text.search(/[\u0600-\u06FF]/) >= 0;
    };
    
    // Function to reverse the order of words if the text is in Hebrew or Arabic
    const rightToLeftText = (text) => {
      // If the text contains either Hebrew or Arabic characters
      if (isHebrew(text) || isArabic(text)) {
        // Split the text into words, reverse the order, and join them back into a string
        return text.split(" ").reverse().join(" ");
      } else {
        // If the text does not contain Hebrew or Arabic, return the text as is
        return text;
      }
    };
    
    // Example usage:
    // Assume we have a variable "data.text" containing the text we want to process
    // Apply the rightToLeftText function to the "data.text" and store the result in the "text" variable
    const text = rightToLeftText(data.text);
    
    // Use a PDF generation library (assumed to be "doc") to set font, size, and text alignment
    doc
      // Set the font using the path to the font file
      .font(`${path.join(__dirname, "../../assets/fonts/Rabar_021.ttf")}`)
      // Set the font size for the text in the PDF
      .fontSize(10)
      // Add the text to the PDF document with right alignment
      .text(text, { align: "right" });