Skip to content

Subscripts affect vertical alignment in an undesired way #44

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
hooyuser opened this issue Jul 1, 2024 · 5 comments
Open

Subscripts affect vertical alignment in an undesired way #44

hooyuser opened this issue Jul 1, 2024 · 5 comments

Comments

@hooyuser
Copy link

hooyuser commented Jul 1, 2024

The vertical alignment of the subscripts seems to be off, which disrupts the readability of the formula. Here is the link of the code snippet: https://typst.app/project/rcUVH6fe_sLns_uLrFA4tE

Expected Behavior

The formula is expected to align with the baseline of $\sum$ , ignoring the subscripts $i \in U$.

fletcher_alignment

$ sum_(i in  U) F(U)-->F(U) $

Current Behavior

The subscripts in the formula affect the vertical alignment, causing them to appear misaligned with the rest of the formula elements.

fletcher_alignment_2

#diagram({
  let (A, B) = ((0,0), (1,0))
  node(A, $ sum_(i in  U) F(U) $)
  node(B, $ F(U)$)
  edge(A, B, "->")
})

#diagram($
  limits(sum)_(i in  U) F(U)edge("->")& F(U)
$)

Is there a way to manually adjust or change the alignment for subscripts? Any guidance or documentation on this would be greatly appreciated. I'm also wondering if this misalignment should be adjusted to improve the default behavior.

@hooyuser hooyuser changed the title Superscripts affect vertical alignment in an undesired way Subscripts affect vertical alignment in an undesired way Jul 1, 2024
@Jollywatt
Copy link
Owner

Hmm. This occurs because each node gets its own bounding box and is aligned separately. But I agree that it's probably more desirable to align by baseline for diagrams in math mode.

I'm not sure how this could be made automatic, since fundamentally each node exists in its own box, so baseline information is lost.

In the meantime, a non-ideal workaround is to use move(dy: ..) to manually adjust:

#diagram($
  #move(dy: .35em, $ limits(sum)_(i in  U) F(U) $) edge("->") & F(U)
$)

@hooyuser
Copy link
Author

hooyuser commented Jul 2, 2024

I may not have fully considered this yet, but here's a quick thought: could we allow an alignment pivot point that is different from the center of the bounding box? Consider a naive implementation for trimming attachments (see https://typst.app/project/rYLF85ECFVpZUGgR5w_G3p) :

#let trim_attachments(x) = {
  if repr(x.func()) == "equation" and x.block {
    let trimmed = for child in x.body.children {
      if repr(child.func()) == "attach" {
        child.base.text
      }
      else {
        child
      }
    }
    $ trimmed $
  }
  else {
    x
  }
}

Does it make sense to calculate the center of the bounding box for trim_attachments(node_text) and use it as the pivot point for alignment? And we could still compute the bounding box for node_text in the usual manner.

@Jollywatt
Copy link
Owner

Jollywatt commented Jul 2, 2024

Not sure. With block math, it’s not only the attachments, but everything which affects the bounding box - including the $\Sigma$ itself. For instance, look at the output of:

#let eq = $ sum_(i in  U) F(U)-->F(U) $
#let trimmed_eq = trim_attachments(eq)
#set rect(inset: 0pt, stroke: 0.5pt + red)
#rect(eq)
#rect(trimmed_eq)
#rect($ F(U)-->F(U) $)

However, fletcher diagrams in math mode use inline math by default, exactly for this purpose of reusing the same baseline.
(Typst gives us two package deals: use inline math and get a baseline-aligned bounding box, or use block math and get an optical bounding box.)

However, it seems that when inline math is wrapped in a box, the baseline is not preserved:

foo [$sum_(n=0) 1/n! x^n$] bar
foo [$limits(sum)_(n=0) 1/n! x^n$] bar

#set box(stroke: 0.5pt + red)
foo [#box[$sum_(n=0) 1/n! x^n$]] bar
foo [#box[$limits(sum)_(n=0) 1/n! x^n$]] bar
Screenshot 2024-07-02 at 18 17 11

So to fix this, I need to figure out how to wrap inline math nodes in a box (which is passed to cetz for drawing) while preserving the baseline. I'll ask in Discord: link to question.

@hooyuser
Copy link
Author

Recently, I noticed a workaround for obtaining baseline information in cetz-package/cetz#683. I'm curious if there's a similar method to "record" baseline information in Fletcher. Could you share any insights? Thank you!

@hooyuser
Copy link
Author

hooyuser commented Mar 11, 2025

I've discovered a method to measure baseline information for math equations in Typst, inspired by rehype-typst project. Here's a demo example hosted on the Typst app: https://typst.app/project/rgJTABbO0i0AWBDMBzqYQ0

However, there's a somewhat hacky aspect to this implementation—it uses a rather inconvenient technique to measure the distance from the baseline to the top bounds of an equation. Specifically, the snippet inserts a custom function named pin at the beginning of an equation. Internally, pin calls here().position(), which appears coincidentally to represent the baseline position of the first line of an equation. This position is then stored in a state variable.

In my opinion, this method feels like an inferior workaround compared to Typst’s built-in measure function. It’s limited, inefficient, ergonomically lacking, and potentially not robust enough for broader applications. Thus, it is significantly far from an ideal solution.

Given these limitations, I believe it would be beneficial to submit a feature request to Typst—a dedicated functionality similar to measure, specifically designed for reliably measuring the baseline of math equations. For multi-line equations, the baseline might introduce some ambiguity (e.g., referring to the first line vs. the last line), but even with these nuances, having such a function would substantially benefit real-world use cases.

Additionally, I previously raised a related issue in the CeTZ project at cetz-package/cetz#794. CeTZ has successfully implemented vertical alignment based on baseline anchors using Typst's measure function. Unfortunately, since Typst lacks a dedicated measure_equation function, CeTZ baseline anchor currently doesn't support math content properly.

If we aspire to equip Typst with the capability to create math diagrams comparable to those offered by TikZ or TikZ-cd, I guess a convenient and robust method to access baseline information seems crucial. I'm interested in hearing your thoughts on this issue. Do you think the absence of such a feature significantly complicates creating math diagrams, or do you see alternative pathways to achieve similar outcomes effectively?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants