Compare commits
13 Commits
511368d405
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| fe66e5a72a | |||
| 01d930bfd5 | |||
|
f33fe8f932
|
|||
|
7da39889d4
|
|||
|
a46bb8534b
|
|||
|
00d52fe83f
|
|||
|
47e9f42d5f
|
|||
|
a815037f24
|
|||
|
fab45bd8ab
|
|||
|
4231233f76
|
|||
|
34ec00768f
|
|||
| a7db89b214 | |||
| 6bf98ebcb8 |
@@ -14,7 +14,7 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install tytanic
|
||||
run: cargo binstall tytanic@0.2.2
|
||||
run: cargo binstall tytanic@0.3.3
|
||||
|
||||
- name: Run test suite
|
||||
run: tt run
|
||||
|
||||
@@ -15,7 +15,7 @@ This package lets you render sequence diagrams directly in Typst. The following
|
||||
<td>
|
||||
|
||||
```typst
|
||||
#import "@preview/chronos:0.2.2"
|
||||
#import "@preview/chronos:0.3.0"
|
||||
#chronos.diagram({
|
||||
import chronos: *
|
||||
_par("Alice")
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#chronos.diagram({
|
||||
import chronos: *
|
||||
_seq("User", "A", comment: "DoWork", enable-dst: true)
|
||||
_seq("A", "B", comment: [#sym.quote.angle.l createRequest #sym.quote.angle.r], enable-dst: true)
|
||||
_seq("A", "B", comment: [#sym.quote.chevron.l createRequest #sym.quote.chevron.r], enable-dst: true)
|
||||
_seq("B", "C", comment: "DoWork", enable-dst: true)
|
||||
_seq("C", "B", comment: "WorkDone", destroy-src: true, disable-src: true, dashed: true)
|
||||
_seq("B", "A", comment: "RequestCreated", disable-src: true, dashed: true)
|
||||
@@ -15,7 +15,7 @@
|
||||
import chronos: *
|
||||
_seq("User", "A", comment: "DoWork", enable-dst: true, lifeline-style: (fill: rgb("#FFBBBB")))
|
||||
_seq("A", "A", comment: "Internal call", enable-dst: true, lifeline-style: (fill: rgb("#E9967A")))
|
||||
_seq("A", "B", comment: [#sym.quote.angle.l createRequest #sym.quote.angle.r], enable-dst: true)
|
||||
_seq("A", "B", comment: [#sym.quote.chevron.l createRequest #sym.quote.chevron.r], enable-dst: true)
|
||||
_seq("B", "A", comment: "RequestCreated", disable-src: true, disable-dst: true, dashed: true)
|
||||
_seq("A", "User", comment: "Done", disable-src: true)
|
||||
})
|
||||
|
||||
|
Before Width: | Height: | Size: 88 KiB After Width: | Height: | Size: 88 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
7
justfile
@@ -4,6 +4,13 @@
|
||||
gallery_dir := "./gallery"
|
||||
set shell := ["bash", "-uc"]
|
||||
|
||||
@version:
|
||||
echo $'\e[1mTypst:\e[0m'
|
||||
typst --version
|
||||
echo
|
||||
echo $'\e[1mTytanic:\e[0m'
|
||||
tt util about
|
||||
|
||||
manual:
|
||||
typst c manual.typ manual.pdf
|
||||
|
||||
|
||||
7777
manual.pdf
@@ -1 +1 @@
|
||||
#import "@preview/cetz:0.4.0": *
|
||||
#import "@preview/cetz:0.4.2": *
|
||||
@@ -394,6 +394,11 @@
|
||||
set-ctx(c => {
|
||||
c.y = end-info.y
|
||||
c.lifelines = ctx.lifelines
|
||||
c.last-drawn = (
|
||||
type: "seq",
|
||||
start-info: start-info,
|
||||
end-info: end-info
|
||||
)
|
||||
return c
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,32 +1,66 @@
|
||||
#import "/src/core/utils.typ": get-ctx, is-elmt, set-ctx
|
||||
#import "/src/cetz.typ": draw
|
||||
|
||||
#let render(sync) = get-ctx(ctx => {
|
||||
set-ctx(c => {
|
||||
c.sync-ys = ()
|
||||
c.sync = (
|
||||
ctx: ctx,
|
||||
bottoms: (),
|
||||
starts: (),
|
||||
start-y: ctx.y,
|
||||
align-y: ctx.y
|
||||
)
|
||||
c.in-sync = true
|
||||
return c
|
||||
})
|
||||
})
|
||||
|
||||
#let in-sync-render(elmt) = {
|
||||
set-ctx(c => {
|
||||
c.y = c.sync.start-y
|
||||
return c
|
||||
})
|
||||
draw.hide({
|
||||
(elmt.draw)(elmt)
|
||||
})
|
||||
set-ctx(c => {
|
||||
c.sync.starts.push(c.last-drawn.start-info.y)
|
||||
c.sync.bottoms.push(c.y)
|
||||
return c
|
||||
})
|
||||
}
|
||||
|
||||
#let render-end(sync) = get-ctx(ctx => {
|
||||
for e in sync.elmts {
|
||||
assert(is-elmt(e), message: "Sync element can only contain chronos elements, found " + repr(e))
|
||||
assert(
|
||||
e.type == "seq",
|
||||
message: "Sync element can only contain sequences, found '" + e.type + "'"
|
||||
)
|
||||
|
||||
set-ctx(c => {
|
||||
c.y = ctx.y
|
||||
return c
|
||||
})
|
||||
(e.draw)(e)
|
||||
set-ctx(c => {
|
||||
c.sync-ys.push(c.y)
|
||||
return c
|
||||
})
|
||||
}
|
||||
|
||||
set-ctx(c => {
|
||||
c.y = calc.min(..c.sync-ys)
|
||||
c.remove("sync-ys")
|
||||
let new-sync = c.sync
|
||||
if new-sync.starts.len() != 0 {
|
||||
new-sync.align-y = calc.min(..new-sync.starts)
|
||||
}
|
||||
new-sync.remove("ctx")
|
||||
return c.sync.ctx + (sync: new-sync)
|
||||
})
|
||||
|
||||
for (i, e) in sync.elmts.enumerate() {
|
||||
set-ctx(c => {
|
||||
let dy = c.sync.starts.at(i) - c.sync.start-y
|
||||
c.y = c.sync.align-y - dy
|
||||
return c
|
||||
})
|
||||
(e.draw)(e)
|
||||
}
|
||||
|
||||
set-ctx(c => {
|
||||
let heights = c.sync.starts.zip(c.sync.bottoms).map(((s, b)) => b - s)
|
||||
c.y = c.sync.align-y + calc.min(..heights)
|
||||
c.remove("sync")
|
||||
return c
|
||||
})
|
||||
})
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#import "draw/note.typ": get-box as get-note-box, get-size as get-note-size
|
||||
#import "draw/participant.typ"
|
||||
#import "draw/sync.typ": in-sync-render
|
||||
#import "utils.typ": *
|
||||
#import "/src/consts.typ": *
|
||||
|
||||
@@ -15,22 +16,6 @@
|
||||
})
|
||||
}
|
||||
|
||||
#let unwrap-syncs(elements) = {
|
||||
let i = 0
|
||||
while i < elements.len() {
|
||||
let elmt = elements.at(i)
|
||||
if elmt.type == "sync" {
|
||||
elements = (
|
||||
elements.slice(0, i + 1) +
|
||||
elmt.elmts +
|
||||
elements.slice(i + 1)
|
||||
)
|
||||
}
|
||||
i += 1
|
||||
}
|
||||
return elements
|
||||
}
|
||||
|
||||
#let seq-update-lifelines(participants, pars-i, seq) = {
|
||||
let participants = participants
|
||||
let com = if seq.comment == none {""} else {seq.comment}
|
||||
@@ -308,7 +293,6 @@
|
||||
|
||||
#let compute-columns-width(participants, elements, pars-i) = {
|
||||
elements = elements.filter(is-elmt)
|
||||
elements = unwrap-syncs(elements)
|
||||
|
||||
let cells
|
||||
(participants, elements, cells) = compute-max-lifeline-levels(participants, elements, pars-i)
|
||||
@@ -334,7 +318,8 @@
|
||||
lifelines: participants.map(_ => (
|
||||
level: 0,
|
||||
lines: ()
|
||||
))
|
||||
)),
|
||||
in-sync: false
|
||||
)
|
||||
chronos-ctx.insert(
|
||||
"widths",
|
||||
@@ -393,7 +378,13 @@
|
||||
if not is-elmt(elmt) {
|
||||
(elmt,)
|
||||
} else if "draw" in elmt and elmt.type != "par" {
|
||||
(elmt.draw)(elmt)
|
||||
get-ctx(ctx => {
|
||||
if ctx.in-sync and elmt.type != "sync-end" {
|
||||
in-sync-render(elmt)
|
||||
} else {
|
||||
(elmt.draw)(elmt)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#import "draw/group.typ": render-end as grp-render-end
|
||||
#import "draw/sync.typ": render-end as sync-render-end
|
||||
#import "utils.typ": get-group-span, is-elmt
|
||||
#import "/src/participant.typ": _exists as par-exists, _par
|
||||
#import "/src/sequence.typ": _seq
|
||||
@@ -18,6 +19,24 @@
|
||||
)
|
||||
}
|
||||
|
||||
#let flatten-sync(elmts, i) = {
|
||||
let sync = elmts.at(i)
|
||||
elmts.at(i) = sync
|
||||
let start = sync
|
||||
start.remove("elmts")
|
||||
return (
|
||||
elmts.slice(0, i) +
|
||||
(start,) +
|
||||
sync.elmts +
|
||||
((
|
||||
type: "sync-end",
|
||||
draw: sync-render-end,
|
||||
elmts: sync.elmts
|
||||
),) +
|
||||
elmts.slice(i + 1)
|
||||
)
|
||||
}
|
||||
|
||||
#let update-group-children(elmts, i) = {
|
||||
let elmts = elmts
|
||||
let group-end = elmts.at(i)
|
||||
@@ -58,6 +77,9 @@
|
||||
|
||||
if elmt.type == "grp" {
|
||||
elmts = flatten-group(elmts, i)
|
||||
|
||||
} else if elmt.type == "sync" {
|
||||
elmts = flatten-sync(elmts, i)
|
||||
|
||||
} else if elmt.type == "seq" {
|
||||
if elmt.enable-dst {
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
let (i0, i1) = get-group-span(participants, elmt)
|
||||
min-i = calc.min(min-i, i0)
|
||||
max-i = calc.max(max-i, i1)
|
||||
} else if elmt.type == "sync" {
|
||||
} else if elmt.type == "sync-end" {
|
||||
let (i0, i1) = get-group-span(participants, elmt)
|
||||
min-i = calc.min(min-i, i0)
|
||||
max-i = calc.max(max-i, i1)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#let version = version(0, 2, 2)
|
||||
#let version = version(0, 3, 0)
|
||||
#import "diagram.typ": diagram, from-plantuml
|
||||
|
||||
#import "sequence.typ": _seq, _ret
|
||||
|
||||
|
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 6.7 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
4
tests/sequence/sync/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
# generated by tytanic, do not edit
|
||||
|
||||
diff/**
|
||||
out/**
|
||||
BIN
tests/sequence/sync/ref/1.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
tests/sequence/sync/ref/2.png
Normal file
|
After Width: | Height: | Size: 8.4 KiB |
47
tests/sequence/sync/test.typ
Normal file
@@ -0,0 +1,47 @@
|
||||
#set page(width: auto, height: auto)
|
||||
#import "/src/lib.typ": *
|
||||
|
||||
#diagram({
|
||||
_par("a")
|
||||
_par("b")
|
||||
_par("c")
|
||||
_sync({
|
||||
_seq("b", "a")
|
||||
_seq("b", "c")
|
||||
})
|
||||
_gap()
|
||||
_sync({
|
||||
_seq("b", "a", comment: [Comment])
|
||||
_seq("b", "c")
|
||||
})
|
||||
_gap()
|
||||
_sync({
|
||||
_seq("b", "a")
|
||||
_seq("b", "c", comment: [Comment])
|
||||
})
|
||||
_gap()
|
||||
_sync({
|
||||
_seq("b", "a", comment: [Two\ lines])
|
||||
_seq("b", "c", comment: [Comment])
|
||||
})
|
||||
|
||||
_sync({
|
||||
_seq("b", "a")
|
||||
_seq("b", "c", slant: 10)
|
||||
})
|
||||
|
||||
_sync({
|
||||
_seq("b", "a")
|
||||
_seq("b", "b")
|
||||
})
|
||||
})
|
||||
|
||||
#pagebreak()
|
||||
|
||||
#diagram({
|
||||
_sync({
|
||||
_seq("a", "b", comment: [Abcdefgh])
|
||||
_seq("b", "c", comment: [Foo\ bar], slant: 10)
|
||||
_seq("c", "c", slant: 20)
|
||||
})
|
||||
})
|
||||
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "chronos"
|
||||
version = "0.2.2"
|
||||
compiler = "0.13.1"
|
||||
version = "0.3.0"
|
||||
compiler = "0.14.2"
|
||||
repository = "https://git.kb28.ch/HEL/chronos"
|
||||
entrypoint = "src/lib.typ"
|
||||
authors = [
|
||||
|
||||