typst / typst

A new markup-based typesetting system that is powerful and easy to learn.
https://typst.app
Apache License 2.0
32.67k stars 877 forks source link

Reuse alignment points of previous display math #1079

Open ParadaCarleton opened 1 year ago

ParadaCarleton commented 1 year ago

Description

AMS has an intertext function that allows you to insert normal text between lines of an equation, while still keeping everything aligned.

Use Case

Useful whenever fully left-justified text is needed within an equation, without changing the layout of equations.

Enivex commented 1 year ago

An alternative to this that achieves the same effect is some way to reuse alignment from the previous equation. I'd actually prefer that to LaTeX' intertext.

laurmaedje commented 1 year ago

An alternative to this that achieves the same effect is some way to reuse alignment from the previous equation. I'd actually prefer that to LaTeX' intertext.

Me too!

Enivex commented 1 year ago

An alternative to this that achieves the same effect is some way to reuse alignment from the previous equation. I'd actually prefer that to LaTeX' intertext.

Me too!

Upon further reflection it's more of a symbiotic relationship than reuse. Link would perhaps be a better word. You would want the alignment to function as if they were a single math environment.

laurmaedje commented 1 year ago

I have no idea how user-facing configuration for this should look, but I like the idea of linking them better than having text inside of the equation.

ParadaCarleton commented 1 year ago

Upon further reflection it's more of a symbiotic relationship than reuse. Link would perhaps be a better word. You would want the alignment to function as if they were a single math environment.

I'd like to ask, could intertext still be included as an option even if linking is included? (Probably by making intertext use linking under the hood.) Feels like having to write something like #link(a, b, c, d, ...) at the end of every equation could end up being a bit of a pain.

lcnbr commented 1 year ago

Maybe if we could label aligment points that would enable this. Something like &<1> and then refering to that alignment point: &@1. This could even be useful in single equation contexts:

$ sum_(k=0)^n norm(u_k) &<1> = norm( y_0 ) +&<2> norm( y_1 - y_0 )  + \ 
                                            &@2 quad +  dots.c  + \ 
                                            &@2 quad +  norm( y_k - y_(k-1) ) \ 
                        &@1 <= limits(sum)_(k=1)^n 1/2^(k-1) + norm(y_0) \ 
                        &@1= (1-1/2^n)/(1-1/2) + norm(y_0). $
yaksher commented 10 months ago

I'd like bump this with the comment that this feels like an essential feature for pretty-formatting math.

That said, labeling and linking to previous alignment points, aside from, IMO, being extremely messy to write, would have the problem that it creates an asymmetric representation of a symmetric relationship.

My alternative proposal is that instead any two equations with the same label are treated as one equation for the purposes of alignment points, since in general, you want this functionality when they are one sequence of equations and you're just interspersing some text. So to achieve intertext-like functionality, you could do something like

$
    a &= b\
      &= c\
$<eqn:blah>
And because of how `c`'s tend to behave, we then have
$
      &= d
$<eqn:blah>

Ideally this would be combined with some kind of "arbitrary unique label" shorthand, <_>, like Rust's anonymous lifetime, and "the previous label" shorthand, which could be used to both cite and replicate the anonymous label, like <^>/@^.

AjaiKN commented 10 months ago

Is it realistic that someone would want to reuse alignment points that aren't adjacent? If that's not a realistic situation, maybe ^& could mean "align with the previous alignment point (even if the previous alignment point is in a different math block)."

$
    a &= b \
      &= c \
$
And because of how $c$s tend to behave, we then have
$
     ^&= d
$
yaksher commented 10 months ago

I think that

I do maintain that "same label equations have the same alignment" is reasonable semantics.

That said, I do think some kind of convenient "attach to the previous equation" syntax could also be nice. Maybe <^&> (not really meaning a label, just borrowing existing markdown syntax with (I think?) invalid characters to avoid introducing new special characters).

AjaiKN commented 10 months ago

Good point! I retract my suggestion then.

ruifengx commented 10 months ago

I also think this is a critical feature for pretty typesetting maths equations, and +1 for labelling alignment points because it is useful even inside the same equation. I would go even further to propose that we allow configuring each alignment points for left/right/centre alignment.

I'd like to present one use case for this feature. In a lot of papers, code in Haskell (or other functional programming languages) are printed as maths equations, e.g., by using lhs2TeX. Here is an example screenshot for the output of lhs2TeX (for other examples, please refer to its documentation):

Output for lhs2TeX

Note There are (at least) three groups of alignments: (1) the top-level "::" and "=", (2) the "|" in the where clauses, and (3) the "=" in the where clauses. (1) and (2) should not interfere with each other, hence alignment point labelling is necessary. Also, the placement of (3) would rely on the result of (2).

Note The "::" and "=" are placed in the same "column", with the alignment set to "centre". This is how manual configuration of each alignment point is important. Other "columns" are left-aligned (by default).

Under the hood, lhs2TeX relies on the LaTeX package polytable, which provides fine-grained control for "columns" (fragments to be aligned) and the alignment for each columns. Just like other LaTeX packages for advanced alignments, it sometimes relies on multi-pass compilation to tweak the columns to the right positions. Things could be much better if labelled alignments and custom alignment point configuration is built into Typst. I plan to work on porting lhs2TeX to Typst (probably as a plugin), and this is a blocking feature.

42triangles commented 2 months ago

Depending on the implementation of alignment point reuse/linkage, specifically if it allows equations within equations to reuse alignment points, things like #1244 could also be handled similarly. (Though "recursive reuse" is probably much more difficult to implement I'd imagine)

I don't know if there's something that already would allow something similar, but another reason to allow "recursive reuse" would be things like wanting to draw boxes around equations without losing alignment easily. You currently can, in the case of a single "attracting" (instead of "repelling", so in a & b & c & d the first and third work) alignment point, just create two #blocks that have a stroke set for all sides except for the sides next to the alignment point, but this breaks down for more than one alignment point / "repelling" alignment points in most situations (due to introducing gaps without outset or not filling the full width because another row takes up more space in the same column).