diff --git a/src/command/render/pandoc.ts b/src/command/render/pandoc.ts index 3e6108a310c..d4f03d4f19c 100644 --- a/src/command/render/pandoc.ts +++ b/src/command/render/pandoc.ts @@ -202,6 +202,11 @@ import { } from "../../core/markdown-pipeline.ts"; import { getEnv } from "../../../package/src/util/utils.ts"; import { canonicalizeTitlePostprocessor } from "../../format/html/format-html-title.ts"; +import { + BrandFontBunny, + BrandFontFile, + BrandFontGoogle, +} from "../../resources/types/schema-types.ts"; // in case we are running multiple pandoc processes // we need to make sure we capture all of the trace files @@ -1359,18 +1364,25 @@ async function resolveExtras( const ttf_urls = [], woff_urls: Array = []; if (brand?.data.typography) { const fonts = brand.data.typography.fonts || []; - for (const font of fonts) { - if (font.source === "file") { + for (const _font of fonts) { + // if font lacks a source, we assume google in typst output + + // deno-lint-ignore no-explicit-any + const source: string = (_font as any).source ?? "google"; + if (source === "file") { + const font = _font as BrandFontFile; for (const file of font.files || []) { const path = typeof file === "object" ? file.path : file; fontdirs.add(dirname(join(brand.brandDir, path))); } - } else if (font.source === "bunny") { + } else if (source === "bunny") { + const font = _font as BrandFontBunny; console.log( "Font bunny is not yet supported for Typst, skipping", font.family, ); - } else if (font.source === "google" /* || font.source === "bunny" */) { + } else if (source === "google" /* || font.source === "bunny" */) { + const font = _font as BrandFontGoogle; let { family, style, weight } = font; const parts = [family!]; if (style) { @@ -1382,7 +1394,7 @@ async function resolveExtras( parts.push(weight.join(",")); } const response = await fetch( - `${base_urls[font.source]}?family=${parts.join(":")}`, + `${base_urls[source]}?family=${parts.join(":")}`, ); const lines = (await response.text()).split("\n"); for (const line of lines) { diff --git a/src/core/sass/brand.ts b/src/core/sass/brand.ts index 9004b0653a1..23faceae596 100644 --- a/src/core/sass/brand.ts +++ b/src/core/sass/brand.ts @@ -18,6 +18,7 @@ import { ProjectContext } from "../../project/types.ts"; import { BrandFont, BrandFontBunny, + BrandFontCommon, BrandFontGoogle, BrandFontWeight, } from "../../resources/types/schema-types.ts"; @@ -110,7 +111,7 @@ const fontFileFormat = (file: string): string => { } }; -const bunnyFontImportString = (description: BrandFontBunny) => { +const bunnyFontImportString = (description: BrandFontCommon) => { const bunnyName = (name: string) => name.replace(/ /g, "-"); const bunnyFamily = description.family; if (!bunnyFamily) { @@ -137,7 +138,6 @@ const bunnyFontImportString = (description: BrandFontBunny) => { return `@import url('https://fonts.bunny.net/css?family=${ bunnyName(bunnyFamily) }:${weights}&display=${display}');`; - // } }; const googleFontImportString = (description: BrandFontGoogle) => { @@ -198,7 +198,7 @@ const brandColorBundle = ( ); colorCssVariables.push( ` --brand-${colorVar}: ${brand.getColor(colorKey)};`, - ) + ); } // Map theme colors directly to Sass variables @@ -222,7 +222,10 @@ const brandColorBundle = ( } // const colorEntries = Object.keys(brand.color); colorVariables.push('// quarto-scss-analysis-annotation { "action": "pop" }'); - colorCssVariables.push("}", '// quarto-scss-analysis-annotation { "action": "pop" }'); + colorCssVariables.push( + "}", + '// quarto-scss-analysis-annotation { "action": "pop" }', + ); const colorBundle: SassBundleLayers = { key, // dependency: "bootstrap", @@ -239,13 +242,13 @@ const brandColorBundle = ( const brandBootstrapBundle = ( brand: Brand, - key: string + key: string, ): SassBundleLayers => { // Bootstrap Variables from brand.defaults.bootstrap - const brandBootstrap = (brand?.data?.defaults?.bootstrap as unknown as Record< + const brandBootstrap = brand?.data?.defaults?.bootstrap as unknown as Record< string, Record - >); + >; const bsVariables: string[] = [ "/* Bootstrap variables from _brand.yml */", @@ -276,7 +279,7 @@ const brandBootstrapBundle = ( "green", "teal", "cyan", - ] + ]; const bsColors: string[] = [ "/* Bootstrap color variables from _brand.yml */", @@ -368,6 +371,41 @@ const brandTypographyBundle = ( return googleFamily; }; + const resolveBunnyFontFamily = ( + font: BrandFont[], + ): string | undefined => { + let googleFamily = ""; + for (const _resolvedFont of font) { + const resolvedFont = + _resolvedFont as (BrandFont | BrandFontGoogle | BrandFontBunny); + // Typescript's type checker doesn't understand that it's ok to attempt + // to access a property that might not exist on a type when you're + // only testing for its existence. + + // deno-lint-ignore no-explicit-any + const source = (resolvedFont as any).source; + if (source && source !== "bunny") { + return undefined; + } + const thisFamily = resolvedFont.family; + if (!thisFamily) { + continue; + } + if (googleFamily === "") { + googleFamily = thisFamily; + } else if (googleFamily !== thisFamily) { + throw new Error( + `Inconsistent Google font families found: ${googleFamily} and ${thisFamily}`, + ); + } + typographyImports.add(bunnyFontImportString(resolvedFont)); + } + if (googleFamily === "") { + return undefined; + } + return googleFamily; + }; + type HTMLFontInformation = { [key: string]: unknown }; type FontKind = @@ -389,7 +427,7 @@ const brandTypographyBundle = ( const font = getFontFamilies(family); const result: HTMLFontInformation = {}; result.family = resolveGoogleFontFamily(font) ?? - // resolveBunnyFontFamily(font) ?? + resolveBunnyFontFamily(font) ?? // resolveFilesFontFamily(font) ?? family; for ( @@ -566,7 +604,12 @@ export async function brandBootstrapSassBundleLayers( nameMap: Record = {}, ): Promise { const brand = await project.resolveBrand(fileName); - const sassBundles = await brandSassBundleLayers(fileName, project, key, nameMap); + const sassBundles = await brandSassBundleLayers( + fileName, + project, + key, + nameMap, + ); if (brand?.data?.defaults?.bootstrap) { const bsBundle = brandBootstrapBundle(brand, key); diff --git a/src/resources/editor/tools/vs-code.mjs b/src/resources/editor/tools/vs-code.mjs index 1803bb0daef..bb2d371af3d 100644 --- a/src/resources/editor/tools/vs-code.mjs +++ b/src/resources/editor/tools/vs-code.mjs @@ -12301,6 +12301,9 @@ var require_yaml_intelligence_resources = __commonJS({ }, { ref: "brand-font-system" + }, + { + ref: "brand-font-common" } ] }, @@ -21778,6 +21781,7 @@ var require_yaml_intelligence_resources = __commonJS({ "A link or path to the brand\u2019s dark-colored logo or icon.", "Alternative text for the logo, used for accessibility.", "Provide definitions and defaults for brand\u2019s logo in various formats\nand sizes.", + "A dictionary of named logo resources.", "A link or path to the brand\u2019s small-sized logo or icon, or a link or\npath to both the light and dark versions.", "A link or path to the brand\u2019s medium-sized logo, or a link or path to\nboth the light and dark versions.", "A link or path to the brand\u2019s large- or full-sized logo, or a link or\npath to both the light and dark versions.", @@ -21801,13 +21805,13 @@ var require_yaml_intelligence_resources = __commonJS({ "Typography definitions for the brand.", "Font files and definitions for the brand.", "The base font settings for the brand. These are used as the default\nfor all text.", - "Settings for headings", - "Settings for monospace text", - "Settings for inline code", - "Settings for code blocks", - "Settings for links", - "Typographic options.", - "Typographic options without a font size.", + "Settings for headings, or a string specifying the font family\nonly.", + "Settings for monospace text, or a string specifying the font family\nonly.", + "Settings for inline code, or a string specifying the font family\nonly.", + "Settings for code blocks, or a string specifying the font family\nonly.", + "Settings for links.", + "Base typographic options.", + "Typographic options for headings.", "Typographic options for monospace elements.", "Typographic options for inline monospace elements.", "Line height", diff --git a/src/resources/editor/tools/yaml/web-worker.js b/src/resources/editor/tools/yaml/web-worker.js index 9d90994b941..877fc79c071 100644 --- a/src/resources/editor/tools/yaml/web-worker.js +++ b/src/resources/editor/tools/yaml/web-worker.js @@ -12302,6 +12302,9 @@ try { }, { ref: "brand-font-system" + }, + { + ref: "brand-font-common" } ] }, @@ -21779,6 +21782,7 @@ try { "A link or path to the brand\u2019s dark-colored logo or icon.", "Alternative text for the logo, used for accessibility.", "Provide definitions and defaults for brand\u2019s logo in various formats\nand sizes.", + "A dictionary of named logo resources.", "A link or path to the brand\u2019s small-sized logo or icon, or a link or\npath to both the light and dark versions.", "A link or path to the brand\u2019s medium-sized logo, or a link or path to\nboth the light and dark versions.", "A link or path to the brand\u2019s large- or full-sized logo, or a link or\npath to both the light and dark versions.", @@ -21802,13 +21806,13 @@ try { "Typography definitions for the brand.", "Font files and definitions for the brand.", "The base font settings for the brand. These are used as the default\nfor all text.", - "Settings for headings", - "Settings for monospace text", - "Settings for inline code", - "Settings for code blocks", - "Settings for links", - "Typographic options.", - "Typographic options without a font size.", + "Settings for headings, or a string specifying the font family\nonly.", + "Settings for monospace text, or a string specifying the font family\nonly.", + "Settings for inline code, or a string specifying the font family\nonly.", + "Settings for code blocks, or a string specifying the font family\nonly.", + "Settings for links.", + "Base typographic options.", + "Typographic options for headings.", "Typographic options for monospace elements.", "Typographic options for inline monospace elements.", "Line height", diff --git a/src/resources/editor/tools/yaml/yaml-intelligence-resources.json b/src/resources/editor/tools/yaml/yaml-intelligence-resources.json index dc93ab848ce..3e8126dd1e6 100644 --- a/src/resources/editor/tools/yaml/yaml-intelligence-resources.json +++ b/src/resources/editor/tools/yaml/yaml-intelligence-resources.json @@ -5273,6 +5273,9 @@ }, { "ref": "brand-font-system" + }, + { + "ref": "brand-font-common" } ] }, @@ -14750,6 +14753,7 @@ "A link or path to the brand’s dark-colored logo or icon.", "Alternative text for the logo, used for accessibility.", "Provide definitions and defaults for brand’s logo in various formats\nand sizes.", + "A dictionary of named logo resources.", "A link or path to the brand’s small-sized logo or icon, or a link or\npath to both the light and dark versions.", "A link or path to the brand’s medium-sized logo, or a link or path to\nboth the light and dark versions.", "A link or path to the brand’s large- or full-sized logo, or a link or\npath to both the light and dark versions.", @@ -14773,13 +14777,13 @@ "Typography definitions for the brand.", "Font files and definitions for the brand.", "The base font settings for the brand. These are used as the default\nfor all text.", - "Settings for headings", - "Settings for monospace text", - "Settings for inline code", - "Settings for code blocks", - "Settings for links", - "Typographic options.", - "Typographic options without a font size.", + "Settings for headings, or a string specifying the font family\nonly.", + "Settings for monospace text, or a string specifying the font family\nonly.", + "Settings for inline code, or a string specifying the font family\nonly.", + "Settings for code blocks, or a string specifying the font family\nonly.", + "Settings for links.", + "Base typographic options.", + "Typographic options for headings.", "Typographic options for monospace elements.", "Typographic options for inline monospace elements.", "Line height", diff --git a/src/resources/schema/definitions.yml b/src/resources/schema/definitions.yml index f57b4212876..3564e722729 100644 --- a/src/resources/schema/definitions.yml +++ b/src/resources/schema/definitions.yml @@ -2688,7 +2688,7 @@ description: Settings for headings, or a string specifying the font family only. ref: brand-typography-options-headings monospace: - description: Settings for monospace text, or a string specifying the font family only. + description: Settings for monospace text, or a string specifying the font family only. ref: brand-typography-options-monospace monospace-inline: description: Settings for inline code, or a string specifying the font family only. @@ -2697,7 +2697,7 @@ description: Settings for code blocks, or a string specifying the font family only. ref: brand-typography-options-monospace-block link: - description: Settings for links. + description: Settings for links. ref: brand-typography-options-link - id: brand-typography-options-base @@ -2811,7 +2811,12 @@ - ref: brand-font-bunny - ref: brand-font-file - ref: brand-font-system - + # a font definition missing source information, + # from which we will assume a default source + # + # in Quarto, the default source for typst is `google` + # and the default source for html formats is `bunny` + - ref: brand-font-common - id: brand-font-weight description: A font weight. enum: diff --git a/src/resources/schema/json-schemas.json b/src/resources/schema/json-schemas.json index 19083f5d4b7..71c00c47152 100644 --- a/src/resources/schema/json-schemas.json +++ b/src/resources/schema/json-schemas.json @@ -3593,6 +3593,9 @@ }, { "$ref": "#/$defs/BrandFontSystem" + }, + { + "$ref": "#/$defs/BrandFontCommon" } ] }, diff --git a/src/resources/types/schema-types.ts b/src/resources/types/schema-types.ts index cb0d76d3bee..25af59ee32f 100644 --- a/src/resources/types/schema-types.ts +++ b/src/resources/types/schema-types.ts @@ -1405,7 +1405,8 @@ export type BrandFont = | BrandFontGoogle | BrandFontBunny | BrandFontFile - | BrandFontSystem; /* Font files and definitions for the brand. */ + | BrandFontSystem + | BrandFontCommon; /* Font files and definitions for the brand. */ export type BrandFontWeight = | 100