From 63b8bc7bd96368bc87202ebee0e0d92925ec22a3 Mon Sep 17 00:00:00 2001 From: Chi Nguyen Date: Thu, 19 Dec 2024 14:43:20 +0100 Subject: [PATCH 1/2] feat: Add support for coollabs fonts --- docs/custom/config-fonts.md | 6 +++--- packages/slidev/node/setups/indexHtml.ts | 7 +++++-- packages/slidev/node/utils.ts | 13 ++++++++++--- packages/types/src/config.ts | 2 +- packages/types/src/frontmatter.ts | 2 +- packages/vscode/schema/headmatter.json | 3 ++- test/__snapshots__/utils.test.ts.snap | 4 ++++ test/utils.test.ts | 21 ++++++++++++++++++++- 8 files changed, 46 insertions(+), 12 deletions(-) diff --git a/docs/custom/config-fonts.md b/docs/custom/config-fonts.md index 89810e531c..fa6faf392f 100644 --- a/docs/custom/config-fonts.md +++ b/docs/custom/config-fonts.md @@ -18,7 +18,7 @@ fonts: And that's all. -Fonts will be **imported automatically from [Google Fonts](https://fonts.google.com/)**. That means you can use any fonts available on Google Fonts directly. +Fonts will be **imported automatically from a provider via CDN, by default it is [Google Fonts](https://fonts.google.com/)**. That means you can use any fonts available on Google Fonts directly. ## Local Fonts @@ -92,10 +92,10 @@ fonts: ## Providers -- Options: `google` | `none` +- Options: `google` | `coollabs` | `none` - Default: `google` -Currently, only Google Fonts is supported, we are planning to add more providers in the future. Specify to `none` will disable the auto-importing feature entirely and treat all the fonts locally. +Currently, only [Google Fonts](https://fonts.google.com/) and [coolLabs](https://fonts.coollabs.io/) supported, we are planning to add more providers in the future. Specify to `none` will disable the auto-importing feature entirely and treat all the fonts locally. ```yaml --- diff --git a/packages/slidev/node/setups/indexHtml.ts b/packages/slidev/node/setups/indexHtml.ts index 56b6c3c342..a9c03a9c41 100644 --- a/packages/slidev/node/setups/indexHtml.ts +++ b/packages/slidev/node/setups/indexHtml.ts @@ -7,7 +7,7 @@ import { escapeHtml } from 'markdown-it/lib/common/utils.mjs' import { version } from '../../package.json' import { getSlideTitle } from '../commands/shared' import { toAtFS } from '../resolver' -import { generateGoogleFontsUrl } from '../utils' +import { generateCoollabsFontsUrl, generateGoogleFontsUrl } from '../utils' function toAttrValue(unsafe: unknown) { return JSON.stringify(escapeHtml(String(unsafe))) @@ -49,9 +49,12 @@ export default function setupIndexHtml({ mode, entry, clientRoot, userRoot, root if (data.features.tweet) body += '\n' - if (data.config.fonts.webfonts.length && data.config.fonts.provider !== 'none') + if (data.config.fonts.webfonts.length && data.config.fonts.provider === 'google') head += `\n` + if (data.config.fonts.webfonts.length && data.config.fonts.provider === 'coollabs') + head += `\n` + if (data.headmatter.lang) main = main.replace('', ``) diff --git a/packages/slidev/node/utils.ts b/packages/slidev/node/utils.ts index cc78985538..981d5d93c3 100644 --- a/packages/slidev/node/utils.ts +++ b/packages/slidev/node/utils.ts @@ -21,16 +21,23 @@ export function stringifyMarkdownTokens(tokens: Token[]) { .join(' ') } -export function generateGoogleFontsUrl(options: ResolvedFontOptions) { +export function generateFontParams(options: ResolvedFontOptions) { const weights = options.weights .flatMap(i => options.italic ? [`0,${i}`, `1,${i}`] : [`${i}`]) .sort() .join(';') - const fonts = options.webfonts + const fontParams = options.webfonts .map(i => `family=${i.replace(/^(['"])(.*)\1$/, '$1').replace(/\s+/g, '+')}:${options.italic ? 'ital,' : ''}wght@${weights}`) .join('&') + return fontParams +} + +export function generateGoogleFontsUrl(options: ResolvedFontOptions) { + return `https://fonts.googleapis.com/css2?${generateFontParams(options)}&display=swap` +} - return `https://fonts.googleapis.com/css2?${fonts}&display=swap` +export function generateCoollabsFontsUrl(options: ResolvedFontOptions) { + return `https://api.fonts.coollabs.io/fonts?${generateFontParams(options)}&display=swap` } /** diff --git a/packages/types/src/config.ts b/packages/types/src/config.ts index 05f2737c14..39e61a6027 100644 --- a/packages/types/src/config.ts +++ b/packages/types/src/config.ts @@ -18,7 +18,7 @@ export interface ResolvedFontOptions { serif: string[] weights: string[] italic: boolean - provider: 'none' | 'google' + provider: 'none' | 'google' | 'coollabs' webfonts: string[] local: string[] } diff --git a/packages/types/src/frontmatter.ts b/packages/types/src/frontmatter.ts index a9ae54f123..941a2234b0 100644 --- a/packages/types/src/frontmatter.ts +++ b/packages/types/src/frontmatter.ts @@ -398,7 +398,7 @@ export interface FontOptions { /** * @default 'google' */ - provider?: 'none' | 'google' + provider?: 'none' | 'google' | 'coollabs' /** * Specify web fonts names, will detect from `sans`, `mono`, `serif` if not provided */ diff --git a/packages/vscode/schema/headmatter.json b/packages/vscode/schema/headmatter.json index ea664d20f4..1a3082e1d3 100644 --- a/packages/vscode/schema/headmatter.json +++ b/packages/vscode/schema/headmatter.json @@ -712,7 +712,8 @@ "type": "string", "enum": [ "none", - "google" + "google", + "coollabs" ], "default": "google" }, diff --git a/test/__snapshots__/utils.test.ts.snap b/test/__snapshots__/utils.test.ts.snap index 6961c93c7c..e3e0d04865 100644 --- a/test/__snapshots__/utils.test.ts.snap +++ b/test/__snapshots__/utils.test.ts.snap @@ -1,5 +1,9 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html +exports[`utils > coollabs-fonts 1`] = `"https://api.fonts.coollabs.io/fonts?family=Fira+Code:wght@200;400;600&family=PT+Serif:wght@200;400;600&display=swap"`; + +exports[`utils > coollabs-fonts 2`] = `"https://api.fonts.coollabs.io/fonts?family=Fira+Code:ital,wght@0,200;0,400;0,600;1,200;1,400;1,600&family=PT+Serif:ital,wght@0,200;0,400;0,600;1,200;1,400;1,600&display=swap"`; + exports[`utils > google-fonts 1`] = `"https://fonts.googleapis.com/css2?family=Fira+Code:wght@200;400;600&family=PT+Serif:wght@200;400;600&display=swap"`; exports[`utils > google-fonts 2`] = `"https://fonts.googleapis.com/css2?family=Fira+Code:ital,wght@0,200;0,400;0,600;1,200;1,400;1,600&family=PT+Serif:ital,wght@0,200;0,400;0,600;1,200;1,400;1,600&display=swap"`; diff --git a/test/utils.test.ts b/test/utils.test.ts index c6854504d3..1d17f7a99c 100644 --- a/test/utils.test.ts +++ b/test/utils.test.ts @@ -6,7 +6,7 @@ import { describe, expect, it } from 'vitest' import YAML from 'yaml' import { parseAspectRatio, parseRangeString } from '../packages/parser/src' import { getRoots } from '../packages/slidev/node/resolver' -import { generateGoogleFontsUrl, stringifyMarkdownTokens, updateFrontmatterPatch } from '../packages/slidev/node/utils' +import { generateCoollabsFontsUrl, generateGoogleFontsUrl, stringifyMarkdownTokens, updateFrontmatterPatch } from '../packages/slidev/node/utils' describe('utils', () => { it('page-range', () => { @@ -61,6 +61,25 @@ describe('utils', () => { ).toMatchSnapshot() }) + it('coollabs-fonts', () => { + expect( + generateCoollabsFontsUrl({ + webfonts: ['Fira Code', 'PT Serif'], + weights: ['200', '400', '600'], + provider: 'google', + } as ResolvedFontOptions), + ).toMatchSnapshot() + + expect( + generateCoollabsFontsUrl({ + webfonts: ['Fira Code', 'PT Serif'], + weights: ['200', '400', '600'], + italic: true, + provider: 'google', + } as ResolvedFontOptions), + ).toMatchSnapshot() + }) + it('roots', async () => { const { cliRoot, clientRoot, userRoot, userWorkspaceRoot } = await getRoots(resolve('slides.md')) const expectRelative = (v: string) => expect(slash(relative(__dirname, v))) From 730cb003b19a061cd50ced26e0bb08ccd9a332f8 Mon Sep 17 00:00:00 2001 From: _Kerman Date: Thu, 19 Dec 2024 22:06:12 +0800 Subject: [PATCH 2/2] chore: update --- packages/slidev/node/setups/indexHtml.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/slidev/node/setups/indexHtml.ts b/packages/slidev/node/setups/indexHtml.ts index a9c03a9c41..4c0668bcd7 100644 --- a/packages/slidev/node/setups/indexHtml.ts +++ b/packages/slidev/node/setups/indexHtml.ts @@ -49,11 +49,13 @@ export default function setupIndexHtml({ mode, entry, clientRoot, userRoot, root if (data.features.tweet) body += '\n' - if (data.config.fonts.webfonts.length && data.config.fonts.provider === 'google') - head += `\n` - - if (data.config.fonts.webfonts.length && data.config.fonts.provider === 'coollabs') - head += `\n` + if (data.config.fonts.webfonts.length) { + const { provider } = data.config.fonts + if (provider === 'google') + head += `\n` + else if (provider === 'coollabs') + head += `\n` + } if (data.headmatter.lang) main = main.replace('', ``)