added alt/else, loops and other group shortcuts

This commit is contained in:
Louis Heredero 2024-10-04 19:19:17 +02:00
parent 56cc1b11c0
commit feff030510
Signed by: HEL
GPG Key ID: 8D83DE470F8544E7
6 changed files with 96 additions and 9 deletions

Binary file not shown.

View File

@ -33,15 +33,38 @@ Alice <-- Bob: Another authentication Response
#chronos.diagram({
import chronos: *
_seq("Alice", "Bob", comment: "Authentication Request")
_alt(
"successful case", {
_seq("Bob", "Alice", comment: "Authentication Accepted")
},
"some kind of failure", {
_seq("Bob", "Alice", comment: "Authentication Failure")
_grp("My own label", desc: "My own label2", {
_seq("Alice", "Log", comment: "Log attack start")
_grp("loop", desc: "1000 times", {
_loop("1000 times", {
_seq("Alice", "Bob", comment: "DNS Attack")
})
_seq("Alice", "Bob", comment: "Log attack end")
_seq("Alice", "Log", comment: "Log attack end")
})
},
"Another type of failure", {
_seq("Bob", "Alice", comment: "Please repeat")
}
)
})
#chronos.diagram({
import chronos: *
_par("a", display-name: box(width: 1.5em, height: .5em), show-bottom: false)
_par("b", display-name: box(width: 1.5em, height: .5em), show-bottom: false)
_col("a", "b", width: 2cm)
_loop("a<1", min: 1, {
_seq("a", "b", end-tip: ">>")
_seq("b", "a", end-tip: ">>")
})
_seq("a", "b", end-tip: ">>")
})
#chronos.diagram({

View File

@ -185,7 +185,7 @@
// Compute groups spans (horizontal)
for (i, elmt) in elmts.enumerate() {
if elmt.type == "grp" {
if elmt.type == "grp" or elmt.type == "alt" {
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)

View File

@ -11,6 +11,36 @@
),)
}
#let _alt(desc, elmts, ..args) = {
let all-elmts = ()
all-elmts += elmts
let args = args.pos()
for i in range(0, args.len(), step: 2) {
let else-desc = args.at(i)
let else-elmts = args.at(i + 1, default: ())
all-elmts.push((
type: "else",
desc: else-desc
))
all-elmts += else-elmts
}
return _grp("alt", desc: desc, type: "alt", all-elmts)
}
#let _loop(desc, min: none, max: auto, elmts) = {
let name = "loop"
if min != none {
if max == auto {
max = "*"
}
name += "(" + str(min) + "," + str(max) + ")"
}
_grp(name, desc: desc, type: "loop", elmts)
}
#let _opt(desc, elmts) = grp("opt", desc: desc, type: "opt", elmts)
#let _break(desc, elmts) = grp("break", desc: desc, type: "break", elmts)
#let render(x0, x1, y0, y1, group) = {
let shapes = ()
let name = text(group.name, weight: "bold")
@ -52,3 +82,18 @@
return shapes
}
#let render-else(x0, x1, y, elmt) = {
let shapes = draw.line(
(x0, y),
(x1, y),
stroke: (dash: (2pt, 1pt), thickness: .5pt)
)
shapes += draw.content(
(x0, y),
text([\[#elmt.desc\]], weight: "bold", size: .8em),
anchor: "north-west",
padding: 3pt
)
return shapes
}

View File

@ -2,7 +2,7 @@
#import "diagram.typ": diagram, from-plantuml, _gap, _evt, _col
#import "sequence.typ": _seq
#import "group.typ": _grp
#import "group.typ": _grp, _loop, _alt, _opt, _break
#import "participant.typ": _par
#import "separator.typ": _sep
#import "note.typ": _note

View File

@ -242,6 +242,7 @@
let draw-seq = sequence.render.with(pars-i, x-pos, participants)
let draw-group = group.render.with()
let draw-else = group.render-else.with()
let draw-sep = separator.render.with(x-pos)
let draw-par = participant.render.with(x-pos)
let draw-note = note.render.with(pars-i, x-pos)
@ -283,6 +284,9 @@
if g.at(1).max-i == elmt.max-i { g.at(3) += 1 }
g
})
if elmt.grp-type == "alt" {
elmt.insert("elses", ())
}
groups.push((y, elmt, 0, 0))
y -= m.height / 1pt
@ -294,6 +298,21 @@
let x1 = x-pos.at(group.max-i) + end-lvl * 10 + 20
shapes += draw-group(x0, x1, start-y, y, group)
if group.grp-type == "alt" {
for (else-y, else-elmt) in group.elses {
shapes += draw-else(x0, x1, else-y, else-elmt)
}
}
// Alt's elses -> reserve space for label + store position
} else if elmt.type == "else" {
y -= Y-SPACE
let m = measure(text([\[#elmt.desc\]], weight: "bold", size: .8em))
groups.last().at(1).elses.push((
y, elmt
))
y -= m.height / 1pt
// Separator
} else if elmt.type == "sep" {
let shps