diff --git a/pages/package-lock.json b/pages/package-lock.json index c986ec9..de1c7cd 100644 --- a/pages/package-lock.json +++ b/pages/package-lock.json @@ -16,6 +16,8 @@ "astro-rehype-relative-markdown-links": "^0.6.1", "fuse.js": "^7.0.0", "github-slugger": "^2.0.0", + "html-truncator": "^1.0.17", + "marked": "^13.0.2", "remark-collapse": "^0.1.2", "remark-toc": "^9.0.0", "satori": "^0.10.11", @@ -5862,7 +5864,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", - "dev": true, "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", @@ -5876,7 +5877,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "dev": true, "funding": [ { "type": "github", @@ -5888,7 +5888,6 @@ "version": "5.0.3", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", - "dev": true, "dependencies": { "domelementtype": "^2.3.0" }, @@ -5903,7 +5902,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", - "dev": true, "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", @@ -7685,6 +7683,35 @@ "node": "^14.13.1 || >=16.0.0" } }, + "node_modules/html-truncator": { + "version": "1.0.17", + "resolved": "https://mirrors.huaweicloud.com/repository/npm/html-truncator/-/html-truncator-1.0.17.tgz", + "integrity": "sha512-qa4vQJUGH4oZqdbAxsT4RG+PbBiVJHyPrvXI1P7FQegsxvuxozdAgxq5msPXzYD56JjO+nRh37mob6svIxBcDw==", + "license": "MIT", + "dependencies": { + "htmlparser2": "^8.0.2", + "lodash": "^4.17.21" + } + }, + "node_modules/html-truncator/node_modules/htmlparser2": { + "version": "8.0.2", + "resolved": "https://mirrors.huaweicloud.com/repository/npm/htmlparser2/-/htmlparser2-8.0.2.tgz", + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "entities": "^4.4.0" + } + }, "node_modules/html-void-elements": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", @@ -9126,8 +9153,7 @@ "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "node_modules/lodash-es": { "version": "4.17.21", @@ -9459,6 +9485,18 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/marked": { + "version": "13.0.2", + "resolved": "https://mirrors.huaweicloud.com/repository/npm/marked/-/marked-13.0.2.tgz", + "integrity": "sha512-J6CPjP8pS5sgrRqxVRvkCIkZ6MFdRIjDkwUwgJ9nL2fbmM6qGQeB2C16hi8Cc9BOzj6xXzy0jyi0iPIfnMHYzA==", + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 18" + } + }, "node_modules/mdast-util-definitions": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-6.0.0.tgz", diff --git a/pages/package.json b/pages/package.json index 2d91614..e07b16e 100644 --- a/pages/package.json +++ b/pages/package.json @@ -22,6 +22,8 @@ "astro-rehype-relative-markdown-links": "^0.6.1", "fuse.js": "^7.0.0", "github-slugger": "^2.0.0", + "html-truncator": "^1.0.17", + "marked": "^13.0.2", "remark-collapse": "^0.1.2", "remark-toc": "^9.0.0", "satori": "^0.10.11", diff --git a/pages/src/components/Card.tsx b/pages/src/components/Card.tsx index 93064cd..5c42792 100644 --- a/pages/src/components/Card.tsx +++ b/pages/src/components/Card.tsx @@ -1,6 +1,33 @@ import { STATUS_LIST } from "@config"; import { slugifyStr } from "@utils/slugify"; import type { CollectionEntry } from "astro:content"; +import { marked } from 'marked'; +import truncate from "html-truncator"; + +// 定义一个函数,解析body为markdown格式,然后去掉解析出来的所有h标签元素 +const parseBody = (body: string, href: string) => { + let marked_content = marked(body.substring(0, 1000)); // 避免过长的解析 + // check type of marked_content + if (typeof marked_content !== 'string') { + return body.substring(0, 130) + "……  [阅读更多]"; + } + // remove h1 + marked_content = marked_content.replace(/.*?<\/h.>/g, ''); + // remove img + marked_content = marked_content.replace(//g, ''); + // limit shown content length, but keep the html tags which are not closed + marked_content = truncate(marked_content, 130); + // default end is '...', remove it + marked_content = marked_content.replace(/\.\.\.$/, ""); + // get the last tag of the content + let lastTag = marked_content.lastIndexOf('<'); + // record the last tag + let lastTagContent = marked_content.substring(lastTag); + // remove the last tag + marked_content = marked_content.substring(0, lastTag); + let end = "……  [阅读更多]" + lastTagContent; + return marked_content + end; +} export interface Props { id?: string; @@ -60,10 +87,14 @@ export default function Card({ id, href, frontmatter, secHeading = true, body, p {/* */} {publishCard && -

- {body?.replace("#", "")?.substring(0, 130)} - [阅读更多] -

+ // 去掉段后间隔 +
+ {/* 注意需要my-0否则继承 */} +

+

+ +
} );