Skip to content

Commit 44f2600

Browse files
committed
refactor: compute reading time from body, drop legacy remark plugin for Astro 7
1 parent 0ccccb9 commit 44f2600

8 files changed

Lines changed: 32 additions & 29 deletions

File tree

astro.config.mjs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
import { defineConfig } from 'astro/config';
22
import sitemap from '@astrojs/sitemap';
3-
import { readingTimePlugin } from './src/plugins/readingTimePlugin.js';
43
import siteConfig from './site.config.mjs';
54

65
export default defineConfig({
76
site: siteConfig.SITE_URL,
87
integrations: [sitemap()],
9-
markdown: {
10-
remarkPlugins: [readingTimePlugin],
11-
},
128
});

bun.lock

Lines changed: 0 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@
1515
"@astrojs/sitemap": "^3.7.2",
1616
"astro": "^7.0.0",
1717
"isomorphic-git": "^1.37.5",
18-
"marked": "^18.0.0",
19-
"mdast-util-to-string": "^4.0.0"
18+
"marked": "^18.0.0"
2019
},
2120
"devDependencies": {
2221
"typescript": "^6.0.2"

src/components/BlogCard.astro

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { CollectionEntry } from 'astro:content';
33
import PostMeta from './PostMeta.astro';
44
import { getPostTitle } from '../utils/content';
55
import { getPostComputedMetadataById } from '../utils/postMetadata';
6+
import { getReadingTime } from '../utils/readingTime';
67
import siteConfig from '../../site.config.mjs';
78
89
export interface Props {
@@ -11,6 +12,7 @@ export interface Props {
1112
1213
const { post } = Astro.props;
1314
const { description, date, tags, readTime, commitHash } = post.data;
15+
const effectiveReadTime = readTime ?? getReadingTime(post.body ?? '');
1416
const title = getPostTitle(post);
1517
const postUrl = `/blog/${post.id.replace(/\.md$/, '')}/`;
1618
@@ -23,7 +25,7 @@ const effectiveCommitURL = siteConfig.SHOW_COMMIT_INFO ? computed?.commitURL : u
2325
<article class="blog-post" data-title={title} data-description={description} data-tags={tags.join(',')}>
2426
<h3>
2527
<a href={postUrl} class="post-link">{title}</a>
26-
{effectiveDate && <PostMeta date={effectiveDate} commitURL={effectiveCommitURL} commitHash={effectiveCommitHash} readTime={readTime} />}
28+
{effectiveDate && <PostMeta date={effectiveDate} commitURL={effectiveCommitURL} commitHash={effectiveCommitHash} readTime={effectiveReadTime} />}
2729
</h3>
2830
{description && <p class="post-description">{description}</p>}
2931
</article>

src/content.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { defineCollection, z } from 'astro:content';
22
import { glob } from 'astro/loaders';
33

44
const blog = defineCollection({
5-
loader: glob({ pattern: '**/*.md', base: './src/content/blog' }),
5+
loader: glob({ pattern: '**/*.md', base: './src/content/blog', retainBody: true }),
66
schema: z.object({
77
author: z.string().default('Kreato'),
88
tags: z.array(z.string()).default([]),

src/layouts/BlogLayout.astro

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import ThemeSettings from '../components/ThemeSettings.astro';
66
import type { CollectionEntry } from 'astro:content';
77
import { getPostTitle } from '../utils/content';
88
import { getPostComputedMetadataById } from '../utils/postMetadata';
9+
import { getReadingTime } from '../utils/readingTime';
910
import { render } from 'astro:content';
1011
1112
export interface Props {
@@ -15,6 +16,7 @@ export interface Props {
1516
1617
const { entry, relatedPosts = [] } = Astro.props;
1718
const { title: frontmatterTitle, description, author, date, tags, readTime } = entry.data;
19+
const effectiveReadTime = readTime ?? getReadingTime(entry.body ?? '');
1820
const title = frontmatterTitle || getPostTitle(entry);
1921
const { Content } = await render(entry);
2022
@@ -47,12 +49,12 @@ const structuredData = {
4749
<h1>{title}</h1>
4850
<p class="post-meta">
4951
{tags.length > 0 && <TagList tags={tags} />}
50-
{tags.length > 0 && (author || effectiveDate || readTime) && <span class="meta-separator">·</span>}
52+
{tags.length > 0 && (author || effectiveDate || effectiveReadTime) && <span class="meta-separator">·</span>}
5153
{author && <span>by {author}</span>}
52-
{author && (effectiveDate || readTime) && <span class="meta-separator">·</span>}
54+
{author && (effectiveDate || effectiveReadTime) && <span class="meta-separator">·</span>}
5355
{effectiveDate && <time datetime={effectiveDate.toISOString()}>{effectiveDate.toLocaleDateString()}</time>}
54-
{effectiveDate && readTime && <span class="meta-separator">·</span>}
55-
{readTime && <span>{readTime}</span>}
56+
{effectiveDate && effectiveReadTime && <span class="meta-separator">·</span>}
57+
{effectiveReadTime && <span>{effectiveReadTime}</span>}
5658
</p>
5759
</header>
5860
<div class="content">

src/plugins/readingTimePlugin.js

Lines changed: 0 additions & 13 deletions
This file was deleted.

src/utils/readingTime.js

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,26 @@
11
export function calculateReadingTime(content) {
22
const wordsPerMinute = 200;
3-
const words = content.trim().split(/\s+/).length;
3+
const words = content.trim().split(/\s+/).filter(Boolean).length;
44
const minutes = Math.ceil(words / wordsPerMinute);
55
return `~${minutes} min read`;
66
}
7+
8+
function stripMarkdown(body = '') {
9+
return body
10+
.replace(/```[\s\S]*?```/g, ' ')
11+
.replace(/~~~[\s\S]*?~~~/g, ' ')
12+
.replace(/`[^`]*`/g, ' ')
13+
.replace(/!\[[^\]]*\]\([^)]*\)/g, ' ')
14+
.replace(/\[([^\]]*)\]\([^)]*\)/g, '$1')
15+
.replace(/^>{1,}\s+/gm, ' ')
16+
.replace(/^#{1,6}\s+/gm, ' ')
17+
.replace(/^\s*[-*+]\s+/gm, ' ')
18+
.replace(/[*_~]/g, ' ')
19+
.replace(/^\s*[-*_]{3,}\s*$/gm, ' ')
20+
.replace(/\s+/g, ' ')
21+
.trim();
22+
}
23+
24+
export function getReadingTime(body) {
25+
return calculateReadingTime(stripMarkdown(body));
26+
}

0 commit comments

Comments
 (0)