Thanks for your answer. I used your nice idea with metadata and implemented a tabed environment myself. So far its working quite well.
#let t = metadata("tab")
#let tabed(c, tab_width: 1.55cm) = context {
let rows = c.children.split(linebreak())
for (j, row) in rows.enumerate() {
let advance = 0.0pt
let num_tabs = 0
let cont = []
for child in row + (t,) { // add extra tab stop for loop logic
if child == t {
if (num_tabs == 0) {
advance += measure(cont).width
cont // emit content
cont = []
}
num_tabs += 1
} else {
if (num_tabs > 0) {
let column = calc.trunc( advance / tab_width ) // column where the first tab is located
let advance_by = tab_width * (column + num_tabs) - advance
h(advance_by) // emit space
advance += advance_by
}
cont += child
num_tabs = 0
}
}
if (j < rows.len() - 1) {linebreak()} // emit line break
}
}