Mathup

一款使用快速编写的语法轻松创建 MathML 的工具。

你写…

E[X] = int_(-oo)^oo x f(x) dx
Decimal mark Column separators Row Separators Display block Direction rtl

…然后看到

grad f(x,y) = ((del f)/(del x) (x, y), (del f)/(del y)(x,y))

使用 MathJax 代替原生 MathML

Installation

npm
npm install mathup
import mathup from "mathup";
Client

下载以下其中一项:

…并包含 module :

<script type="module" src="mathup.js"></script>
<link rel="stylesheet" href="mathup.css" />

custom element :

<script type="module" src="math-up-element.js"></script>

…或 script :

<script src="mathup.iife.js"></script>
<link rel="stylesheet" href="mathup.css" />

Usage

const expression = "1+1 = 2";
const options = {}; // optional
const mathml = mathup(expression, options);
mathml.toString();
// => "<math><mrow><mn>1</mn><mo>+</mo><mn>1</mn></mrow><mo>=</mo><mn>2</mn></math>"
const mathNode = mathml.toDOM();
// => [object MathMLElement]
// Update existing <math> node in place
mathup("3-2 = 1", { bare: true }).updateDOM(mathNode);

Custom Element
<math-up
 display="inline"
 dir="ltr"
 decimal-mark=","
 col-sep=";"
 row-sep=";;"
>
 1+1 = 2
</math-up>
Command line
npm install -g mathup
mathup [options] -- <expression>
# or from stdin
echo <expression> | mathup [options]

Options (with defaults)

const options = {
 decimalMark: ".",  // -m --decimal-mark="."
 colSep: ",",    // -c --col-sep=","
 rowSep: ";",    // -r --row-sep=";"
 display: "inline", // -d --display="inline"
 dir: "ltr",     //   --rtl
 bare: false,    // -b --bare
};

Note: 如果你选择 , 作为你的 decimal mark,那么 ; 将成为新的默认 column separator。 并且如果 ; 是你的 column separator,那么新的默认 row separator 变为 ;;。 如果你小心地在 row separator 和后面的数字之间添加一个空格,则可以使用 , 作为 decimal mark row separator。 但是,你必须明确地设置两者。

const options = {
 decimalMark: ",",
 colSep: ",",
};

Quick to write / Easy to read

这个包公开了一个名为 mathup 的单一函数,它可以直观地接受以受 AsciiMath 启发的标记语言编写的简单数学表达式,并输出结构化的 MathML。 你可以在命令行或服务器上将其用作 node 包,或者通过包含 script source 在浏览器中使用。 在浏览器中,你可以选择如何解析文档中的数学公式——努力查找任何数学相关的子字符串,解析用 $$ 包裹的所有表达式,或者使用其他一些优秀的工具来为你完成。 你还可以选择如何处理输出——将其传递给另一个程序,直接将其注入到 DOM 中,或者只是将其记录到控制台中。

Why not just use MathJax?

MathJax 是一个优秀的工具,如果你只想在一个文档中包含复杂的数学表达式,可以安全地使用它。 然而,MathJax 是一个复杂的软件,它所做的事情远远不止将简单的表达式翻译成结构化的形式,如果这仅仅是你想要做的事情,那么 MathJax 绝对是大材小用。 Mathup 承诺比 MathJax 快得多(通过做更少的事情)。 MathJax 会搜索表达式、解析它们、翻译和渲染它们,而 Mathup 仅解析和翻译它们,并让浏览器进行渲染。

Why AsciiMath / Why not TeΧ?

我编写这个工具是因为我希望能够快速编写数学表达式,而没有任何开销(想象一下 1/2 而不是 \frac{1}{2})。 TeΧ 表达式很容易变得冗长且难以编写(尤其是在键盘上难以访问 \, {, 和 } 键)。 但是,这个包的目的 不是 以一种非冗长的方式让人们完全控制 MathML,目的是让人们可以简单地编写简单的表达式。 当然,我会尽力以这种方式提供尽可能多的表达能力,但我不会承诺使所有复杂的事情都成为可能。

如果你想要完全支持 MathML,并且不想编写所有这些标签,也许你应该寻找另一个工具。 还有其他一些伟大的努力旨在使人们能够以 TeX 格式编写 MathML,例如看看 TeXZilla

Reference

Basics

