From dc5d868a5d3b5c72cebcef1bce0327d5f396bb2e Mon Sep 17 00:00:00 2001 From: LordBaryhobal Date: Tue, 18 Jun 2024 16:09:06 +0200 Subject: [PATCH] added groups --- gallery/example1.pdf | Bin 16907 -> 43464 bytes gallery/example1.typ | 14 ++++++++ src/diagram.typ | 44 +++++++++++++++++++++-- src/renderer.typ | 83 ++++++++++++++++++++++++++++++++++++------- src/utils.typ | 27 ++++++++++++++ 5 files changed, 153 insertions(+), 15 deletions(-) create mode 100644 src/utils.typ diff --git a/gallery/example1.pdf b/gallery/example1.pdf index 63f94d3e8cd1659ab5f7836dad9acb0056260c8e..a3c2da1acec91e6ec4021cc6b0f67f725dd63724 100644 GIT binary patch delta 36632 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

5M9QPEm{*e^2X&J4cbDL_HT4_d5 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 WIJr3(n;?TY*}*)>)YM<)#r_v+OU8)+ diff --git a/gallery/example1.typ b/gallery/example1.typ index a259669..902d151 100644 --- a/gallery/example1.typ +++ b/gallery/example1.typ @@ -28,4 +28,18 @@ Alice <-- Bob: Another authentication Response import "/src/diagram.typ": * _seq("Alice", "Bob", comment: "This is a test") _seq("Alice", "Callum", comment: "This is another test with a long text") +}) + +#chronos.diagram({ + import "/src/diagram.typ": * + _seq("Alice", "Bob", comment: "Authentication Request") + _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", { + _seq("Alice", "Bob", comment: "DNS Attack") + }) + _seq("Alice", "Bob", comment: "Log attack end") + }) }) \ No newline at end of file diff --git a/src/diagram.typ b/src/diagram.typ index d152ac2..bbc9ea2 100644 --- a/src/diagram.typ +++ b/src/diagram.typ @@ -1,3 +1,4 @@ +#import "utils.typ": get-group-span #import "renderer.typ": render #let _seq( @@ -37,9 +38,40 @@ return false } +#let _grp(name, desc: none, type: "default", elmts) = { + return (( + type: "grp", + name: name, + desc: desc, + grp-type: type, + elmts: elmts + ),) +} + #let diagram(elements) = { let participants = () - for elmt in elements { + let elmts = elements + let i = 0 + let a = elmts.len() + 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 + } + let b = elmts.len() + [#a / #b] + [#elmts.map(e => e.type)] + + for elmt in elmts { if elmt.type == "par" { participants.push(elmt) } else if elmt.type == "seq" { @@ -52,7 +84,15 @@ } } - render(participants, elements) + 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) = { diff --git a/src/renderer.typ b/src/renderer.typ index 32cd8f1..ab67726 100644 --- a/src/renderer.typ +++ b/src/renderer.typ @@ -1,16 +1,10 @@ #import "@preview/cetz:0.2.2": canvas, draw +#import "utils.typ": get-participants-i -#let Y-SPACE = 20 +#let Y-SPACE = 10 #let PAR-PAD = (5pt, 3pt) #let PAR-SPACE = 10 -#let get-participants-i(participants) = { - let pars-i = (:) - for (i, p) in participants.enumerate() { - pars-i.insert(p.name, i) - } - return pars-i -} #let get-columns-width(participants, elements) = { let pars-i = get-participants-i(participants) @@ -62,6 +56,44 @@ return widths } +#let draw-group(x0, x1, y0, y1, group) = { + let m = measure(box(group.name)) + let w = m.width / 1pt + 15 + let h = m.height / 1pt + 6 + draw.rect( + (x0, y0), + (x1, y1) + ) + draw.merge-path( + fill: gray.lighten(20%), + close: true, + { + draw.line( + (x0, y0), + (x0 + w, y0), + (x0 + w, y0 - h / 2), + (x0 + w - 5, y0 - h), + (x0, y0 - h) + ) + } + ) + draw.content( + (x0, y0), + group.name, + anchor: "north-west", + padding: (left: 5pt, right: 10pt, top: 3pt, bottom: 3pt) + ) + + if group.desc != none { + draw.content( + (x0 + w, y0), + text([\[#group.desc\]], weight: "bold"), + anchor: "north-west", + padding: 3pt + ) + } +} + #let render(participants, elements) = context canvas(length: 1pt, { let pars-i = get-participants-i(participants) @@ -85,6 +117,8 @@ } let y = -Y-SPACE + let groups = () + // Draw sequences for elmt in elements { if elmt.type == "seq" { @@ -98,12 +132,8 @@ ) ) - draw.line( - (x1, y), - (x2, y), - ..style - ) if elmt.comment != none { + y -= measure(box(elmt.comment)).height / 1pt + 6 draw.content( (calc.min(x1, x2), y), elmt.comment, @@ -111,6 +141,33 @@ padding: 3pt ) } + + draw.line( + (x1, y), + (x2, y), + ..style + ) + y -= Y-SPACE + } else if elmt.type == "grp" { + let m = measure( + box( + inset: (left: 5pt, right: 5pt, top: 3pt, bottom: 3pt), + ) + ) + groups = groups.map(g => { + if g.at(1).min-i == elmt.min-i { g.at(2) += 1 } + if g.at(1).max-i == elmt.max-i { g.at(3) += 1 } + g + }) + groups.push((y, elmt, 0, 0)) + y -= m.height / 1pt + Y-SPACE + + } else if elmt.type == "grp-end" { + let (start-y, group, start-lvl, end-lvl) = groups.pop() + let x0 = x-pos.at(group.min-i) - start-lvl * 10 - 20 + let x1 = x-pos.at(group.max-i) + end-lvl * 10 + 20 + draw-group(x0, x1, start-y, y, group) + y -= Y-SPACE } } diff --git a/src/utils.typ b/src/utils.typ new file mode 100644 index 0000000..bbe073f --- /dev/null +++ b/src/utils.typ @@ -0,0 +1,27 @@ +#let get-participants-i(participants) = { + let pars-i = (:) + for (i, p) in participants.enumerate() { + pars-i.insert(p.name, i) + } + return pars-i +} + +#let get-group-span(participants, group) = { + let min-i = participants.len() - 1 + let max-i = 0 + let pars-i = get-participants-i(participants) + + for elmt in group.elmts { + if elmt.type == "seq" { + let i1 = pars-i.at(elmt.p1) + let i2 = pars-i.at(elmt.p2) + min-i = calc.min(min-i, i1, i2) + max-i = calc.max(max-i, i1, i2) + } else if elmt.type == "grp" { + let (i0, i1) = get-group-span(participants, elmt) + min-i = calc.min(min-i, i0) + max-i = calc.max(max-i, i1) + } + } + return (min-i, max-i) +} \ No newline at end of file