From a904d2313a3d76e4dce161670d38d0e1d1c3b886 Mon Sep 17 00:00:00 2001 From: Jared Knowles Date: Thu, 9 Jul 2026 15:57:47 -0400 Subject: [PATCH 1/2] fix(quarto): repair LaTeX + Typst branded templates - LaTeX: capture pandoc's \subtitle into \thesubtitle so subtitled PDFs compile; suppress the default \maketitle/abstract so only the branded title page renders (no double title); drop the unused tikz dependency from the title partial (#13) - LaTeX: stop requiring a "Source Serif 4 SemiBold" face that the setup never installs; use the family's native Bold weight (#14) - Typst: wrap title/subtitle/date in [ ] so text containing Typst keywords ("for"/"in") no longer breaks compilation (#12) - Fix footer URL civilytics.consulting -> civilytics.com in the LaTeX and Typst templates and the slides example (#11) - Bump version to 0.3.0 --- DESCRIPTION | 2 +- inst/quarto/examples/slides.qmd | 2 +- inst/quarto/latex/civilytics-title.tex | 7 +++++-- inst/quarto/latex/civilytics.tex | 29 +++++++++++++++++++++++--- inst/quarto/typst/civilytics-typst.typ | 11 ++++++---- 5 files changed, 40 insertions(+), 11 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 235325a..d15352f 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: civilytics Type: Package Title: Brand Themes, Color Palettes, and Utility Functions for Civilytics -Version: 0.2.0 +Version: 0.3.0 Authors@R: person("Jared", "E. Knowles", email = "jared@civilytics.com", role = c("aut", "cre")) diff --git a/inst/quarto/examples/slides.qmd b/inst/quarto/examples/slides.qmd index c70a6c4..1485bd9 100644 --- a/inst/quarto/examples/slides.qmd +++ b/inst/quarto/examples/slides.qmd @@ -62,4 +62,4 @@ Civilytics Research, 2026 Questions? - jared@civilytics.com -- civilytics.consulting +- civilytics.com diff --git a/inst/quarto/latex/civilytics-title.tex b/inst/quarto/latex/civilytics-title.tex index 2d31ca2..86e3e0d 100644 --- a/inst/quarto/latex/civilytics-title.tex +++ b/inst/quarto/latex/civilytics-title.tex @@ -2,6 +2,11 @@ % Replaces Quarto's default \maketitle. Uses values from YAML % (\thetitle, \theauthor, \thedate) plus an \ifabstract block. +% Guard: \thesubtitle is normally defined by civilytics.tex's subtitle +% capture; provide a fallback so this partial degrades gracefully if used +% without that preamble. See civilyticsR issue #13. +\providecommand{\thesubtitle}{} + \begin{titlepage} \pagecolor{paper} \color{ink} @@ -33,8 +38,6 @@ % Pulse mark, in ember \begin{center} - \begin{tikzpicture}[overlay, remember picture] - \end{tikzpicture} {\color{ember}\rule{40pt}{2pt}} \end{center} \end{titlepage} diff --git a/inst/quarto/latex/civilytics.tex b/inst/quarto/latex/civilytics.tex index 5bdcc4e..43878b9 100644 --- a/inst/quarto/latex/civilytics.tex +++ b/inst/quarto/latex/civilytics.tex @@ -40,17 +40,40 @@ \color{ink} % --- Fonts (require local install or fontspec lookup) --- +% Bold uses the family's native Bold weight (present in every Source Serif 4 +% install). Do NOT hard-require a "SemiBold" face: the package installs no +% system fonts for the PDF path, and standard Source Serif 4 ships only +% Regular/Bold/Italic/BoldItalic. See civilyticsR issue #14. \setmainfont{Source Serif 4}[ UprightFont = *, ItalicFont = * Italic, - BoldFont = * SemiBold, - BoldItalicFont = * SemiBold Italic, Ligatures = TeX, ] \setsansfont{Inter}[Ligatures = TeX] \setmonofont{JetBrains Mono}[Scale = 0.92] \newfontfamily\displayfont{Libre Franklin}[Ligatures = TeX] +% --- Subtitle capture --- +% Quarto/pandoc defines \subtitle (which appends to \@title) but never +% \thesubtitle, which the title page uses. This preamble is emitted before +% pandoc's \providecommand{\subtitle}, so our definition wins: capture the +% subtitle into \thesubtitle instead. See civilyticsR issue #13. +\makeatletter +\providecommand{\thesubtitle}{} +\def\subtitle#1{\renewcommand{\thesubtitle}{#1}} +\makeatother + +% --- Use the Civilytics title page, not pandoc's default --- +% civilytics-title.tex (include-before-body) IS the title page. Quarto emits +% its default \maketitle + abstract *before* include-before-body, which would +% print a second, unstyled title. Neutralise both here, in the preamble +% (runs at \begin{document}, before the default title). The branded title page +% does not display the abstract. See civilyticsR issue #13. +\AtBeginDocument{% + \renewcommand{\maketitle}{}% + \renewenvironment{abstract}{\setbox0=\vbox\bgroup}{\egroup}% +} + % --- Hyperlinks --- \hypersetup{ colorlinks = true, @@ -77,7 +100,7 @@ \renewcommand{\footrulewidth}{0pt} \fancyhead[L]{\sffamily\scriptsize\color{ink3}\MakeUppercase{Civilytics Consulting}} \fancyhead[R]{\sffamily\scriptsize\color{ink3}\thetitle} -\fancyfoot[L]{\sffamily\scriptsize\color{ink3}civilytics.consulting} +\fancyfoot[L]{\sffamily\scriptsize\color{ink3}civilytics.com} \fancyfoot[C]{\sffamily\scriptsize\color{ink3}\thepage} \fancyfoot[R]{\sffamily\scriptsize\color{ink3}\textcopyright\ 2026} diff --git a/inst/quarto/typst/civilytics-typst.typ b/inst/quarto/typst/civilytics-typst.typ index 097f4d4..61b3a42 100644 --- a/inst/quarto/typst/civilytics-typst.typ +++ b/inst/quarto/typst/civilytics-typst.typ @@ -54,7 +54,7 @@ grid( columns: (1fr, auto, 1fr), align: (left, center, right), - [civilytics.consulting], + [civilytics.com], counter(page).display("1 / 1", both: true), [© 2026] ) @@ -231,11 +231,14 @@ } // 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$ + 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(date)$date: [$date$],$endif$ $if(abstract)$abstract: [$abstract$],$endif$ toc: $if(toc)$true$else$false$endif$, doc -- 2.54.0 From b9d427eb767ca117bc523195aa580ffdeb50b60e Mon Sep 17 00:00:00 2001 From: Jared Knowles Date: Thu, 9 Jul 2026 16:10:15 -0400 Subject: [PATCH 2/2] 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$ -- 2.54.0