This is a package inspired by the LaTeX algorithmicx package
for Typst. It’s useful for writing pseudocode and typesetting it all nicely.

Example:
#import "@preview/algorithmic:1.0.3"
#import algorithmic: style-algorithm, algorithm-figure
#show: style-algorithm
#algorithm-figure(
"Binary Search",
vstroke: .5pt + luma(200),
{
import algorithmic: *
Procedure(
"Binary-Search",
("A", "n", "v"),
{
Comment[Initialize the search range]
Assign[$l$][$1$]
Assign[$r$][$n$]
LineBreak
While(
$l <= r$,
{
Assign([mid], FnInline[floor][$(l + r) / 2$])
IfElseChain(
$A ["mid"] < v$,
{
Assign[$l$][$m + 1$]
},
[$A ["mid"] > v$],
{
Assign[$r$][$m - 1$]
},
Return[$m$],
)
},
)
Return[*null*]
},
)
}
)
This DSL is implemented using the same trick as CeTZ uses: a code block of arrays gets those arrays joined together.
Reference
Documentation
algorithm(inset: 0.2em, indent: 0.5em, vstroke: 0pt + luma(200), ..bits)
This is the main function of the package. It takes a list of arrays and
returns a typesetting of the algorithm. You can modify the inset
between lines with the inset parameter.
#algorithm(
inset: 1em, // more spacing between lines
indent: 0.5em, // indentation for the algorithm
{ // provide an array
import algorithmic: * // import all names in the array
Assign[$x$][$y$]
},
{ // provide another array
import algorithmic: *
Assign[$y$][$x$]
},
{ // provide a third array
import algorithmic: *
Assign[$z$][$x + y$]
}
)

algorithm-figure(title, supplement: "Algorithm", inset: 0.2em, indent: 0.5em, vstroke: 0pt + luma(200), ..bits)
The algorithm-figure function is a wrapper around algorithm that returns a
figure element of the algorithm. It takes the same parameters as
algorithm, but also takes a title and a supplement parameter for the figure.
#let algorithm-figure(title, supplement: "Algorithm", inset: 0.2em, indent: 0.5em, vstroke: 0pt + luma(200), ..bits) = {
return figure(
supplement: supplement,
kind: "algorithm", // the kind of figure
caption: title,
placement: none,
algorithm(inset: inset, ..bits),
)
}
In order to use the algorithm-figure function, you need to style the figure
with the style-algorithm show rule.
#import algorithmic: algorithm-figure, style-algorithm
#show: style-algorithm // Do not forget!
#algorithm-figure("Variable Assignment", {
import algorithmic: *
Assign[$x$][$y$]
})
style-algorithm provides several options to customize the appearance of the algorithm figure:
caption-style (function): strongis applied to the algorithm’s title. Normal text can be used withcaption-style: text, orcaption-style: c => c.caption-align (alignment): startaligns the title to the start (left for LTR, and right for RTL languages) by defaultbreakable (bool): truecontrols whether or not the figure will break across pages.hlines (array of 3 content): (grid.hline(), grid.hline(), grid.hline())provides horizontal lines at the top, middle, and bottom of the algorithm figure.
An example of how to style the algorithm figure:
#show: style-algorithm.with(
breakable: false,
caption-align: end,
caption-style: emph,
hlines: (grid.hline(stroke: 2pt + red), grid.hline(stroke: 2pt + blue), grid.hline(stroke: 2pt + green)),
)
which will result in something like
.
Control flow
Algorithmic provides basic control flow statements: If, While, For,
Else, ElseIf, and a IfElseChain utility.
If
If(condition: content, ..bits)
If($x < y$, {
Assign[$x$][$y$]
})
ElseIf
ElseIf(condition: content, ..bits)
ElseIf($x > y$, {
Assign[$y$][$x$]
})
Else
Else(..bits)
Else({
Return[$y$]
})
While
While(condition: content, ..bits)
While($i < 10$, {
Assign[$i$][$i + 1$]
})
For
For(condition: content, ..bits)
For($i <= 10$, {
Assign[$x_i$][$i$]
})
IfElseChain
IfElseChain(..bits)
IfElseChain( // Alternating content and bits
$x < y$, // If: content 1 (condition)
{ // Then: bits 1
Assign[$x$][$y$]
},
[$x > y$], // ElseIf: content 2 (condition)
{ // Then: bits 2
Assign[$y$][$x$]
},
Return[$y$], // Else: content 3 (no more bits afterwards)
)
Commands
The package provides a few commands: Function, Procedure, Assign,
Return, Terminate and Break.
Function
Function(name, args, ..bits)
Function("Add", ($a$, $b$), {
Assign[$a$][$b$]
})
Procedure
Procedure(name, args, ..bits)
Procedure("Add", ("a", "b"), {
Assign[$a$][$a+b$]
})
Assign
Assign(var, value)
Assign[$x$][$y$]
Return
Return(value)
Return[$x$]
Terminate
Terminate(value)
Terminate[$x$]
Break
Break()
Break()
Users can also define their own commands using both Call(..args) and
Fn(..args) and their inline versions CallInline and FnInline.
#import "../../algorithmic.typ"
#import algorithmic: algorithm
#set page(margin: .1cm, width: 4cm, height: auto)
#algorithm({
import algorithmic: *
let Solve = Call.with("Solve")
let mean = Fn.with("mean")
Assign($x$, Solve[$A$, $b$])
Assign($y$, mean[$x$])
})

Standalone lines and line breaks
You can use Line to create a standalone line and LineBreak to insert a line break.
#algorithm({
import algorithmic: *
Line($1+1$)
LineBreak
})

Comments
There are three kinds of comments: Comment, CommentInline, and LineComment.
Commentis a block comment that takes up a whole line.CommentInlineis an inline comment that returns content on the same line.LineCommentplaces a comment on the same line as a line of code to the right.
Comment
Comment(content)
Comment[This is a comment]
CommentInline
CommentInline(content)
CommentInline[This is a comment]
LineComment
LineComment(line, comment)
LineComment(Assign[a][1], [Initialize $a$ to 1])