From be6e8d1dddb386b2d34cd2566400672817c3e415 Mon Sep 17 00:00:00 2001 From: Mat Manna Date: Fri, 8 May 2026 21:32:55 -0400 Subject: [PATCH] fix: excerpt block extraction (#44) --- src/lib/content.ts | 17 ++++++++++++++++- src/pages/index.astro | 18 ++++++++++++++++-- src/styles/main.scss | 11 ++++------- 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/src/lib/content.ts b/src/lib/content.ts index a1c591d..dd1d025 100644 --- a/src/lib/content.ts +++ b/src/lib/content.ts @@ -170,14 +170,29 @@ function extractTextBlocks(body: string): string[] { return blocks .slice(leadingImage ? 1 : 0) + .filter((block) => { + if (/^#{1,6}\s+/.test(block.trim())) return false; + if (/^[=-]{3,}\s*$/.test(block.trim())) return false; + return true; + }) .map((block) => stripMarkdown(block)) .filter(Boolean); } function toExcerpt(entry: { body: string; data: { excerpt?: string } }): string { const explicitExcerpt = entry.data.excerpt; - const source = explicitExcerpt ?? extractTextBlocks(entry.body)[0] ?? ""; + if (explicitExcerpt) { + return stripMarkdown(explicitExcerpt); + } + + const blocks = extractTextBlocks(entry.body); + const substantial = blocks.find((b) => { + const cleaned = stripMarkdown(b); + const wordCount = cleaned.split(/\s+/).filter(Boolean).length; + return wordCount >= 8 && cleaned.length >= 60; + }); + const source = substantial ?? blocks[0] ?? ""; return stripMarkdown(source); } diff --git a/src/pages/index.astro b/src/pages/index.astro index a9d7c2c..3e569e0 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -17,7 +17,21 @@ const overrideHeadline = site.headlineOverride ? posts.find((post) => post.slug === site.headlineOverride) : undefined; const headline = overrideHeadline ?? allNews[0]; -const headlineExcerpts = headline?.paragraphs ?? []; +const headlineExcerpts = (() => { + const paras = headline?.paragraphs ?? []; + const filtered = paras.filter((p) => { + const s = p.replace(/\s+/g, " ").trim(); + if (!s) return false; + if (/^#{1,6}\s+/.test(s)) return false; + if (/^[=-]{3,}\s*$/.test(s)) return false; + const words = s.split(/\s+/).length; + if (words < 6) return false; + if (s.length < 40) return false; + return true; + }); + + return filtered.slice(0, headline?.leadingImage ? 1 : 2); +})(); const displayOpinion = posts.filter((post) => post.category === "opinion").slice(0, 3); @@ -51,7 +65,7 @@ const acknowledgements = await getAcknowledgements();
{headlineExcerpts.map((paragraph) => ( -

{headline.leadingImage ? paragraph : truncateWords(paragraph, 28)}

+

{headline.leadingImage ? paragraph : truncateWords(paragraph, 120)}

))}
diff --git a/src/styles/main.scss b/src/styles/main.scss index 1a041ce..f98e6f3 100644 --- a/src/styles/main.scss +++ b/src/styles/main.scss @@ -139,6 +139,7 @@ a { display: block; color: #000; transition: background 0.15s; + overflow: hidden; &:hover { background: #f0f0eb; @@ -188,11 +189,10 @@ a { .block-excerpts { flex: 1; min-height: 0; - max-height: calc(1.6em * 10); display: -webkit-box; -webkit-box-orient: vertical; - -webkit-line-clamp: 10; - line-clamp: 10; + -webkit-line-clamp: 6; + line-clamp: 6; overflow: hidden; text-overflow: ellipsis; } @@ -200,10 +200,7 @@ a { font-size: 1rem; line-height: 1.6; color: #222; - margin: 0; - } - .block-excerpt + .block-excerpt { - margin-top: 0.8em; + margin: 0 0 1.2em 0; } } -- 2.51.2