AsciiMath Parser

   

What’s this?

A JavaScript implementation of simple mathematical formula markup language. It is more readable and easy to learn compared with LaTeX\LaTeX.

How to Use

API

You can use either asciimath-parser or asciimath-parser-nearley. This documentation is for the former, while the latter has some differences. Please refer to its README.

Basic Usage

Install the package with npm/yarn/pnpm.

pnpm i -D asciimath-parser

Import it and create an instance of Asciimath, then use the toTex method to generate LaTeX code.

import { AsciiMath } from 'asciimath-parser'
const am = new AsciiMath()
console.log(am.toTex('sum_(n=1)^(+oo)1/n^2=pi^2/6'))
// \displaystyle{ \sum _{ n = 1 } ^{ + \infty } \frac{ 1 }{ n ^{ 2 } } = \frac{ \pi ^{ 2 } }{ 6 } }

Configuration and Custom Tokens

The following is the type declaration of AsciiMath config.

type ReplaceLaw = [RegExp | string, string | ((substring: string, ...args: any[]) => string)]

interface AsciiMathConfig {
  display?: boolean
  replaceBeforeTokenizing?: ReplaceLaw[]
  symbols?: Array<[string, SymbolValueType]> | Record<string, SymbolValueType>
}
display

Specify whether the generated formula is wrapped in \displaystyle environment. The default value is true.

replaceBeforeTokenizing

Replace the matched strings with the target strings respectively before the formula is parsed by AsciiMath.

Click to show details.

For example, if you specify it like below:

const cfg: AsciiMathConfig = {
  replaceBeforeTokenizing: [
    [/d0/g, '{:"d"theta:}'],
    [/x(\d+)/g, (_, $1) => `x^(${$1})`],
  ]
}
const am = new AsciiMath(cfg)
console.log(am.toTex('...'))
  • All of the d0 will be replaced with {:"d"theta:}, and then be parsed into { \text{d} \theta } by AsciiMath.
  • Strings like x2 and x10 will be replaced with x^(2) and x^(10), and then be parsed into x^{ 2 } and x^{ 10 }, respectively. (I think no one should write them like this, though ¯\_(ツ)_/¯)
symbols

Specify the extended tokens. If you want to view all of the token types, please refer to symbols.ts. However, it is not recommended to extend all of them. The following lists the recommended token types for extension

enum TokenTypes {
  Const, // transform matched string into tex
  OperatorOA, // with unary operand, like `abs(a)`
  OperatorOAB, // with binary operands, like `frac(a)(b)`
  OperatorAOB, // infix operator, like `a / b`
  OperatorAO, // suffix operator, like factorial `n!`
}
Click to show details.

You can specify it below

const cfg: AsciiMathConfig = {
  symbols: {
    dx: { type: TokenTypes.Const, tex: '{\\mathrm{d}x}' },
    rm: { type: TokenTypes.OperatorOA, tex: '\\mathrm{$1}', eatNext: true },
    frac: { type: TokenTypes.OperatorOAB, tex: '\\frac{ $1 }{ $2 }' },
    over: { type: TokenTypes.OperatorAOB, tex: '{ $1 \\over $2 }' },
  }
}
const am = new AsciiMath(cfg)
console.log(am.toTex('...'))

Then dx, rm, frac and over will be recognized as tokens of AsciiMath, and the results will be

  • dx into {\mathrm{d}x}

  • rm(absc) into \mathrm{absc}, where $1 will be replaced with absc

    If eatNext is set to true, then the next word will be “eaten” by tokenizer and recognized as a literal string even if there is any token in it. In the example above, absc contains the token abs, but the program just simply read the word and put absc at the $1.

    Without eatNext, you will get \mathrm{ \left|c\right| }.

    If you want to read a longer sentense, just wrap it with doublequotes " or parens ( ) like rm "here is a mathrm block"

    eatNext is only recommended to be used with OperatorOA and OperatorOAB.

  • frac(m)(n) into \frac{ m }{ n }, where $1 and $2 will be replaced with m and n, respectively

  • a over b into { a \over b }, where $1 and $2 will be replaced with a and b, respectively

Cli

Install the cli locally or globally.

pnpm add -g asciimath-parser-cli

Transform input files with inline asciimath formulas (wrapped with backticks) to LaTeX formulas.

am-parse input.txt
# It will yield input_parsed_xxx.tex

User Story

Caution

  • This library is refactored by me, which means that some of the syntax may be inconsistent with asciimath.org, especially the matrix.
  • Asciimath parser itself does not depend on DOM or mathml, it simply parses your input code into LaTeX code. If you want to display formulas, please work it out with KaTeX or mathjax (for websites) or LaTeX (for articles).

Special Thanks

zmx0142857’s note and his great help.

Report an Issue

Go to GitHub issue and provide a template that can reproduce the problem you ran into.

Examples

Themeoutputsource
Super and subscripta12+b12=c12\displaystyle{ a _{ 1 } ^{ 2 } + b _{ 1 } ^{ 2 } = c _{ 1 } ^{ 2 } }a_1^2 + b_1^2 = c_1^2
Texthello world\displaystyle{ \text{hello world} }"hello world"
Fractionab,a/b\displaystyle{ \frac{ a }{ b } , a {/} b }a/b, a//b
Square rootn,xn,a2b\displaystyle{ \sqrt{ n } , \sqrt[ n ]{ x } , \frac{ a ^{ 2 } }{ \sqrt{ b } } }sqrt n, root n x, a^2/sqrt b
Limitlimn(1+1n)n\displaystyle{ \lim _{ n \to \infty } \left( 1 + \frac{ 1 }{ n } \right) ^{ n } }lim_(n->oo) (1+1/n)^n
Integralabf(x)dx\displaystyle{ \int _{ a } ^{ b } f \left( x \right) {\text{d}x} }int_a^b f(x) dx
Hidden parenssinx2\displaystyle{ \sin { \frac{ x }{ 2 } } }sin {: x/2 :}
Differentialdydx,drdθ,f(x)\displaystyle{ \frac{ {\text{d}y} }{ {\text{d}x} } , \frac{ \text{d} r }{ \text{d} \theta } , f ^{\prime\prime} \left( x \right) }dy/dx, ("d"r)/("d"theta), f''(x)
Differential (exprimental)dfdx,d2fdx2,x¨\displaystyle{ \frac{ \mathrm{d} f }{ \mathrm{d} x } , \frac{ \mathrm{d} ^{ 2 } f }{ \mathrm{d} x ^{ 2 } } , \ddot{ x } }ddfx , dd^2 f x , ddot x
Partialfx,3fxy2\displaystyle{ \frac{ \partial f }{ \partial x } , \frac{ \partial ^{ 3 } f }{ \partial x \partial y ^{ 2 } } }(del f)/(del x), (del^3 f)/(del x del y^2)
Partial (experiment)fx,3fxy2,x\displaystyle{ \frac{ \partial f }{ \partial x } , \frac{ \partial ^{ 3 } f }{ \partial x \partial y ^{ 2 } } , \frac{ \partial { } }{ \partial x } }ppfx, pp^3 f (x y^2), pp {::} x
Matrix[abcd],[abcdef]\displaystyle{ \left[ \begin{array}{cc} a & b \\ c & d \end{array} \right] , \left[ \begin{array}{cc|c} a & b & c \\ d & e & f \end{array} \right] }[a, b; c, d], [a, b | c; d, e | f]
Piecewise functionx={xifx>0xotherwise\displaystyle{ \left| x \right| = \left\lbrace \begin{array}{ll} x & \text{if}\quad x > 0 \\ - x & \text{otherwise}\quad \end{array} \right. }|x| = { x, if x > 0; -x, otherwise :}

Manual

Greek Alphabet

outputsourceoutputsourceoutputsourceoutputsource
α\displaystyle{ \alpha }alphaβ\displaystyle{ \beta }betaχ\displaystyle{ \chi }chiδ\displaystyle{ \delta }delta
Δ\displaystyle{ \Delta }Deltaε\displaystyle{ \varepsilon }epsiϵ\displaystyle{ \epsilon }epsilonη\displaystyle{ \eta }eta
γ\displaystyle{ \gamma }gammaΓ\displaystyle{ \Gamma }Gammaι\displaystyle{ \iota }iotaκ\displaystyle{ \kappa }kappa
λ\displaystyle{ \lambda }lambdaΛ\displaystyle{ \Lambda }Lambdaμ\displaystyle{ \mu }muν\displaystyle{ \nu }nu
ω\displaystyle{ \omega }omegaΩ\displaystyle{ \Omega }Omegaϕ\displaystyle{ \phi }phiφ\displaystyle{ \varphi }varphi
Φ\displaystyle{ \Phi }PhiΦ\displaystyle{ \varPhi }varPhiπ\displaystyle{ \pi }piΠ\displaystyle{ \Pi }Pi
ψ\displaystyle{ \psi }psiΨ\displaystyle{ \Psi }Psiρ\displaystyle{ \rho }rhoσ\displaystyle{ \sigma }sigma
Σ\displaystyle{ \Sigma }Sigmaτ\displaystyle{ \tau }tauθ\displaystyle{ \theta }thetaϑ\displaystyle{ \vartheta }vartheta
Θ\displaystyle{ \Theta }Thetaυ\displaystyle{ \upsilon }upsilonξ\displaystyle{ \xi }xiΞ\displaystyle{ \Xi }Xi
ζ\displaystyle{ \zeta }zeta

Paren

outputsourceoutputsourceoutputsourceoutputsource
(\displaystyle{ \left( \right. }()\displaystyle{ ) })\displaystyle{ \left. \right. }{:.\displaystyle{ . }:}
[\displaystyle{ \left[ \right. }[]\displaystyle{ ] }]{\displaystyle{ \left\lbrace \right. }{}\displaystyle{ \rbrace }}
\displaystyle{ \left\langle \right. }(:\displaystyle{ \rangle }:)\displaystyle{ \left\lfloor \right. }|__\displaystyle{ \rfloor }__|
\displaystyle{ \left\lceil \right. }|~\displaystyle{ \rceil }~|\displaystyle{ \mid }|x\displaystyle{ \left| x \right| }abs(x)
v\displaystyle{ \left\| \mathbf{ v } \right\| }norm(bb(v))x2\displaystyle{ \left\lfloor \frac{ x }{ 2 } \right\rfloor }floor(x/2)x3\displaystyle{ \left\lceil \frac{ x }{ 3 } \right\rceil }ceil(x/3)

Operator

outputsourceoutputsourceoutputsourceoutputsource
+\displaystyle{ + }+\displaystyle{ - }-\displaystyle{ \cdot }*\displaystyle{ \ast }**
/\displaystyle{ {/} }//\\displaystyle{ \backslash }\\×\displaystyle{ \times }xx÷\displaystyle{ \div }-:
\displaystyle{ \circ }@\displaystyle{ \oplus }o+\displaystyle{ \otimes }ox\displaystyle{ \odot }o.
\displaystyle{ \sum }sum\displaystyle{ \prod }prod\displaystyle{ \wedge }^^\displaystyle{ \bigwedge }^^^
\displaystyle{ \vee }vv\displaystyle{ \bigvee }vvv\displaystyle{ \cap }nn\displaystyle{ \bigcap }nnn
\displaystyle{ \cup }uu\displaystyle{ \bigcup }uuu%\displaystyle{ \% }%

Relation Symbol

outputsourceoutputsourceoutputsourceoutputsource
=\displaystyle{ = }=\displaystyle{ \ne }!=\displaystyle{ \equiv }-=≢\displaystyle{ \not\equiv }!-=
\displaystyle{ \cong }~=\displaystyle{ \approx }~~<\displaystyle{ < }lt>\displaystyle{ > }gt
\displaystyle{ \ge }ge\displaystyle{ \le }le\displaystyle{ \leqslant }<=\displaystyle{ \geqslant }>=
\displaystyle{ \prec }-<\displaystyle{ \succ }>-\displaystyle{ \in }in\displaystyle{ \notin }!in
\displaystyle{ \subset }sub\displaystyle{ \supset }sup\displaystyle{ \subseteq }sube\displaystyle{ \supseteq }supe
⊈\displaystyle{ \not\subseteq }!sube\displaystyle{ \subsetneqq }subne\displaystyle{ \unlhd }normal\displaystyle{ \unrhd }rnormal
\displaystyle{ \lhd }lhd\displaystyle{ \rhd }rhd\displaystyle{ ∽ }S~\displaystyle{ \propto }prop
\displaystyle{ \complement }complement

Logical Operator

outputsourceoutputsourceoutputsourceoutputsource
 and \displaystyle{ \text{ and } }and or \displaystyle{ \text{ or } }or¬\displaystyle{ \neg }not\displaystyle{ \Rightarrow }rArr
if\displaystyle{ \text{if}\quad }if    \displaystyle{ \iff }iff\displaystyle{ \forall }AA\displaystyle{ \exists }EE
\displaystyle{ \bot }_|_\displaystyle{ \top }TT\displaystyle{ \vdash }|--\displaystyle{ \models }|==

Others

outputsourceoutputsourceoutputsourceoutputsource
\displaystyle{ \int }int\displaystyle{ \iint }iint\displaystyle{ \iiint }iiint\displaystyle{ \oint }oint
\displaystyle{ \partial }del\displaystyle{ \nabla }grad±\displaystyle{ \pm }+-\displaystyle{ \varnothing }O/
\displaystyle{ \infty }oo\displaystyle{ \aleph }aleph\displaystyle{ \angle }/_\displaystyle{ \therefore }:.
\displaystyle{ \because }:'\displaystyle{ \ldots }...\displaystyle{ \cdots }cdots\displaystyle{ \vdots }vdots
\displaystyle{ \ddots }ddots\displaystyle{ \square }squareN\displaystyle{ \mathbb{N} }NNQ\displaystyle{ \mathbb{Q} }QQ
R\displaystyle{ \mathbb{R} }RRC\displaystyle{ \mathbb{C} }CCZ\displaystyle{ \mathbb{Z} }ZZ(Nk)\displaystyle{ { N \choose k } }N choose k

Math Function

outputsourceoutputsourceoutputsourceoutputsource
sin\displaystyle{ \sin }sincos\displaystyle{ \cos }costan\displaystyle{ \tan }tancot\displaystyle{ \cot }cot
sec\displaystyle{ \sec }seccsc\displaystyle{ \csc }cscsinh\displaystyle{ \sinh }sinhcosh\displaystyle{ \cosh }cosh
tanh\displaystyle{ \tanh }tanhcoth\displaystyle{ \coth }cothcsch\displaystyle{ \operatorname{csch} }cschsech\displaystyle{ \operatorname{sech} }sech
arcsin\displaystyle{ \arcsin }arcsinarccos\displaystyle{ \arccos }arccosarctan\displaystyle{ \arctan }arctanlog\displaystyle{ \log }log
ln\displaystyle{ \ln }lndet\displaystyle{ \det }detdim\displaystyle{ \dim }dimlim\displaystyle{ \lim }lim
mod\displaystyle{ \operatorname{mod} }modgcd\displaystyle{ \gcd }gcdlcm\displaystyle{ \operatorname{lcm} }lcmmin\displaystyle{ \min }min
max\displaystyle{ \max }maxsgn\displaystyle{ \operatorname{sgn} }sgnsup\displaystyle{ \sup }Supinf\displaystyle{ \inf }inf
exp\displaystyle{ \exp }exp

Arrow

outputsourceoutputsourceoutputsourceoutputsource
\displaystyle{ \uparrow }uarr\displaystyle{ \downarrow }darr\displaystyle{ \rightarrow }rarr\displaystyle{ \leftarrow }larr
\displaystyle{ \to }->\displaystyle{ \mapsto }|->\displaystyle{ \leftrightarrow }harr\displaystyle{ \Rightarrow }rArr
\displaystyle{ \Leftarrow }lArr\displaystyle{ \Leftrightarrow }hArr\displaystyle{ \twoheadrightarrow }->>\displaystyle{ \rightarrowtail }>->
\displaystyle{ \curvearrowleft }curvArrLt\displaystyle{ \curvearrowright }curvArrRt\displaystyle{ \circlearrowleft }circArrLt\displaystyle{ \circlearrowright }circArrRt
\displaystyle{ \rightsquigarrow }~>\displaystyle{ \nrightarrow }-/->\displaystyle{ \nleftarrow }<-/-\displaystyle{ \nleftrightarrow }<-/->

Font

outputsourceoutputsourceoutputsourceoutputsource
A\displaystyle{ \mathbf{ A } }bb AA\displaystyle{ \boldsymbol{ A } }bm AA\displaystyle{ \mathbb{ A } }bbb AA\displaystyle{ \mathcal{ A } }cc A
A\displaystyle{ \mathtt{ A } }tt AA\displaystyle{ \mathfrak{ A } }fr AA\displaystyle{ \mathsf{ A } }sf AA\displaystyle{ \mathscr{ A } }scr A

Notation

outputsourceoutputsourceoutputsourceoutputsource
x^\displaystyle{ \hat{ x } }hat xxˉ\displaystyle{ \bar{ x } }bar xx\displaystyle{ \underline{ x } }ul xx\displaystyle{ \vec{ x } }vec x
x˙\displaystyle{ \dot{ x } }dot xx¨\displaystyle{ \ddot{ x } }ddot xx\displaystyle{ \stackrel{\frown}{ x } }arc xx~\displaystyle{ \tilde{ x } }tilde x
AB\displaystyle{ \overrightarrow{ A B } }Vec(AB)AB^\displaystyle{ \widehat{ A B } }Hat(AB)AB~\displaystyle{ \widetilde{ A B } }Tilde(AB)

Superposition

outputsourceoutputsource
xbala\displaystyle{ \overset{ \text{bala} }{ x } }overset("bala")(x)12345n\displaystyle{ \overbrace{ 12345 } ^{ n } }overbrace(12345)^n
12345n\displaystyle{ \underbrace{ 12345 } _{ n } }underbrace(12345)_n=123456\displaystyle{ \xlongequal[ 123 ]{ 456 } }==_(123)^(456)
ab\displaystyle{ \xrightarrow[ a ]{ b } }-->_(a)^(b)ab\displaystyle{ { a \atop b } }a atop b

Special

outputsourceoutputsource
I’m here\displaystyle{ \text{I'm here} }text(I'm here)\displaystyle{ \hbar }tex"\hbar"
abc\displaystyle{ { \color{red} ab c } }color(red)(abc)hello world\displaystyle{ \text{hello world} }"hello world"

Escape

outputsourceoutputsourceoutputsourceoutputsource
#\displaystyle{ \# }\#$\displaystyle{ \$ }\$@\displaystyle{ @ }\@_\displaystyle{ \_ }\_

Font Size

outputsourceoutputsource
text\displaystyle{ {\tiny \text{text} } }tiny "text"text\displaystyle{ {\small \text{text} } }small "text"
text\displaystyle{ {\large \text{text} } }large "text"text\displaystyle{ {\huge \text{text} } }huge "text"

Syntax Sugar

outputsourceoutputsourceoutputsourceoutputsource
dx\displaystyle{ {\text{d}x} }dxdy\displaystyle{ {\text{d}y} }dydz\displaystyle{ {\text{d}z} }dzdt\displaystyle{ {\text{d}t} }dt

Use # to insert displaystyle

outputsource
[2fx22fxy2fyx2fy2]\displaystyle{ \left[ \begin{array}{cc} \displaystyle \frac{ \partial ^{ 2 } f }{ \partial x ^{ 2 } } & \frac{ \partial ^{ 2 } f }{ \partial x \partial y } \\ \frac{ \partial ^{ 2 } f }{ \partial y \partial x } & \displaystyle \frac{ \partial ^{ 2 } f }{ \partial y ^{ 2 } } \end{array} \right] }[#part^2 f x, part^2 f (x y); part^2 f (y x), #part^2 f y]

With aligned environment

f(x) & = x "e"^x
                            <-- a blank line here
f'(x) & = (x + 1) "e"^x
                            <-- a blank line here
f''(x) & = (x + 2) "e"^x
f(x)=xexf(x)=(x+1)exf(x)=(x+2)ex\displaystyle{ \begin{aligned}f \left( x \right) & = x \text{e} ^{ x } \\ f ^{\prime} \left( x \right) & = \left( x + 1 \right) \text{e} ^{ x } \\ f ^{\prime\prime} \left( x \right) & = \left( x + 2 \right) \text{e} ^{ x }\end{aligned} }

Caution The & acts as & in aligned env, and the blank lines act as \\ in LaTeX.

Spaces

outputsourcewidth
ab\displaystyle{ a \quad b }a quad b1 em
ab\displaystyle{ a \qquad b }a qquad b2 em
ab\displaystyle{ a \enspace b }a enspace b0.5 em
a  b\displaystyle{ a \; b }a \; b5/18 em
ab\displaystyle{ a \: b }a \: b4/18 em
ab\displaystyle{ a \, b }a \, b3/18 em
a ⁣b\displaystyle{ a \! b }a \! b-3/18 em
ab\displaystyle{ a \hspace{12pt} b }a hspace(12pt) b12 pt
Playground built with Astro     Deploys on Netlify