This release marks one of Quarkdown's most significant milestones towards becoming a mature, community-driven project!
Added
Packages & package manager
This release comes with Quarkdown's long-awaited package manager! You can browse the available packages in the new catalog.
A package, called atom, can be easily included into your document the same way you .include any other local Quarkdown file, with the special syntax @scope/name:version.
The officially maintained scope, @atoms, is a GitHub-hosted repository anyone can contribute to.
.include {@atoms/cowsay:1.0.0}
.cowsay {Hello, Quarkdown!}We can't wait to see your creations!
Project templates from packages
quarkdown create can now scaffold a project from a template package, via the new --template option:
quarkdown create --template @atoms/simple-cv:1.0.0
Linux-ARM support
Quarkdown now runs on Linux-aarch64!
Thanks @maximilianbarg!
Styling options on .row, .column and .grid
Stack functions now accept the same styling options as .container, such as background, foreground, border, padding, radius and the font options, along with width and height, without relying on container wrapping.
.row gap:{1cm} width:{12cm} background:{teal} foreground:{white} padding:{12px} radius:{8px}
A
B
Scoped page formatting in slides
The pages and side parameters of .pageformat, previously available only in paged documents, now also work in slides documents. A scoped format applies its properties to the selected slides only.
.pageformat pages:{2..3} background:{navy} alignment:{start}
Page content padding
.pageformat accepts a new padding parameter, which adds blank space inside the content area of each page, between its borders and the content.
.pageformat padding:{1cm} bordercolor:{red}
Color building and derivation
The new .color function builds a color from its red, green, blue and alpha components, each optional, and a base color:
.var {brand} {red}
.container background:{.brand::color alpha:{0.25}}
New boolean operations: and and or
The new and and or functions combine two boolean values, complementing the existing not.
.if {.x::islower than:{10}::and {.x::isgreater than:{0}}}
x is between 0 and 10
New collection operation: contains
The new contains function checks whether a string contains some text, a collection contains an element, or a dictionary contains a key.
.var {letters}
- A
- B
.if {.letters::contains {B}}
B is in the list
New collection operation: withindices
The new withindices function turns a collection into a dictionary that maps each element's position, starting at 1, to the element itself.
This makes numbered iteration straightforward.
.var {letters}
- A
- B
.letters::withindices::foreach
index letter:
.index .letterOutput:
1 A
2 B
New collection operations: findfirst and findall
The new findfirst function returns the first element of a collection that satisfies a condition, or none if there is no such element.
findall returns all of them as a new collection instead, like a filter.
.var {numbers}
- 3
- 8
- 12
.numbers::findfirst {n: .n::isgreater than:{5}}Output:
8
New loop: join
The new join function merges the elements of a collection into a single inline content, separated by , or by a custom separator.
.var {letters}
- A
- B
- C
.letters::joinOutput: A, B, C
Like foreach, it also accepts a body that transforms each element before joining.
.letters::withindices::join
index letter:
.index **.letter**Output: 1 A, 2 B, 3 C
New string operation: split
The new split function breaks a string into a collection of its parts, delimited by , or by a custom separator.
.var {date} {2026-10-24}
.date::split separator:{-}::firstOutput:
2026
New factory functions: emptycollection and emptydictionary
The new emptycollection and emptydictionary functions create an empty collection and an empty dictionary, respectively.
.emptycollection::sizeOutput:
0
Changed
Pure black text in printed paperwhite documents
The paperwhite color theme now uses pure black as its main text color in paged documents and when printing, for a crisper result on paper. On screen, other document types keep the softer black.
Sidebar stays hidden while selecting text
In the HTML view of plain and paged documents, dragging the mouse to select text across the right edge of the page no longer expands the navigation sidebar.
Fixed
Missing lines at page breaks
In paged documents, a page could lose its last lines when either:
- the last line of a page ended with a word hyphenated by the browser
- a footnote needed more room at the bottom of its page than Quarkdown had reserved for it
Page breaks no longer split words, footnotes are measured correctly, and long links in footnotes now wrap.
Custom fonts in slides
In slides documents, fonts set via .font were ignored when the layout theme defined its own fonts.
CSS styles on Android
Injecting !important into CSS rules used to raise syntax errors on Android's ICU-based Pattern.
Thanks @YoannDev90!
Stack traces when the export port is taken
When the port used to serve the document during PDF export was already in use, Quarkdown already moved on to the next free port, but printed a java.net.BindException stack trace for every occupied port it went through. The scan is now quiet on info and higher log levels.
Iterating a dictionary stored in a variable
Fixed an issue that caused a dictionary assigned to a variable, such as .var {x} {.data::dictionary}, to be rejected by functions that accept a collection, like .withindices or .foreach.
Sponsors
Thanks to our sponsors! 🎉
