#import "utils.typ": get-group-span #import "renderer.typ": render #let _seq( p1, p2, comment: none, dashed: false, tip: "default", color: black ) = { return (( type: "seq", p1: p1, p2: p2, comment: comment, dashed: dashed, tip: tip, color: color, ),) } #let _par(name, display-name: auto, start-at: 0) = { return (( type: "par", name: name, display-name: if display-name == auto {name} else {display-name}, start-at: start-at ),) } #let _par-exists(participants, name) = { for p in participants { if name == p.name { return true } } return false } #let _grp(name, desc: none, type: "default", elmts) = { return (( type: "grp", name: name, desc: desc, grp-type: type, elmts: elmts ),) } #let _sep(name) = { return (( type: "sep", name: name ),) } #let diagram(elements) = { let participants = () let elmts = elements let i = 0 while i < elmts.len() { let elmt = elmts.at(i) if elmt.type == "grp" { elmts = ( elmts.slice(0, i + 1) + elmt.elmts + (( type: "grp-end" ),) + elmts.slice(i+1) ) } i += 1 } for elmt in elmts { if elmt.type == "par" { participants.push(elmt) } else if elmt.type == "seq" { if not _par-exists(participants, elmt.p1) { participants.push(_par(elmt.p1).first()) } if not _par-exists(participants, elmt.p2) { participants.push(_par(elmt.p2).first()) } } } for (i, elmt) in elmts.enumerate() { if elmt.type == "grp" { let (min-i, max-i) = get-group-span(participants, elmt) elmts.at(i).insert("min-i", min-i) elmts.at(i).insert("max-i", max-i) } } render(participants, elmts) } #let from-plantuml(code) = { let code = code.text }