From 771110a72ae005da42169da261f8b8513c9421db Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Tue, 18 Mar 2025 08:56:06 -0700 Subject: [PATCH 1/6] fix(git): deprioritize git, dont fail on non-git content folders --- quartz.config.ts | 2 +- quartz/plugins/transformers/lastmod.ts | 24 +++++++++++++----------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/quartz.config.ts b/quartz.config.ts index 03ef0d7f8..195f521dc 100644 --- a/quartz.config.ts +++ b/quartz.config.ts @@ -57,7 +57,7 @@ const config: QuartzConfig = { transformers: [ Plugin.FrontMatter(), Plugin.CreatedModifiedDate({ - priority: ["git", "frontmatter", "filesystem"], + priority: ["frontmatter", "git", "filesystem"], }), Plugin.SyntaxHighlighting({ theme: { diff --git a/quartz/plugins/transformers/lastmod.ts b/quartz/plugins/transformers/lastmod.ts index aeabad19e..e17d894b0 100644 --- a/quartz/plugins/transformers/lastmod.ts +++ b/quartz/plugins/transformers/lastmod.ts @@ -35,13 +35,23 @@ export const CreatedModifiedDate: QuartzTransformerPlugin> = (u return [ () => { let repo: Repository | undefined = undefined + if (opts.priority.includes("git")) { + try { + repo = Repository.discover(ctx.argv.directory) + } catch (e) { + console.log( + chalk.yellow(`\nWarning: couldn't find git repository for ${ctx.argv.directory}`), + ) + } + } + return async (_tree, file) => { let created: MaybeDate = undefined let modified: MaybeDate = undefined let published: MaybeDate = undefined const fp = file.data.relativePath! - const fullFp = path.posix.join(ctx.argv.directory, fp) + const fullFp = file.data.filePath! for (const source of opts.priority) { if (source === "filesystem") { const st = await fs.promises.stat(fullFp) @@ -51,21 +61,13 @@ export const CreatedModifiedDate: QuartzTransformerPlugin> = (u created ||= file.data.frontmatter.created as MaybeDate modified ||= file.data.frontmatter.modified as MaybeDate published ||= file.data.frontmatter.published as MaybeDate - } else if (source === "git") { - if (!repo) { - // Get a reference to the main git repo. - // It's either the same as the workdir, - // or 1+ level higher in case of a submodule/subtree setup - repo = Repository.discover(ctx.argv.directory) - } - + } else if (source === "git" && repo) { try { modified ||= await repo.getFileLatestModifiedDateAsync(fullFp) } catch { console.log( chalk.yellow( - `\nWarning: ${file.data - .filePath!} isn't yet tracked by git, last modification date is not available for this file`, + `\nWarning: ${file.data.filePath!} isn't yet tracked by git, dates will be inaccurate`, ), ) } From 9818e1ad5788906162fca5e62665ac21ef0d9639 Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Tue, 18 Mar 2025 09:00:15 -0700 Subject: [PATCH 2/6] chore: remove unused import --- quartz/plugins/transformers/lastmod.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/quartz/plugins/transformers/lastmod.ts b/quartz/plugins/transformers/lastmod.ts index e17d894b0..09c12941f 100644 --- a/quartz/plugins/transformers/lastmod.ts +++ b/quartz/plugins/transformers/lastmod.ts @@ -1,5 +1,4 @@ import fs from "fs" -import path from "path" import { Repository } from "@napi-rs/simple-git" import { QuartzTransformerPlugin } from "../types" import chalk from "chalk" From 25979ab216ca2cc2539696420f23be8508d3184f Mon Sep 17 00:00:00 2001 From: Felix Nie Date: Wed, 19 Mar 2025 12:43:32 +0800 Subject: [PATCH 3/6] feat(fonts): allow PageTitle to have its own font subset (#1848) * fix(explorer): vertically center the Explorer toggle under mobile view * Added a separate title font configuration * Added googleSubFontHref function * Applied --titleFont to PageTitle * Made googleFontHref return array of URLs * Dealing with empty and undefined title * Minor update * Dealing with empty and undefined title * Refined font inclusion logic * Adopted the googleFontHref + googleFontSubsetHref method * Adaptively include font subset for PageTitle * Restored default config * Minor changes on configuration docs * Formatted source code --- docs/configuration.md | 9 +++++---- quartz/components/Head.tsx | 5 ++++- quartz/components/PageTitle.tsx | 1 + quartz/plugins/emitters/componentResources.ts | 16 ++++++++++++++-- quartz/util/theme.ts | 18 +++++++++++++++--- 5 files changed, 39 insertions(+), 10 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index e29dc807b..4026c5197 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -41,11 +41,12 @@ This part of the configuration concerns anything that can affect the whole site. - `ignorePatterns`: a list of [glob]() patterns that Quartz should ignore and not search through when looking for files inside the `content` folder. See [[private pages]] for more details. - `defaultDateType`: whether to use created, modified, or published as the default date to display on pages and page listings. - `theme`: configure how the site looks. - - `cdnCaching`: If `true` (default), use Google CDN to cache the fonts. This will generally will be faster. Disable (`false`) this if you want Quartz to download the fonts to be self-contained. + - `cdnCaching`: if `true` (default), use Google CDN to cache the fonts. This will generally be faster. Disable (`false`) this if you want Quartz to download the fonts to be self-contained. - `typography`: what fonts to use. Any font available on [Google Fonts](https://fonts.google.com/) works here. - - `header`: Font to use for headers - - `code`: Font for inline and block quotes. - - `body`: Font for everything + - `title`: font for the title of the site (optional, same as `header` by default) + - `header`: font to use for headers + - `code`: font for inline and block quotes + - `body`: font for everything - `colors`: controls the theming of the site. - `light`: page background - `lightgray`: borders diff --git a/quartz/components/Head.tsx b/quartz/components/Head.tsx index 60dce6edd..23183ca8c 100644 --- a/quartz/components/Head.tsx +++ b/quartz/components/Head.tsx @@ -1,7 +1,7 @@ import { i18n } from "../i18n" import { FullSlug, getFileExtension, joinSegments, pathToRoot } from "../util/path" import { CSSResourceToStyleElement, JSResourceToScriptElement } from "../util/resources" -import { googleFontHref } from "../util/theme" +import { googleFontHref, googleFontSubsetHref } from "../util/theme" import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "./types" import { unescapeHTML } from "../util/escape" import { CustomOgImagesEmitterName } from "../plugins/emitters/ogImage" @@ -45,6 +45,9 @@ export default (() => { + {cfg.theme.typography.title && ( + + )} )} diff --git a/quartz/components/PageTitle.tsx b/quartz/components/PageTitle.tsx index 046dc5276..53ee8240a 100644 --- a/quartz/components/PageTitle.tsx +++ b/quartz/components/PageTitle.tsx @@ -17,6 +17,7 @@ PageTitle.css = ` .page-title { font-size: 1.75rem; margin: 0; + font-family: var(--titleFont); } ` diff --git a/quartz/plugins/emitters/componentResources.ts b/quartz/plugins/emitters/componentResources.ts index 540a3738c..5dd67e6aa 100644 --- a/quartz/plugins/emitters/componentResources.ts +++ b/quartz/plugins/emitters/componentResources.ts @@ -9,7 +9,12 @@ import styles from "../../styles/custom.scss" import popoverStyle from "../../components/styles/popover.scss" import { BuildCtx } from "../../util/ctx" import { QuartzComponent } from "../../components/types" -import { googleFontHref, joinStyles, processGoogleFonts } from "../../util/theme" +import { + googleFontHref, + googleFontSubsetHref, + joinStyles, + processGoogleFonts, +} from "../../util/theme" import { Features, transform } from "lightningcss" import { transform as transpile } from "esbuild" import { write } from "./helpers" @@ -211,9 +216,16 @@ export const ComponentResources: QuartzEmitterPlugin = () => { // let the user do it themselves in css } else if (cfg.theme.fontOrigin === "googleFonts" && !cfg.theme.cdnCaching) { // when cdnCaching is true, we link to google fonts in Head.tsx - const response = await fetch(googleFontHref(ctx.cfg.configuration.theme)) + const theme = ctx.cfg.configuration.theme + const response = await fetch(googleFontHref(theme)) googleFontsStyleSheet = await response.text() + if (theme.typography.title) { + const title = ctx.cfg.configuration.pageTitle + const response = await fetch(googleFontSubsetHref(theme, title)) + googleFontsStyleSheet += `\n${await response.text()}` + } + if (!cfg.baseUrl) { throw new Error( "baseUrl must be defined when using Google Fonts without cfg.theme.cdnCaching", diff --git a/quartz/util/theme.ts b/quartz/util/theme.ts index 56261e35b..4a064255f 100644 --- a/quartz/util/theme.ts +++ b/quartz/util/theme.ts @@ -25,6 +25,7 @@ export type FontSpecification = export interface Theme { typography: { + title?: FontSpecification header: FontSpecification body: FontSpecification code: FontSpecification @@ -48,7 +49,10 @@ export function getFontSpecificationName(spec: FontSpecification): string { return spec.name } -function formatFontSpecification(type: "header" | "body" | "code", spec: FontSpecification) { +function formatFontSpecification( + type: "title" | "header" | "body" | "code", + spec: FontSpecification, +) { if (typeof spec === "string") { spec = { name: spec } } @@ -82,12 +86,19 @@ function formatFontSpecification(type: "header" | "body" | "code", spec: FontSpe } export function googleFontHref(theme: Theme) { - const { code, header, body } = theme.typography + const { header, body, code } = theme.typography const headerFont = formatFontSpecification("header", header) const bodyFont = formatFontSpecification("body", body) const codeFont = formatFontSpecification("code", code) - return `https://fonts.googleapis.com/css2?family=${bodyFont}&family=${headerFont}&family=${codeFont}&display=swap` + return `https://fonts.googleapis.com/css2?family=${headerFont}&family=${bodyFont}&family=${codeFont}&display=swap` +} + +export function googleFontSubsetHref(theme: Theme, text: string) { + const title = theme.typography.title || theme.typography.header + const titleFont = formatFontSpecification("title", title) + + return `https://fonts.googleapis.com/css2?family=${titleFont}&text=${encodeURIComponent(text)}&display=swap` } export interface GoogleFontFile { @@ -135,6 +146,7 @@ ${stylesheet.join("\n\n")} --highlight: ${theme.colors.lightMode.highlight}; --textHighlight: ${theme.colors.lightMode.textHighlight}; + --titleFont: "${getFontSpecificationName(theme.typography.title || theme.typography.header)}", ${DEFAULT_SANS_SERIF}; --headerFont: "${getFontSpecificationName(theme.typography.header)}", ${DEFAULT_SANS_SERIF}; --bodyFont: "${getFontSpecificationName(theme.typography.body)}", ${DEFAULT_SANS_SERIF}; --codeFont: "${getFontSpecificationName(theme.typography.code)}", ${DEFAULT_MONO}; From bcde2abcb20ad02a0c3f1430b9d620ee60e6cb63 Mon Sep 17 00:00:00 2001 From: dralagen Date: Wed, 19 Mar 2025 05:47:35 +0100 Subject: [PATCH 4/6] fix(transformer): find last modified date form commit on submodule (#1831) * fix(transformer): find last modified date form commit on submodule when the content folder has a submodule git, the relative path start in content folder and not root folder of quartz * fix(transformer): use path.relative for improved path handling in last modified date calculation * fix(transformer): keep find file from relative path of repo workdir * fix(transformer): use variable for repository workdir use default value if repo.workdir is undefined to user fullFp value --- quartz/plugins/transformers/lastmod.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/quartz/plugins/transformers/lastmod.ts b/quartz/plugins/transformers/lastmod.ts index 09c12941f..01054bb57 100644 --- a/quartz/plugins/transformers/lastmod.ts +++ b/quartz/plugins/transformers/lastmod.ts @@ -2,6 +2,7 @@ import fs from "fs" import { Repository } from "@napi-rs/simple-git" import { QuartzTransformerPlugin } from "../types" import chalk from "chalk" +import path from "path" export interface Options { priority: ("frontmatter" | "git" | "filesystem")[] @@ -34,9 +35,11 @@ export const CreatedModifiedDate: QuartzTransformerPlugin> = (u return [ () => { let repo: Repository | undefined = undefined + let repositoryWorkdir: string if (opts.priority.includes("git")) { try { repo = Repository.discover(ctx.argv.directory) + repositoryWorkdir = repo.workdir() ?? "" } catch (e) { console.log( chalk.yellow(`\nWarning: couldn't find git repository for ${ctx.argv.directory}`), @@ -62,7 +65,8 @@ export const CreatedModifiedDate: QuartzTransformerPlugin> = (u published ||= file.data.frontmatter.published as MaybeDate } else if (source === "git" && repo) { try { - modified ||= await repo.getFileLatestModifiedDateAsync(fullFp) + const relativePath = path.relative(repositoryWorkdir, fullFp) + modified ||= await repo.getFileLatestModifiedDateAsync(relativePath) } catch { console.log( chalk.yellow( From eccad3da5d7b84b0f78a85b357efedef8c0127fc Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Tue, 18 Mar 2025 21:48:24 -0700 Subject: [PATCH 5/6] fix(lastmod): fallback to ctx.arg.directory instead of empty string --- quartz/plugins/transformers/lastmod.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quartz/plugins/transformers/lastmod.ts b/quartz/plugins/transformers/lastmod.ts index 01054bb57..572d9d322 100644 --- a/quartz/plugins/transformers/lastmod.ts +++ b/quartz/plugins/transformers/lastmod.ts @@ -39,7 +39,7 @@ export const CreatedModifiedDate: QuartzTransformerPlugin> = (u if (opts.priority.includes("git")) { try { repo = Repository.discover(ctx.argv.directory) - repositoryWorkdir = repo.workdir() ?? "" + repositoryWorkdir = repo.workdir() ?? ctx.argv.directory } catch (e) { console.log( chalk.yellow(`\nWarning: couldn't find git repository for ${ctx.argv.directory}`), From fbca56f2783b9e5bfaeffec990990d4330c31b9d Mon Sep 17 00:00:00 2001 From: Shane McDonald Date: Wed, 19 Mar 2025 15:47:16 -0400 Subject: [PATCH 6/6] fix(lastmod) Change defaultDateType to "modified" (#1862) Making this change as per https://github.com/jackyzha0/quartz/issues/1857#issuecomment-2737098252 This is necessary for the `git` source to work properly in the CreatedModifiedDate plugin. --- quartz.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quartz.config.ts b/quartz.config.ts index 195f521dc..efe96485c 100644 --- a/quartz.config.ts +++ b/quartz.config.ts @@ -18,7 +18,7 @@ const config: QuartzConfig = { locale: "en-US", baseUrl: "quartz.jzhao.xyz", ignorePatterns: ["private", "templates", ".obsidian"], - defaultDateType: "created", + defaultDateType: "modified", theme: { fontOrigin: "googleFonts", cdnCaching: true,