diff --git a/TODO.md b/TODO.md index cefe5b4..77e47f9 100644 --- a/TODO.md +++ b/TODO.md @@ -22,6 +22,7 @@ - [ ] Add args verification to catch user errors + pretty error messages - [ ] PlantUML parser - [ ] (Message numbering) +- [ ] Mainframes - [ ] Different types of groups (alt/loop/etc.) - [ ] Delays - [ ] Auto-fit in parent \ No newline at end of file diff --git a/docs/participants.typ b/docs/participants.typ index d6cd62c..c9aea7a 100644 --- a/docs/participants.typ +++ b/docs/participants.typ @@ -48,4 +48,20 @@ custom-image: none, show-bottom: true, show-top: true, +) = {} + +/// Sets some options for columns between participants +/// +/// Parameters `p1` and `p2` MUST be consecutive participants (also counting found/lost messages), but they do not need to be in the left to right order +/// - p1 (str): The first neighbouring participant +/// - p2 (str): The second neighbouring participant +/// - width (auto, int, float, length): Optional fixed width of the column\ If the column's content (e.g. sequence comments) is larger, it will overflow +/// - margin (int, float, length): Additional margin to add to the column\ This margin is not included in `width` and `min-width`, but rather added separately +/// - min-width (int, float, length): Minimum width of the column\ If set to a larger value than `width`, the latter will be overriden +#let _col( + p1, + p2, + width: auto, + margin: 0, + min-width: 0 ) = {} \ No newline at end of file diff --git a/gallery/example3.pdf b/gallery/example3.pdf index 7e9f09a..f6c5c11 100644 Binary files a/gallery/example3.pdf and b/gallery/example3.pdf differ diff --git a/gallery/example3.typ b/gallery/example3.typ index 4c48a04..09a4090 100644 --- a/gallery/example3.typ +++ b/gallery/example3.typ @@ -144,4 +144,23 @@ chronos.diagram({ _par("d", display-name: "Danny", show-bottom: false, show-top: false) _gap() +}) + +#chronos.diagram({ + import chronos: * + + _par("a", display-name: "Alice") + _par("b", display-name: "Bob") + _par("c", display-name: "Caleb") + _par("d", display-name: "Danny") + _par("e", display-name: "Erika") + + _col("a", "b") + _col("b", "c", width: 2cm) + _col("c", "d", margin: .5cm) + _col("d", "e", min-width: 2cm) + + //_seq("b", "c", comment: [Hello World !]) + //_seq("c", "d", comment: [Hello World]) + //_seq("d", "e", comment: [Hello World]) }) \ No newline at end of file diff --git a/manual.pdf b/manual.pdf index e950552..cccf85c 100644 Binary files a/manual.pdf and b/manual.pdf differ diff --git a/manual.typ b/manual.typ index bc888a1..557ecf6 100644 --- a/manual.typ +++ b/manual.typ @@ -155,7 +155,7 @@ chronos.diagram({ doc-ref: doc-ref ) ) -#tidy.show-module(par-docs, show-outline: false) +#tidy.show-module(par-docs, show-outline: false, sort-functions: none) #pagebreak(weak: true) diff --git a/src/diagram.typ b/src/diagram.typ index fbba74a..b70eef5 100644 --- a/src/diagram.typ +++ b/src/diagram.typ @@ -18,6 +18,17 @@ ),) } +#let _col(p1, p2, width: auto, margin: 0, min-width: 0) = { + return (( + type: "col", + p1: p1, + p2: p2, + width: width, + margin: margin, + min-width: min-width + ),) +} + #let diagram(elements, width: auto) = { if elements == none { return diff --git a/src/lib.typ b/src/lib.typ index 0317a12..6afc60f 100644 --- a/src/lib.typ +++ b/src/lib.typ @@ -1,5 +1,5 @@ #let version = version(0, 1, 1) -#import "diagram.typ": diagram, from-plantuml, _gap, _evt +#import "diagram.typ": diagram, from-plantuml, _gap, _evt, _col #import "sequence.typ": _seq #import "group.typ": _grp diff --git a/src/renderer.typ b/src/renderer.typ index ace3830..a772654 100644 --- a/src/renderer.typ +++ b/src/renderer.typ @@ -1,5 +1,5 @@ #import "@preview/cetz:0.2.2": canvas, draw -#import "utils.typ": get-participants-i, get-style +#import "utils.typ": get-participants-i, get-style, normalize-units #import "group.typ" #import "participant.typ" #import participant: PAR-SPECIALS @@ -194,6 +194,37 @@ } widths.at(i) = w } + + for elmt in elements { + if elmt.type == "col" { + let i1 = pars-i.at(elmt.p1) + let i2 = pars-i.at(elmt.p2) + if calc.abs(i1 - i2) != 1 { + let i-min = calc.min(i1, i2) + let i-max = calc.max(i1, i2) + let others = pars-i.pairs() + .sorted(key: p => p.last()) + .slice(i-min + 1, i-max) + .map(p => "'" + p.first() + "'") + .join(", ") + panic( + "Column participants must be consecutive (participants (" + + others + + ") are in between)" + ) + } + let i = calc.min(i1, i2) + + if elmt.width != auto { + widths.at(i) = normalize-units(elmt.width) + } + widths.at(i) = calc.max( + widths.at(i), + normalize-units(elmt.min-width) + ) + normalize-units(elmt.margin) + } + } + return widths } diff --git a/src/utils.typ b/src/utils.typ index 219501c..a97a3b5 100644 --- a/src/utils.typ +++ b/src/utils.typ @@ -1,3 +1,12 @@ +#let normalize-units(value) = { + if type(value) == int or type(value) == float { + return value + } + if type(value) == length { + return value / 1pt + } + panic("Unsupported type '" + str(type(value)) + "'") +} #let get-participants-i(participants) = { let pars-i = (:) for (i, p) in participants.enumerate() {