Rand Stats

LaTeX::Grammar

zef:antononcube

LaTeX::Grammar

Raku package with a parser and interpreters of LaTeX code. The implemented interpretation formats are:

The MathJSON interpreter was the first to be implemented, and it is the most important one -- the rest are derived from it.

The primary motivation to make this package is:

For example, the LaTeX parser can be used to recognize (detect or extract) LaTeX expressions in texts and make certain computations with them.

As for the interpreters:


Installation

From Zef ecosystem:

zef install LaTeX::Grammar

Usage examples

Interpretation to MathJSON (default interpreter):

use LaTeX::Grammar;

latex-interpret('\frac{1}{x}=\sqrt{y}')
# [Equal [Divide 1 x] [Root y 2]]

A table that show interpretations to different formats:

use Data::Translators;
use Data::Reshapers;

my @formulas = (
'\frac{-1214}{117}',
'\\sqrt{4 * x^2 + 12 * x + 9}',
'\\int_{0}^{1} x^{2} d x',
'\\sum_{n=1}^{10} n^2',
'\\lim_{x\\to0} \\frac{\\sin(x)}{x}',
'\\log_{5} x',
'\log\left( \frac{x+1}{x-1} \right)'
);
my @targets = <AsciiMath WL MathJSON>;

my @res = do for @formulas -> $fm {
    [
     LaTeX => $fm, 
     MathML => "latex«$fm»",
     RakuAST => latex-interpret($fm, actions => 'RakuAST').DEPARSE,
     |@targets.map({ $_ => latex-interpret($fm, actions => $_).raku })
    ].Hash
}

@res 
==> { .&to-long-format(id-columns => 'LaTeX', variables-to => 'Format', values-to => 'Translation') }()
==> { group-by($_, 'LaTeX').map({ $_.value.sort(*<LaTeX Format>).kv.map(-> $i, %r { %r<LaTeX> ='' if $i; %r }) }) }()
==> { $_.flat(1) }()
==> to-html(field-names => <LaTeX Format Translation>, align => 'left')
==> { .subst(/ 'latex«' (.*?) '»' /, { latex-interpret($0.Str, actions => 'MathML')}, :g) }()
==> { .subst(/ '"' | '&quot;' /, :g).subst('\{', '{', :g) }()
LaTeXFormatTranslation
\log_{5} xAsciiMathlog_5(x)
MathJSON$[Log, x, 5]
MathMLlog5(x)
RakuASTlog(x)
WLLog[5,x]
\sqrt{4 * x^2 + 12 * x + 9}AsciiMathsqrt((4*x^2+12*x)+9)
MathJSON$[Root, [Add, [Add, [Multiply, 4, [Power, x, 2]], [Multiply, 12, x]], 9], 2]
MathML4×x2+12×x+9
RakuASTsqrt((((4 * (x ** 2)) + (12 * x)) + 9))
WLSqrt[Plus[Plus[Times[4,Power[x,2]],Times[12,x]],9]]
\log\left( \frac{x+1}{x-1} \right)AsciiMathlog((x+1)/(x-1))
MathJSON$[Log, [Divide, [Add, x, 1], [Subtract, x, 1]]]
MathMLlog(x+1x-1)
RakuASTlog(((x + 1) / (x - 1)))
WLLog[Rational[Plus[x,1],Plus[x,Times[-1,1]]]]
\frac{-1214}{117}AsciiMath-1214/117
MathJSON$[Rational, -1214, 117]
MathML-1214117
RakuAST(-1214 / 117)
WLRational[-1214,117]
\lim_{x\to0} \frac{\sin(x)}{x}AsciiMathlim_(x->0) sin(x)/x
MathJSON$[Limit, [Function, [Block, [Divide, [Sin, x], x]], x], 0]
MathMLlimx→0sin(x)x
RakuASTlimit((sin(x) / x), x, 0, TwoSided)
WLLimit[Times[ Sin[x] , Power[x, -1]],x->0]
\int_{0}^{1} x^{2} d xAsciiMathint_(0)^(1) x^2 dx
MathJSON$[Integrate, [Function, [Block, [Power, x, 2]], x], [Limits, x, 0, 1]]
MathML∫01x2dx
RakuASTintegral((x ** 2), x, 0, 1)
WLIntegrate[Power[x,2],{x,0,1}]
\sum_{n=1}^{10} n^2AsciiMathsum_(n=1)^(10) n^2
MathJSON$[Sum, [Power, n, 2], [Limits, n, 1, 10]]
MathML∑n=110n2
RakuAST[+] (1 .. 10).map(-> $n! { ($n ** 2) })
WLSum[Power[n,2],{n,1,10}]

See also the Jupyter notebook "Basic-usage.ipynb".

Remark: In the table above "RakuAST" fields show the "deparsed" RakuAST constructs, i.e., Raku code.

Remark: The MathML code might be rendered incorrectly in GitHub's README. In Jupyter notebooks and specialized Markdown viewers it can be seen that the generated MathML code corresponds to the LaTeX code.

Here is a LaTeX translation to RakuAST structure:

latex-interpret('\sin(x + 2)', actions => 'RakuAST')
# RakuAST::Call::Name.new(
#   name => RakuAST::Name.from-identifier("sin"),
#   args => RakuAST::ArgList.new(
#     RakuAST::Circumfix::Parentheses.new(
#       RakuAST::SemiList.new(
#         RakuAST::Statement::Expression.new(
#           expression => RakuAST::ApplyInfix.new(
#             left  => RakuAST::Term::Name.new(
#               RakuAST::Name.new(
#                 RakuAST::Name::Part::Expression.new(
#                   RakuAST::QuotedString.new(
#                     segments   => (
#                       RakuAST::StrLiteral.new("x"),
#                     )
#                   )
#                 )
#               )
#             ),
#             infix => RakuAST::Infix.new("+"),
#             right => RakuAST::IntLiteral.new(2)
#           )
#         )
#       )
#     )
#   )
# )

CLI

The package provides Command Line Interface (CLI) script. Here is usage message:

from-latex --help
# Usage:
#   from-latex <text> [-t|--actions|--to=<Str>] [-f|--format=<Str>] [-o|--output=<Str>] -- Converts LaTeX code or files into AsciiMath, MathJSON, MathML, Mathematica, or Raku files.
#   
#     <text>                     Input file or LaTeX spec.
#     -t|--actions|--to=<Str>    Language to translate to. (One of 'asciimath', 'mathjson', 'mathml', 'mathematica', 'raku', 'rakuast', 'wolfram', or 'Whatever'.) [default: 'Whatever']
#     -f|--format=<Str>          Format of the result. (One of 'ast', 'json', 'raku', or 'Whatever'.) [default: 'Whatever']
#     -o|--output=<Str>          Output file; if an empty string then the result is printed to stdout. [default: '']

TODO


References

Packages

[AAp1] Anton Antonov, CortexJS, Raku package, (2026), GitHub/antononcube.

[AAp2] Anton Antonov, Proc::ZMQed, Raku package, (2022), GitHub/antononcube.

Videos

[AAv1] Anton Antonov, ["Using Wolfram Engine in Raku sessions"], video presentation, (2022), YouTube/@AAA4prediction.