Mathup 使用 MathML 的四个标记元素(identifiers <mi>, operators <mo>, numbers <mn> 和 text <mtext>)。 当你编写简单的表达式时,Mathup 会识别出你指的是哪一个。

例如:1+1 = 2

<mrow>
 <mn>1</mn>
 <mo>+</mo>
 <mn>1</mn>
</mrow>
<mo>=</mo>
<mn>2</mn>

并且 sin theta

<mi>sin</mi><mi>θ</mi>

Mathup 还会识别出你编写的大多数 unicode 字符。 如果一个字符来自数学运算符代码块之一,它将用 <mo> 标签将其包裹,否则它将被包裹在 <mi> 标签中。 此外,如果 d 显然是微分的一部分,则它将被包裹在 <mo> 标签中。

Numbers

数字通常是你认为的那样(包括像 Ⅻ 或 ↋ 这样的 unicode 数字)。 但是,如果你想以一种奇怪的方式编写一个数字(比如拼写出来,作为一个十六进制字符串,或者作为一个罗马数字),你可以在字符串前面加上 #,(例如 #0x2A)或者——如果你的数字包含一个非字母数字字符——在前面加上一个反引号 fence(就像在 markdown 中一样) #``…```,像这样:#forty two`` 或 #`42 ``` 使42` 成为一个数字。

Operators

任何在 Pc, Pd, Pe, Pf, Pi, Po, Ps, Sm, 或 So unicode 分类中的东西都被认为是 operator。 此外,紧跟在反斜杠 \ 后面的符号字符或字母数字字符串将成为一个 operator (<mo>)。 如果你需要在 operator 中使用不止一个符号字符,或者不止一个单词作为一个 operator(例如 <mo>for each</mo>),你可以按照 markdown 语义 fence 它;(例如 \for each 或 `\ ``` 表示). 以下内容也将映射到相应的 operator。 Operational .$ FUNCTION APPLICATION(_零宽度_). INVISIBLE TIMES(_零宽度_).+ INVISIBLE PLUS(_零宽度_)lim limmod mod-+- ±-+ ·xx ×-: ÷//prodsum@^^vvnnuuintdintoint!=!==o+oxo.^^^vvvnnnuuu*|><||><><| ⋊ Miscellaneous''''''''''alephdelgradoc, prop//` △ ||~=~~subsupsubesupe<>, diamond[], square<||> ⊳ Relational in!in-=, ==<=>=-<>--<=>-=<<<>>> ≫ Logical and and if if or or otherwise otherwise not ¬ AAEE|--TT_|_|== ⊨ Arrows <-, larruarr->, rarrdarrharr->>>->|->lArr=>, rArr<=>, iff, hArr>->> ⤖ Punctuations ., INVISIBLE SEPARATOR (零宽度) ...:.vdotscdotsddots

Identifiers

任何不是数字、operator 或 text 的东西都被认为是 identifier。 这包括拉丁字母、希腊字母或阿拉伯字母(Aπح)甚至 emoji。 除非这些字符拼出了下表或上面的 operator 表中的某个单词,否则每个字符都被认为是一个单独的 identifier。

