nassi is a package for Typst to draw Nassi-Shneiderman diagrams (Struktogramme).
Usage
Import nassi in your document:
#import "@preview/nassi:0.1.1"
There are several options to draw diagrams. One is to parse all code-blocks with the language “nassi”. Simply add a show-rule like this:
#import "@preview/nassi:0.1.1"
#show: nassi.shneiderman()
```nassi
function ggt(a, b)
while a > 0 and b > 0
if a > b
a <- a - b
else
b <- b - a
endif
endwhile
if b == 0
return a
else
return b
endif
endfunction
```
In this case, the diagram is created from a simple pseudocode. To have more control over the output, you can add blocks manually using the element functions provided in nassi.elements
:
#import "@preview/nassi:0.1.1"
#nassi.diagram({
import nassi.elements: *
function("ggt(a, b)", {
loop("a > b and b > 0", {
branch("a > b", {
assign("a", "a - b")
}, {
assign("b", "b - a",
fill: gradient.linear(..color.map.rainbow),
stroke:red + 2pt
)
})
})
branch("b == 0", { process("return a") }, { process("return b") })
})
})
Since nassi uses cetz for drawing, you can add diagrams directly to a canvas. Each block gets a name within the diagram group to reference it in the drawing:
#import "@preview/cetz:0.2.2"
#import "@preview/nassi:0.1.1"
#cetz.canvas({
import nassi.draw: diagram
import nassi.elements: *
import cetz.draw: *
diagram((4,4), {
function("ggt(a, b)", {
loop("a > b and b > 0", {
branch("a > b", {
assign("a", "a - b")
}, {
assign("b", "b - a")
})
})
branch("b == 0", { process("return a") }, { process("return b") })
})
})
for i in range(8) {
content(
"nassi.e" + str(i+1) + ".north-west",
stroke:red,
fill:red.transparentize(50%),
frame:"circle",
padding:.05,
anchor:"north-west",
text(white, weight:"bold", "e"+str(i)),
)
}
})
This can be useful to annotate a diagram:
See assets/
for usage examples.
Changelog
Version 0.1.1
- Fixed labels option not working for branches in other elements.
- Added
switch
statements (thanks to @Geronymos).
Version 0.1.0
Initial release of nassi.