mirror of
https://github.com/reonokiy/blog.nokiy.net.git
synced 2025-06-16 03:32:51 +02:00
chore: improve article auto-excerpt, allow inline code to wrap
This commit is contained in:
parent
dfc30d7f85
commit
018f1c9b6c
11 changed files with 230 additions and 58 deletions
|
@ -8,7 +8,7 @@ lang: zh
|
|||
abbrlink: birth-of-retypeset
|
||||
---
|
||||
|
||||
[Retypeset](https://github.com/radishzzz/astro-theme-retypeset) 是一款基于 Astro 框架的静态博客主题,中文名为重新编排。作为一名编程小白,我花三个月时间开发了这款主题,感受颇多。这篇文章,就来分享一下 Retypeset 诞生的故事。
|
||||
Retypeset 是一款基于 Astro 框架的静态博客主题,中文名为重新编排。作为一名编程小白,我花三个月时间开发了这款主题,感受颇多。这篇文章,就来分享一下 Retypeset 诞生的故事。
|
||||
|
||||
## 初遇
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ Retypeset is a static blog theme based on the [Astro](https://astro.build/) fram
|
|||
|
||||
## Theme Configuration
|
||||
|
||||
Customize your blog through the configuration file [src/config.ts](https://github.com/radishzzz/astro-theme-retypeset/blob/master/src/config.ts).
|
||||
Customize your blog by modifying the configuration file [src/config.ts](https://github.com/radishzzz/astro-theme-retypeset/blob/master/src/config.ts).
|
||||
|
||||
### Site Information
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ Retypeset es un tema de blog estático basado en el framework [Astro](https://as
|
|||
|
||||
## Configuración del Tema
|
||||
|
||||
Personaliza tu blog a través del archivo de configuración [src/config.ts](https://github.com/radishzzz/astro-theme-retypeset/blob/master/src/config.ts).
|
||||
Personaliza tu blog mediante la modificación del archivo de configuración [src/config.ts](https://github.com/radishzzz/astro-theme-retypeset/blob/master/src/config.ts).
|
||||
|
||||
### Información del Sitio
|
||||
|
||||
|
|
|
@ -10,11 +10,11 @@ lang: ja
|
|||
abbrlink: theme-guide
|
||||
---
|
||||
|
||||
Retypesetは、日本語では「再組版」と呼ばれる、[Astro](https://astro.build/) フレームワークをベースにした静的ブログテーマです。本ガイドではテーマの設定方法と新しい記事の作成方法を紹介し、個人ブログを素早く構築できるようサポートします。
|
||||
Retypesetは、日本語では「再組版」と呼ばれる、[Astro](https://astro.build/) フレームワークをベースにした静的ブログテーマです。本ガイドではテーマの設定方法と新しい記事の作成方法を紹介し、個人ブログを素早く構築できるよう支援します。
|
||||
|
||||
## テーマ設定
|
||||
|
||||
設定ファイル [src/config.ts](https://github.com/radishzzz/astro-theme-retypeset/blob/master/src/config.ts) からあなたのブログをカスタマイズできます。
|
||||
設定ファイル [src/config.ts](https://github.com/radishzzz/astro-theme-retypeset/blob/master/src/config.ts) を変更してあなたのブログをカスタマイズできます。
|
||||
|
||||
### サイト情報
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ Retypeset — это статическая тема блога, основан
|
|||
|
||||
## Конфигурация темы
|
||||
|
||||
Настройте свой блог через конфигурационный файл [src/config.ts](https://github.com/radishzzz/astro-theme-retypeset/blob/master/src/config.ts).
|
||||
Настройте свой блог путем изменения конфигурационного файла [src/config.ts](https://github.com/radishzzz/astro-theme-retypeset/blob/master/src/config.ts).
|
||||
|
||||
### Информация о сайте
|
||||
|
||||
|
|
|
@ -10,11 +10,11 @@ lang: zh-tw
|
|||
abbrlink: theme-guide
|
||||
---
|
||||
|
||||
Retypeset 是一款基於 [Astro](https://astro.build/) 框架的靜態部落格主題,中文名為重新編排。本文為 Retypeset 主題上手指南,主要介紹主題配置與如何創建新文章,幫助你快速搭建個人部落格。
|
||||
Retypeset 是一款基於 [Astro](https://astro.build/) 框架的靜態部落格主題,中文名為重新編排。本文為 Retypeset 主題上手指南,主要介紹主題配置與如何創建新文章,來幫助你快速搭建個人部落格。
|
||||
|
||||
## 主題配置
|
||||
|
||||
通過配置文件 [src/config.ts](https://github.com/radishzzz/astro-theme-retypeset/blob/master/src/config.ts) 自定義你的部落格。
|
||||
通過修改配置文件 [src/config.ts](https://github.com/radishzzz/astro-theme-retypeset/blob/master/src/config.ts) 來自定義你的部落格。
|
||||
|
||||
### 站點信息
|
||||
|
||||
|
|
|
@ -10,11 +10,11 @@ lang: zh
|
|||
abbrlink: theme-guide
|
||||
---
|
||||
|
||||
Retypeset 是一款基于 [Astro](https://astro.build/) 框架的静态博客主题,中文名为重新编排。本文为 Retypeset 主题上手指南,主要介绍主题配置与如何创建新文章,帮助你快速搭建个人博客。
|
||||
Retypeset 是一款基于 [Astro](https://astro.build/) 框架的静态博客主题,中文名为重新编排。本文为 Retypeset 主题上手指南,主要介绍主题配置与如何创建新文章,来帮助你快速搭建个人博客。
|
||||
|
||||
## 主题配置
|
||||
|
||||
通过配置文件 [src/config.ts](https://github.com/radishzzz/astro-theme-retypeset/blob/master/src/config.ts) 自定义你的博客。
|
||||
通过修改配置文件 [src/config.ts](https://github.com/radishzzz/astro-theme-retypeset/blob/master/src/config.ts) 来自定义你的博客。
|
||||
|
||||
### 站点信息
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
/* Links */
|
||||
.heti :where(a) {
|
||||
--at-apply: 'underline decoration-secondary/40 underline-0.075em underline-offset-0.14em lg:underline-0.1em';
|
||||
--at-apply: 'underline decoration-secondary/40 underline-0.075em underline-offset-0.1em lg:underline-0.1em';
|
||||
--at-apply: 'font-medium transition-colors tracking-0 hover:(c-primary decoration-secondary/80) ';
|
||||
}
|
||||
|
||||
|
@ -102,7 +102,7 @@ html.dark .heti pre :where(span) {
|
|||
|
||||
/* Inline Code */
|
||||
.heti :where(code) {
|
||||
--at-apply: 'p-0.5 bg-secondary/5 rounded text-0.85em border border-solid border-secondary/5';
|
||||
--at-apply: 'px-1 py-0.5 bg-secondary/5 rounded text-0.85em border border-solid border-secondary/5 break-all';
|
||||
counter-reset: line;
|
||||
}
|
||||
.heti :where(code) span.line {
|
||||
|
|
|
@ -30,6 +30,15 @@ const EXCERPT_LENGTHS: Record<ExcerptScene, {
|
|||
},
|
||||
}
|
||||
|
||||
const HTML_ENTITIES: Record<string, string> = {
|
||||
'<': '<',
|
||||
'>': '>',
|
||||
'&': '&',
|
||||
'"': '"',
|
||||
''': '\'',
|
||||
' ': ' ',
|
||||
}
|
||||
|
||||
// Generate an excerpt from Markdown content
|
||||
export function generateExcerpt(
|
||||
content: string,
|
||||
|
@ -39,33 +48,41 @@ export function generateExcerpt(
|
|||
if (!content)
|
||||
return ''
|
||||
|
||||
// Remove Markdown headings
|
||||
const contentWithoutHeadings = content
|
||||
.replace(/^#{1,6}\s+\S.*$/gm, '')
|
||||
.replace(/\n{2,}/g, '\n\n')
|
||||
|
||||
const length = isCJKLang(lang)
|
||||
? EXCERPT_LENGTHS[scene].cjk
|
||||
: EXCERPT_LENGTHS[scene].other
|
||||
|
||||
// Remove all HTML tags and decode HTML entities
|
||||
const plainText = parser.render(content)
|
||||
// Remove all HTML tags
|
||||
let plainText = parser.render(contentWithoutHeadings)
|
||||
.replace(/<[^>]*>/g, '')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/&/g, '&')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, '\'')
|
||||
.replace(/ /g, ' ')
|
||||
|
||||
// Decode HTML entities using the mapping table
|
||||
Object.entries(HTML_ENTITIES).forEach(([entity, char]) => {
|
||||
plainText = plainText.replace(new RegExp(entity, 'g'), char)
|
||||
})
|
||||
|
||||
// Replace line breaks with spaces
|
||||
const normalizedText = plainText.replace(/\s+/g, ' ')
|
||||
// Remove spaces after CJK punctuation marks
|
||||
.replace(/([。?!:"」』])\s+/g, '$1')
|
||||
const excerpt = normalizedText.slice(0, length).trim()
|
||||
// Add ellipsis if text was truncated
|
||||
return normalizedText.length > length ? `${excerpt}...` : excerpt
|
||||
// Remove trailing punctuation from the excerpt
|
||||
if (normalizedText.length > length)
|
||||
return `${excerpt.replace(/\p{P}+$/u, '')}...`
|
||||
return excerpt
|
||||
}
|
||||
|
||||
// Automatically generate a description for the article
|
||||
// Automatically Generate article description
|
||||
export function generateDescription(
|
||||
post: CollectionEntry<'posts'>,
|
||||
scene: ExcerptScene,
|
||||
): string {
|
||||
// If the article already has a description, return it directly
|
||||
// Prioritize existing description
|
||||
if (post.data.description)
|
||||
return post.data.description
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue