diff --git a/docs/features/OxHugo compatibility.md b/docs/features/OxHugo compatibility.md
new file mode 100644
index 000000000..12774e725
--- /dev/null
+++ b/docs/features/OxHugo compatibility.md
@@ -0,0 +1,38 @@
+---
+tags:
+ - plugin/transformer
+---
+
+Quartz is a static-site generator that transforms markdown content into web pages. [org-roam](https://www.orgroam.com/) is a plain-text(`org`) personal knowledge management system for [emacs](https://en.wikipedia.org/wiki/Emacs). [ox-hugo](https://github.com/kaushalmodi/ox-hugo) is org exporter backend that exports `org-mode` files to [Hugo](https://gohugo.io/) compatible markdown.
+
+Because the markdown generated by ox-hugo is not pure markdown but Hugo specific, we need to transform it to fit into Quartz. This is done by `Plugin.OxHugoFlavouredMarkdown`. Even though this [[making plugins|plugin]] was written with `ox-hugo` in mind, it should work for any Hugo specific markdown.
+
+```typescript title="quartz.config.ts"
+plugins: {
+ transformers: [
+ Plugin.FrontMatter({ delims: "+++", language: "toml" }), // if toml frontmatter
+ // ...
+ Plugin.OxHugoFlavouredMarkdown(),
+ Plugin.GitHubFlavoredMarkdown(),
+ // ...
+ ],
+},
+```
+
+## Usage
+
+Quartz by default doesn't understand `org-roam` files as they aren't Markdown. You're responsible for using an external tool like `ox-hugo` to export the `org-roam` files as Markdown content to Quartz and managing the static assets so that they're available in the final output.
+
+## Configuration
+
+- Link resolution
+ - `wikilinks`: Whether to replace `{{ relref }}` with Quartz [[wikilinks]]
+ - `removePredefinedAnchor`: Whether to remove [pre-defined anchor set by ox-hugo](https://ox-hugo.scripter.co/doc/anchors/).
+- Image handling
+ - `replaceFigureWithMdImg`: Whether to replace `` with `![]()`
+- Formatting
+ - `removeHugoShortcode`: Whether to remove hugo shortcode syntax (`{{}}`)
+
+> [!warning]
+>
+> While you can use `Plugin.OxHugoFlavoredMarkdown` and `Plugin.ObsidianFlavoredMarkdown` together, it's not recommended because it might mutate the file in unexpected ways. Use with caution.
diff --git a/quartz/plugins/transformers/frontmatter.ts b/quartz/plugins/transformers/frontmatter.ts
index a7249c19e..571aa04d0 100644
--- a/quartz/plugins/transformers/frontmatter.ts
+++ b/quartz/plugins/transformers/frontmatter.ts
@@ -21,7 +21,7 @@ export const FrontMatter: QuartzTransformerPlugin | undefined>
name: "FrontMatter",
markdownPlugins() {
return [
- remarkFrontmatter,
+ [remarkFrontmatter, ["yaml", "toml"]],
() => {
return (_, file) => {
const { data } = matter(file.value, {
diff --git a/quartz/plugins/transformers/index.ts b/quartz/plugins/transformers/index.ts
index 8013ab7cc..d9f2854c0 100644
--- a/quartz/plugins/transformers/index.ts
+++ b/quartz/plugins/transformers/index.ts
@@ -5,5 +5,6 @@ export { Latex } from "./latex"
export { Description } from "./description"
export { CrawlLinks } from "./links"
export { ObsidianFlavoredMarkdown } from "./ofm"
+export { OxHugoFlavouredMarkdown } from "./oxhugofm"
export { SyntaxHighlighting } from "./syntax"
export { TableOfContents } from "./toc"
diff --git a/quartz/plugins/transformers/oxhugofm.ts b/quartz/plugins/transformers/oxhugofm.ts
new file mode 100644
index 000000000..0d7b9199a
--- /dev/null
+++ b/quartz/plugins/transformers/oxhugofm.ts
@@ -0,0 +1,73 @@
+import { QuartzTransformerPlugin } from "../types"
+
+export interface Options {
+ /** Replace {{ relref }} with quartz wikilinks []() */
+ wikilinks: boolean
+ /** Remove pre-defined anchor (see https://ox-hugo.scripter.co/doc/anchors/) */
+ removePredefinedAnchor: boolean
+ /** Remove hugo shortcode syntax */
+ removeHugoShortcode: boolean
+ /** Replace with ![]() */
+ replaceFigureWithMdImg: boolean
+}
+
+const defaultOptions: Options = {
+ wikilinks: true,
+ removePredefinedAnchor: true,
+ removeHugoShortcode: true,
+ replaceFigureWithMdImg: true,
+}
+
+const relrefRegex = new RegExp(/\[([^\]]+)\]\(\{\{< relref "([^"]+)" >\}\}\)/, "g")
+const predefinedHeadingIdRegex = new RegExp(/(.*) {#(?:.*)}/, "g")
+const hugoShortcodeRegex = new RegExp(/{{(.*)}}/, "g")
+const figureTagRegex = new RegExp(/< ?figure src="(.*)" ?>/, "g")
+
+/**
+ * ox-hugo is an org exporter backend that exports org files to hugo-compatible
+ * markdown in an opinionated way. This plugin adds some tweaks to the generated
+ * markdown to make it compatible with quartz but the list of changes applied it
+ * is not exhaustive.
+ * */
+export const OxHugoFlavouredMarkdown: QuartzTransformerPlugin | undefined> = (
+ userOpts,
+) => {
+ const opts = { ...defaultOptions, ...userOpts }
+ return {
+ name: "OxHugoFlavouredMarkdown",
+ textTransform(_ctx, src) {
+ if (opts.wikilinks) {
+ src = src.toString()
+ src = src.replaceAll(relrefRegex, (value, ...capture) => {
+ const [text, link] = capture
+ return `[${text}](${link})`
+ })
+ }
+
+ if (opts.removePredefinedAnchor) {
+ src = src.toString()
+ src = src.replaceAll(predefinedHeadingIdRegex, (value, ...capture) => {
+ const [headingText] = capture
+ return headingText
+ })
+ }
+
+ if (opts.removeHugoShortcode) {
+ src = src.toString()
+ src = src.replaceAll(hugoShortcodeRegex, (value, ...capture) => {
+ const [scContent] = capture
+ return scContent
+ })
+ }
+
+ if (opts.replaceFigureWithMdImg) {
+ src = src.toString()
+ src = src.replaceAll(figureTagRegex, (value, ...capture) => {
+ const [src] = capture
+ return `![](${src})`
+ })
+ }
+ return src
+ },
+ }
+}