Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AOUSD example node definitions #2180

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

anderslanglands
Copy link
Contributor

@anderslanglands anderslanglands commented Jan 13, 2025

Hello, as part of the effort under AOUSD to write an ISO standard for MaterialX in OpenUSD, we would like to suggest some updates to the node definitions in the MaterialX spec. This Draft PR contains a couple of example files to aid discussion.

In the PR, example.md contains some introductory descriptions of the specification structure as well as a dummy node example showing how that looks. math.md is a (nearly) complete update of the math nodes to this format, to show how it would look rendered.

The main motiviation here is to provide a concise, exact, normative definition of each node's behavior such that a developer could implement the nodes using the definition alone, that will be suitable for direct referencing in the ISO specification. We also believe the consistent formatting and depth of information will be useful for users as well.

We look forward to your comments and discussion.

Copy link

CLA Not Signed

@kwokcb
Copy link
Contributor

kwokcb commented Jan 13, 2025

Hi @anderslanglands,

Some testing deployment notes:

Syntax (Minor)

  • I tried to see compatibility with html output and to let you know it can all be pre-processed thus far to give you something that can be consumed by Web math formatters: MathJax and Katex. (see below)
  • \lparan, and \rparan may not be supported well so may be better to use \left, \right
  • items like subscripts: _{i} for compatibility need to be escaped these using \_{i}
  • \aligned vs \align may be more compatible depending on library

Maintainability

  • I'm wondering if it's better to pull information off of nodedefs to build docs. Currently you can have the documentation in 2 places: here and in the nodedefs -- or in the current case no documentation on nodedefs or places in a 3rd place as comments in the XML file.

  • If deriving from nodedefs a possible option is to clean up the Python script called mxdoc which scans nodedefs to build docs.

  • Especially things like the listing arg type variations could become cumbersome to maintain.

  • If using information here, the alternative suggestion is to inject this documentation into nodedefs. If there was some id tag
    for each category of node then it should be pretty easy to do. e.g. Instead of:

## add

use

<h2 id="add">add</h2> 

"LaTex" / Markdown / HTML Processing

Here the example preprocessing for Web I have worked out.
Place math.md in the same folder as these files, start a local http server,
and load in the html file below.

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">

  <!-- Use KaTex -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.css">

  <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>

  <!-- Uncomment to use MathJax
  <script type="text/javascript" async>
    window.MathJax = {
      tex: {
        packages: {'[+]': ['mathtools']}, // Load the mathtools package
        inlineMath: [['$', '$']], // Enable single dollar signs for inline math
        displayMath: [['$$', '$$']] // Double dollar signs for block math
      },
      options: {
        skipHtmlTags: ['script', 'noscript', 'style', 'textarea', 'pre'], // Avoid parsing code blocks
      }
    };
  </script>
  <script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
  -->

  <!-- Custom styling as desired -->
  <link rel="stylesheet" href="style.css">   
</head>

