Compare commits
	
		
			9 Commits
		
	
	
		
			feat/parse
			...
			dev
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| e8d737ff00 | |||
| df3a2ddf68 | |||
| 42e8e26aa7 | |||
| b33531bef5 | |||
| ab1386e721 | |||
| 1f155063a8 | |||
| d986284e4e | |||
| a037727edf | |||
| b0950f5e68 | 
| @@ -15,7 +15,7 @@ This package lets you render sequence diagrams directly in Typst. The following | |||||||
| <td> | <td> | ||||||
|  |  | ||||||
| ```typst | ```typst | ||||||
| #import "@preview/chronos:0.1.0" | #import "@preview/chronos:0.2.0" | ||||||
| #chronos.diagram({ | #chronos.diagram({ | ||||||
|   import chronos: * |   import chronos: * | ||||||
|   _par("Alice") |   _par("Alice") | ||||||
|   | |||||||
| @@ -1,5 +1,18 @@ | |||||||
| #import "example.typ": example | #import "example.typ": example | ||||||
|  |  | ||||||
|  | #let seq-return = example(``` | ||||||
|  | _seq( | ||||||
|  |   "Bob", "Alice", | ||||||
|  |   comment: [hello], | ||||||
|  |   enable-dst: true | ||||||
|  | ) | ||||||
|  | _seq( | ||||||
|  |   "Alice", "Alice", | ||||||
|  |   comment: [some action] | ||||||
|  | ) | ||||||
|  | _ret(comment: [bye]) | ||||||
|  | ```) | ||||||
|  |  | ||||||
| #let seq-comm-align = example(``` | #let seq-comm-align = example(``` | ||||||
| _par("p1", display-name: "Start participant") | _par("p1", display-name: "Start participant") | ||||||
| _par("p2", display-name: "End participant") | _par("p2", display-name: "End participant") | ||||||
| @@ -121,15 +134,58 @@ _sync({ | |||||||
| }) | }) | ||||||
| ```) | ```) | ||||||
|  |  | ||||||
| #let gaps-seps = example(``` | #let gaps = example(``` | ||||||
| _par("alice", display-name: "Alice") | _par("a", display-name: "Alice") | ||||||
| _par("bob", display-name: "Bob") | _par("b", display-name: "Bob") | ||||||
|  |  | ||||||
| _seq("alice", "bob", comment: "Hello") | _seq("a", "b", comment: [message 1]) | ||||||
| _gap(size: 10) | _seq("b", "a", comment: [ok], dashed: true) | ||||||
| _seq("bob", "alice", comment: "Hi") | _gap() | ||||||
| _sep("Another day") | _seq("a", "b", comment: [message 2]) | ||||||
| _seq("alice", "bob", comment: "Hello again") | _seq("b", "a", comment: [ok], dashed: true) | ||||||
|  | _gap(size: 40) | ||||||
|  | _seq("a", "b", comment: [message 3]) | ||||||
|  | _seq("b", "a", comment: [ok], dashed: true) | ||||||
|  | ```) | ||||||
|  |  | ||||||
|  | #let seps = example(``` | ||||||
|  | _par("a", display-name: "Alice") | ||||||
|  | _par("b", display-name: "Bob") | ||||||
|  |  | ||||||
|  | _sep[Initialization] | ||||||
|  | _seq("a", "b", comment: [Request 1]) | ||||||
|  | _seq( | ||||||
|  |   "b", "a", | ||||||
|  |   comment: [Response 1], | ||||||
|  |   dashed: true | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | _sep[Repetition] | ||||||
|  | _seq("a", "b", comment: [Request 2]) | ||||||
|  | _seq( | ||||||
|  |   "b", "a", | ||||||
|  |   comment: [Response 2], | ||||||
|  |   dashed: true | ||||||
|  | ) | ||||||
|  | ```) | ||||||
|  |  | ||||||
|  | #let delays = example(``` | ||||||
|  | _par("a", display-name: "Alice") | ||||||
|  | _par("b", display-name: "Bob") | ||||||
|  |  | ||||||
|  | _seq("a", "b", comment: [Auth Request]) | ||||||
|  | _delay() | ||||||
|  | _seq( | ||||||
|  |   "b", "a", | ||||||
|  |   comment: [Auth Response], | ||||||
|  |   dashed: true | ||||||
|  | ) | ||||||
|  | _delay(name: [5 minutes later]) | ||||||
|  | _seq( | ||||||
|  |   "b", "a", | ||||||
|  |   comment: [Good Bye !], | ||||||
|  |   dashed: true | ||||||
|  | ) | ||||||
| ```) | ```) | ||||||
|  |  | ||||||
| #let notes-shapes = example(``` | #let notes-shapes = example(``` | ||||||
|   | |||||||
| @@ -1,8 +1,15 @@ | |||||||
| /// Creates a gap before the next element |  | ||||||
| /// - size (int): Size of the gap |  | ||||||
| #let _gap(size: 20) = {} |  | ||||||
|  |  | ||||||
| /// Creates a separator before the next element | /// Creates a separator before the next element | ||||||
| /// #examples.gaps-seps | /// #examples.seps | ||||||
| /// - name (content): Name to display in the middle of the separator | /// - name (content): Name to display in the middle of the separator | ||||||
| #let _sep(name) = {} | #let _sep(name) = {} | ||||||
|  |  | ||||||
|  | /// Creates a delay before the next element | ||||||
|  | /// #examples.delays | ||||||
|  | /// - name (content, none): Name to display in the middle of the delay area | ||||||
|  | /// - size (int): Size of the delay | ||||||
|  | #let _delay(name: none, size: 30) = {} | ||||||
|  |  | ||||||
|  | /// Creates a gap before the next element | ||||||
|  | /// #examples.gaps | ||||||
|  | /// - size (int): Size of the gap | ||||||
|  | #let _gap(size: 20) = {} | ||||||
| @@ -58,10 +58,12 @@ | |||||||
| /// - 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 | /// - 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 | /// - 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 | /// - min-width (int, float, length): Minimum width of the column\ If set to a larger value than `width`, the latter will be overriden | ||||||
|  | /// - max-width (int, float, length, none): Maximum width of the column\ If set to a lower value than `width`, the latter will be overriden\ If set to `none`, no restriction is applied | ||||||
| #let _col( | #let _col( | ||||||
|   p1, |   p1, | ||||||
|   p2, |   p2, | ||||||
|   width: auto, |   width: auto, | ||||||
|   margin: 0, |   margin: 0, | ||||||
|   min-width: 0 |   min-width: 0, | ||||||
|  |   max-width: none | ||||||
| ) = {} | ) = {} | ||||||
| @@ -42,6 +42,17 @@ | |||||||
|   slant: none |   slant: none | ||||||
| ) = {} | ) = {} | ||||||
|  |  | ||||||
|  | /// Creates a return sequence | ||||||
|  | /// #examples.seq-return | ||||||
|  | /// - comment (none, content): Optional comment to display along the arrow | ||||||
|  | #let _ret(comment: none) = {} | ||||||
|  |  | ||||||
|  | /// Accepted values for `comment-align` argument of @@_seq() | ||||||
|  | /// #examples.seq-comm-align | ||||||
|  | #let comment-align = ( | ||||||
|  |   "start", "end", "left", "center", "right" | ||||||
|  | ) | ||||||
|  |  | ||||||
| /// Accepted values for `event` argument of @@_evt() | /// Accepted values for `event` argument of @@_evt() | ||||||
| ///  | ///  | ||||||
| /// `EVENTS = ("create", "destroy", "enable", "disable")` | /// `EVENTS = ("create", "destroy", "enable", "disable")` | ||||||
| @@ -52,9 +63,3 @@ | |||||||
| #let tips = ( | #let tips = ( | ||||||
|   "", ">", ">>", "\\", "\\\\", "/", "//", "x", "o", |   "", ">", ">>", "\\", "\\\\", "/", "//", "x", "o", | ||||||
| ) | ) | ||||||
|  |  | ||||||
| /// Accepted values for `comment-align` argument of @@_seq() |  | ||||||
| /// #examples.seq-comm-align |  | ||||||
| #let comment-align = ( |  | ||||||
|   "start", "end", "left", "center", "right" |  | ||||||
| ) |  | ||||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB | 
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 96 KiB After Width: | Height: | Size: 92 KiB | 
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB | 
							
								
								
									
										
											BIN
										
									
								
								manual.pdf
									
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								manual.pdf
									
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							| @@ -30,8 +30,8 @@ | |||||||
|  |  | ||||||
| #set page(numbering: "1/1", header: align(right)[chronos #sym.dash.em v#chronos.version]) | #set page(numbering: "1/1", header: align(right)[chronos #sym.dash.em v#chronos.version]) | ||||||
| #set page( | #set page( | ||||||
|   header: locate(loc => align(left)[chronos #sym.dash.em v#chronos.version]), |   header: align(left)[chronos #sym.dash.em v#chronos.version], | ||||||
|   footer: locate(loc => align(center, counter(page).display("1/1", both: true))) |   footer: context align(center, counter(page).display("1/1", both: true)) | ||||||
| ) | ) | ||||||
|  |  | ||||||
| = Introduction | = Introduction | ||||||
| @@ -197,7 +197,7 @@ chronos.diagram({ | |||||||
|     examples: examples |     examples: examples | ||||||
|   ) |   ) | ||||||
| ) | ) | ||||||
| #tidy.show-module(gap-sep-docs, show-outline: false) | #tidy.show-module(gap-sep-docs, show-outline: false, sort-functions: none) | ||||||
|  |  | ||||||
| #pagebreak(weak: true) | #pagebreak(weak: true) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -19,14 +19,15 @@ | |||||||
|   ),) |   ),) | ||||||
| } | } | ||||||
|  |  | ||||||
| #let _col(p1, p2, width: auto, margin: 0, min-width: 0) = { | #let _col(p1, p2, width: auto, margin: 0, min-width: 0, max-width: none) = { | ||||||
|   return (( |   return (( | ||||||
|     type: "col", |     type: "col", | ||||||
|     p1: p1, |     p1: p1, | ||||||
|     p2: p2, |     p2: p2, | ||||||
|     width: width, |     width: width, | ||||||
|     margin: margin, |     margin: margin, | ||||||
|     min-width: min-width |     min-width: min-width, | ||||||
|  |     max-width: max-width | ||||||
|   ),) |   ),) | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -240,7 +241,6 @@ | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   set text(font: "Source Sans 3") |  | ||||||
|   let canvas = render(participants, elmts) |   let canvas = render(participants, elmts) | ||||||
|   fit-canvas(canvas, width: width) |   fit-canvas(canvas, width: width) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| #import "@preview/cetz:0.2.2": draw | #import "@preview/cetz:0.3.1": draw | ||||||
| #import "consts.typ": * | #import "consts.typ": * | ||||||
|  |  | ||||||
| #let _grp(name, desc: none, type: "default", elmts) = { | #let _grp(name, desc: none, type: "default", elmts) = { | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| #let version = version(0, 1, 1) | #let version = version(0, 2, 0) | ||||||
| #import "diagram.typ": diagram, from-plantuml, _gap, _evt, _col | #import "diagram.typ": diagram, from-plantuml, _gap, _evt, _col | ||||||
|  |  | ||||||
| #import "sequence.typ": _seq, _ret | #import "sequence.typ": _seq, _ret | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| #import "@preview/cetz:0.2.2": draw | #import "@preview/cetz:0.3.1": draw | ||||||
| #import "consts.typ": * | #import "consts.typ": * | ||||||
|  |  | ||||||
| #let SIDES = ( | #let SIDES = ( | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| #import "@preview/cetz:0.2.2": draw | #import "@preview/cetz:0.3.1": draw | ||||||
| #import "consts.typ": * | #import "consts.typ": * | ||||||
|  |  | ||||||
| #let PAR-SPECIALS = "?[]" | #let PAR-SPECIALS = "?[]" | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| #import "@preview/cetz:0.2.2": canvas, draw | #import "@preview/cetz:0.3.1": canvas, draw | ||||||
| #import "utils.typ": get-participants-i, get-style, normalize-units | #import "utils.typ": get-participants-i, get-style, normalize-units | ||||||
| #import "group.typ" | #import "group.typ" | ||||||
| #import "participant.typ" | #import "participant.typ" | ||||||
| @@ -218,10 +218,13 @@ | |||||||
|       if elmt.width != auto { |       if elmt.width != auto { | ||||||
|         widths.at(i) = normalize-units(elmt.width) |         widths.at(i) = normalize-units(elmt.width) | ||||||
|       } |       } | ||||||
|       widths.at(i) = calc.max( |  | ||||||
|         widths.at(i), |       let width = widths.at(i) | ||||||
|         normalize-units(elmt.min-width) |       width = calc.max(width, normalize-units(elmt.min-width)) | ||||||
|       ) + normalize-units(elmt.margin) |       if elmt.max-width != none { | ||||||
|  |         width = calc.min(width, normalize-units(elmt.max-width)) | ||||||
|  |       } | ||||||
|  |       widths.at(i) = width + normalize-units(elmt.margin) | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| #import "@preview/cetz:0.2.2": draw | #import "@preview/cetz:0.3.1": draw | ||||||
| #import "consts.typ": * | #import "consts.typ": * | ||||||
|  |  | ||||||
| #let _sep(name) = { | #let _sep(name) = { | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| #import "@preview/cetz:0.2.2": draw, vector | #import "@preview/cetz:0.3.1": draw, vector | ||||||
| #import "consts.typ": * | #import "consts.typ": * | ||||||
| #import "participant.typ" | #import "participant.typ" | ||||||
| #import "note.typ" | #import "note.typ" | ||||||
| @@ -100,19 +100,27 @@ | |||||||
|  |  | ||||||
|   y -= Y-SPACE |   y -= Y-SPACE | ||||||
|  |  | ||||||
|  |   let i1 = pars-i.at(elmt.p1) | ||||||
|  |   let i2 = pars-i.at(elmt.p2) | ||||||
|  |   let width = calc.abs(x-pos.at(i1) - x-pos.at(i2)) | ||||||
|  |  | ||||||
|   let h = 0 |   let h = 0 | ||||||
|  |   let comment = if elmt.comment == none {none} else { | ||||||
|  |     let w = calc.min(width * 1pt, measure(elmt.comment).width) | ||||||
|  |     box( | ||||||
|  |       width: if i1 == i2 {auto} else {w}, | ||||||
|  |       elmt.comment | ||||||
|  |     ) | ||||||
|  |   } | ||||||
|   // Reserve space for comment |   // Reserve space for comment | ||||||
|   if elmt.comment != none { |   if comment != none { | ||||||
|     h = calc.max(h, measure(box(elmt.comment)).height / 1pt + 6) |     h = calc.max(h, measure(comment).height / 1pt + 6) | ||||||
|   } |   } | ||||||
|   if "linked-note" in elmt { |   if "linked-note" in elmt { | ||||||
|     h = calc.max(h, note.get-size(elmt.linked-note).height / 2) |     h = calc.max(h, note.get-size(elmt.linked-note).height / 2) | ||||||
|   } |   } | ||||||
|   y -= h |   y -= h | ||||||
|  |  | ||||||
|   let i1 = pars-i.at(elmt.p1) |  | ||||||
|   let i2 = pars-i.at(elmt.p2) |  | ||||||
|  |  | ||||||
|   let start-info = ( |   let start-info = ( | ||||||
|     i: i1, |     i: i1, | ||||||
|     x: x-pos.at(i1), |     x: x-pos.at(i1), | ||||||
| @@ -169,7 +177,7 @@ | |||||||
|     let m = measure(box(par.display-name)) |     let m = measure(box(par.display-name)) | ||||||
|     let f = if i1 > i2 {-1} else {1} |     let f = if i1 > i2 {-1} else {1} | ||||||
|     end-info.x -= (m.width + PAR-PAD.last() * 2) / 2pt * f |     end-info.x -= (m.width + PAR-PAD.last() * 2) / 2pt * f | ||||||
|     shapes += participant.render(x-pos, par, y: end-info.y - CREATE-OFFSET) |     shapes += participant.render(x-pos, par, y: end-info.y) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   end-info.ll-lvl = lifelines.at(i2).level * LIFELINE-W / 2 |   end-info.ll-lvl = lifelines.at(i2).level * LIFELINE-W / 2 | ||||||
| @@ -244,7 +252,7 @@ | |||||||
|       (x2, end-info.y) |       (x2, end-info.y) | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|     if elmt.comment != none { |     if comment != none { | ||||||
|       comment-anchor = ( |       comment-anchor = ( | ||||||
|         start: if x-mid < x1 {"south-east"} else {"south-west"}, |         start: if x-mid < x1 {"south-east"} else {"south-west"}, | ||||||
|         end: if x-mid < x1 {"south-west"} else {"south-east"}, |         end: if x-mid < x1 {"south-west"} else {"south-east"}, | ||||||
| @@ -268,7 +276,7 @@ | |||||||
|       (x2, end-info.y) |       (x2, end-info.y) | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|     if elmt.comment != none { |     if comment != none { | ||||||
|       let start-pt = pts.first() |       let start-pt = pts.first() | ||||||
|       let end-pt = pts.last() |       let end-pt = pts.last() | ||||||
|       if elmt.start-tip != "" { |       if elmt.start-tip != "" { | ||||||
| @@ -348,27 +356,26 @@ | |||||||
|  |  | ||||||
|   shapes += draw.line(..pts, ..style) |   shapes += draw.line(..pts, ..style) | ||||||
|  |  | ||||||
|   if elmt.comment != none { |   if comment != none { | ||||||
|     shapes += draw.content( |     shapes += draw.content( | ||||||
|       comment-pt, |       comment-pt, | ||||||
|       elmt.comment, |       comment, | ||||||
|       anchor: comment-anchor, |       anchor: comment-anchor, | ||||||
|       angle: comment-angle, |       angle: comment-angle, | ||||||
|       padding: 3pt |       padding: 3pt | ||||||
|     ) |     ) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   if elmt.create-dst { | ||||||
|  |     let dst-line = lifelines.at(i2) | ||||||
|  |     dst-line.lines.push(("create", end-info.y)) | ||||||
|  |     lifelines.at(i2) = dst-line | ||||||
|  |   } | ||||||
|   if elmt.enable-dst { |   if elmt.enable-dst { | ||||||
|     let dst-line = lifelines.at(i2) |     let dst-line = lifelines.at(i2) | ||||||
|     dst-line.lines.push(("enable", end-info.y, elmt.lifeline-style)) |     dst-line.lines.push(("enable", end-info.y, elmt.lifeline-style)) | ||||||
|     lifelines.at(i2) = dst-line |     lifelines.at(i2) = dst-line | ||||||
|   } |   } | ||||||
|   if elmt.create-dst { |  | ||||||
|     end-info.y -= CREATE-OFFSET |  | ||||||
|     let dst-line = lifelines.at(i2) |  | ||||||
|     dst-line.lines.push(("create", end-info.y)) |  | ||||||
|     lifelines.at(i2) = dst-line |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if "linked-note" in elmt { |   if "linked-note" in elmt { | ||||||
|     let m = note.get-size(elmt.linked-note) |     let m = note.get-size(elmt.linked-note) | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| [package] | [package] | ||||||
| name = "chronos" | name = "chronos" | ||||||
| version = "0.1.1" | version = "0.2.0" | ||||||
| compiler = "0.11.0" | compiler = "0.12.0" | ||||||
| repository = "https://git.kb28.ch/HEL/chronos" | repository = "https://git.kb28.ch/HEL/chronos" | ||||||
| entrypoint = "src/lib.typ" | entrypoint = "src/lib.typ" | ||||||
| authors = [ | authors = [ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user