Skip to content

Issue with MathJax on server side across multiple page renders and impacting the rendering of pages after the first - essential CSS styles are missing from the output. #3377

Open
@gorai-sunil

Description

@gorai-sunil

Issue Summary

Here issue is when I convert MathJax for a single XHTML file, then all respective styles are generated, but with multiple files in the same XHTML file doesn't create all styles for MathJax after the first file.

Steps to Reproduce:

  1. Extract an EPUB/ZIP file and provide the path for each extracted file.
  2. Convert MathJax tags using the MathJax object for each page render.
  3. Write output files

The below MathJax styles are not generating in the case of multiple file conversions, while they generate when we process a single file or the first file.

mjx-c.mjx-c2A7D.TEX-A::before {
padding: 0.636em 0.778em 0.138em 0;
content: "\2A7D";
}
mjx-c.mjx-c3E::before {
padding: 0.54em 0.778em 0.04em 0;
content: ">";
}
mjx-c.mjx-c2A7E.TEX-A::before {
padding: 0.636em 0.778em 0.138em 0;
content: "\2A7E";
}
mjx-c.mjx-c2260::before {
padding: 0.716em 0.778em 0.215em 0;
content: "\2260";
}
mjx-c.mjx-c31::before {
padding: 0.666em 0.5em 0 0;
content: "1";
}
mjx-c.mjx-c30::before {
padding: 0.666em 0.5em 0.022em 0;
content: "0";
}
mjx-c.mjx-cD7::before {
padding: 0.491em 0.778em 0 0;
content: "\D7";
}
mjx-c.mjx-c2009::before {
padding: 0 0.167em 0 0;
content: "";
}
mjx-c.mjx-c3D::before {
padding: 0.583em 0.778em 0.082em 0;
content: "=";
}
mjx-c.mjx-c2C::before {
padding: 0.121em 0.278em 0.194em 0;
content: ",";
}
mjx-c.mjx-c3C::before {
padding: 0.54em 0.778em 0.04em 0;
content: "<";
}

Technical details:

  • MathJax Version: 3.2
  • Node.js v20

I am using the following MathJax configuration:

async function renderMathML(INPUT_PATH, callback) {
 try {
     const FILENAME = path.basename(INPUT_PATH);
     const OUTPUT_PATH = path.join('output', FILENAME);
    if (!fs.existsSync(INPUT_PATH)) {
      return callback(new Error(`Input file not found: ${INPUT_PATH}`));
    }

    const HTML_FILE = fs.readFileSync(INPUT_PATH, 'utf-8');

    // Initialize MathJax instance
      const MathJax = require('mathjax');
      mjInstance = await MathJax.init({
        loader: {
          load: ['adaptors/liteDOM', 'input/mml', 'output/chtml', 'a11y/assistive-mml']
        },
        chtml: {
          fontURL: FONT_URL,
        },
        startup: {
          document: HTML_FILE
        }
      });
    

    // Get content
    const adaptor = mjInstance.startup.adaptor;
    const doc = mjInstance.startup.document;

    if (Array.from(doc.math).length === 0) adaptor.remove(doc.outputJax.chtmlStyles);
    const renderedDoc = adaptor.outerHTML(adaptor.root(doc.document));
     fs.writeFileSync(OUTPUT_PATH, renderedDoc);
    // Return the output
    callback(null, renderedDoc);
  } catch (error) {
    console.error("MathJax Error:", error);
    callback(error);
  }
}
module.exports = { renderMathML };

and calling the above function via a file in for loop as below:

      return new Promise((resolve, reject) => {
        renderMathML(folderpath, (err, result) => {
          if (err) reject(err);
          else resolve(result);
        });
      });
    }
   
    for (const zipEntry of zipEntries) {
      if (zipEntry.entryName.endsWith(".xhtml")) {
        let found = MathJaxFileList.find((file) => zipEntry.entryName.endsWith(file)); 
        if (found) {
          let fileData = zip.readAsText(zipEntry.entryName, 'utf8');
          if (!fileData.match(/mathjax/g)) {
            let folderpath = path.join("/tmp/" + s3FileName.replace(".epub", ""), zipEntry.entryName);
              try {
                    const renderedHTML = await renderMathMLAsync(folderpath);
                    zip.updateFile(zipEntry, Buffer.from(renderedHTML, 'utf8'));
              } catch (err) {
                console.error("MathJax render error", err);
              }
          }
        }
      }
    }

Supporting information:

Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    AcceptedIssue has been reproduced by MathJax teamCode ExampleContains an illustrative code example, solution, or work-aroundv3

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions