How to align symbols at start of equation?

Consider the following formula:

$
&(P and Q -> R) or not(not R -> S)  \
equiv^"Impl. Elim." &(not (P and Q) or R) or ((not not R) or S) \
equiv^"De M." &(not P or not Q or R) or ((not not R) or S) \
equiv^"DNE" &(not P or not Q or R) or (R or S) \
equiv^("Idempotenz" or) &not P or not Q or R or S \
$

I would like the $equiv$-symbols to be aligned, not the text above it. Ideally, all $equiv$-symbols would start at the same vertical line. The text above would still be centrally aligned, going into both directions. The formulas could then be re-aligned in the current way.

Two alignment points alone don’t seem to help:

Summary
$
&&(P and Q -> R) or not(not R -> S)  \
&equiv^"Impl. Elim." &(not (P and Q) or R) or ((not not R) or S) \
&equiv^"De M." &(not P or not Q or R) or ((not not R) or S) \
&equiv^"DNE" &(not P or not Q or R) or (R or S) \
&equiv^("Idempotenz" or) &not P or not Q or R or S \
$

What is the best way to achieve the intended layout using Typst?

1 Like

Here an attempt by me, no idea if there is a better solution.

#let expand(base, attach) = context {
  let w = measure($attach$).width / 2
  h(w)
  $&base^#box(width: 0pt, move(dy:-0.2em, $attach$))$
  h(w)
}

$
&&&(P and Q -> R) or not(not R -> S)  \
expand(equiv, "Impl. Elim.") &&(not (P and Q) or R) or ((not not R) or S) \
expand(equiv, "De M.") &&(not P or not Q or R) or ((not not R) or S) \
expand(equiv, "DNE") &&(not P or not Q or R) or (R or S) \
expand(equiv, "Idempotenz" or) &&not P or not Q or R or S \
$

4 Likes

It Might be worth looking at, I tried using this as a reference:

I tried this for example:

#set page(width: auto, height: auto, margin: 1cm)

// No context, no measure, no box — just stretch + limits
#let a-equiv(lbl) = math.class("relation",
  math.attach(
    math.limits(math.stretch($equiv$)),
    t: math.upright(text(size: 0.65em, lbl))
  )
)
$
&&& (P and Q arrow.r R) or not(not R arrow.r S)  \
& #a-equiv("Impl. Elim.")   && (not (P and Q) or R) or ((not not R) or S) \
& #a-equiv("De M.")         && (not P or not Q or R) or ((not not R) or S) \
& #a-equiv("DNE")           && (not P or not Q or R) or (R or S) \
& #a-equiv("Idempotenz or") && not P or not Q or R or S \
$

1 Like

Here’s another try in the spirit of keeping it simple - first “smash” the spacing so that alignment applies to the equivalence, and use explicit space to pad it out.

#set page(width: auto, height: auto, margin: 1cm)

// simple version of smash operator
#let smashscript(elt) = box(width: 0pt, box(width: calc.inf * 1pt, math.equation(math.script(elt))))
#let aequiv(lbl, space: $quad quad med$) = $equiv^smashscript(lbl) space$
$
& (P and Q arrow.r R) or not(not R arrow.r S)  \
aequiv("Impl. Elim.")   & (not (P and Q) or R) or ((not not R) or S) \
aequiv("De M.")         & (not P or not Q or R) or ((not not R) or S) \
aequiv("DNE")           & (not P or not Q or R) or (R or S) \
aequiv("Idempotenz" or) & not P or not Q or R or S \
$

I guess this one is a bit dangerous - it puts the label text outside the equation boundary/margin, but maybe it can be adjusted for that too.

2 Likes