A Typst package for creating horizontal columned lists, similar to LaTeX’s tasks package. Perfect for exercises, multiple-choice questions, and any content that benefits from a compact columned layout.
Gallery
Click on an image to see the source code.
| Basic Tasks | Math Exercises | Custom Labels | Styled Layout |
| Vertical Flow | Column Spanning | Bold Labels | Resume Numbering |
| Adaptive Row Heights |
Features
- Indentation-independent parsing - Output is completely independent of source code indentation
- Horizontal flow layout - Items flow left-to-right across columns (like LaTeX’s tasks)
- Flexible column counts - 2, 3, 4 or any number of columns
- Auto-fit columns - Use the largest column count that does not introduce a new wrap or overflow
- Column spanning - Items can span multiple columns using
(N)syntax - Multiple label formats - Alphabetic (
a),A)), numeric (1),(1)), roman (i),I)), bullets, or custom - Bold labels - Make labels stand out with bold weight
- Resume numbering - Continue numbering across multiple task blocks
- Two flow directions - Horizontal (a b | c d) or vertical (a c | b d)
- Global configuration - Set defaults for all tasks in your document
- Shorthand functions -
tasks2,tasks3,tasks4for quick column setup - Spacing & alignment controls - Fine-grained gutters, label alignment, baselines, and block spacing
Manual
A full manual is available as a PDF, with a Typst source version in docs/manual.typ.
Quick Start
#import "@preview/taskize:0.2.7": tasks
#tasks[
+ First item
+ Second item
+ Third item
+ Fourth item
]
Basic Usage
Simple Two-Column Layout
#import "@preview/taskize:0.2.7": tasks
#tasks[
+ $2 + 3 = ?$
+ $5 - 2 = ?$
+ $4 times 3 = ?$
+ $8 div 2 = ?$
]
Three-Column Layout
#import "@preview/taskize:0.2.7": tasks
#tasks(columns: 3)[
+ Option A
+ Option B
+ Option C
+ Option D
+ Option E
+ Option F
]
Auto-Fit Columns
Use columns: "auto-fit" to choose the largest column count that does not make any item wrap or overflow compared with a one-column layout. Limit the search with max-columns.
#import "@preview/taskize:0.2.7": tasks
#tasks(columns: "auto-fit", max-columns: 4)[
+ Medium length task with detail
+ Short
+ Short
+ Short
]
By default, auto-fit uses auto-fit-mode: "fill": an item too wide for one
column automatically spans the minimum number of columns it needs — no
explicit +(N) required — so wide items share rows with densely packed short
items. Use auto-fit-mode: "uniform" when every item must fit one ordinary
column; in that mode, the column count is the largest value where no item
wraps at one-column width, so a wide item can force the whole block to fewer
columns. If an item already wraps in the one-column layout, auto-fit keeps
one column, because no no-wrap multi-column layout exists.
Shorthand Functions
#import "@preview/taskize:0.2.7": tasks2, tasks3, tasks4
// Two columns
#tasks2[
+ Item 1
+ Item 2
]
// Three columns
#tasks3[
+ Item 1
+ Item 2
+ Item 3
]
// Four columns
#tasks4[
+ A
+ B
+ C
+ D
]
Label Formats
Built-in Formats
#import "@preview/taskize:0.2.7": tasks
// Lowercase letters with parenthesis (default)
#tasks(label: "a)")[+ One + Two + Three]
// Uppercase letters
#tasks(label: "A)")[+ One + Two + Three]
// Numbers with parenthesis
#tasks(label: "1)")[+ One + Two + Three]
// Numbers in parentheses
#tasks(label: "(1)")[+ One + Two + Three]
// Lowercase roman numerals
#tasks(label: "i)")[+ One + Two + Three]
// Uppercase roman numerals
#tasks(label: "I)")[+ One + Two + Three]
// Bullet points
#tasks(label: "*")[+ One + Two + Three]
// Dashes
#tasks(label: "-")[+ One + Two + Three]
// No labels
#tasks(label: none)[+ One + Two + Three]
Custom Label Function
#import "@preview/taskize:0.2.7": tasks
// Custom emoji labels
#tasks(label: n => "Q" + str(n) + ":")[
+ What is 2+2?
+ What is the capital of France?
+ What color is the sky?
]
Flow Direction
Horizontal Flow (Default)
Items fill rows first: a b | c d | e f
#import "@preview/taskize:0.2.7": tasks
#tasks(columns: 2, flow: "horizontal")[
+ a
+ b
+ c
+ d
+ e
+ f
]
// Layout:
// a) b)
// c) d)
// e) f)
Vertical Flow
Items fill columns first: a c e | b d f
#import "@preview/taskize:0.2.7": tasks
#tasks(columns: 2, flow: "vertical")[
+ a
+ b
+ c
+ d
+ e
+ f
]
// Layout:
// a) d)
// b) e)
// c) f)
Resuming Numbering
#import "@preview/taskize:0.2.7": tasks, tasks-reset
#tasks[
+ First
+ Second
+ Third
]
Some text between task blocks...
// Continue numbering from where we left off
#tasks(resume: true)[
+ Fourth
+ Fifth
+ Sixth
]
// Reset counter to start fresh
#tasks-reset()
#tasks[
+ Back to one
+ Two again
]
Starting from a Specific Number
#import "@preview/taskize:0.2.7": tasks
#tasks(start: 5)[
+ This is item 5
+ This is item 6
+ This is item 7
]
Global Configuration
Set defaults for all tasks in your document:
#import "@preview/taskize:0.2.7": tasks, tasks-setup
// Configure global defaults
#tasks-setup(
columns: 3,
label-format: "1)",
column-gutter: 1.5em,
row-gutter: 0.8em,
)
// All subsequent tasks use these defaults
#tasks[
+ Item 1
+ Item 2
+ Item 3
]
// Override specific settings per-call
#tasks(columns: 2, label: "a)")[
+ Override A
+ Override B
]
Advanced Features
Label Baseline Alignment
Control the vertical alignment of labels relative to content:
#import "@preview/taskize:0.2.7": tasks
// Center alignment (default)
#tasks(label-baseline: "center")[
+ Short item
+ Multi-line item\
with more text
]
// Top alignment
#tasks(label-baseline: "top")[
+ Item aligned at top
+ Another item
]
// Bottom alignment
#tasks(label-baseline: "bottom")[
+ Item aligned at bottom
+ Another item
]
Bold Labels
Make labels stand out by using bold weight:
#import "@preview/taskize:0.2.7": tasks
// Bold labels for emphasis
#tasks(label-weight: "bold")[
+ Important task
+ Critical item
+ Key point
]
// Regular labels (default)
#tasks(label-weight: "regular")[
+ Normal item
+ Standard task
]
Column Spanning
Items can span multiple columns using the +() or +(N) syntax (no space after +). This is similar to LaTeX’s \task* command:
#import "@preview/taskize:0.2.7": tasks
#tasks(columns: 3)[
+ Short
+ Short
+ Short
+(2) This item spans 2 columns
+ Short
+() This item spans all columns (full width)
+ Normal
+ Normal
]
// Practical example: Multiple choice with explanation
#tasks(columns: 2, label: "A)")[
+ Paris
+ London
+ Berlin
+ Madrid
+() The capital of France is Paris, known for the Eiffel Tower.
]
Syntax:
+ Content- Normal item (spans 1 column)+(2) Content- Spans 2 columns (no space after +)+(3) Content- Spans 3 columns+() Content- Spans all columns (full width)
Notes:
- Important: No space between
+and()or(N) - If an item with span doesn’t fit in the current row, it wraps to the next row
- Column spans are clamped to the total number of columns
- Great for adding explanations, headings, or long content within lists
Parameters Reference
tasks Function
| Parameter | Type | Default | Description |
|---|---|---|---|
columns |
int/string | 2 | Number of columns, or "auto-fit" to choose the largest no-wrap count |
label |
string/function | "a)" |
Label format (shorthand for label-format) |
label-format |
string/function | "a)" |
Label format |
start |
int | 1 | Starting number for labels |
resume |
bool | false | Continue numbering from previous block |
column-gutter |
length | 1em | Space between columns |
row-gutter |
length/string | 0.6em | Space between rows. "auto" (or "adaptive") sizes rows to the true ink of their content so tall inline math (display fractions, matrices) no longer bleeds into the gutter |
max-columns |
int/auto | auto | Maximum column count tested by columns: "auto-fit"; auto means up to the number of items |
auto-fit-mode |
string | "fill" |
"fill" measures spans at their rendered width; "uniform" requires every item to fit one ordinary column |
auto-fit-tolerance |
length | 0.5pt | Measurement tolerance for auto-fit wrap detection |
label-width |
auto/length | auto | Width reserved for labels |
label-align |
alignment | right | Label alignment |
label-baseline |
string/length | "center" |
Label vertical alignment: "center", "top", "bottom", or length |
label-weight |
string | "regular" |
Label font weight: "regular" or "bold" |
indent-after-label |
length | 0.4em | Space between label and content |
indent |
length | 0pt | Left indentation of entire block |
above |
length | 0.5em | Space before block |
below |
length | 0.5em | Space after block |
flow |
string | "horizontal" |
Flow direction: "horizontal" or "vertical" |
Label Format Options
| Format | Example | Description |
|---|---|---|
"a)" |
a) b) c) | Lowercase letters with closing paren |
"a." |
a. b. c. | Lowercase letters with period |
"(a)" |
(a) (b) © | Lowercase letters in parentheses |
"A)" |
A) B) C) | Uppercase letters with closing paren |
"A." |
A. B. C. | Uppercase letters with period |
"1)" |
1) 2) 3) | Numbers with closing paren |
"1." |
1. 2. 3. | Numbers with period |
"(1)" |
(1) (2) (3) | Numbers in parentheses |
"i)" |
i) ii) iii) | Lowercase roman numerals |
"I)" |
I) II) III) | Uppercase roman numerals |
"*" |
bullet | Bullet points |
"-" |
dash | En-dashes |
none |
(none) | No labels |
| function | custom | Custom function n => content |
Examples
Math Exercise Sheet
#import "@preview/taskize:0.2.7": tasks
= Algebra Practice
Simplify the following expressions:
#tasks(columns: 2)[
+ $x^2 + 2x + 1$
+ $(a + b)^2$
+ $3x - 5 + 2x + 8$
+ $frac(x^2 - 4, x - 2)$
]
Solve for $x$:
#tasks(columns: 2, label: "1)")[
+ $2x + 5 = 13$
+ $x^2 = 16$
+ $3(x - 2) = 15$
+ $frac(x, 4) = 7$
]
Multiple Choice Questions
#import "@preview/taskize:0.2.7": tasks
*Question 1:* What is the capital of France?
#tasks(columns: 2, label: "A)")[
+ London
+ Paris
+ Berlin
+ Madrid
]
*Question 2:* Which planet is closest to the Sun?
#tasks(columns: 2, label: "A)")[
+ Venus
+ Mercury
+ Mars
+ Earth
]
Vocabulary List
#import "@preview/taskize:0.2.7": tasks
= French Vocabulary
#tasks(columns: 3, label: none)[
+ *bonjour* - hello
+ *merci* - thank you
+ *oui* - yes
+ *non* - no
+ *s'il vous plait* - please
+ *au revoir* - goodbye
]
When to Use taskize
taskize is specifically designed for horizontal columned layouts where items flow left-to-right across multiple columns, perfect for exercises, multiple-choice questions, and compact lists. Choose taskize when you need:
- Horizontal flow layout - Items arranged in rows across columns (a b | c d | e f)
- Compact exercise sheets - Mathematical exercises, vocabulary lists, multiple-choice questions
- Flexible column control - Easy 2, 3, 4+ column layouts with shorthand functions
- Resume numbering - Continue numbering across multiple task blocks
- LaTeX tasks compatibility - Familiar syntax for users migrating from LaTeX’s tasks package
Comparison with itemize
itemize is an excellent, feature-rich package for vertical list styling with advanced customization capabilities. Use itemize when you need:
- Vertical lists with advanced styling (colors, custom markers, spacing)
- Nested lists with sophisticated formatting
- Rich marker customization (emojis, custom content, per-item markers)
- Advanced typography control over list appearance
- Complex list hierarchies with fine-grained control
In summary: Use taskize for horizontal multi-column layouts (exercises, quizzes, compact lists), and use itemize for feature-rich vertical lists with advanced styling. They complement each other well for different layout needs.
License
MIT License - see LICENSE file for details.
Changelog
All notable changes to taskize are documented here.
[0.2.7] - 2026-07-13
Added
- Auto-fit columns -
columns: "auto-fit"selects the largest column count, bounded bymax-columns(default: up to the number of items), that does not introduce a new item wrap or fixed-size content overflow. Useful for exercises mixing short choices, longer text, math, spans, and small figures. - Auto-spanning in fill mode - with
auto-fit-mode: "fill"(default), a regular+item too wide for one column automatically spans the minimum number of columns it needs — no explicit+(N)required — so wide items share rows with densely packed short items.auto-fit-mode: "uniform"instead requires every item to fit one ordinary column and falls back to fewer columns when the widest item no longer fits. - Adaptive row heights -
row-gutter: "auto"(or"adaptive") sizes rows to the true ink of their content, so tall inline math (display fractions, matrices) no longer bleeds into the row-gutter and the configured numeric gutter becomes the real visual gap. Rows with ordinary content keep exactly the same spacing as before. Can be set document-wide withtasks-setup(row-gutter: "adaptive").
[0.2.6] - 2026-07-02
Added
- True baseline alignment — with
label-baseline: "center"(default), inline content (text, inline math, symbols) now shares the same paragraph line as the label via hanging-indent layout, so fractions and tall inline elements align their baselines with the label instead of sitting above it
Fixed
compilerminimum lowered from0.14.2to0.14.0— patch releases add no new language features, so users on0.14.0/0.14.1were incorrectly excluded
[0.2.5] - 2026-01-27
Added
- Full manual (
docs/manual.typ+docs/manual.pdf) with structured examples - Expanded gallery with styled configuration and resume numbering examples
Fixed
- Indentation-independent parsing - Tasks now render identically regardless of source code indentation
- All
+items at any indentation level in the sametasks[]block are automatically flattened to the same level - Inconsistent indentation no longer creates nested enums with different numbering
- Moving one character in the source no longer breaks the layout
- All
- Column spanning support - Fixed
+(2)and+()syntax to work correctly with the new parser- Handles both
enum.itemnodes and text nodes starting with “+”
- Handles both
- Multiline tasks now capture unindented continuation lines as part of the previous item
Changed
- Internal parser completely rewritten to recursively extract and flatten all enum items
- Parent items with nested enums (from indentation) have enum nodes stripped from their content
- README gallery layout refreshed and feature list expanded
- Documentation updated for the new manual and examples
[0.2.0] - 2026-01-15
Fixed
- Indentation-independent parsing - Tasks now render identically regardless of source code indentation
- All
+items at any indentation level in the sametasks[]block are automatically flattened to the same level - Inconsistent indentation no longer creates nested enums with different numbering
- Moving one character in the source no longer breaks the layout
- All
- Column spanning support - Fixed
+(2)and+()syntax to work correctly with the new parser- Handles both
enum.itemnodes and text nodes starting with “+”
- Handles both
Changed
- Internal parser completely rewritten to recursively extract and flatten all enum items
- Parent items with nested enums (from indentation) have enum nodes stripped from their content
Added
- Column spanning - Items can span multiple columns using
(N)syntax (e.g.,+ (2) Contentor+ () Full width) label-baselineparameter for controlling vertical alignment of labels ("center","top","bottom", or custom length)label-weightparameter for bold labels ("regular"or"bold")- Advanced Features section in documentation with examples
- Gallery examples for column spanning and bold labels
Changed
- Repository URL updated to GitLab:
https://gitlab.com/nathan-ed/typst-package-taskize - Description enhanced to mention “Horizontal and vertical” flow directions
[0.1.0] - 2026-01-14
Added
- Initial release with horizontal columned list layout
- Flexible column counts (2, 3, 4, or custom)
- Multiple label formats (alphabetic, numeric, roman, bullets, custom)
- Resume numbering across multiple task blocks
- Two flow directions: horizontal (a b | c d) and vertical (a c | b d)
- Global configuration system with
tasks-setup() - Shorthand functions
tasks2,tasks3,tasks4 - Comprehensive parameter customization
- Full documentation with examples and parameter reference