Commit 16eb26d
Changed files (8)
src/plugins/rehype-wrap-tables.mjs → src/plugins/rehype-wrap-tables.ts
@@ -1,13 +1,8 @@
+import type { RehypePlugin } from '@astrojs/markdown-remark';
+import type { ElementContent } from 'hast';
import { visit } from 'unist-util-visit';
-/**
- * Rehype plugin to wrap tables with a div for overflow auto
- *
- * Rehype 插件,为表格包裹一个带有 overflow auto 样式的 div
- *
- * @returns {import('unified').Plugin}
- */
-export function rehypeWrapTables() {
+export const rehypeWrapTables: RehypePlugin = function () {
return (tree) => {
visit(tree, 'element', (node, index, parent) => {
if (node.tagName === 'table' && parent && typeof index === 'number') {
@@ -17,8 +12,8 @@ export function rehypeWrapTables() {
properties: { className: ['overflow-auto'] },
children: [node],
};
- parent.children[index] = wrapper;
+ parent.children[index] = wrapper as ElementContent;
}
});
};
-}
+};
src/plugins/remark-excerpt.js → src/plugins/remark-excerpt.ts
@@ -1,22 +1,17 @@
+import type { RemarkPlugin } from '@astrojs/markdown-remark';
import { toString } from 'mdast-util-to-string';
-/**
- * Remark plugin to extract the first paragraph as excerpt
- *
- * 提取第一个段落作为摘要的 Remark 插件
- *
- * @returns {import('unified').Plugin}
- */
-export function remarkExcerpt() {
+export const remarkExcerpt: RemarkPlugin = function () {
return (tree, { data }) => {
let excerpt = '';
- for (let node of tree.children) {
+ for (const node of tree.children) {
if (node.type !== 'paragraph') {
continue;
}
excerpt = toString(node);
break;
}
+ // @ts-expect-error data.astro.frontmatter must be defined
data.astro.frontmatter.excerpt = excerpt;
};
-}
+};
src/plugins/remark-heading-shift.mjs
@@ -1,17 +0,0 @@
-import { visit } from 'unist-util-visit';
-
-/**
- * Remark plugin to shift all heading levels down by one (starting from h2)
- *
- * Remark 插件,将所有标题层级下移一级(从 h2 开始)
- *
- * @type {import('unified').Plugin}
- */
-export default function remarkHeadingShift() {
- return (tree) => {
- visit(tree, 'heading', (node) => {
- // 将所有标题层级加1(最大到6)
- node.depth = Math.min(node.depth + 1, 6);
- });
- };
-}
src/plugins/remark-heading-shift.ts
@@ -0,0 +1,11 @@
+import type { RemarkPlugin } from '@astrojs/markdown-remark';
+import { visit } from 'unist-util-visit';
+
+export const remarkHeadingShift: RemarkPlugin = function () {
+ return (tree) => {
+ visit(tree, 'heading', (node) => {
+ // 将所有标题层级加1(最大到6)
+ node.depth = Math.min(node.depth + 1, 6) as 1 | 2 | 3 | 4 | 5 | 6;
+ });
+ };
+};
src/plugins/remark-image-process.mjs → src/plugins/remark-image-process.ts
@@ -1,9 +1,7 @@
+import type { RemarkPlugin } from '@astrojs/markdown-remark';
import { visit } from 'unist-util-visit';
-/**
- * Remark plugin to add data-zoom attribute to all images
- */
-export function remarkImageProcess() {
+export const remarkImageProcess: RemarkPlugin = function () {
return (tree) => {
visit(tree, 'image', (node) => {
// 添加 data-zoom 属性到图片节点
@@ -16,4 +14,4 @@ export function remarkImageProcess() {
node.data.hProperties.decoding = 'async';
});
};
-}
+};
src/plugins/remark-reading-time.mjs → src/plugins/remark-reading-time.ts
@@ -1,18 +1,16 @@
+import type { RemarkPlugin } from '@astrojs/markdown-remark';
import { toString } from 'mdast-util-to-string';
import getReadingTime from 'reading-time';
-/**
- * Remark plugin to calculate reading time and word count
- *
- * Remark 插件,用于计算阅读时间和字数
- *
- * @returns {import('unified').Plugin}
- */
-export function remarkReadingTime() {
+export const remarkReadingTime: RemarkPlugin = function () {
return (tree, { data }) => {
const textOnPage = toString(tree);
const readingTime = getReadingTime(textOnPage);
+
+ // @ts-expect-error data.astro.frontmatter must be defined
data.astro.frontmatter.minutes = Math.max(1, Math.round(readingTime.minutes));
+
+ // @ts-expect-error data.astro.frontmatter must be defined
data.astro.frontmatter.words = readingTime.words;
};
-}
+};
astro.config.mjs
@@ -1,9 +1,10 @@
// @ts-check
import { CDN } from './src/constants/cdn.mjs';
-import { rehypeWrapTables } from './src/plugins/rehype-wrap-tables.mjs';
-import { remarkExcerpt } from './src/plugins/remark-excerpt';
-import { remarkImageProcess } from './src/plugins/remark-image-process.mjs';
-import { remarkReadingTime } from './src/plugins/remark-reading-time.mjs';
+import { rehypeWrapTables } from './src/plugins/rehype-wrap-tables.ts';
+import { remarkExcerpt } from './src/plugins/remark-excerpt.ts';
+// import { remarkHeadingShift } from './src/plugins/remark-heading-shift.ts';
+import { remarkImageProcess } from './src/plugins/remark-image-process.ts';
+import { remarkReadingTime } from './src/plugins/remark-reading-time.ts';
import { rehypeHeadingIds } from '@astrojs/markdown-remark';
import mdx from '@astrojs/mdx';
import sitemap from '@astrojs/sitemap';
package.json
@@ -49,6 +49,7 @@
"@astrojs/ts-plugin": "^1.10.4",
"@eslint/js": "^9.20.0",
"@trivago/prettier-plugin-sort-imports": "^5.2.2",
+ "@types/hast": "^3.0.4",
"@types/markdown-it": "^14.1.2",
"@types/mdast": "^4.0.4",
"@types/sanitize-html": "^2.13.0",