{"id":46685120,"url":"https://github.com/mcanouil/quarto-typst-render","last_synced_at":"2026-05-11T15:19:15.857Z","repository":{"id":343107160,"uuid":"1176030905","full_name":"mcanouil/quarto-typst-render","owner":"mcanouil","description":"Quarto extension to compile Typst code blocks to images (PNG, SVG, PDF) for use across all output formats.","archived":false,"fork":false,"pushed_at":"2026-03-11T22:18:31.000Z","size":150,"stargazers_count":9,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-12T03:16:08.475Z","etag":null,"topics":["experimental","quarto","quarto-extension","quarto-filter","quarto-pub","quartopub","typst","typst-render"],"latest_commit_sha":null,"homepage":"https://m.canouil.dev/quarto-typst-render/","language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mcanouil.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":"CITATION.cff","codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"mcanouil","patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"lfx_crowdfunding":null,"custom":null}},"created_at":"2026-03-08T14:22:30.000Z","updated_at":"2026-03-11T22:16:04.000Z","dependencies_parsed_at":"2026-03-13T01:00:34.243Z","dependency_job_id":null,"html_url":"https://github.com/mcanouil/quarto-typst-render","commit_stats":null,"previous_names":["mcanouil/quarto-typst-render"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/mcanouil/quarto-typst-render","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcanouil%2Fquarto-typst-render","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcanouil%2Fquarto-typst-render/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcanouil%2Fquarto-typst-render/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcanouil%2Fquarto-typst-render/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mcanouil","download_url":"https://codeload.github.com/mcanouil/quarto-typst-render/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcanouil%2Fquarto-typst-render/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30452878,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-12T21:31:01.033Z","status":"ssl_error","status_checked_at":"2026-03-12T21:30:43.161Z","response_time":114,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["experimental","quarto","quarto-extension","quarto-filter","quarto-pub","quartopub","typst","typst-render"],"created_at":"2026-03-09T01:11:36.112Z","updated_at":"2026-05-11T15:19:15.851Z","avatar_url":"https://github.com/mcanouil.png","language":"Lua","funding_links":["https://github.com/sponsors/mcanouil"],"categories":[],"sub_categories":[],"readme":"# Typst Render Extension For Quarto\n\nA Quarto filter extension that compiles ` ```{typst} ` code blocks and inline `` `{typst} ...` `` expressions to images (PNG, SVG, or PDF) using the Typst binary bundled with Quarto.\nThis makes Typst diagrams, figures, tables, and equations usable across all output formats (HTML, PDF via LaTeX, DOCX, RevealJS, and more).\n\nBy default, blocks are compiled to images for all output formats, including Typst.\nUse `output: asis` for native passthrough when the output format is Typst.\n\n## Installation\n\n```bash\nquarto add mcanouil/quarto-typst-render@0.12.2\n```\n\nThis will install the extension under the `_extensions` subdirectory.\n\nIf you are using version control, you will want to check in this directory.\n\n## Usage\n\nTo use the extension, add the following to your document's front matter:\n\n```yaml\nfilters:\n  - typst-render\n```\n\nFor cross-referencing support, use timing control:\n\n```yaml\nfilters:\n  - path: typst-render\n    at: pre-quarto\n```\n\nThen write Typst code blocks in your document:\n\n````markdown\n```{typst}\n#set text(size: 16pt)\nHello from *Typst*!\n```\n````\n\n### Inline Expressions\n\nRender Typst expressions inline using backtick code with the `typst` class.\nThe rendered image scales to match the surrounding text size.\n\n```markdown\nHere is a red word `{typst} #text(red)[hello]` in the middle of a sentence.\n\nInline maths: `{typst} $ x^2 + y^2 = z^2 $` renders as a formula image.\n```\n\nGlobal options (`format`, `dpi`, `preamble`, `background`, `foreground`, `output`) apply to inline expressions.\nBlock-only options (`echo`, `eval`, `label`, `cap`, `alt`, `file`, `output-filename`, `pages`, `layout-ncol`, `output-location`) are not available for inline expressions.\n\nProvide explicit alt text for accessibility using the `alt` attribute:\n\n```markdown\nThe area is `{typst} $pi r^2$`{alt=\"pi r squared\"} for a circle of radius r.\n```\n\nWhen no `alt` attribute is provided, the Typst source code is used as alt text.\n\n\u003e [!NOTE]\n\u003e Inline Typst is not supported for PowerPoint (PPTX) output.\n\u003e Pandoc cannot embed images inside text runs in PPTX slides, so inline code is kept as-is.\n\u003e Block-level `{typst}` code blocks work normally in PPTX.\n\n### Per-Block Options\n\nUse comment+pipe syntax (`//| key: value`) at the top of the code block:\n\n````markdown\n```{typst}\n//| width: 10cm\n//| dpi: 288\n//| format: png\n#align(center)[A custom-sized block.]\n```\n````\n\n### Cross-Referencing\n\nUse `//| label:` and `//| cap:` for Quarto cross-references.\nGeneric `cap` and `alt` options work with any label prefix.\nPrefix-specific variants (e.g., `fig-cap`, `tbl-alt`) override the generic options when the label matches.\nAny Quarto cross-reference type is supported (`fig-`, `tbl-`, `lst-`, etc.), including custom types defined under `crossref.custom` in the document YAML.\n\n````markdown\n```{typst}\n//| label: fig-my-diagram\n//| cap: \"A captioned Typst figure.\"\n//| alt: \"Description for screen readers.\"\n#circle(radius: 1cm, fill: blue)\n```\n\nSee @fig-my-diagram for the rendered figure.\n````\n\n### Echo and Eval Control\n\nShow source code alongside the rendered output, or display source only:\n\n````markdown\n```{typst}\n//| echo: true\n$ E = m c^2 $\n```\n\n```{typst}\n//| echo: fenced\n$ E = m c^2 $\n```\n\n```{typst}\n//| eval: false\n//| echo: true\nThis code is shown but not compiled.\n```\n````\n\nUse `echo: fenced` to display source code wrapped in fenced code block markers (` ```{typst} `), including any comment+pipe options (except `echo` itself).\nThis mirrors Quarto's native `echo: fenced` behaviour for computational cells.\n\n### External File Rendering\n\nRender an external `.typ` file instead of inline code:\n\n````markdown\n```{typst}\n//| file: path/to/file.typ\n```\n````\n\n### Multi-Page Output\n\nWhen Typst produces multiple pages (e.g., using `#pagebreak()`), all pages are included by default.\nUse `pages` to select specific pages and `layout-ncol` to arrange them in columns.\n\n````markdown\n```{typst}\n//| layout-ncol: 2\n//| width: 8cm\n//| height: 6cm\n#align(center + horizon)[*Page 1*]\n#pagebreak()\n#align(center + horizon)[*Page 2*]\n```\n````\n\nSelect specific pages with `pages`:\n\n````markdown\n```{typst}\n//| pages: 1\n//| width: 8cm\n//| height: 6cm\n#align(center + horizon)[*Shown*]\n#pagebreak()\n#align(center + horizon)[*Hidden*]\n```\n````\n\n### Engine-Generated Blocks\n\nR, Python, or Julia cells with `output: asis` can output ` ```{typst} ` blocks.\nThe filter processes these after engine execution.\n\n## Configuration\n\nConfigure the filter globally in your document YAML.\nMost options can be set globally and overridden per block using comment+pipe syntax (`//| key: value`).\nSee [Global-Only Options](#global-only-options) for options that cannot be overridden per block.\n\nInline preamble:\n\n```yaml\nextensions:\n  typst-render:\n    dpi: 288\n    margin: \"1em\"\n    preamble: '#set text(font: \"Libertinus Serif\")'\n```\n\nFile-based preamble (any value ending in `.typ` is read as a file):\n\n```yaml\nextensions:\n  typst-render:\n    preamble: \"preamble.typ\"\n```\n\nInput variables (accessible via `sys.inputs` in Typst code):\n\n```yaml\nextensions:\n  typst-render:\n    input:\n      theme: dark\n      lang: en\n```\n\nCache cleanup removes stale files from previous renders:\n\n```yaml\nextensions:\n  typst-render:\n    cache-refresh: true\n```\n\n### Output Directory\n\nBy default, compiled images are only stored in the internal cache directory (`.quarto/typst-render/`) with auto-generated filenames.\nSet `output-directory` to also save copies to a predictable location, and optionally override the filename per block with `output-filename`.\n\nPaths follow Quarto conventions: a leading `/` is relative to the project root, otherwise relative to the document directory.\n\nGlobal directory (all blocks are saved automatically):\n\n```yaml\nextensions:\n  typst-render:\n    output-directory: /images/typst/\n```\n\nWhen `output-directory` is set and no `output-filename` is given, the filename is auto-generated from the block label (e.g., `fig-diagram.png`) or block counter (e.g., `typst-block-1.png`).\n\nPer-block filename override:\n\n````markdown\n```{typst}\n//| output-filename: my-diagram.png\n#circle(radius: 1cm, fill: blue)\n```\n````\n\nCombined usage:\n\n````markdown\n```{typst}\n//| label: fig-chart\n//| output-filename: chart.svg\n#rect(width: 3cm, height: 2cm, fill: eastern)\n```\n````\n\nWith a global `output-directory: /images/`, this saves to `/images/chart.svg` (project root).\nA per-block `output-filename` starting with `/` overrides the global directory entirely (e.g., `//| output-filename: /other/result.png` saves to `/other/result.png`).\n\nFor multi-page output, page numbers are appended before the extension (e.g., `diagram1.png`, `diagram2.png`).\nFor dual-mode (light/dark) rendering, `-light` and `-dark` suffixes are appended (e.g., `diagram-light.svg`, `diagram-dark.svg`).\n\n### Foreground and Background Colours\n\nSet text and page fill colours for rendered images.\nValues can be Typst colour literals, CSS hex strings (converted automatically), `auto` (reads from `_brand.yml`), or a map with `light`/`dark` keys for theme-aware rendering.\n\nStatic colours:\n\n```yaml\nextensions:\n  typst-render:\n    foreground: \"eastern\"\n    background: \"luma(245)\"\n```\n\nBrand-aware colours (requires a `_brand.yml` with `color.foreground` and/or `color.background` defined):\n\n```yaml\nextensions:\n  typst-render:\n    foreground: auto\n    background: auto\n```\n\nExplicit light/dark values (HTML/Reveal.js renders both variants using Quarto's `.light-content`/`.dark-content` classes; other formats use `brand-mode` to select one):\n\n```yaml\nbrand-mode: light\nextensions:\n  typst-render:\n    foreground:\n      light: \"#1a1a2e\"\n      dark: \"#eaeaea\"\n    background:\n      light: \"#ffffff\"\n      dark: \"#1a1a2e\"\n```\n\nPer-block override using comment+pipe syntax:\n\n````markdown\n```{typst}\n//| foreground: eastern\n//| background: luma(245)\n#align(center)[Styled text.]\n```\n````\n\nPer-block input override using comma-separated syntax:\n\n````markdown\n```{typst}\n//| input: theme=light,lang=fr\n#sys.inputs.at(\"theme\")\n```\n````\n\n### Options\n\n| Option            | Type            | Default   | Description                                                                                   |\n| ----------------- | --------------- | --------- | --------------------------------------------------------------------------------------------- |\n| `format`          | string          | (auto)    | Image format: `png`, `svg`, `pdf`.                                                            |\n| `dpi`             | number          | `144`     | Pixels per inch (PNG only).                                                                   |\n| `width`           | string          | `\"auto\"`  | Page width for image compilation (ignored with `output: asis`).                               |\n| `height`          | string          | `\"auto\"`  | Page height for image compilation (ignored with `output: asis`).                              |\n| `margin`          | string          | `\"0.5em\"` | Page margin for image compilation; block `inset` with `output: asis`.                         |\n| `background`      | string\\|object  | `\"none\"`  | Page fill colour. Accepts a Typst colour, `auto` (from `_brand.yml`), or `{light, dark}` map. |\n| `foreground`      | string\\|object  | (none)    | Text fill colour. Accepts a Typst colour, `auto` (from `_brand.yml`), or `{light, dark}` map. |\n| `preamble`        | string          | `\"\"`      | Typst code or path to a `.typ` file prepended before user code.                               |\n| `cache`           | boolean         | `true`    | Cache compiled images. Set `false` to skip cache (existing files are preserved).              |\n| `cache-refresh`   | boolean         | `false`   | Remove stale cache files after each render (global only).                                     |\n| `input`           | object          | (none)    | Key-value pairs passed as `--input` flags to Typst CLI.                                       |\n| `file`            | string          | (none)    | Path to external `.typ` file to render.                                                       |\n| `output-directory` | string         | (none)    | Directory for saving compiled images. See [Output Directory](#output-directory).               |\n| `output-filename`  | string         | (none)    | Filename for the saved image. Leading `/` overrides `output-directory`. Auto-generated if omitted. |\n| `echo`            | boolean\\|string | `false`   | Show Typst source code alongside output (`true`, `false`, `fenced`).                          |\n| `eval`            | boolean         | `true`    | Compile Typst code to image.                                                                  |\n| `include`         | boolean         | `true`    | Include block in output. Set `false` to suppress entirely.                                    |\n| `output`          | boolean\\|string | `true`    | Show rendered output. Use `asis` for native Typst passthrough.                                |\n| `output-location` | string          | (none)    | Output placement in Reveal.js (`fragment`, `slide`, `column`, `column-fragment`).             |\n| `classes`         | string          | (none)    | Space-separated CSS classes on the output image (e.g., `r-stretch`).                          |\n| `pages`           | string          | `\"all\"`   | Pages to include from multi-page output: `all`, `1`, `1-3`, `2,5`, `3-`.                      |\n| `layout-ncol`     | string          | (none)    | Number of columns for arranging multi-page output. Omit for vertical stack.                   |\n| `align`           | string          | (none)    | Horizontal alignment: `left`, `center`, `right`, `default`.                                   |\n\nAny unknown option with a string value is forwarded as an HTML attribute on the output image element (e.g., `//| style: \"max-height: 300px;\"`).\nValues that look like booleans (`true`/`false`) must be quoted to be forwarded (e.g., `//| data-lazy: \"true\"`).\n\n### Global-Only Options\n\nThese options can only be set in the document YAML and cannot be overridden per block.\n\n| Option         | Type          | Default             | Description                                                           |\n| -------------- | ------------- | ------------------- | --------------------------------------------------------------------- |\n| `root`         | string        | (project directory) | Root directory for Typst compilation.                                 |\n| `font-path`    | string\\|array | (none)              | Path or list of paths to directories containing additional fonts.     |\n| `package-path` | string        | (none)              | Path to a directory containing Typst packages (offline/reproducible). |\n\n### Per-Block Cross-Referencing Options\n\n| Option         | Type   | Description                                                                      |\n| -------------- | ------ | -------------------------------------------------------------------------------- |\n| `label`        | string | Quarto cross-ref label (e.g., `fig-x`, `tbl-y`, `lst-z`).                        |\n| `cap`          | string | Caption text for the labelled block.                                             |\n| `alt`          | string | Alternative text for accessibility. Falls back to caption, then source code.     |\n| `\u003cprefix\u003e-cap` | string | Prefix-specific caption (e.g., `fig-cap`). Overrides `cap` for matching labels.  |\n| `\u003cprefix\u003e-alt` | string | Prefix-specific alt text (e.g., `fig-alt`). Overrides `alt` for matching labels. |\n\n### Auto-Selected Image Format\n\n| Output Format   | Default Image Format |\n| --------------- | -------------------- |\n| HTML / RevealJS | `svg`                |\n| LaTeX / Beamer  | `pdf`                |\n| Typst           | `png`                |\n| DOCX / PPTX     | `png`                |\n| Other           | `png`                |\n\n### Echo/Eval Behaviour\n\n| `eval`  | `echo`   | Result                                           |\n| ------- | -------- | ------------------------------------------------ |\n| `true`  | `false`  | Image only (default).                            |\n| `true`  | `true`   | Source code block + image below.                 |\n| `true`  | `fenced` | Fenced source code block (with markers) + image. |\n| `false` | `true`   | Source code listing only.                        |\n| `false` | `fenced` | Fenced source code listing only (with markers).  |\n| `false` | `false`  | Nothing rendered (hidden block).                 |\n\nThe `include` and `output` options take precedence over the eval/echo matrix:\n\n- `include: false` hides the entire block regardless of eval/echo settings.\n- `output: false` skips compilation and shows only the source code (if echo is enabled).\n- `output: asis` uses native passthrough for Typst output; behaves as `true` for other formats.\n\n## Example\n\nHere is the source code for a minimal example: [`example.qmd`](example.qmd).\n\nOutput of `example.qmd`:\n\n- [HTML](https://m.canouil.dev/quarto-typst-render/).\n- [Typst](https://m.canouil.dev/quarto-typst-render/example-typst.pdf).\n- [PDF (XeLaTeX)](https://m.canouil.dev/quarto-typst-render/example-xelatex.pdf).\n- [PDF (LuaLaTeX)](https://m.canouil.dev/quarto-typst-render/example-lualatex.pdf).\n- [PDF (PDFLaTeX)](https://m.canouil.dev/quarto-typst-render/example-pdflatex.pdf).\n- [RevealJS](https://m.canouil.dev/quarto-typst-render/example-revealjs.html).\n- [Beamer](https://m.canouil.dev/quarto-typst-render/example-beamer.pdf).\n- [DOCX](https://m.canouil.dev/quarto-typst-render/example-docx.docx).\n- [PPTX](https://m.canouil.dev/quarto-typst-render/example-pptx.pptx).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmcanouil%2Fquarto-typst-render","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmcanouil%2Fquarto-typst-render","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmcanouil%2Fquarto-typst-render/lists"}