Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@mkorje
Copy link
Collaborator

@mkorje mkorje commented Nov 22, 2025

Supersedes #7206, depends on typst/typst-assets#13.

Note that it is not quite as complete as the old PR just yet.

Notes

Stylesheet

To have the output in a browser match Typst's paged output exactly, we'd ideally override parts of the user agent stylesheet instead of having to supply things to each instance of an element. Since doing the former isn't possible yet and the latter isn't great (we are initially focusing on semantics after all), I'm ignoring all of this stuff. There is one exception, though: I need to disable the text-transform: math-auto property for mi (by using the mathvariant="normal" attribute) to stop the browser from auto italicizing things.

Questions

What Should the Width of a Space Be?

We occasionally need to emit a single space, but we cannot obtain the font's space width! So we may need to choose something. Some choices I've found elsewhere:

Resources

Specifications

Other Implementations

Fonts

Browser Problems

Below I collect issues in the main 3 browser engine's MathML implementations that cause the MathML generated by this PR to display incorrectly. Whilst I do think we should work around these where possible, for my initial implementation I have not done so.

Gecko

Blink

WebKit

@laurmaedje laurmaedje added math Related to math syntax, layout, etc. html Related to HTML export interface PRs that add to or change Typst's user-facing interface as opposed to internals or docs changes. waiting-on-author Pull request waits on author labels Nov 24, 2025
@laurmaedje laurmaedje mentioned this pull request Dec 4, 2025
14 tasks
@mkorje mkorje force-pushed the mathml branch 6 times, most recently from 7ec9507 to f6b9f6f Compare January 4, 2026 05:17
Comment on lines +460 to +499
if let Some((tag, other_children)) = match (tl, tr, bl, br) {
(None, None, None, None) => None,
(None, None, None, Some(br)) => Some((tag::msub, eco_vec![br])),
(None, Some(tr), None, None) => Some((tag::msup, eco_vec![tr])),
(None, Some(tr), None, Some(br)) => Some((tag::msubsup, eco_vec![br, tr])),
(tl, tr, bl, br) => {
let unwrap = |node: Option<HtmlNode>| {
node.unwrap_or(HtmlElement::new(tag::mrow).into())
};
Some((
tag::mmultiscripts,
eco_vec![
unwrap(br),
unwrap(tr),
HtmlElement::new(tag::mprescripts).into(),
unwrap(bl),
unwrap(tl),
],
))
}
} {
let mut children = eco_vec![base];
children.extend(other_children);
base = HtmlElement::new(tag).with_children(children).into();
}

if let Some((tag, other_children)) = match (t, b) {
(None, None) => None,
(Some(t), None) => Some((tag::mover, eco_vec![t])),
(None, Some(b)) => Some((tag::munder, eco_vec![b])),
(Some(t), Some(b)) => Some((tag::munderover, eco_vec![b, t])),
} {
let mut children = eco_vec![base];
children.extend(other_children);
base = HtmlElement::new(tag).with_children(children).into();
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got curious about this from my other work on scripts with primes, and when both under/over and sub/super scripts are present, Firefox and Chrome seem to render better when doing under/over inside sub/super. In particular if you have attach(sum, tr: 2, t: n), placing the mover outside the msup causes the n to be centered around sum^2, which looks quite bad.

<math display="block">
  <mover><msup><mo></mo><mn>2</mn></msup><mi>n</mi></mover>
  <mo></mo>
  <msup><mover><mo></mo><mi>n</mi></mover><mn>2</mn></msup>
</math>

However, this makes me worried about how users would typeset annotations on something with a normal attachment, e.g. attach(limits(x^2), b: "squared"). So I think we should consider updating the attachment model to improve this generally, although maybe after this PR or after my other fix for scripts lands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

html Related to HTML export interface PRs that add to or change Typst's user-facing interface as opposed to internals or docs changes. math Related to math syntax, layout, etc. waiting-on-author Pull request waits on author

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants