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
| | |
| | | - `ignorePatterns`: a list of [glob](<https://en.wikipedia.org/wiki/Glob_(programming)>) 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 |
| | |
| | | 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" |
| | |
| | | <link rel="preconnect" href="https://fonts.googleapis.com" /> |
| | | <link rel="preconnect" href="https://fonts.gstatic.com" /> |
| | | <link rel="stylesheet" href={googleFontHref(cfg.theme)} /> |
| | | {cfg.theme.typography.title && ( |
| | | <link rel="stylesheet" href={googleFontSubsetHref(cfg.theme, cfg.pageTitle)} /> |
| | | )} |
| | | </> |
| | | )} |
| | | <link rel="preconnect" href="https://cdnjs.cloudflare.com" crossOrigin="anonymous" /> |
| | |
| | | .page-title { |
| | | font-size: 1.75rem; |
| | | margin: 0; |
| | | font-family: var(--titleFont); |
| | | } |
| | | ` |
| | | |
| | |
| | | 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" |
| | |
| | | // 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", |
| | |
| | | |
| | | export interface Theme { |
| | | typography: { |
| | | title?: FontSpecification |
| | | header: FontSpecification |
| | | body: FontSpecification |
| | | code: FontSpecification |
| | |
| | | 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 } |
| | | } |
| | |
| | | } |
| | | |
| | | 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 { |
| | |
| | | --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}; |