🎄 This release focuses on Quarkdown as a reliable static site generator. The HTML output is now ready to be deployed straight out of the compiler, with enhanced SEO, polished responsiveness, and better support for multi-page (subdocuments) projects.
Check out iamgio.eu, my new personal website, for an example of a website fully powered by Quarkdown, with even a blog!
The sources are available here, and its deployment on GitHub Pages uses the brand-new Quarkdown GitHub Action.
Main features and changes
Enhanced metadata
Quarkdown now takes better care of HTML metadata for an improved SEO, to let your websites rank higher in search engines.
Additionally, new metadata functions are introduced: .docdescription and .dockeywords.
.docname {Quarkdown}
.docdescription {A Markdown-based typesetting system}
.dockeywords
- markdown
- typesetting
- papers
Improved viewport for plain documents
Plain documents are now more beautifully responsive than ever, for portable websites.
- On small (mobile) screens, the navigation sidebar is hidden, spacing is refined, font size is slightly increased, and footnotes appear at the bottom.
- On very large screens, the maximum width of the content area is capped to improve readability.
Scoped page margins
When used in paged and slides documents, the .pagemargin function now takes effect only from the page where it's declared onward. This allows for different page margin settings in different parts of the document.
If you used to call the function at the start of the document to set global margins, this behavior is unchanged.
.pagemargin {topcenter}
On all pages
# First page
# Second page
.pagemargin {topleft}
From second page
# Third page
Thanks @sanoakr!
Page number resets
The new .resetpagenumber {from?} function allows overwriting the current page number at any point in a paged or slides document.
These changes are reflected in .currentpage and page numbers in the table of contents.
.pagemargin {topcenter}
.currentpage
# First page
# Second page
.resetpagenumber from:{20}
# Third page
Thanks @sanoakr!
Page numbers in slides' table of contents
Along with paged documents, table of contents in slides documents now also shows page numbers for each entry.
List files in a directory
The new .listfiles function returns a collection of the files in a directory on the file system. It's unordered by default, or can be sorted by name or date.
The output can be iterated upon, or supplied to other functions. For example, it's possible to perform automatic bulk inclusions:
.includeall {.listfiles {somedirectory} sortby:{name}}
Subdocument function
A new .subdocument {path} {label?} function has been added as a more flexible alternative to the [Label](path.qd) syntax to register subdocuments to the knowledge graph and link to them.
As opposed to the static link syntax, the function accepts dynamic paths. Thus, it's possible to use .listfiles to automatically link all documents in a directory.
Great for blogs!
.foreach {.listfiles {somedirectory}}
path:
.path::subdocument label:{.path::filename extension:{no}}
The example also shows the new .filename {path} function, which allows retrieving a file name from its path.
Control over .include's sandbox
The main difference between inclusion and subdocuments is how the included document is sandboxed:
by default, .include lets all changes propagate to the parent document, while subdocuments isolate them.
Now, .include accepts an optional sandbox parameter to control this behavior. In ascending order of isolation:
share(default): all changes propagate to the parent document.scope: likeshare, but function and variable declarations do not propagate.subdocument: changes, including metadata and layout options, do not propagate.
Rich content in CSV
mode:{markdown} can now be used in .csv to parse cell content as inline Quarkdown source code. This allows for formatting, rich content, and even function calls inside CSV.
Alphanumeric sorting
String sorting operations performed in the stdlib now prefer alphanumeric comparisons. This applies to .tablesort and .listfiles.
- Before:
abc120<abc30 - Now:
abc120>abc30
This is more natural and correct. .tablesort can now be used for real-world leaderboards!
Changed text replacement for em-dashes
Up to now, a dash (-) surrounded by spaces was replaced by an em-dash (—). Now, it produces an en-dash (–) instead.
To get an em-dash, use two dashes (--), not necessarily surrounded by spaces.
Sidebar now ignores decorative headings
Decorative headings (#! Title) are now ignored in the navigation sidebar.
Document modifications in a subdocument do not affect the parent document
When importing a subdocument, modifications to document metadata, layout, or other properties no longer propagate to the parent document.
This allows, for instance, to call .docname in a subdocument to set its own title, which will be shown in the browser tab when viewing that subdocument.
Unset properties will still fall back to the parent document's values.
Working directory now correctly updates on .include
When including documents from different directories via .include, the working directory is now updated accordingly. This allows relative paths to work as expected inside included documents.
Consider the tree:
main.qd
dir/
| other.qd
| image.png
From main.qd:
.include {dir/other.qd}
Previously, in order to access image.png from other.qd:

Now, with the updated working directory:

Changes to subdocument HTML export
When exporting multi-document projects as HTML:
- Subdocuments are now directories rather than HTML files, for better URLs (
example.com/subdocrather thanexample.com/subdoc.html). - Each subdocument now has its own media storage (
mediasubdirectory), rather than having a shared one for all subdocuments.
What's Changed
- feat(postrenderer): export authors to html metadata by @iamgio in #248
- feat(postrenderer): always set viewport meta by @iamgio in #249
- feat(postrenderer): add document description metadata by @iamgio in #250
- feat(project-creator): add document description by @iamgio in #251
- feat: add .dockeywords metadata function by @iamgio in #252
- feat(project-creator): add keywords metadata by @iamgio in #253
- fix(theme): improve mobile responsiveness of plain doc margins by @iamgio in #255
- feat(stdlib): add
.listfilesby @iamgio in #260 - feat(stdlib): add
.subdocumentby @iamgio in #261 - feat(stdlib): add alphanumeric sorting by @iamgio in #262
- feat!: let
.includechange the working directory by @iamgio in #266 - fix(parser): trim initial spaces from fenced code block by @iamgio in #274
- feat(stdlib): allow parsing inline Markdown in csv by @iamgio in #277
- feat: let subdocuments edit their own document metadata by @iamgio in #278
- feat!: add en-dash text replacement, change em-dash by @iamgio in #279
- feat: Page number reset support with TOC integration by @sanoakr in #280
- feat: Scoped page margins with reset support by @sanoakr in #281
- feat: change subdocument HTML generation by @iamgio in #282
- feat(stdlib): add
sandboxparameter to.includeby @iamgio in #283
Full Changelog: v1.12.1...v1.13.0
Sponsors
Shout out to our sponsors! 🎉