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
This commit is contained in:
		@@ -41,11 +41,12 @@ This part of the configuration concerns anything that can affect the whole site.
 | 
			
		||||
- `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
 | 
			
		||||
 
 | 
			
		||||
@@ -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 (() => {
 | 
			
		||||
            <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" />
 | 
			
		||||
 
 | 
			
		||||
@@ -17,6 +17,7 @@ PageTitle.css = `
 | 
			
		||||
.page-title {
 | 
			
		||||
  font-size: 1.75rem;
 | 
			
		||||
  margin: 0;
 | 
			
		||||
  font-family: var(--titleFont);
 | 
			
		||||
}
 | 
			
		||||
`
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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",
 | 
			
		||||
 
 | 
			
		||||
@@ -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};
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user