From b0e6576b338b514ec5addeb4061b0b8fcbb87fe9 Mon Sep 17 00:00:00 2001 From: Joseph Montanaro Date: Tue, 3 Mar 2026 20:31:46 -0500 Subject: [PATCH] add SmallCaps component and use for title --- .astro/content-modules.mjs | 4 +-- src/components/Post.astro | 9 ++++-- src/components/SmallCaps.astro | 50 ++++++++++++++++++++++++++++++++++ src/components/Toc.vue | 13 ++++----- 4 files changed, 63 insertions(+), 13 deletions(-) create mode 100644 src/components/SmallCaps.astro diff --git a/.astro/content-modules.mjs b/.astro/content-modules.mjs index 4abc3e2..e966991 100644 --- a/.astro/content-modules.mjs +++ b/.astro/content-modules.mjs @@ -1,6 +1,6 @@ export default new Map([ ["posts/after.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=posts%2Fafter.mdx&astroContentModuleFlag=true")], -["posts/test.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=posts%2Ftest.mdx&astroContentModuleFlag=true")], -["posts/before.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=posts%2Fbefore.mdx&astroContentModuleFlag=true")]]); +["posts/before.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=posts%2Fbefore.mdx&astroContentModuleFlag=true")], +["posts/test.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=posts%2Ftest.mdx&astroContentModuleFlag=true")]]); \ No newline at end of file diff --git a/src/components/Post.astro b/src/components/Post.astro index 596768b..23ce955 100644 --- a/src/components/Post.astro +++ b/src/components/Post.astro @@ -2,6 +2,7 @@ import type { CollectionEntry } from 'astro:content'; import { render } from 'astro:content'; +import SmallCaps from '@components/SmallCaps.astro'; import Toc from '@components/Toc.vue'; import { formatDate } from '@lib/datefmt'; @@ -39,9 +40,9 @@ article { } .subtitle { - font-size: 0.9em; + font-size: 0.85em; font-style: italic; - margin-top: -0.75rem; + margin-top: -1rem; } .post { @@ -73,7 +74,9 @@ footer {
-

{ entry.data.title }

+

+ +

{ formatDate(entry.data.date) }

diff --git a/src/components/SmallCaps.astro b/src/components/SmallCaps.astro new file mode 100644 index 0000000..62cfead --- /dev/null +++ b/src/components/SmallCaps.astro @@ -0,0 +1,50 @@ +--- +// few web fonts have "true" smallcaps, so instead they just take the full-size caps and scale them +// down to match the height of lowercase letters. But this leads to an awkward effect where the +// scaled-down caps are "lighter" looking than the regular-sized caps, so here we reduce the weight +// of just the full-sized caps to compensate. +export interface Props { + text: string, + upperWeight?: number | string, + lowerWeight?: number | string, +}; + +const { text, upperWeight = 'inherit', lowerWeight = 'bolder' } = Astro.props; + +const upperOrDigit = /[A-Z0-9]+/g; +let prevIdx = 0; +let segments = []; +for (const match of text.matchAll(upperOrDigit)) { + const lower = text.slice(prevIdx, match.index); + // if the first letter of the text is upper, this first segment will be '', so skip it + if (lower) { + segments.push({type: 'lower', chars: lower}) + }; + segments.push({type: 'upper', chars: match[0]}) + prevIdx = match.index + match[0].length; +} +const final = text.slice(prevIdx); +// if there is a final segment, it wasn't a match, so it must be lowercase +if (final) { + segments.push({type: 'lower', chars: final}) +}; +--- + + + { segments.map(s => { s.chars }) } + + + + diff --git a/src/components/Toc.vue b/src/components/Toc.vue index 6b37ca3..717fa43 100644 --- a/src/components/Toc.vue +++ b/src/components/Toc.vue @@ -69,7 +69,7 @@ onBeforeUnmount(() => {