<body>
  <h1>MaterialX Node Library</h1>
  <div id="content">Loading...</div>
  <textarea id="html_result" rows="20" style="width: 100%"></textarea>

  <!-- Include KaTeX JS and auto-render extension -->
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/contrib/auto-render.min.js" onload="renderMathInElement(document.body, {
      delimiters: [
        { left: '$$', right: '$$', display: true },  // Block math
        { left: '$', right: '$', display: false }    // Inline math
      ]
    });">
    </script>

  <script id="render_page">

    const replaceMath = (match, content) => {
      // Split the content into lines
      // Filter out empty lines (lines with only whitespace)
      // Join the non-empty lines back together with \n
      const lines = content.split('\n');
      const nonEmptyLines = lines.filter(line => line.trim() !== '');
      let modifiedContent = nonEmptyLines.join('\n');

      // Replace \\ with \\\\ to escape backslashes
      modifiedContent = modifiedContent.replace(/\\\\/g, '\\\\\\\\');

      // Perform if \align not handled
      let replaceAlign = false
      if (replaceAlign) {
        // Replace \begin{align} with \begin{aligned} and \end{align} with \end{aligned}
        modifiedContent = modifiedContent      
          .replace(/\\begin\{align\}/g, '\\begin{aligned}')
          .replace(/\\end\{align\}/g, '\\end{aligned}');
      }

      //console.log('Replace:', content, '\nwith:', `\n$$${modifiedContent}$$\n`)

      // Wrap the content with $$ and preserve the triple backticks
      return `\n$$${modifiedContent}$$\n`;
    };

    // Load the Markdown file
    fetch('math.md')
      .then(response => response.text())
      .then(text => {

        const pattern = /```math\s*\n([\s\S]*?)\n\s*```/g
        text = text.replace(pattern, replaceMath);

        //console.log(text)

        // Convert Markdown to HTML using marked.js
        html = marked.parse(text);

        // Insert the HTML into the content div
        document.getElementById('content').innerHTML = html;

        // Output the converted page before rendering.
        const clonedDocument = document.documentElement.cloneNode(true);
        // - Remove the script with id="render_page" from the cloned document
        const scriptToRemove = clonedDocument.querySelector('#render_page');
        if (scriptToRemove) {
          scriptToRemove.remove();
        }
        // - Remove the html result area
        const htmlResultRemove = clonedDocument.querySelector('#html_result');
        if (htmlResultRemove) {
          htmlResultRemove.remove();
        }

        // Re-render formulas
        setTimeout(() => {
          // Use KaTex
          renderMathInElement(document.getElementById('content'),
            {
              delimiters: [
                { left: '$$', right: '$$', display: true },  // Block math
                { left: '$', right: '$', display: false }    // Inline math
              ]
            });

          // OR Use MathJax for the new content
          //MathJax.typesetPromise();

          // Get the outerHTML of the modified clone
          const renderedPageContent = clonedDocument.outerHTML;
          //console.log('Fully evaluated page content:', renderedPageContent);
          document.getElementById('html_result').value = "\<!DOCTYPE html\>\n" + renderedPageContent;
        }, 100); // Adjust the delay as needed

      })
      .catch(error => {
        console.error('Error loading the Markdown file:', error);
        document.getElementById('content').textContent = 'Error loading the Markdown file.';
      });
  </script>
</body>

</html>

CSS file style.css:

body {
    font-family: Arial, sans-serif;
    line-height: 1.6;
    /* max-width: 800px; */
    margin: 20px auto;
    padding: 40px;
}

pre {
    background: #f4f4f4;
    padding: 10px;
    border-radius: 5px;
    overflow-x: auto;
}

table {
    border-collapse: collapse;
    width: 100%;
    max-height: 300px;   /* Set a maximum height for the table */
    overflow-y: auto;    /* Enable vertical scrolling */
    display: block
}

th,
td {
    width: 100%;
    border: 1px solid black;
    padding: 4px;
    text-align: left;
}

th {
    background-color: rgb(0, 98, 133); /* Black background */
    color: white;           /* White text */
    font-weight: bold;      /* Bold text for headers */
    padding: 8px;           /* Padding for better spacing */
    border: 1px solid black; /* Ensure borders are consistent */
}

@kwokcb
Copy link
Contributor

kwokcb commented Jan 14, 2025

Couple of small items if your having issues with MathJax: you may be running into issues with blank lines between \begin{} and \end{} delimiters. Also I don't think folks should use $$ block delimiters and instead go with ```math which is what you are using.

In any case if you or anyone else working on this would like to see the Markdown->HTML conversion live I left a page here

You can load in your Markdown file as desired. You can look at the page source to see the "funky" pre-processing I needed to do to get the html. See: "view-source:https://kwokcb.github.io/MaterialXLab/javascript/formulas/formulas_internal.html".

I added some styling as well but this is superfluous (https://kwokcb.github.io/MaterialXLab/javascript/formulas/style.css)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants