From b9d427eb767ca117bc523195aa580ffdeb50b60e Mon Sep 17 00:00:00 2001 From: Jared Knowles Date: Thu, 9 Jul 2026 16:10:15 -0400 Subject: [PATCH] fix(typst): ship template as partials so code blocks render (#12) The single-file `template: civilytics-typst.typ` discarded Quarto's auto-generated `definitions` partial, so any Typst document containing a code block failed with `unknown variable: Skylighting`. Ship the template as Quarto template-partials instead, so Quarto keeps its definitions (Skylighting + token functions) and syntax-highlighted code blocks render while the Civilytics branding still applies: - split civilytics-typst.typ into typst-template.typ (the styling function) and typst-show.typ (the show/entry point, keyword-safe [ ] wrapping kept); remove the single-file template - use_civilytics_theme() now copies both partials and prints the template-partials usage - example report.qmd uses template-partials Verified: a report with an R code block renders with working syntax highlighting and full branding. --- R/quarto.R | 16 +++++++----- inst/quarto/examples/report.qmd | 4 ++- inst/quarto/typst/typst-show.typ | 17 ++++++++++++ ...ivilytics-typst.typ => typst-template.typ} | 26 ++++++------------- 4 files changed, 37 insertions(+), 26 deletions(-) create mode 100644 inst/quarto/typst/typst-show.typ rename inst/quarto/typst/{civilytics-typst.typ => typst-template.typ} (90%) diff --git a/R/quarto.R b/R/quarto.R index ed3cc06..c3d94e0 100644 --- a/R/quarto.R +++ b/R/quarto.R @@ -135,12 +135,12 @@ use_civilytics_theme <- function(path = ".", force = FALSE) { .copy_pkg_file(file.path("quarto/latex", f), file.path("latex", f), path, force) } - # Typst - .copy_pkg_file( - "quarto/typst/civilytics-typst.typ", - "typst/civilytics-typst.typ", - path, force - ) + # Typst — shipped as template-partials so Quarto keeps its Skylighting + # definitions and syntax-highlighted code blocks render (see issue #12) + typst_files <- c("typst-template.typ", "typst-show.typ") + for (f in typst_files) { + .copy_pkg_file(file.path("quarto/typst", f), file.path("typst", f), path, force) + } # Logos — for _brand.yml (expects assets/logo/) .copy_logos("assets/logo", path, force) @@ -158,7 +158,9 @@ use_civilytics_theme <- function(path = ".", force = FALSE) { message(" include-in-header: latex/civilytics.tex") message(" include-before-body: latex/civilytics-title.tex") message(" typst:") - message(" template: typst/civilytics-typst.typ") + message(" template-partials:") + message(" - typst/typst-template.typ") + message(" - typst/typst-show.typ") message("---") message("\nSee examples/report.qmd for a complete example.") invisible(NULL) diff --git a/inst/quarto/examples/report.qmd b/inst/quarto/examples/report.qmd index 76aecf0..832fb3c 100644 --- a/inst/quarto/examples/report.qmd +++ b/inst/quarto/examples/report.qmd @@ -19,7 +19,9 @@ format: toc: true toc-location: right typst: - template: ../typst/civilytics-typst.typ + template-partials: + - ../typst/typst-template.typ + - ../typst/typst-show.typ pdf: include-in-header: ../latex/civilytics.tex include-before-body: ../latex/civilytics-title.tex diff --git a/inst/quarto/typst/typst-show.typ b/inst/quarto/typst/typst-show.typ new file mode 100644 index 0000000..8e5c313 --- /dev/null +++ b/inst/quarto/typst/typst-show.typ @@ -0,0 +1,17 @@ +// Civilytics — Typst show/entry partial for Quarto (typst-show.typ). +// Pairs with typst-template.typ. Quarto appends the rendered document body +// after this partial, so this file intentionally ends with the show rule and +// no trailing body token. (Do not write that token in a comment here: Quarto +// interpolates its template variables even inside comments.) +// Title/subtitle/date are wrapped in [ ] so arbitrary text (including words +// that are Typst keywords like "for"/"in") is treated as content, not code. +// See civilyticsR issue #12. +#show: doc => civilytics( + title: [$title$], + $if(subtitle)$subtitle: [$subtitle$],$endif$ + $if(by-author)$authors: ($for(by-author)$"$it.name.literal$",$endfor$),$endif$ + $if(date)$date: [$date$],$endif$ + $if(abstract)$abstract: [$abstract$],$endif$ + toc: $if(toc)$true$else$false$endif$, + doc +) diff --git a/inst/quarto/typst/civilytics-typst.typ b/inst/quarto/typst/typst-template.typ similarity index 90% rename from inst/quarto/typst/civilytics-typst.typ rename to inst/quarto/typst/typst-template.typ index 61b3a42..c1d7038 100644 --- a/inst/quarto/typst/civilytics-typst.typ +++ b/inst/quarto/typst/typst-template.typ @@ -1,9 +1,15 @@ // ============================================================= -// Civilytics — Typst template for Quarto PDF +// Civilytics — Typst template partial for Quarto PDF (typst-template.typ). +// Shipped as a Quarto template-partial (paired with typst-show.typ) rather +// than a full `template:` so Quarto keeps its own `definitions` partial — +// which defines Skylighting/token functions needed for syntax-highlighted +// code blocks. See civilyticsR issue #12. // Usage in YAML: // format: // typst: -// template: quarto/typst/civilytics-typst.typ +// template-partials: +// - quarto/typst/typst-template.typ +// - quarto/typst/typst-show.typ // ============================================================= #let paper-bg = rgb("#FAF7F2") @@ -229,19 +235,3 @@ doc } - -// Quarto entry point -// Title/subtitle/date are wrapped in [ ] so arbitrary text (incl. words that -// are Typst keywords like "for"/"in") is treated as content, not code. -// See civilyticsR issue #12. -#show: doc => civilytics( - title: [$title$], - $if(subtitle)$subtitle: [$subtitle$],$endif$ - $if(by-author)$authors: ($for(by-author)$"$it.name.literal$",$endfor$),$endif$ - $if(date)$date: [$date$],$endif$ - $if(abstract)$abstract: [$abstract$],$endif$ - toc: $if(toc)$true$else$false$endif$, - doc -) - -$body$