How to achieve equivalent multline in LaTeX?

Is there anything in Typst (either in the core language or a package) that behaves as LaTeX’s multline? Eg from the amsmath manual,

screenshot_2025-05-27-144620

The functionality I want is the following: given a long equation,

  1. if broken in two parts, align left/right,
  2. if broken in three parts, align left/center/right.
$
  a + b + c + d + & e + f             \
        + med i + & j + k + l + m + n
$
$
  a + b + c + & d + e             \
        + med & f + i             \
        + med & j + k + l + m + n
$

Thanks, I understand how to align things manually.

I am looking for a way to make Typst align the lines left/center/right.

How do you precisely define what counts as left/center/right align? Exact formula/definition/algorithm. It looks totally random to me. With manual alignment, you know exactly how to align the lines.

It seems clear to me from the first post: the line breaks are marked explicitly, then the first line should be fully on the left, the middle part centered (if any) and the right part fully on the right.

Left is all whitespace on the right, center is the same amount of whitespace on left & right, etc.

Are you familiar with \multline in LaTeX? Again, I am looking for something similar.

Ahhh, there is a width limit, now I see it. It’s so uneven, it doesn’t look like anything.

No.

I don’t know how to properly handle math, but this looks close enough:

#let multiline(body) = {
  show math.equation: it => {
    if it.body.func() != [].func() { return it }
    let parts = it.body.children.split(linebreak())
    if parts.len() not in (2, 3) { return it }
    set par(spacing: 1em)
    if parts.len() == 2 {
      let (a, b) = parts.map(array.join)
      align(left, $#a$)
      align(right, $#b$)
    } else {
      let (a, b, c) = parts.map(array.join)
      align(left, $#a$)
      $#b$
      align(right, $#c$)
    }
  }
  body
}

#block(width: 7cm, stroke: 1pt, {
  multiline[$
    a + b + c + d + e + f \
    + med i + j + k + l + m + n
  $]
  multiline[$
    a + b + c + d + e \
    + med f + i \
    + med j + k + l + m + n
  $]
})

#multiline[$
  a + b + c + d + e + f \
  + med i + j + k + l + m + n
$]
#multiline[$
  a + b + c + d + e \
  + med f + i \
  + med j + k + l + m + n
$]

2 Likes

@Andrew, this is a bit more confrontational than it needs to be, please try to avoid that.


@Tamas_K_Papp did Andrew’s last response satisfy your use case? If if so, be sure to give it a checkmark :ballot_box_with_check:. This will help others find the solution in the future. If something is missing, please let us know what so we can resolve your issue. Thanks!

2 Likes

Since Andrew suggested that the solution “doesn’t properly handle math”, I am keeping the issue open in case someone suggests a better one (I don’t know enough about Typst to say if the solution ¨"properly" handles math).

1 Like

Here’s @Andrew’s answer adapted to produce block equations instead of inline equations (this also takes directly an equation as parameter instead of content):

#let align-eq(alignment, eq) = {
  show math.equation.where(block: true): set align(alignment)
  eq
}

#let multiline(it) = {
  if it.body.func() != [].func() { return it }
  let parts = it.body.children.split(linebreak())
  if parts.len() not in (2, 3) { return it }
  if parts.len() == 2 {
    let (a, b) = parts.map(array.join)
    align-eq(left, $ #a $)
    show math.equation.where(block: true): set block(above: 0.65em)
    align-eq(right, $ #b $)
  } else {
    let (a, b, c) = parts.map(array.join)
    align-eq(left, $ #a $)
    show math.equation.where(block: true): set block(above: 0.65em)
    align-eq(center, $ #b $)
    align-eq(right, $ #c $)
  }
}

#multiline($
  a + b + c + d + e + f \
  + med i + j + k + l + m + n
$)
#multiline($
  a + b + c + d + e \
  + med f + i \
  + med j + k + l + m + n
$)

However this has various problems, e.g. with equation numbering and in cases where “multiline” should be used for only a part of the whole equation. Also the question has come up before here. It would probably make sense to file a feature request.

2 Likes