Skip to content

Repository files navigation

TeXpressions

BuildTestscodecov

TeXpressions is a framework for .NET 6+ that can do:

  • Run-time parsing of LaTeX math and logical strings
  • Compile-time expression building, similar to the Linq.Expressions API
  • Evaluation of expressions
  • Simplification of expressions (including intermediate steps)
  • Formatting of expressions to LaTeX strings

Contributing

I encourage members of the community, regardless of experience level, to participate in the design and implementation of this software. All new contributors should read the contributing guidelines. Good candidate issues for first time contributors can be found in the issues tab.

Please don't forget to comment in an issue (or create a new issue) prior to submitting a pull request. This makes it easier for other contributors to know what's being worked on.

How to Use

There are two primary ways to build TeXpression trees. All of the code in the following two sections can be found and run yourself from samples/ReadmeExample/Program.cs.

What you see below is just the most basic explanation. See the wiki (TODO) for more details and features.

1. Parsing LaTeX strings

The "more powerful" method of building TeXpressions is feeding it LaTeX strings. These are parsed into their respective TeXpression trees. Let's look at an example:

$\frac{2 \times 10}{4}$ which renders to $\frac{2 \times 10}{4}$ Using some mental math, we can quickly see that this should evaluate to 5.

We can easily parse it to a variable called texpr like this:

vartexpr=ParseUtility.ParseInlineExpression<TeXpression<double>>(@"$\frac{2 \times 10}{4}$");// the @ before the string makes it a verbatim string, so backslash \ doesn't get escaped// slightly cleaner than the alternative "$\\frac{2 \\times 10}{4}$" :)

How will this get parsed? It might be easier to explain with an image of the resulting tree:

image

Hopefully it's pretty clear what's happening here:

  • The "outer" or "top" most TeXpression is a BinaryTeXpression representing the \frac LaTeX function.
    • The dividend (a.k.a. numerator) is the root's "Left" inner TeXpression, and is another BinaryTeXpression, but this time for the \times operator. Being a BinaryTeXpression, it has a Left and Right of its own:
      • The Left is a ConstantTeXpression with value 2.
      • The Right is a ConstantTeXpression with value 10.
    • The divisor is the "Right" TeXpression and is a ConstantTeXpression with a value of 4.

Great, we have a TeXpression tree! What can we do with it? Well, we can turn it back into LaTeX which is nice:

Console.WriteLine($"The expression back to inline LaTeX: ${texpr.ToLaTeX()}$");

We can also evaluate the TeXpression because there's no unknown parameters:

Console.WriteLine($"And it evaluates to: ${texpr.Evaluate()}$");

Here is the resulting output for both lines:

The expression back to inline LaTeX: $\frac{2 \times 10}{4}$
And it evaluates to: 5

Not bad!

2. Using built-in builder APIs

Okay, so we just saw how the parser can turn an inline LaTeX expression and turn it into a TeXpression tree. What if we wanted to build this at design time?

The built-in Numeric static class is great for building TeXpression trees for common math functions, and working with the double value-type. Let's make the above example using the Numeric API:

vartexpr2=Numeric.Divide(// Root: BinaryTeXpressionNumeric.Multiply(// Root.Left: BinaryTeXpressionNumeric.Constant(2),// Root.Left.Left: ConstantTeXpressionNumeric.Constant(10)// Root.Left.Right: ConstantTeXpression),Numeric.Constant(4)// Root.Right: ConstantTeXpression);

Let's format the LaTeX string and evaluate this one. Hopefully it all comes out the same:

Console.WriteLine($"texpr2 back to inline LaTeX: ${texpr2.ToLaTeX()}$");Console.WriteLine($"This one evaluates to: ${texpr2.Evaluate()}$");

And the resulting output:

texpr2 back to inline LaTeX: $\frac{2 \times 10}{4}$
This one evaluates to: 5

It looks like it matches, phew!

Extensibility

None of the classes in this library are sealed so you're free to create your own inherited classes for your own use-case.

Please open a new issue if you want to merge your implementation to this library! It should be common enough to benefit others, so please keep that in mind before submitting.

Why doesn't this use Linq.Expressions?

TeXpressions was never intended to replace Linq.Expressions. While some inspiration was drawn from the runtime's expression tree architecture and builder API and there is minor overlap in capabilties, TeXpressions use-cases are quite different. It is meant to be a math and logic centric expression tree builder that includes built-in LaTeX support. Not all TeXpressions have Linq.Expressions counterparts and vice-versa. Perhaps someday there could be some integration but at time of conception it doesn't seem to make sense.

1.0.0 Roadmap

  • Iterables (sums, etc.)
  • SigFigLaTeXFormatter
  • How to handle rounding error - should number rounding in simplifications cascade to future steps? Make it configurable?

Disclaimer

I'm not very smart, I'm not the best programmer or software architect, I'm certainly not a great mathematician or LaTeX wizard. I wrote this in my spare time to fulfill my own niche use-case at work, while trying to generalize it enough to be helpful to others. I'm sure it can be improved and that there are mistakes. If you have suggestions or questions, please open a new issue or a discussion thread.

At the moment this code base is highly volatile - it is very likely to change quite a lot before I choose to release 1.0.0. Use at your own risk!

I do not guarantee or certify the accuracy of the LaTeX parsing, expression simplifications, evaluation, or LaTeX formatting! It is up to you as the consumer to independently verify that this software is sufficiently safe and accurate for your needs. See LICENSE.txt for more details.

References

[1] Downes, Michael, and Barbara Beeton. “Short Math Guide for LATEX." http://mirror.ctan.org/info/short-math-guide

[2] "LaTeX/Mathematics." Wikibooks, The Free Textbook Project. 25 Oct 2022, 10:02 UTC. 16 Mar 2023, 09:48 https://en.wikibooks.org/w/index.php?title=LaTeX/Mathematics&oldid=4197055.

About

A .NET 6+ LaTeX-based expression parsing, building, formatting, and evaluation framework.

Topics

Resources

Code of conduct

Contributing

Stars

4 stars

Watchers

1 watching

Forks

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
GitHub - lwestfall/TeXpressions: A .NET 6+ LaTeX-based expression parsing, building, formatting, and evaluation framework. · GitHub
Skip to content

Repository files navigation

TeXpressions

BuildTestscodecov

TeXpressions is a framework for .NET 6+ that can do:

  • Run-time parsing of LaTeX math and logical strings
  • Compile-time expression building, similar to the Linq.Expressions API
  • Evaluation of expressions
  • Simplification of expressions (including intermediate steps)
  • Formatting of expressions to LaTeX strings

Contributing

I encourage members of the community, regardless of experience level, to participate in the design and implementation of this software. All new contributors should read the contributing guidelines. Good candidate issues for first time contributors can be found in the issues tab.

Please don't forget to comment in an issue (or create a new issue) prior to submitting a pull request. This makes it easier for other contributors to know what's being worked on.

How to Use

There are two primary ways to build TeXpression trees. All of the code in the following two sections can be found and run yourself from samples/ReadmeExample/Program.cs.

What you see below is just the most basic explanation. See the wiki (TODO) for more details and features.

1. Parsing LaTeX strings

The "more powerful" method of building TeXpressions is feeding it LaTeX strings. These are parsed into their respective TeXpression trees. Let's look at an example:

$\frac{2 \times 10}{4}$ which renders to $\frac{2 \times 10}{4}$ Using some mental math, we can quickly see that this should evaluate to 5.

We can easily parse it to a variable called texpr like this:

vartexpr=ParseUtility.ParseInlineExpression<TeXpression<double>>(@"$\frac{2 \times 10}{4}$");// the @ before the string makes it a verbatim string, so backslash \ doesn't get escaped// slightly cleaner than the alternative "$\\frac{2 \\times 10}{4}$" :)

How will this get parsed? It might be easier to explain with an image of the resulting tree:

image

Hopefully it's pretty clear what's happening here:

  • The "outer" or "top" most TeXpression is a BinaryTeXpression representing the \frac LaTeX function.
    • The dividend (a.k.a. numerator) is the root's "Left" inner TeXpression, and is another BinaryTeXpression, but this time for the \times operator. Being a BinaryTeXpression, it has a Left and Right of its own:
      • The Left is a ConstantTeXpression with value 2.
      • The Right is a ConstantTeXpression with value 10.
    • The divisor is the "Right" TeXpression and is a ConstantTeXpression with a value of 4.

Great, we have a TeXpression tree! What can we do with it? Well, we can turn it back into LaTeX which is nice:

Console.WriteLine($"The expression back to inline LaTeX: ${texpr.ToLaTeX()}$");

We can also evaluate the TeXpression because there's no unknown parameters:

Console.WriteLine($"And it evaluates to: ${texpr.Evaluate()}$");

Here is the resulting output for both lines:

The expression back to inline LaTeX: $\frac{2 \times 10}{4}$
And it evaluates to: 5

Not bad!

2. Using built-in builder APIs

Okay, so we just saw how the parser can turn an inline LaTeX expression and turn it into a TeXpression tree. What if we wanted to build this at design time?

The built-in Numeric static class is great for building TeXpression trees for common math functions, and working with the double value-type. Let's make the above example using the Numeric API:

vartexpr2=Numeric.Divide(// Root: BinaryTeXpressionNumeric.Multiply(// Root.Left: BinaryTeXpressionNumeric.Constant(2),// Root.Left.Left: ConstantTeXpressionNumeric.Constant(10)// Root.Left.Right: ConstantTeXpression),Numeric.Constant(4)// Root.Right: ConstantTeXpression);

Let's format the LaTeX string and evaluate this one. Hopefully it all comes out the same:

Console.WriteLine($"texpr2 back to inline LaTeX: ${texpr2.ToLaTeX()}$");Console.WriteLine($"This one evaluates to: ${texpr2.Evaluate()}$");

And the resulting output:

texpr2 back to inline LaTeX: $\frac{2 \times 10}{4}$
This one evaluates to: 5

It looks like it matches, phew!

Extensibility

None of the classes in this library are sealed so you're free to create your own inherited classes for your own use-case.

Please open a new issue if you want to merge your implementation to this library! It should be common enough to benefit others, so please keep that in mind before submitting.

Why doesn't this use Linq.Expressions?

TeXpressions was never intended to replace Linq.Expressions. While some inspiration was drawn from the runtime's expression tree architecture and builder API and there is minor overlap in capabilties, TeXpressions use-cases are quite different. It is meant to be a math and logic centric expression tree builder that includes built-in LaTeX support. Not all TeXpressions have Linq.Expressions counterparts and vice-versa. Perhaps someday there could be some integration but at time of conception it doesn't seem to make sense.

1.0.0 Roadmap

  • Iterables (sums, etc.)
  • SigFigLaTeXFormatter
  • How to handle rounding error - should number rounding in simplifications cascade to future steps? Make it configurable?

Disclaimer

I'm not very smart, I'm not the best programmer or software architect, I'm certainly not a great mathematician or LaTeX wizard. I wrote this in my spare time to fulfill my own niche use-case at work, while trying to generalize it enough to be helpful to others. I'm sure it can be improved and that there are mistakes. If you have suggestions or questions, please open a new issue or a discussion thread.

At the moment this code base is highly volatile - it is very likely to change quite a lot before I choose to release 1.0.0. Use at your own risk!

I do not guarantee or certify the accuracy of the LaTeX parsing, expression simplifications, evaluation, or LaTeX formatting! It is up to you as the consumer to independently verify that this software is sufficiently safe and accurate for your needs. See LICENSE.txt for more details.

References

[1] Downes, Michael, and Barbara Beeton. “Short Math Guide for LATEX." http://mirror.ctan.org/info/short-math-guide

[2] "LaTeX/Mathematics." Wikibooks, The Free Textbook Project. 25 Oct 2022, 10:02 UTC. 16 Mar 2023, 09:48 https://en.wikibooks.org/w/index.php?title=LaTeX/Mathematics&oldid=4197055.

About

A .NET 6+ LaTeX-based expression parsing, building, formatting, and evaluation framework.

Topics

Resources

Code of conduct

Contributing

Stars

4 stars

Watchers

1 watching

Forks

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - lwestfall/TeXpressions: A .NET 6+ LaTeX-based expression parsing, building, formatting, and evaluation framework. · GitHub
Skip to content

Repository files navigation

TeXpressions

BuildTestscodecov

TeXpressions is a framework for .NET 6+ that can do:

  • Run-time parsing of LaTeX math and logical strings
  • Compile-time expression building, similar to the Linq.Expressions API
  • Evaluation of expressions
  • Simplification of expressions (including intermediate steps)
  • Formatting of expressions to LaTeX strings

Contributing

I encourage members of the community, regardless of experience level, to participate in the design and implementation of this software. All new contributors should read the contributing guidelines. Good candidate issues for first time contributors can be found in the issues tab.

Please don't forget to comment in an issue (or create a new issue) prior to submitting a pull request. This makes it easier for other contributors to know what's being worked on.

How to Use

There are two primary ways to build TeXpression trees. All of the code in the following two sections can be found and run yourself from samples/ReadmeExample/Program.cs.

What you see below is just the most basic explanation. See the wiki (TODO) for more details and features.

1. Parsing LaTeX strings

The "more powerful" method of building TeXpressions is feeding it LaTeX strings. These are parsed into their respective TeXpression trees. Let's look at an example:

$\frac{2 \times 10}{4}$ which renders to $\frac{2 \times 10}{4}$ Using some mental math, we can quickly see that this should evaluate to 5.

We can easily parse it to a variable called texpr like this:

vartexpr=ParseUtility.ParseInlineExpression<TeXpression<double>>(@"$\frac{2 \times 10}{4}$");// the @ before the string makes it a verbatim string, so backslash \ doesn't get escaped// slightly cleaner than the alternative "$\\frac{2 \\times 10}{4}$" :)

How will this get parsed? It might be easier to explain with an image of the resulting tree:

image

Hopefully it's pretty clear what's happening here:

  • The "outer" or "top" most TeXpression is a BinaryTeXpression representing the \frac LaTeX function.
    • The dividend (a.k.a. numerator) is the root's "Left" inner TeXpression, and is another BinaryTeXpression, but this time for the \times operator. Being a BinaryTeXpression, it has a Left and Right of its own:
      • The Left is a ConstantTeXpression with value 2.
      • The Right is a ConstantTeXpression with value 10.
    • The divisor is the "Right" TeXpression and is a ConstantTeXpression with a value of 4.

Great, we have a TeXpression tree! What can we do with it? Well, we can turn it back into LaTeX which is nice:

Console.WriteLine($"The expression back to inline LaTeX: ${texpr.ToLaTeX()}$");

We can also evaluate the TeXpression because there's no unknown parameters:

Console.WriteLine($"And it evaluates to: ${texpr.Evaluate()}$");

Here is the resulting output for both lines:

The expression back to inline LaTeX: $\frac{2 \times 10}{4}$
And it evaluates to: 5

Not bad!

2. Using built-in builder APIs

Okay, so we just saw how the parser can turn an inline LaTeX expression and turn it into a TeXpression tree. What if we wanted to build this at design time?

The built-in Numeric static class is great for building TeXpression trees for common math functions, and working with the double value-type. Let's make the above example using the Numeric API:

vartexpr2=Numeric.Divide(// Root: BinaryTeXpressionNumeric.Multiply(// Root.Left: BinaryTeXpressionNumeric.Constant(2),// Root.Left.Left: ConstantTeXpressionNumeric.Constant(10)// Root.Left.Right: ConstantTeXpression),Numeric.Constant(4)// Root.Right: ConstantTeXpression);

Let's format the LaTeX string and evaluate this one. Hopefully it all comes out the same:

Console.WriteLine($"texpr2 back to inline LaTeX: ${texpr2.ToLaTeX()}$");Console.WriteLine($"This one evaluates to: ${texpr2.Evaluate()}$");

And the resulting output:

texpr2 back to inline LaTeX: $\frac{2 \times 10}{4}$
This one evaluates to: 5

It looks like it matches, phew!

Extensibility

None of the classes in this library are sealed so you're free to create your own inherited classes for your own use-case.

Please open a new issue if you want to merge your implementation to this library! It should be common enough to benefit others, so please keep that in mind before submitting.

Why doesn't this use Linq.Expressions?

TeXpressions was never intended to replace Linq.Expressions. While some inspiration was drawn from the runtime's expression tree architecture and builder API and there is minor overlap in capabilties, TeXpressions use-cases are quite different. It is meant to be a math and logic centric expression tree builder that includes built-in LaTeX support. Not all TeXpressions have Linq.Expressions counterparts and vice-versa. Perhaps someday there could be some integration but at time of conception it doesn't seem to make sense.

1.0.0 Roadmap

  • Iterables (sums, etc.)
  • SigFigLaTeXFormatter
  • How to handle rounding error - should number rounding in simplifications cascade to future steps? Make it configurable?

Disclaimer

I'm not very smart, I'm not the best programmer or software architect, I'm certainly not a great mathematician or LaTeX wizard. I wrote this in my spare time to fulfill my own niche use-case at work, while trying to generalize it enough to be helpful to others. I'm sure it can be improved and that there are mistakes. If you have suggestions or questions, please open a new issue or a discussion thread.

At the moment this code base is highly volatile - it is very likely to change quite a lot before I choose to release 1.0.0. Use at your own risk!

I do not guarantee or certify the accuracy of the LaTeX parsing, expression simplifications, evaluation, or LaTeX formatting! It is up to you as the consumer to independently verify that this software is sufficiently safe and accurate for your needs. See LICENSE.txt for more details.

References

[1] Downes, Michael, and Barbara Beeton. “Short Math Guide for LATEX." http://mirror.ctan.org/info/short-math-guide

[2] "LaTeX/Mathematics." Wikibooks, The Free Textbook Project. 25 Oct 2022, 10:02 UTC. 16 Mar 2023, 09:48 https://en.wikibooks.org/w/index.php?title=LaTeX/Mathematics&oldid=4197055.

About

A .NET 6+ LaTeX-based expression parsing, building, formatting, and evaluation framework.

Topics

Resources

Code of conduct

Contributing

Stars

4 stars

Watchers

1 watching

Forks

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - lwestfall/TeXpressions: A .NET 6+ LaTeX-based expression parsing, building, formatting, and evaluation framework. · GitHub
Skip to content

Repository files navigation

TeXpressions

BuildTestscodecov

TeXpressions is a framework for .NET 6+ that can do:

  • Run-time parsing of LaTeX math and logical strings
  • Compile-time expression building, similar to the Linq.Expressions API
  • Evaluation of expressions
  • Simplification of expressions (including intermediate steps)
  • Formatting of expressions to LaTeX strings

Contributing

I encourage members of the community, regardless of experience level, to participate in the design and implementation of this software. All new contributors should read the contributing guidelines. Good candidate issues for first time contributors can be found in the issues tab.

Please don't forget to comment in an issue (or create a new issue) prior to submitting a pull request. This makes it easier for other contributors to know what's being worked on.

How to Use

There are two primary ways to build TeXpression trees. All of the code in the following two sections can be found and run yourself from samples/ReadmeExample/Program.cs.

What you see below is just the most basic explanation. See the wiki (TODO) for more details and features.

1. Parsing LaTeX strings

The "more powerful" method of building TeXpressions is feeding it LaTeX strings. These are parsed into their respective TeXpression trees. Let's look at an example:

$\frac{2 \times 10}{4}$ which renders to $\frac{2 \times 10}{4}$ Using some mental math, we can quickly see that this should evaluate to 5.

We can easily parse it to a variable called texpr like this:

vartexpr=ParseUtility.ParseInlineExpression<TeXpression<double>>(@"$\frac{2 \times 10}{4}$");// the @ before the string makes it a verbatim string, so backslash \ doesn't get escaped// slightly cleaner than the alternative "$\\frac{2 \\times 10}{4}$" :)

How will this get parsed? It might be easier to explain with an image of the resulting tree:

image

Hopefully it's pretty clear what's happening here:

  • The "outer" or "top" most TeXpression is a BinaryTeXpression representing the \frac LaTeX function.
    • The dividend (a.k.a. numerator) is the root's "Left" inner TeXpression, and is another BinaryTeXpression, but this time for the \times operator. Being a BinaryTeXpression, it has a Left and Right of its own:
      • The Left is a ConstantTeXpression with value 2.
      • The Right is a ConstantTeXpression with value 10.
    • The divisor is the "Right" TeXpression and is a ConstantTeXpression with a value of 4.

Great, we have a TeXpression tree! What can we do with it? Well, we can turn it back into LaTeX which is nice:

Console.WriteLine($"The expression back to inline LaTeX: ${texpr.ToLaTeX()}$");

We can also evaluate the TeXpression because there's no unknown parameters:

Console.WriteLine($"And it evaluates to: ${texpr.Evaluate()}$");

Here is the resulting output for both lines:

The expression back to inline LaTeX: $\frac{2 \times 10}{4}$
And it evaluates to: 5

Not bad!

2. Using built-in builder APIs

Okay, so we just saw how the parser can turn an inline LaTeX expression and turn it into a TeXpression tree. What if we wanted to build this at design time?

The built-in Numeric static class is great for building TeXpression trees for common math functions, and working with the double value-type. Let's make the above example using the Numeric API:

vartexpr2=Numeric.Divide(// Root: BinaryTeXpressionNumeric.Multiply(// Root.Left: BinaryTeXpressionNumeric.Constant(2),// Root.Left.Left: ConstantTeXpressionNumeric.Constant(10)// Root.Left.Right: ConstantTeXpression),Numeric.Constant(4)// Root.Right: ConstantTeXpression);

Let's format the LaTeX string and evaluate this one. Hopefully it all comes out the same:

Console.WriteLine($"texpr2 back to inline LaTeX: ${texpr2.ToLaTeX()}$");Console.WriteLine($"This one evaluates to: ${texpr2.Evaluate()}$");

And the resulting output:

texpr2 back to inline LaTeX: $\frac{2 \times 10}{4}$
This one evaluates to: 5

It looks like it matches, phew!

Extensibility

None of the classes in this library are sealed so you're free to create your own inherited classes for your own use-case.

Please open a new issue if you want to merge your implementation to this library! It should be common enough to benefit others, so please keep that in mind before submitting.

Why doesn't this use Linq.Expressions?

TeXpressions was never intended to replace Linq.Expressions. While some inspiration was drawn from the runtime's expression tree architecture and builder API and there is minor overlap in capabilties, TeXpressions use-cases are quite different. It is meant to be a math and logic centric expression tree builder that includes built-in LaTeX support. Not all TeXpressions have Linq.Expressions counterparts and vice-versa. Perhaps someday there could be some integration but at time of conception it doesn't seem to make sense.

1.0.0 Roadmap

  • Iterables (sums, etc.)
  • SigFigLaTeXFormatter
  • How to handle rounding error - should number rounding in simplifications cascade to future steps? Make it configurable?

Disclaimer

I'm not very smart, I'm not the best programmer or software architect, I'm certainly not a great mathematician or LaTeX wizard. I wrote this in my spare time to fulfill my own niche use-case at work, while trying to generalize it enough to be helpful to others. I'm sure it can be improved and that there are mistakes. If you have suggestions or questions, please open a new issue or a discussion thread.

At the moment this code base is highly volatile - it is very likely to change quite a lot before I choose to release 1.0.0. Use at your own risk!

I do not guarantee or certify the accuracy of the LaTeX parsing, expression simplifications, evaluation, or LaTeX formatting! It is up to you as the consumer to independently verify that this software is sufficiently safe and accurate for your needs. See LICENSE.txt for more details.

References

[1] Downes, Michael, and Barbara Beeton. “Short Math Guide for LATEX." http://mirror.ctan.org/info/short-math-guide

[2] "LaTeX/Mathematics." Wikibooks, The Free Textbook Project. 25 Oct 2022, 10:02 UTC. 16 Mar 2023, 09:48 https://en.wikibooks.org/w/index.php?title=LaTeX/Mathematics&oldid=4197055.

About

A .NET 6+ LaTeX-based expression parsing, building, formatting, and evaluation framework.

Topics

Resources

Code of conduct

Contributing

Stars

4 stars

Watchers

1 watching

Forks

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' GitHub - lwestfall/TeXpressions: A .NET 6+ LaTeX-based expression parsing, building, formatting, and evaluation framework. · GitHub
Skip to content

Repository files navigation

TeXpressions

BuildTestscodecov

TeXpressions is a framework for .NET 6+ that can do:

  • Run-time parsing of LaTeX math and logical strings
  • Compile-time expression building, similar to the Linq.Expressions API
  • Evaluation of expressions
  • Simplification of expressions (including intermediate steps)
  • Formatting of expressions to LaTeX strings

Contributing

I encourage members of the community, regardless of experience level, to participate in the design and implementation of this software. All new contributors should read the contributing guidelines. Good candidate issues for first time contributors can be found in the issues tab.

Please don't forget to comment in an issue (or create a new issue) prior to submitting a pull request. This makes it easier for other contributors to know what's being worked on.

How to Use

There are two primary ways to build TeXpression trees. All of the code in the following two sections can be found and run yourself from samples/ReadmeExample/Program.cs.

What you see below is just the most basic explanation. See the wiki (TODO) for more details and features.

1. Parsing LaTeX strings

The "more powerful" method of building TeXpressions is feeding it LaTeX strings. These are parsed into their respective TeXpression trees. Let's look at an example:

$\frac{2 \times 10}{4}$ which renders to $\frac{2 \times 10}{4}$ Using some mental math, we can quickly see that this should evaluate to 5.

We can easily parse it to a variable called texpr like this:

vartexpr=ParseUtility.ParseInlineExpression<TeXpression<double>>(@"$\frac{2 \times 10}{4}$");// the @ before the string makes it a verbatim string, so backslash \ doesn't get escaped// slightly cleaner than the alternative "$\\frac{2 \\times 10}{4}$" :)

How will this get parsed? It might be easier to explain with an image of the resulting tree:

image

Hopefully it's pretty clear what's happening here:

  • The "outer" or "top" most TeXpression is a BinaryTeXpression representing the \frac LaTeX function.
    • The dividend (a.k.a. numerator) is the root's "Left" inner TeXpression, and is another BinaryTeXpression, but this time for the \times operator. Being a BinaryTeXpression, it has a Left and Right of its own:
      • The Left is a ConstantTeXpression with value 2.
      • The Right is a ConstantTeXpression with value 10.
    • The divisor is the "Right" TeXpression and is a ConstantTeXpression with a value of 4.

Great, we have a TeXpression tree! What can we do with it? Well, we can turn it back into LaTeX which is nice:

Console.WriteLine($"The expression back to inline LaTeX: ${texpr.ToLaTeX()}$");

We can also evaluate the TeXpression because there's no unknown parameters:

Console.WriteLine($"And it evaluates to: ${texpr.Evaluate()}$");

Here is the resulting output for both lines:

The expression back to inline LaTeX: $\frac{2 \times 10}{4}$
And it evaluates to: 5

Not bad!

2. Using built-in builder APIs

Okay, so we just saw how the parser can turn an inline LaTeX expression and turn it into a TeXpression tree. What if we wanted to build this at design time?

The built-in Numeric static class is great for building TeXpression trees for common math functions, and working with the double value-type. Let's make the above example using the Numeric API:

vartexpr2=Numeric.Divide(// Root: BinaryTeXpressionNumeric.Multiply(// Root.Left: BinaryTeXpressionNumeric.Constant(2),// Root.Left.Left: ConstantTeXpressionNumeric.Constant(10)// Root.Left.Right: ConstantTeXpression),Numeric.Constant(4)// Root.Right: ConstantTeXpression);

Let's format the LaTeX string and evaluate this one. Hopefully it all comes out the same:

Console.WriteLine($"texpr2 back to inline LaTeX: ${texpr2.ToLaTeX()}$");Console.WriteLine($"This one evaluates to: ${texpr2.Evaluate()}$");

And the resulting output:

texpr2 back to inline LaTeX: $\frac{2 \times 10}{4}$
This one evaluates to: 5

It looks like it matches, phew!

Extensibility

None of the classes in this library are sealed so you're free to create your own inherited classes for your own use-case.

Please open a new issue if you want to merge your implementation to this library! It should be common enough to benefit others, so please keep that in mind before submitting.

Why doesn't this use Linq.Expressions?

TeXpressions was never intended to replace Linq.Expressions. While some inspiration was drawn from the runtime's expression tree architecture and builder API and there is minor overlap in capabilties, TeXpressions use-cases are quite different. It is meant to be a math and logic centric expression tree builder that includes built-in LaTeX support. Not all TeXpressions have Linq.Expressions counterparts and vice-versa. Perhaps someday there could be some integration but at time of conception it doesn't seem to make sense.

1.0.0 Roadmap

  • Iterables (sums, etc.)
  • SigFigLaTeXFormatter
  • How to handle rounding error - should number rounding in simplifications cascade to future steps? Make it configurable?

Disclaimer

I'm not very smart, I'm not the best programmer or software architect, I'm certainly not a great mathematician or LaTeX wizard. I wrote this in my spare time to fulfill my own niche use-case at work, while trying to generalize it enough to be helpful to others. I'm sure it can be improved and that there are mistakes. If you have suggestions or questions, please open a new issue or a discussion thread.

At the moment this code base is highly volatile - it is very likely to change quite a lot before I choose to release 1.0.0. Use at your own risk!

I do not guarantee or certify the accuracy of the LaTeX parsing, expression simplifications, evaluation, or LaTeX formatting! It is up to you as the consumer to independently verify that this software is sufficiently safe and accurate for your needs. See LICENSE.txt for more details.

References

[1] Downes, Michael, and Barbara Beeton. “Short Math Guide for LATEX." http://mirror.ctan.org/info/short-math-guide

[2] "LaTeX/Mathematics." Wikibooks, The Free Textbook Project. 25 Oct 2022, 10:02 UTC. 16 Mar 2023, 09:48 https://en.wikibooks.org/w/index.php?title=LaTeX/Mathematics&oldid=4197055.

About

A .NET 6+ LaTeX-based expression parsing, building, formatting, and evaluation framework.

Topics

Resources

Code of conduct

Contributing

Stars

4 stars

Watchers

1 watching

Forks

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - lwestfall/TeXpressions: A .NET 6+ LaTeX-based expression parsing, building, formatting, and evaluation framework. · GitHub
Skip to content

Repository files navigation

TeXpressions

BuildTestscodecov

TeXpressions is a framework for .NET 6+ that can do:

  • Run-time parsing of LaTeX math and logical strings
  • Compile-time expression building, similar to the Linq.Expressions API
  • Evaluation of expressions
  • Simplification of expressions (including intermediate steps)
  • Formatting of expressions to LaTeX strings

Contributing

I encourage members of the community, regardless of experience level, to participate in the design and implementation of this software. All new contributors should read the contributing guidelines. Good candidate issues for first time contributors can be found in the issues tab.

Please don't forget to comment in an issue (or create a new issue) prior to submitting a pull request. This makes it easier for other contributors to know what's being worked on.

How to Use

There are two primary ways to build TeXpression trees. All of the code in the following two sections can be found and run yourself from samples/ReadmeExample/Program.cs.

What you see below is just the most basic explanation. See the wiki (TODO) for more details and features.

1. Parsing LaTeX strings

The "more powerful" method of building TeXpressions is feeding it LaTeX strings. These are parsed into their respective TeXpression trees. Let's look at an example:

$\frac{2 \times 10}{4}$ which renders to $\frac{2 \times 10}{4}$ Using some mental math, we can quickly see that this should evaluate to 5.

We can easily parse it to a variable called texpr like this:

vartexpr=ParseUtility.ParseInlineExpression<TeXpression<double>>(@"$\frac{2 \times 10}{4}$");// the @ before the string makes it a verbatim string, so backslash \ doesn't get escaped// slightly cleaner than the alternative "$\\frac{2 \\times 10}{4}$" :)

How will this get parsed? It might be easier to explain with an image of the resulting tree:

image

Hopefully it's pretty clear what's happening here:

  • The "outer" or "top" most TeXpression is a BinaryTeXpression representing the \frac LaTeX function.
    • The dividend (a.k.a. numerator) is the root's "Left" inner TeXpression, and is another BinaryTeXpression, but this time for the \times operator. Being a BinaryTeXpression, it has a Left and Right of its own:
      • The Left is a ConstantTeXpression with value 2.
      • The Right is a ConstantTeXpression with value 10.
    • The divisor is the "Right" TeXpression and is a ConstantTeXpression with a value of 4.

Great, we have a TeXpression tree! What can we do with it? Well, we can turn it back into LaTeX which is nice:

Console.WriteLine($"The expression back to inline LaTeX: ${texpr.ToLaTeX()}$");

We can also evaluate the TeXpression because there's no unknown parameters:

Console.WriteLine($"And it evaluates to: ${texpr.Evaluate()}$");

Here is the resulting output for both lines:

The expression back to inline LaTeX: $\frac{2 \times 10}{4}$
And it evaluates to: 5

Not bad!

2. Using built-in builder APIs

Okay, so we just saw how the parser can turn an inline LaTeX expression and turn it into a TeXpression tree. What if we wanted to build this at design time?

The built-in Numeric static class is great for building TeXpression trees for common math functions, and working with the double value-type. Let's make the above example using the Numeric API:

vartexpr2=Numeric.Divide(// Root: BinaryTeXpressionNumeric.Multiply(// Root.Left: BinaryTeXpressionNumeric.Constant(2),// Root.Left.Left: ConstantTeXpressionNumeric.Constant(10)// Root.Left.Right: ConstantTeXpression),Numeric.Constant(4)// Root.Right: ConstantTeXpression);

Let's format the LaTeX string and evaluate this one. Hopefully it all comes out the same:

Console.WriteLine($"texpr2 back to inline LaTeX: ${texpr2.ToLaTeX()}$");Console.WriteLine($"This one evaluates to: ${texpr2.Evaluate()}$");

And the resulting output:

texpr2 back to inline LaTeX: $\frac{2 \times 10}{4}$
This one evaluates to: 5

It looks like it matches, phew!

Extensibility

None of the classes in this library are sealed so you're free to create your own inherited classes for your own use-case.

Please open a new issue if you want to merge your implementation to this library! It should be common enough to benefit others, so please keep that in mind before submitting.

Why doesn't this use Linq.Expressions?

TeXpressions was never intended to replace Linq.Expressions. While some inspiration was drawn from the runtime's expression tree architecture and builder API and there is minor overlap in capabilties, TeXpressions use-cases are quite different. It is meant to be a math and logic centric expression tree builder that includes built-in LaTeX support. Not all TeXpressions have Linq.Expressions counterparts and vice-versa. Perhaps someday there could be some integration but at time of conception it doesn't seem to make sense.

1.0.0 Roadmap

  • Iterables (sums, etc.)
  • SigFigLaTeXFormatter
  • How to handle rounding error - should number rounding in simplifications cascade to future steps? Make it configurable?

Disclaimer

I'm not very smart, I'm not the best programmer or software architect, I'm certainly not a great mathematician or LaTeX wizard. I wrote this in my spare time to fulfill my own niche use-case at work, while trying to generalize it enough to be helpful to others. I'm sure it can be improved and that there are mistakes. If you have suggestions or questions, please open a new issue or a discussion thread.

At the moment this code base is highly volatile - it is very likely to change quite a lot before I choose to release 1.0.0. Use at your own risk!

I do not guarantee or certify the accuracy of the LaTeX parsing, expression simplifications, evaluation, or LaTeX formatting! It is up to you as the consumer to independently verify that this software is sufficiently safe and accurate for your needs. See LICENSE.txt for more details.

References

[1] Downes, Michael, and Barbara Beeton. “Short Math Guide for LATEX." http://mirror.ctan.org/info/short-math-guide

[2] "LaTeX/Mathematics." Wikibooks, The Free Textbook Project. 25 Oct 2022, 10:02 UTC. 16 Mar 2023, 09:48 https://en.wikibooks.org/w/index.php?title=LaTeX/Mathematics&oldid=4197055.

About

A .NET 6+ LaTeX-based expression parsing, building, formatting, and evaluation framework.

Topics

Resources

Code of conduct

Contributing

Stars

4 stars

Watchers

1 watching

Forks

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - lwestfall/TeXpressions: A .NET 6+ LaTeX-based expression parsing, building, formatting, and evaluation framework. · GitHub
Skip to content

Repository files navigation

TeXpressions

BuildTestscodecov

TeXpressions is a framework for .NET 6+ that can do:

  • Run-time parsing of LaTeX math and logical strings
  • Compile-time expression building, similar to the Linq.Expressions API
  • Evaluation of expressions
  • Simplification of expressions (including intermediate steps)
  • Formatting of expressions to LaTeX strings

Contributing

I encourage members of the community, regardless of experience level, to participate in the design and implementation of this software. All new contributors should read the contributing guidelines. Good candidate issues for first time contributors can be found in the issues tab.

Please don't forget to comment in an issue (or create a new issue) prior to submitting a pull request. This makes it easier for other contributors to know what's being worked on.

How to Use

There are two primary ways to build TeXpression trees. All of the code in the following two sections can be found and run yourself from samples/ReadmeExample/Program.cs.

What you see below is just the most basic explanation. See the wiki (TODO) for more details and features.

1. Parsing LaTeX strings

The "more powerful" method of building TeXpressions is feeding it LaTeX strings. These are parsed into their respective TeXpression trees. Let's look at an example:

$\frac{2 \times 10}{4}$ which renders to $\frac{2 \times 10}{4}$ Using some mental math, we can quickly see that this should evaluate to 5.

We can easily parse it to a variable called texpr like this:

vartexpr=ParseUtility.ParseInlineExpression<TeXpression<double>>(@"$\frac{2 \times 10}{4}$");// the @ before the string makes it a verbatim string, so backslash \ doesn't get escaped// slightly cleaner than the alternative "$\\frac{2 \\times 10}{4}$" :)

How will this get parsed? It might be easier to explain with an image of the resulting tree:

image

Hopefully it's pretty clear what's happening here:

  • The "outer" or "top" most TeXpression is a BinaryTeXpression representing the \frac LaTeX function.
    • The dividend (a.k.a. numerator) is the root's "Left" inner TeXpression, and is another BinaryTeXpression, but this time for the \times operator. Being a BinaryTeXpression, it has a Left and Right of its own:
      • The Left is a ConstantTeXpression with value 2.
      • The Right is a ConstantTeXpression with value 10.
    • The divisor is the "Right" TeXpression and is a ConstantTeXpression with a value of 4.

Great, we have a TeXpression tree! What can we do with it? Well, we can turn it back into LaTeX which is nice:

Console.WriteLine($"The expression back to inline LaTeX: ${texpr.ToLaTeX()}$");

We can also evaluate the TeXpression because there's no unknown parameters:

Console.WriteLine($"And it evaluates to: ${texpr.Evaluate()}$");

Here is the resulting output for both lines:

The expression back to inline LaTeX: $\frac{2 \times 10}{4}$
And it evaluates to: 5

Not bad!

2. Using built-in builder APIs

Okay, so we just saw how the parser can turn an inline LaTeX expression and turn it into a TeXpression tree. What if we wanted to build this at design time?

The built-in Numeric static class is great for building TeXpression trees for common math functions, and working with the double value-type. Let's make the above example using the Numeric API:

vartexpr2=Numeric.Divide(// Root: BinaryTeXpressionNumeric.Multiply(// Root.Left: BinaryTeXpressionNumeric.Constant(2),// Root.Left.Left: ConstantTeXpressionNumeric.Constant(10)// Root.Left.Right: ConstantTeXpression),Numeric.Constant(4)// Root.Right: ConstantTeXpression);

Let's format the LaTeX string and evaluate this one. Hopefully it all comes out the same:

Console.WriteLine($"texpr2 back to inline LaTeX: ${texpr2.ToLaTeX()}$");Console.WriteLine($"This one evaluates to: ${texpr2.Evaluate()}$");

And the resulting output:

texpr2 back to inline LaTeX: $\frac{2 \times 10}{4}$
This one evaluates to: 5

It looks like it matches, phew!

Extensibility

None of the classes in this library are sealed so you're free to create your own inherited classes for your own use-case.

Please open a new issue if you want to merge your implementation to this library! It should be common enough to benefit others, so please keep that in mind before submitting.

Why doesn't this use Linq.Expressions?

TeXpressions was never intended to replace Linq.Expressions. While some inspiration was drawn from the runtime's expression tree architecture and builder API and there is minor overlap in capabilties, TeXpressions use-cases are quite different. It is meant to be a math and logic centric expression tree builder that includes built-in LaTeX support. Not all TeXpressions have Linq.Expressions counterparts and vice-versa. Perhaps someday there could be some integration but at time of conception it doesn't seem to make sense.

1.0.0 Roadmap

  • Iterables (sums, etc.)
  • SigFigLaTeXFormatter
  • How to handle rounding error - should number rounding in simplifications cascade to future steps? Make it configurable?

Disclaimer

I'm not very smart, I'm not the best programmer or software architect, I'm certainly not a great mathematician or LaTeX wizard. I wrote this in my spare time to fulfill my own niche use-case at work, while trying to generalize it enough to be helpful to others. I'm sure it can be improved and that there are mistakes. If you have suggestions or questions, please open a new issue or a discussion thread.

At the moment this code base is highly volatile - it is very likely to change quite a lot before I choose to release 1.0.0. Use at your own risk!

I do not guarantee or certify the accuracy of the LaTeX parsing, expression simplifications, evaluation, or LaTeX formatting! It is up to you as the consumer to independently verify that this software is sufficiently safe and accurate for your needs. See LICENSE.txt for more details.

References

[1] Downes, Michael, and Barbara Beeton. “Short Math Guide for LATEX." http://mirror.ctan.org/info/short-math-guide

[2] "LaTeX/Mathematics." Wikibooks, The Free Textbook Project. 25 Oct 2022, 10:02 UTC. 16 Mar 2023, 09:48 https://en.wikibooks.org/w/index.php?title=LaTeX/Mathematics&oldid=4197055.

About

A .NET 6+ LaTeX-based expression parsing, building, formatting, and evaluation framework.

Topics

Resources

Code of conduct

Contributing

Stars

4 stars

Watchers

1 watching

Forks

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); GitHub - lwestfall/TeXpressions: A .NET 6+ LaTeX-based expression parsing, building, formatting, and evaluation framework. · GitHub
Skip to content

Repository files navigation

TeXpressions

BuildTestscodecov

TeXpressions is a framework for .NET 6+ that can do:

  • Run-time parsing of LaTeX math and logical strings
  • Compile-time expression building, similar to the Linq.Expressions API
  • Evaluation of expressions
  • Simplification of expressions (including intermediate steps)
  • Formatting of expressions to LaTeX strings

Contributing

I encourage members of the community, regardless of experience level, to participate in the design and implementation of this software. All new contributors should read the contributing guidelines. Good candidate issues for first time contributors can be found in the issues tab.

Please don't forget to comment in an issue (or create a new issue) prior to submitting a pull request. This makes it easier for other contributors to know what's being worked on.

How to Use

There are two primary ways to build TeXpression trees. All of the code in the following two sections can be found and run yourself from samples/ReadmeExample/Program.cs.

What you see below is just the most basic explanation. See the wiki (TODO) for more details and features.

1. Parsing LaTeX strings

The "more powerful" method of building TeXpressions is feeding it LaTeX strings. These are parsed into their respective TeXpression trees. Let's look at an example:

$\frac{2 \times 10}{4}$ which renders to $\frac{2 \times 10}{4}$ Using some mental math, we can quickly see that this should evaluate to 5.

We can easily parse it to a variable called texpr like this:

vartexpr=ParseUtility.ParseInlineExpression<TeXpression<double>>(@"$\frac{2 \times 10}{4}$");// the @ before the string makes it a verbatim string, so backslash \ doesn't get escaped// slightly cleaner than the alternative "$\\frac{2 \\times 10}{4}$" :)

How will this get parsed? It might be easier to explain with an image of the resulting tree:

image

Hopefully it's pretty clear what's happening here:

  • The "outer" or "top" most TeXpression is a BinaryTeXpression representing the \frac LaTeX function.
    • The dividend (a.k.a. numerator) is the root's "Left" inner TeXpression, and is another BinaryTeXpression, but this time for the \times operator. Being a BinaryTeXpression, it has a Left and Right of its own:
      • The Left is a ConstantTeXpression with value 2.
      • The Right is a ConstantTeXpression with value 10.
    • The divisor is the "Right" TeXpression and is a ConstantTeXpression with a value of 4.

Great, we have a TeXpression tree! What can we do with it? Well, we can turn it back into LaTeX which is nice:

Console.WriteLine($"The expression back to inline LaTeX: ${texpr.ToLaTeX()}$");

We can also evaluate the TeXpression because there's no unknown parameters:

Console.WriteLine($"And it evaluates to: ${texpr.Evaluate()}$");

Here is the resulting output for both lines:

The expression back to inline LaTeX: $\frac{2 \times 10}{4}$
And it evaluates to: 5

Not bad!

2. Using built-in builder APIs

Okay, so we just saw how the parser can turn an inline LaTeX expression and turn it into a TeXpression tree. What if we wanted to build this at design time?

The built-in Numeric static class is great for building TeXpression trees for common math functions, and working with the double value-type. Let's make the above example using the Numeric API:

vartexpr2=Numeric.Divide(// Root: BinaryTeXpressionNumeric.Multiply(// Root.Left: BinaryTeXpressionNumeric.Constant(2),// Root.Left.Left: ConstantTeXpressionNumeric.Constant(10)// Root.Left.Right: ConstantTeXpression),Numeric.Constant(4)// Root.Right: ConstantTeXpression);

Let's format the LaTeX string and evaluate this one. Hopefully it all comes out the same:

Console.WriteLine($"texpr2 back to inline LaTeX: ${texpr2.ToLaTeX()}$");Console.WriteLine($"This one evaluates to: ${texpr2.Evaluate()}$");

And the resulting output:

texpr2 back to inline LaTeX: $\frac{2 \times 10}{4}$
This one evaluates to: 5

It looks like it matches, phew!

Extensibility

None of the classes in this library are sealed so you're free to create your own inherited classes for your own use-case.

Please open a new issue if you want to merge your implementation to this library! It should be common enough to benefit others, so please keep that in mind before submitting.

Why doesn't this use Linq.Expressions?

TeXpressions was never intended to replace Linq.Expressions. While some inspiration was drawn from the runtime's expression tree architecture and builder API and there is minor overlap in capabilties, TeXpressions use-cases are quite different. It is meant to be a math and logic centric expression tree builder that includes built-in LaTeX support. Not all TeXpressions have Linq.Expressions counterparts and vice-versa. Perhaps someday there could be some integration but at time of conception it doesn't seem to make sense.

1.0.0 Roadmap

  • Iterables (sums, etc.)
  • SigFigLaTeXFormatter
  • How to handle rounding error - should number rounding in simplifications cascade to future steps? Make it configurable?

Disclaimer

I'm not very smart, I'm not the best programmer or software architect, I'm certainly not a great mathematician or LaTeX wizard. I wrote this in my spare time to fulfill my own niche use-case at work, while trying to generalize it enough to be helpful to others. I'm sure it can be improved and that there are mistakes. If you have suggestions or questions, please open a new issue or a discussion thread.

At the moment this code base is highly volatile - it is very likely to change quite a lot before I choose to release 1.0.0. Use at your own risk!

I do not guarantee or certify the accuracy of the LaTeX parsing, expression simplifications, evaluation, or LaTeX formatting! It is up to you as the consumer to independently verify that this software is sufficiently safe and accurate for your needs. See LICENSE.txt for more details.

References

[1] Downes, Michael, and Barbara Beeton. “Short Math Guide for LATEX." http://mirror.ctan.org/info/short-math-guide

[2] "LaTeX/Mathematics." Wikibooks, The Free Textbook Project. 25 Oct 2022, 10:02 UTC. 16 Mar 2023, 09:48 https://en.wikibooks.org/w/index.php?title=LaTeX/Mathematics&oldid=4197055.

About

A .NET 6+ LaTeX-based expression parsing, building, formatting, and evaluation framework.

Topics

Resources

Code of conduct

Contributing

Stars

4 stars

Watchers

1 watching

Forks

Packages

Used by

Contributors

Languages