Skip to content

typst-community/typst-algorithmic

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

42 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

typst-algorithmic

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

screenshot of the typst-algorithmic output, showing line numbers, automatic indentation, bolded keywords, and such

Example:

#import "@preview/algorithmic:1.0.0"
#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$]
  }
)

image of the algorithm with three lines of code assigning x to y, y to x, and z to x + y. The inset is set to 1em, the indent to 0.5em

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): strong is applied to the algorithm's title. Normal text can be used with caption-style: text, or caption-style: c => c.
  • caption-align (alignment): start aligns the title to the start (left for LTR, and right for RTL languages) by default
  • breakable (bool): true controls whether or not the figure will break across pages.
  • hlines (array of 3 content): (table.hline(), table.hline(), table.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: (table.hline(stroke: 2pt + red), table.hline(stroke: 2pt + blue), table.hline(stroke: 2pt + green)),
)

which will result in something like image of the binary search algorithm with a right-aligned and italics figure caption enclosed within a red and blue 2pt table horizontal lines. The algorithm is finally ended with a green 2pt horizontal line.

Control flow

Algorithmic provides basic control flow statements: If, While, For, Else, ElseIf, and a IfElseChain utility.

Statement Description Usage Example
If If(condition: content, ..bits)
If($x < y$, {
  Assign[$x$][$y$]
})
image of an if statement with condition x < y and conditional statement assign y to x
ElseIf ElseIf(condition: content, ..bits)
ElseIf($x > y$, {
  Assign[$y$][$x$]
})
image of an elseif statement with condition x > y and conditional statement assign x to y
Else Else(..bits)
Else({
  Return[$y$]
})
image of an else statement with conditional statement return y
While While(condition: content, ..bits)
While($i < 10$, {
  Assign[$i$][$i + 1$]
})
image of a while statement with condition i < 10 and conditional statement assign i + 1 to i
For For(condition: content, ..bits)
For($i <= 10$, {
  Assign[$x_i$][$i$]
})
image of a for loop with condition i <= 10 and conditional statement assign i to x_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)
)
image of an ifelsechain statement with condition x < y and conditional statement assign y to x, then condition x

Commands

The package provides a few commands: Function, Procedure, Assign, Return, Terminate and Break.

Command Description Usage Example
Function Function(name, args, ..bits)
Function("Add", ($a$, $b$), {
Assign[$a$][$b$]
})
image of a function definition with name 'Add' and arguments 'a' and 'b' with body 'return a+b'
Procedure Procedure(name, args, ..bits)
Procedure("Add", ("a", "b"), {
Assign[$a$][$a+b$]
})
image of a procedure definition with name 'Add' and arguments 'a' and 'b' with body 'assign a+b to a'
Assign Assign(var, value)
Assign[$x$][$y$]
image of an assignment statement assigning y to x
Return Return(value)
Return[$x$]
image of a return statement returning x
Terminate Terminate(value)
Terminate[$x$]
image of a terminate statement terminating x
Break Break()
Break()
image of a break statement

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$])
})

image of a custom call "Solve" given parameters "A" and "b" and a custom function "mean" given parameter "x" in the algorithmic environment. The call "Solve" is rendered in smallcaps and the function "mean" is rendered in a strong emphasis.

Comments

There are three kinds of comments: Comment, CommentInline, and LineComment.

  1. Comment is a block comment that takes up a whole line.
  2. CommentInline is an inline comment that returns content on the same line.
  3. LineComment places a comment on the same line as a line of code to the right.
Comment Description Usage Example
Comment Comment(content)
Comment[This is a comment]
image of a block comment with text 'This is a comment'
CommentInline CommentInline(content)
CommentInline[This is a comment]
image of an inline comment with text 'This is a comment'
LineComment LineComment(line, comment)
LineComment(Assign[a][1], [Initialize $a$ to 1])
image of a line comment with text 'Initialize a to 1'

About

Algorithm pseudocode typesetting library for Typst

Resources

License

Code of conduct

Stars

Watchers

Forks

Packages

No packages published

Contributors 6