A calm place to write long-form, and publish it to the open social web. skypress.blog/
0

Configure Feed

Select the types of activity you want to include in your feed.

Add deriveExcerpt helper for description fallback

+49
+32
src/lib/publish/excerpt.test.ts
··· 1 + import { describe, expect, it } from 'vitest'; 2 + import { deriveExcerpt } from './excerpt'; 3 + 4 + describe( 'deriveExcerpt', () => { 5 + it( 'returns empty string for empty or whitespace-only input', () => { 6 + expect( deriveExcerpt( '' ) ).toBe( '' ); 7 + expect( deriveExcerpt( ' \n\t ' ) ).toBe( '' ); 8 + } ); 9 + 10 + it( 'returns short text unchanged, with no ellipsis', () => { 11 + expect( deriveExcerpt( 'A short lede.' ) ).toBe( 'A short lede.' ); 12 + } ); 13 + 14 + it( 'collapses internal whitespace and newlines to single spaces', () => { 15 + expect( deriveExcerpt( 'one\n\ntwo three' ) ).toBe( 'one two three' ); 16 + } ); 17 + 18 + it( 'truncates long text on a word boundary with a trailing ellipsis', () => { 19 + const long = 'word '.repeat( 100 ).trim(); // 499 chars, all word boundaries 20 + const result = deriveExcerpt( long ); 21 + expect( result.endsWith( '…' ) ).toBe( true ); 22 + // Body (sans ellipsis) stays within the limit and never splits a word. 23 + const body = result.slice( 0, -1 ); 24 + expect( body.length ).toBeLessThanOrEqual( 200 ); 25 + expect( body.endsWith( 'word' ) ).toBe( true ); 26 + expect( body.endsWith( ' ' ) ).toBe( false ); 27 + } ); 28 + 29 + it( 'honours a custom maxChars and cuts at the last space within it', () => { 30 + expect( deriveExcerpt( 'alpha beta gamma', 10 ) ).toBe( 'alpha…' ); 31 + } ); 32 + } );
+17
src/lib/publish/excerpt.ts
··· 1 + /** 2 + * A brief plain-text excerpt for a document/card description (the og:description fallback). 3 + * Collapses runs of whitespace to single spaces, cuts on a word boundary at or before 4 + * `maxChars`, and appends an ellipsis when it had to truncate. Returns '' for empty or 5 + * whitespace-only input. Pure + dependency-free (no `@wordpress/*`, no network) so it is 6 + * safe in BOTH the server reader and the browser publisher (AGENTS.md §3). 7 + */ 8 + export function deriveExcerpt( text: string, maxChars = 200 ): string { 9 + const normalized = text.replace( /\s+/g, ' ' ).trim(); 10 + if ( normalized.length <= maxChars ) { 11 + return normalized; 12 + } 13 + const slice = normalized.slice( 0, maxChars ); 14 + const lastSpace = slice.lastIndexOf( ' ' ); 15 + const cut = lastSpace > 0 ? slice.slice( 0, lastSpace ) : slice; 16 + return `${ cut.trimEnd() }…`; 17 + }