你可以通过用 fences 包围任何字符序列来强制任何字符序列成为一个单独的 idendifier(例如,Gamma 产生 <mi>Gamma</mi>,而 f` 产生 <mi>f)。 以下内容也会产生单个 identifier: Standard functions cos coscosh coshcot cotcsc csccosec cosecdet detdim dimgcd gcdlcm lcmln lnlog logmax maxmin minmod modsec secsin sinsinh sinhtan tantanh tanh GreekDelta ΔGamma ΓLambda ΛOmega ΩPhi ΦPi ΠPsi ΨSigma ΣTheta ΘXi Ξalpha αbeta βchi χepsilon ɛeta ηgamma γkappa κlambda λmu μnu νomega ωphi φphiv ϕpi πpsi ψrho ρsigma σtau τtheta θupsilon υxi ξzeta ζ Additional identifiersooO/CCNNQQRRZZ` ℤ

Text

你可以用双引号 ("some text") 包围任何东西,它将被显示为 text。 如果你的 text 注释包含一个引号标记,你可以用更多的引号标记将其包围(就像使用反引号 fences 一样)。 也就是说,"" "text string" "" 会给你 <mtext>"text string"</mtext>

Spaces

MathML 有一个名为 <mspace> 的元素。 两个或更多个连续的空格将被翻译成该元素,如果它有意义的话。 space 的宽度将是: "width" = { 0.35(n - 1),, if n = 2 or n = 3 0.5(n - 1),, if n = 4 or n = 5 n - 3,, if n > 5 其中 n 是后续空格的数量,width 的单位是 ex,它是字体中 ‘x’ 字符的高度。 此外,(mod p) 将在左括号左侧添加 1.65 ex 的 space。

Fractions

在 MathML 中,你将 fractions 包含在一个 <mfrac> 元素中。 在 Mathup 中,你只需用斜杠 (a/b) 分隔 numerator a 和 denominator b。

Mathup 试图通过查看你用 space 包围你的 subexpression 来智能地了解你所说的 numerator 和 denominator,所以 a+b / c+da + b/c + d 不是 同一件事。 通常,subexpression 和斜杠之间的 space 将应用整个 subexpression,而没有 space 则仅应用紧接在之前或之后的内容。

Sub and superscripts

下划线会将以下表达式作为 subscript 放在前面的表达式上(a_i ⇒ ai ),ascii caret 将施加 superscript(a^2 ⇒ a2 ),并且(表达式、下划线、caret)/(experssion、caret、下划线)序列(a_i^2/a^2_i)将在第一个表达式上施加 sub 和 superscript,产生 a i 2 。

Over 和 underscripts 遵循类似的模式,除了 ._ 用于 underscripts,.^ 用于 overscripts。 此外,lim_x 会将 x 作为 underscript,而 sum_a^bprod_a^b 会将 a 和 b 作为 under 和 overscripts。

与 fractions 不同,sub/super 和 under/overscripts 是 right-associative,并且优先于 fractions。 你可以在 sub/sup 或 under/over 字符和周围的 sub expression 之间策略性地放置 whitespace,就像使用 fractions 一样,例如,e^ -1/2 产生 e − 1 2 ,而 e^ -1 / 2 产生 e −1 2 。

Fenced Groups

我们可以使用括号将术语组合在一起。 任何 unicode open parenthesis(unicode 分类 Ps)都会启动一个 fence,任何 closing parenthesis(分类 Pe)都会关闭它。 请注意,parenthesis 不必匹配,但它们必须成对出现(open/close pairs)。

你可以用 {: :} 表示一个 unfenced group。 你可以自由地用任意 operators 包围 unfenced group 的内容,并且它们将成为新的 fence。 例如,如果你需要一个 open parenthesis 来关闭一个 group,你可以将它们转换为 operators 并手动 fence 该 group,如下所示: \]{: a, b :}\[ ⇒ ] a,b [ 。

最后,在 group 中——除了你通常的 seperators(比如 ,)——你可以使用特殊的 :|: 作为 group separators。 这对于编写 bra-ket notation 特别方便: (: Phi :|: Psi :) ⇒ ⟨Φ|Ψ⟩。 Additional fences {:a, b:} a , b (:a:|:b:) ⟨ a | b ⟩ <<a, b>> ⟨ a , b ⟩ |(a, b)| | a , b | |:a, b:| | a , b | ||(a, b)|| ∥ a , b ∥ ||:a, b:|| ∥ a , b ∥ |~x~| ⌈ x ⌉ |__x__| ⌊ x ⌋ Additional fenced shortcuts binom(a, b) ( a b ) abs x | x | norm x ∥ x ∥ ceil x ⌈ x ⌉ floor x ⌊ x ⌋

Matrices

Matrices 是至少有一个 row separator(;)的 fenced group。 例如,A = [1,2,3; 4,5,6] 是一个 2×3 matrix,而 [1,4; 2,5; 3,6] 是 A T 。 允许有 trailing row break,所以你可以将单个 row matrix 写成 [1,2,3;]。 换行符也可以用作 row separator。

所有这些都只是将外部括号作为 fence 放在内部的 table 周围,因此如果你想要 case assignment,你可以编写:

|x| = { x, if x >= 0 ; -x, otherwise :}

Tensors and Indices

要编写 tensors 或任何其他 complex indices,你可以使用 hat ^ 或下划线 _ 字符启动一个 group。 后面的 expression 将分别是你的第一个 upper 或 lower index。 每一个 follow 的 ^_ 都将启动一个新的 index A(^b_c) 用于 A cb 。 如果你希望你的 index 位于一个新列中,你可以在 ^_ 之前添加一个 ,A(^b,_c) A b c 。 你可以通过在逗号之后省略 ^_ 来重复前一个 index 位置:A(_b,c,d,^e,f,g) A b c d e f g 。

你还可以通过立即 follow 一个 expression 来添加 prescripts。 [^14_6]rm C C 614 或同时 (^n)P(_k) P k n 。 Prescripts 具有优先级。

如果你想为你的 indices 添加 sub- 或 superscripts,你可以用括号包围整个 index A(^(a_i),...,(a_n)) ⇒ A ai … an 。 并且如果你想使用逗号或括号作为 index,你可以用反斜杠 \ 转义它 A(_beta, \,, \[, a) A β, [a 。

Roots

MathML 具有用于 roots 的 <msqrt><mroot> 标签。 Mathup 类似地提供了 sqrt xroot n x (或者如果你喜欢 root(n, x))分别用于 x 的平方根和 x 的 n 次方根。

Accents

以下命令将在 follow 的 expression 上方或下方添加 accents 或添加其他类型的 highlighting: Accents hat a a^ bar a a‾ vec a a→ dot a a⋅ ddot a a⋅⋅ tilde aul a a_ oparen a+b a+b ⏜ uparen a+b a+b ⏝ obrace a+b a+b ⏞ ubrace a+b a+b ⏟ obracket a+b a+b ⎴ ubracket a+b a+b ⎵ oshell a+b a+b ⏠ ushell a+b a+b ⏡ cancel a+b a+b

Font commands

你可以用 font 命令为任何 expression 添加前缀。 然后,该 expression 中的所有标记元素都将具有以下 variant。 可以组合一些 variants,顺序无关紧要。

texts(bf tt "text")上的 Bold (bf)、italic (it)、sans-serif (sf) 和 monospace (tt) 使用 CSS 设置。 如果你想控制 sans-serif 和 monospace texts 的 font-family,你可以分别设置 CSS custom properties --mathup-font-family-sans-serif--mathup-font-family-monospace。 Font Commands rm normal bf bold it italic bf it bold italic bb 𝕕𝕠𝕦𝕓𝕝𝕖-𝕤𝕥𝕣𝕦𝕔𝕜 cc 𝓈𝒸𝓇𝒾𝓅𝓉 bf cc 𝓼𝓬𝓻𝓲𝓹𝓽 fr 𝔣𝔯𝔞𝔠𝔱𝔲𝔯 bf fr 𝖋𝖗𝖆𝖈𝖙𝖚𝖗 sf 𝗌𝖺𝗇𝗌-𝗌𝖾𝗋𝗂𝖿 bf sf 𝘀𝗮𝗻𝘀-𝘀𝗲𝗿𝗶𝗳 it sf 𝘴𝘢𝘯𝘴-𝘴𝘦𝘳𝘪𝘧 bf it sf 𝙨𝙖𝙣𝙨-𝙨𝘦𝘳𝘪𝘧 tt 𝚖𝚘𝚗𝚘𝚜𝚙𝚊𝚌𝚎

Colors

你可以简单地通过键入该颜色来更改 expression 的一部分的 color 或 background。 Backgrounds 以 bg.<colorname> 为前缀。 如果你不喜欢那种 color variant,你可以使用 --mathup-color-<colorname>--mathup-background-<colorname> CSS custom properties 覆盖它。 例如: 如果你有一个 emoji 键盘,你可以使用 colored circle emoji (🔴🟠🟡🟢🔵🟣🟤) 表示 color,并使用 colored square emoji (🟥🟧🟨🟩🟦🟪🟫) 表示 background。 Black 和 white circles 使用 medium variant (⚫⚪),而 black 和 white square 使用 large variant (⬛⬜)。

:root {
 --mathup-color-red: lch(50% 130 20);
 --mathup-background-green: lch(50% 132 180);
}

请参阅下面的可用 colors Colors red, 🔴 Red orange, 🟠 Orange yellow, 🟡 Yellow green, 🟢 Green cyan Cyan blue, 🔵 Blue purple, 🟣 Purple brown, 🟤 Brown black, Black gray Gray lightgray Lightgray white, White Backgrounds bg.red, 🟥 Red bg.orange, 🟧 Orange bg.yellow, 🟨 Yellow bg.green, 🟩 Green bg.cyan Cyan bg.blue, 🟦 Blue bg.purple, 🟪 Purple brown,