Repository navigation
Releases
mathra 1.12.0
Where each marked piece is drawn, chemistry included: what a visual editor needs. And what the measured formulas still asked for: commands inside real formulas, and chemfig as its manual writes it.
What changed
- Inside real formulas.
\setlength{\arraycolsep}{…}spaces the columns of the arrays and matrices after it;\lefteqnoverlaps to the right in display style, as ineqnarray;\linebreak[n]is a break hint, as\allowbreak, and amsthm's\qedheredraws nothing, since an equation converted alone is not a proof. Measured on the 174,525 formulas: 39 more convert with no warning (the Stacks Project's\linebreak[0], arXiv's\qedhereand\arraycolsep), and none is drawn worse. - chemfig as its manual writes it. A branch may start with defaults of its own,
B([:60]-D-E),([::-30,1.5]-X-Y), valid in all of it;-#(d1,d2)(or\#,\CFhash) sets the space a bond leaves before the letters;**[30,330]5(…)draws the aromatic circle as an arc, dashed when its TikZ options say so. 17 more examples of the chemfig manual convert with no warning, and none is drawn worse. - Mechanisms and submolecules. A curved arrow of
\chemmovecan point at a bond,-[@{db,0.5}::30], and is read as the bond between its atoms;\definesubmol(with arguments and the dual[code1]{code2}) and!{name};\arrow(--name[yshift=5mm])moves the compound it brings. An unknown!{name}is drawn as written, as before, now with a warning that its definition is missing. - The rest of the measured formulas.
\noalign{\vspace{…}}and\vspaceinside a formula are read as the[length]of\\is, and\noalign{\hrule}is a rule; a\chemnamebreaks into lines at\\;\chemleft{[}takes its delimiter between braces; an arrow can leave a\subscheme's box; a\+right after an arrow is drawn (it was left out); a\chemmovepoint may carry its own move,([yshift=7pt]b1.180). What the 174,505 measured formulas still flag, 202 of them, is listed with the reason for each intools/coverage/REMAINING.md. - Marks inside chemistry. In
\ce, a mark around a piece (a species, its coefficient, formula or state, an arrow with its conditions) is read through: the piece is read as chemistry and the mark goes around it. In\chemfig, a mark around an atom's label is kept on the atom (bonds still reach the same letter), and a mark on a vertex without a label gives its point. Either way the drawing is the one without the marks, andboxessays where each piece is: what lets an editor edit reactions and structures piece by piece. In a scheme, a mark around an arrow's label keeps its text as text. - Where a structure's atoms and bonds are written. In the tree, each chemfig atom and bond has a
span: the characters of the structure's code it is written in (none after a submolecule rewrote the code). An editor changes one atom or bond in place with it. - Where each marked piece sits.
renderreturnsboxes: for each group marked with\htmlData,\htmlIdor\class, the box its content was set in, in the SVG's coordinates (left, top, width, height, baseline and nesting level). What a visual editor needs to place its cursor and read clicks over the SVG; marking draws exactly what the bare formula draws, as long as a marked operator keeps its class with\mathrel{…},\mathbin{…}(a group alone is an ordinary atom, as in TeX). In Rust,Output::boxesandItem::Group'sbounds, a change to the public API. &in a one-column environment.\begin{gather}a&b\end{gather}, and the same ingather*,gathered,multlineandmultline*, is refused in strict mode, as amsmath stops on it ("Misplaced alignment tab character &"); tolerant mode warns (E-REC-9) and joins the cells into the line, whichmultlinethen aligns as any other (#288). None of the 174,505 measured formulas changes.- Nemeth braille. A numeric subscript of a unit's letter takes no subscript indicator, as of any letter (§14.6):
\si{m}_1is ⠍⠂, asm_1; it was ⠍⠰⠂ (#287). - Nemeth braille.
\overleftarrow,\overleftrightarrowand their\under…forms are written as modified expressions with the arrow's full sign, ⠐⠭⠣⠫⠪⠒⠒⠻ (§22); they were the letter and ⠿ (#286). - CMU braille. An expression already in ( ), [ ] or { } written with plain signs no longer takes the auxiliary parentheses ⠢…⠔ as a radicand, numerator, denominator, exponent or index:
\sqrt{(a+b)}is ⠫⠱⠣⠁⠖⠃⠜, as\left(…\right)already was (§1.3);\sqrt{(a)+(b)}, two terms, keeps them (#285). - Fixes. A tikz-cd arrow with
from=starts at that cell and ends at the current one, unlessto=or a direction names the end, which count from the current cell as in tikz-cd:A & B \arrow[from=1-1]and\arrow[from=1-1, to=1-2]are an arrow from A to B (they were left out, as an arrow without a direction or to itself) (#284). - MathML. An
mlabeledtrwhose only cell is its label keeps the label, alone in its row; it was dropped, leaving an empty row (#283). - Fixes. In AsciiMath, a closing bracket where an argument or a script is expected (
sqrt),x^),frac(a))) leaves it empty, with a warning (E-REC-7, as a missing argument in LaTeX), and strict mode refuses it; it made the reader panic (#282).
Equations, drawn live on the project's evolution: \setlength{\arraycolsep}{2pt} \left[ \begin{array}{c|ccc} 0 & 1 & 1 & 2 \\ \hline 1 & 0 & 2 & 1 \end{array} \right] \chemfig{A-B([1]-X([4]-Z)-Y)(-[7]D)-C} \quad \chemfig{**[30,330]5(-----)} \htmlData{m=1}{x} \mathrel{\htmlData{m=2}{=}} \htmlData{m=3}{\frac{\htmlData{m=4}{a}}{\htmlData{m=5}{b}}}
Pull requests
Features
- feat(chem): chemfig branches with their own defaults, #(d1,d2) bond spacing and aromatic arcs by @matheusmota-dev-br in #276
- feat(chem): mechanism arrows to bonds, \definesubmol and compounds moved by their style by @matheusmota-dev-br in #277
- feat(tools): the coverage pipeline over real LaTeX, and an extraction that takes formulas only by @matheusmota-dev-br in #278
- feat(editor): @mathlabs/mathra-editor, a formula editor drawn by mathra by @matheusmota-dev-br in #280
- feat(editor): typing as on a calculator, matrices sized on a grid, chemistry written as math by @matheusmota-dev-br in #298
Bug fixes
- fix(latex): \setlength{\arraycolsep}, \lefteqn, \linebreak and \qedhere inside real formulas by @matheusmota-dev-br in #275
- fix: the rest of the measured formulas, and the list of what stays flagged and why by @matheusmota-dev-br in #279
- fix(asciimath): a closing bracket where an argument is expected is a missing argument, not a panic by @matheusmota-dev-br in #292
- fix(mathml): an mlabeledtr with only its label keeps the label by @matheusmota-dev-br in #289
- fix(latex): tikz-cd from= starts the arrow at that cell, with to= absolute by @matheusmota-dev-br in #291
- fix(braille): CMU leaves out the auxiliary parentheses around an expression already in brackets by @matheusmota-dev-br in #290
- fix(braille): Nemeth modifies an expression with a left arrow by @matheusmota-dev-br in #293
- fix(braille): Nemeth writes a numeric subscript of a unit without the indicator by @matheusmota-dev-br in #294
- fix(latex): & in multline, gather and gathered is refused in strict mode by @matheusmota-dev-br in #295
Documentation
- docs: the reference, the docs page and the README with what 1.11.0 brought, and text_kerning by @matheusmota-dev-br in #274
- docs: accessibility statement, issue templates and a pull request template by @matheusmota-dev-br in #297
Maintenance
- test: cover the workspace to 99.75% of lines, and a coverage floor in the checks by @matheusmota-dev-br in #281
- chore: every line and function of the workspace runs, and the checks hold it at 100% by @matheusmota-dev-br in #296
Install
| Package | Command | |
|---|---|---|
| Rust | mathra |
cargo add mathra@1.12.0 |
| CLI | mathra-cli |
cargo install mathra-cli@1.12.0 |
| npm | @mathlabs/mathra |
npm install @mathlabs/mathra@1.12.0 |
| Python | mathra |
pip install mathra==1.12.0 |
Full changelog: v1.11.0...v1.12.0
mathra 1.11.0
MathML and PNG out, lines that break, a fallback font, and the commands physics and chemistry papers use, measured against 174,525 formulas of real LaTeX.
What changed
- New outputs. MathML Core next to the SVG, with
intentwhere the tree knows more than the drawing (pt-BRsenissine), read back by mathra to the same tree; what MathML cannot draw (chemfig, diagrams,\divchave) keeps its source in an annotation (#112). PNG from the terminal and Python, with--dpi,--backgroundand--color; the npm package leaves rasterizing to the browser (#113). - Long equations break into lines with
--max-width,{ maxWidth }ormax_width=: after a relation first, then after+and−, never inside a fraction or a root; the continuation starts under the right-hand side (#111). - A fallback font for what the math font lacks: emoji from Noto Emoji (in the terminal and Python), CJK or anything else from a font you give (#125).
- Reading. Content MathML from CAS and assessment tools (#114); words in mhchem as words,
\ce{sodium chloride -> sodium + chlorine}(#115);\eqref,\refand\citewith numbers you pass in,(??)and[?]without them, as LaTeX's first run (#126, #127). - Physics.
\slashedfor the Feynman slash, physics' matrices (\mqty,\pmqty,\paulimatrix…), spaced text (\qq,\qand…), the starred forms (\abs*,\dv*) and\sin[2](x); a bold\nablaunder\bm; 𝟙 for\mathds{1}; the rest of esint (\ointclockwise) and upgreek (#157–#159, #165–#168). - Packages. The rest of mathtools (
\splitfrac,\adjustlimits,psmallmatrix…), siunitx 3 (\complexqty,\DeclareSIUnit,\sisetup, constant units),\definecolorand xcolor mixes, MathJax's\bbox,\encloseand\class/\style,\vvand the accents packages, unicode-math's alphabets, textcomp, KaTeX's texvc aliases (\R,\Rarr), stmaryrd and mathabx (the symbols Unicode lacks are drawn from the font's own pieces),\vdotswithin,\stackbin,\overgroup,\shoveleft,\tablenum,\root…\of, the corner delimiters (#116–#124, #169–#177). - Chemistry and diagrams. chemfig's start options, distant bonds,
\charge,-U>,\chemleft, offset double bonds; xymatrix paths through entries,\holeand 2-cells (#210, #214, #215). - Real LaTeX. Measured on 174,525 formulas (the Stacks Project, 95 arXiv papers, the mhchem and chemfig manuals): a line break or tab is whitespace,
\before a line break is a control space, a line break in\textis a space, a measure mathra cannot read is a warning instead of a refusal, and the one crash, in a chemfig ring, is gone. Against 1.10.1, 535 more formulas convert with no warning and none is drawn worse (#206, #208–#213, #216). - mhchem. The bonds
\bond{~}(a dashed line, as mhchem draws it; it was ∼),\bond{~-},\bond{~=},\bond{-~-}and\bond{....}are drawn as mhchem draws them and read as what they are; an arrow label between braces is text (->[{text above}]);$…$in a subscript is math;&and\\inside\cego to the alignment around it (#267–#270). - Fixes. A chemfig label like
Nuis kept whole, no longer read as N (#271);%starts a comment in strict mode;^²reads as^2; braces have a minimum width;\upvarrhois ϱ;\mathbf{1}is bold;\unicode{8918}is decimal;\notover a long arrow is a short slash (#128–#132, #160–#164, #202–#205, #207). - What may change for you. An unknown command is drawn whole in red; it is no longer cut into a known one (
\vertAwas\vert A) (#209). A stray$,&ory__know warns, and strict mode refuses it (#129, #130).\color[rgb]{1,0,0}is red; it came out nearly black (#122). In Rust, the tree andOptionshave new variants and fields: code that matches them all or lists every field needs a new arm or..Default::default().
Equations, drawn live on the project's evolution: \mathcal{L} = -\frac{1}{4} F_{\mu\nu} F^{\mu\nu} + i \bar{\psi} \slashed{D} \psi + \left| D_\mu \phi \right|^2 - V(\phi) \sigma_x = \pmqty{0 & 1 \\ 1 & 0} \ce{Hydrogen + Oxygen -> Water} \llceil x \rrceil + \mathbf{1} \otimes \mathds{1}
Pull requests
Features
- feat: the enhancements of 2026-11-08 (#111–#125) by @matheusmota-dev-br in #151
- feat(mathml): read content MathML by @matheusmota-dev-br in #140
- feat(chem): mhchem text mode by @matheusmota-dev-br in #141
- feat(latex): \bbox and \enclose by @matheusmota-dev-br in #142
- feat(latex): \class, \style, \cssId and KaTeX's \html* attributes by @matheusmota-dev-br in #143
- feat(latex): \overgroup and \undergroup by @matheusmota-dev-br in #144
- feat(latex): \shoveleft and \shoveright in multline by @matheusmota-dev-br in #145
- feat(latex): \stackbin by @matheusmota-dev-br in #146
- feat(latex): \definecolor, \colorlet and xcolor mixes by @matheusmota-dev-br in #147
- feat(siunitx): \tablenum by @matheusmota-dev-br in #148
- feat(latex): \lightning, \Lightning, \mathbold and stmaryrd symbols by @matheusmota-dev-br in #149
- feat(latex): \vdotswithin and \shortvdotswithin by @matheusmota-dev-br in #150
- feat(core): PNG output by @matheusmota-dev-br in #152
- feat(core): automatic line breaking by @matheusmota-dev-br in #153
- feat(core): fallback fonts for characters the math font lacks by @matheusmota-dev-br in #154
- feat(core): MathML output by @matheusmota-dev-br in #155
- feat: the second round of enhancements of 2026-11-08 (#165–#177) by @matheusmota-dev-br in #200
- feat(latex): \slashed, the Feynman slash notation by @matheusmota-dev-br in #187
- feat(latex): physics' matrices, spaced text and remaining aliases by @matheusmota-dev-br in #188
- feat(latex): the rest of esint (\ointclockwise, \varointctrclockwise, \dotsint) by @matheusmota-dev-br in #189
- feat(latex): upgreek's uppercase and var letters by @matheusmota-dev-br in #190
- feat(latex): the remaining mathtools commands and environments by @matheusmota-dev-br in #191
- feat(latex): \root…\of, \leftroot, \atopwithdelims and corner delimiters by @matheusmota-dev-br in #192
- feat(latex): \vv, \accentset, \underaccent and mathabx accents by @matheusmota-dev-br in #193
- feat(latex): KaTeX's texvc aliases (\R, \N, \Rarr, \hearts…) by @matheusmota-dev-br in #194
- feat(latex): unicode-math alphabets (\mathbfcal, \symcal…) by @matheusmota-dev-br in #195
- feat(latex): textcomp and gensymb ...
mathra 1.10.1
The fonts of the mathfonts catalog, by name.
What changed
- mathfonts is a catalog of 30 OpenType math fonts that are free to share, each one checked with mathra. JavaScript gets
catalogFonts()andloadFontFromCatalog(slug), and Python getscatalog_fonts()andload_font_from_catalog(slug), which keeps the file in~/.cache/mathra. A font is downloaded only when asked for, once, and refused if it does not match the catalog's sha256, so the same name always gives the same SVG (#109). - The playground lists the catalog's fonts in its font picker and downloads one only when it is picked.
- The Rust crate and the terminal download nothing;
--fontin the help points to the catalog. Loading a font from a file is unchanged, and so is what mathra draws.
Equations, drawn live on the project's evolution: e^{i\pi} + 1 = 0
Pull requests
Features
- feat: load the fonts of the mathfonts catalog by name by @matheusmota-dev-br in #109
Install
| Package | Command | |
|---|---|---|
| Rust | mathra |
cargo add mathra@1.10.1 |
| CLI | mathra-cli |
cargo install mathra-cli@1.10.1 |
| npm | @mathlabs/mathra |
npm install @mathlabs/mathra@1.10.1 |
| Python | mathra |
pip install mathra==1.10.1 |
Full changelog: v1.10.0...v1.10.1
mathra 1.10.0
A pen that writes the equation, and any OpenType math font.
What changed
mathra::pendraws an SVG where a pen tip goes over each glyph's outline, rule and line in the order the layout set them, and each one fills in once drawn. It uses SMIL only, plays in a loop and needs no script. Its time follows the length of the ink. wasm getstexToPen, and the playground gets a Pen button and a Pen SVG download (#104).- Any OpenType math font (an
.otfor.ttfwith a MATH table, such as Libertinus Math, Fira Math or Euler Math) can set an equation. UseMathFont::load(bytes)andOptions::fontin Rust,--fontin the terminal,loadFontand{ font }in JavaScript, andload_fontandfont=in Python. The playground loads one from your computer. A font without a MATH table is refused with a reason. STIX Two Math stays embedded and is the default, and without a font the SVG is unchanged (#106). - Code that builds an
Optionslisting every field needs the new one (..Default::default()). A missing glyph now reads "the math font has no …" (#106).
Equations, drawn live on the project's evolution: x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}
Pull requests
Features
- feat(core): a pen that writes the equation by @matheusmota-dev-br in #105
- feat(core): set an equation in any OpenType math font by @matheusmota-dev-br in #107
Maintenance
- ci: triage of issues and pull requests, and richer release notes by @matheusmota-dev-br in #103
Install
| Package | Command | |
|---|---|---|
| Rust | mathra |
cargo add mathra@1.10.0 |
| CLI | mathra-cli |
cargo install mathra-cli@1.10.0 |
| npm | @mathlabs/mathra |
npm install @mathlabs/mathra@1.10.0 |
| Python | mathra |
pip install mathra==1.10.0 |
Full changelog: v1.9.3...v1.10.0
mathra 1.9.3
The site, banner and icon take an identity of their own, and a new demo video.
- A slate board with a wood tray in the banner, the icon and the top of the site, where a derivation writes itself line by line. Around it the site is plain paper, or charcoal in the dark theme.
- Code blocks are colored on every page, the SVG, the tree and the reference's grammar included.
- In the reference tables the braille wraps, so the source keeps its room.
- A new 60-second demo video in the README and on the site.
- What the packages draw does not change.
Equations: x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}
mathra 1.9.2
\boldmath in bold italic, and \SI's values as siunitx prints them.
\SI{+10}{V}leaves out the plus and\SI{.25}{V}gets its zero, as siunitx does (#97).\boldmathsets letters in bold italic, as TeX's bold math font does, and reaches the text of a\rotatebox(#97).
Equations: \text{{\boldmath $x$}}, \text{{\boldmath \rotatebox{90}{$x$}}}, \SI{+10}{V}, \SI{.25}{V}
mathra 1.9.1
Italic text set as a text font sets it, and \mathit's letters as one word.
- Inside
\text{…},\textit{…}and\emph{…}set their argument in italic and\itshape,\itand\emthe rest of their group, with no italic correction between the letters or after a word; after\textit{…}and\emph{…}comes their last letter's correction, as LaTeX's\/, except before a period or a comma.\textit{…}in math is text in italic (L-TXT-5, #93). \mathit{…}'s letters make one word, with no italic correction between them, as in TeX's text font: since 1.9.0 each letter had one, as in math italic (#92).
Equations: \text{an \emph{italic} word, {\itshape and more}}, \mathit{diff} \ne diff
mathra 1.9.0
Chemistry, color, fills and math environments inside text, and TeX's italic correction at the end of a formula.
- Inside
\text{…}, mhchem's\ce{…}and\pu{…}are read as in math (\text{water, \ce{H2O}}), instead of being written as is (L-CHE-1, #84). - Inside
\text{…},\color{…}(also\color[model]{…}) colors the rest of its group and\textcolor{…}{…}its argument, math included, keeping the text's bold, small capitals or monospace (L-TXT-4, #85). - Inside
\text{…},\hfill,\hfiland\hsstake no room, as in a box of natural width, and\newlineand\linebreakare a space, as\\is (L-TXT-3, #86). - Inside
\text{…},\begin{equation},align,gather,multlineand the other displays are read as math up to their\end, like\[…\];array,pmatrix,cases,alignedand the other math-only environments too, with a warning (E-REC-1), since TeX refuses them in text (L-TXT-2, #87). - A slanted letter that ends a math list gets its italic correction after it, as TeX does (Appendix G, rule 17). That covers the end of the formula, of a script, a fraction's parts, a radicand, a phantom, a lap and a table cell. In scripts, the base letter's correction stands in at the script's size.
$V$was 5.83pt wide, TeX gives 8.06pt (#89). layout::compose_list: a math list composed on its own, with that correction.
Equations: \text{water, \ce{H2O}, at \pu{20 mol}}, \text{the {\color{red}warm} and {\color{blue}cold} sides}, \text{so \begin{align*}a&=1\\b&=2\end{align*}}, V = f, V_0 + R_1, \frac{V}{f}, \sqrt{f}
mathra 1.8.0
Space and phantoms inside text, and text kerned as TeX kerns it.
- Inside
\text{…},\hspace{…}and\hspace*{…}add their space, and\phantom,\hphantomand\vphantomleave the room of their argument, instead of being written in red (L-TXT-3, #79). Options::text_kerning: text in\text{…}kerned by the pairs of TeX's OT1 Computer Modern (cmr10,cmbx10) or T1 Latin Modern (ec-lmr10,ec-lmbx10) fonts, as TeX's tables do (va,AV,To); none by default, as before (#81).- Code that builds an
Optionsor alayout::Contextlisting every field needs the new one (..Default::default()) (#81).
Equations: \text{a\hspace{1cm}b}, \text{a\phantom{xy}b}, \text{AVA Today}
mathra 1.7.1
Bold text stays bold after math inside it.
- Inside
\text{…}, the text after math ($…$,\(…\),\ensuremath,\textsubscript, siunitx, graphicx boxes) keeps the bold, small capitals or monospace of its group: in\textbf{Z $x$ Z}the second Z was upright (#77).
Equations: \text{\textbf{Z $x$ Z} and \textsc{Small $x$ Caps}}