add description for verification
This commit is contained in:
200
lib/rss.tsx
200
lib/rss.tsx
@@ -1,100 +1,100 @@
|
|||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import { CopyrightAnnouncement, LatestPostCountInHomePage, WebsiteURL } from "@/consts/consts";
|
import { CopyrightAnnouncement, LatestPostCountInHomePage, WebsiteURL } from "@/consts/consts";
|
||||||
import { Config } from "@/data/config";
|
import { Config } from "@/data/config";
|
||||||
import { Feed } from "feed";
|
import { Feed } from "feed";
|
||||||
import { JSDOM } from "jsdom";
|
import { JSDOM } from "jsdom";
|
||||||
import { MDXRemote } from "next-mdx-remote";
|
import { MDXRemote } from "next-mdx-remote";
|
||||||
import { serialize } from "next-mdx-remote/serialize";
|
import { serialize } from "next-mdx-remote/serialize";
|
||||||
import { renderToString } from "react-dom/server";
|
import { renderToString } from "react-dom/server";
|
||||||
import rehypeAutolinkHeadings from "rehype-autolink-headings";
|
import rehypeAutolinkHeadings from "rehype-autolink-headings";
|
||||||
import rehypeMathJax from "rehype-mathjax/svg";
|
import rehypeMathJax from "rehype-mathjax/svg";
|
||||||
import rehypePresetMinify from "rehype-preset-minify";
|
import rehypePresetMinify from "rehype-preset-minify";
|
||||||
import rehypeRaw from "rehype-raw";
|
import rehypeRaw from "rehype-raw";
|
||||||
import rehypeSlug from "rehype-slug";
|
import rehypeSlug from "rehype-slug";
|
||||||
import externalLinks from "remark-external-links";
|
import externalLinks from "remark-external-links";
|
||||||
import remarkGfm from "remark-gfm";
|
import remarkGfm from "remark-gfm";
|
||||||
import remarkMath from "remark-math";
|
import remarkMath from "remark-math";
|
||||||
import remarkPrism from "remark-prism";
|
import remarkPrism from "remark-prism";
|
||||||
import { getPostFileContent, sortedPosts } from "./post-process";
|
import { getPostFileContent, sortedPosts } from "./post-process";
|
||||||
|
|
||||||
const NoticeForRSSReaders = (postId: string) => `
|
const NoticeForRSSReaders = (postId: string) => `
|
||||||
---
|
---
|
||||||
**NOTE:** Different RSS reader may have deficient even no support for svg formulations rendering.
|
**NOTE:** Different RSS reader may have deficient even no support for svg formulations rendering.
|
||||||
If it happens, [please read the origin web page](https://${Config.SiteDomain}/blog/${postId}) to have better experience
|
If it happens, [please read the origin web page](https://${Config.SiteDomain}/blog/${postId}) to have better experience
|
||||||
`;
|
`;
|
||||||
|
|
||||||
function minifyHTMLCode(htmlString: string): string {
|
function minifyHTMLCode(htmlString: string): string {
|
||||||
const dom = new JSDOM(htmlString);
|
const dom = new JSDOM(htmlString);
|
||||||
const document = dom.window.document;
|
const document = dom.window.document;
|
||||||
const elements = document.querySelectorAll("*");
|
const elements = document.querySelectorAll("*");
|
||||||
const unusedElements = document.querySelectorAll("script, style");
|
const unusedElements = document.querySelectorAll("script, style");
|
||||||
|
|
||||||
// Remove all class attributes.
|
// Remove all class attributes.
|
||||||
elements.forEach((element) => {
|
elements.forEach((element) => {
|
||||||
element.removeAttribute("class");
|
element.removeAttribute("class");
|
||||||
});
|
});
|
||||||
|
|
||||||
// Remove all script and style tags.
|
// Remove all script and style tags.
|
||||||
unusedElements.forEach((element) => {
|
unusedElements.forEach((element) => {
|
||||||
element.parentElement?.removeChild(element);
|
element.parentElement?.removeChild(element);
|
||||||
});
|
});
|
||||||
|
|
||||||
return dom.serialize();
|
return dom.serialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate the RSS Feed File in `./public` so it could be visited by https://domain/rss.xml
|
* Generate the RSS Feed File in `./public` so it could be visited by https://domain/rss.xml
|
||||||
*/
|
*/
|
||||||
export const generateRSSFeed = async () => {
|
export const generateRSSFeed = async () => {
|
||||||
const feed = new Feed({
|
const feed = new Feed({
|
||||||
title: Config.SiteTitle,
|
title: Config.SiteTitle,
|
||||||
description: Config.Sentence,
|
description: Config.Sentence,
|
||||||
id: Config.SiteDomain,
|
id: Config.SiteDomain,
|
||||||
link: WebsiteURL,
|
link: WebsiteURL,
|
||||||
image: Config.PageCovers.websiteCoverURL,
|
image: Config.PageCovers.websiteCoverURL,
|
||||||
favicon: `https://${Config.SiteDomain}/favcion.ico`,
|
favicon: `https://${Config.SiteDomain}/favcion.ico`,
|
||||||
copyright: CopyrightAnnouncement,
|
copyright: CopyrightAnnouncement,
|
||||||
generator: "Node.js Feed",
|
generator: "Node.js Feed",
|
||||||
author: {
|
author: {
|
||||||
name: Config.AuthorName,
|
name: Config.AuthorName,
|
||||||
email: Config.SocialLinks.email,
|
email: Config.SocialLinks.email,
|
||||||
link: WebsiteURL,
|
link: WebsiteURL,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
for (let i = 0; i < Math.min(LatestPostCountInHomePage, sortedPosts.allPostList.length); i++) {
|
for (let i = 0; i < Math.min(LatestPostCountInHomePage, sortedPosts.allPostList.length); i++) {
|
||||||
const post = sortedPosts.allPostList[i];
|
const post = sortedPosts.allPostList[i];
|
||||||
const postFileContent = `${getPostFileContent(post.id)}${NoticeForRSSReaders(post.id)}`;
|
const postFileContent = `${getPostFileContent(post.id)}${NoticeForRSSReaders(post.id)}`;
|
||||||
const dateNumber = post.frontMatter.time.split("-").map((num: string) => Number.parseInt(num));
|
const dateNumber = post.frontMatter.time.split("-").map((num: string) => Number.parseInt(num));
|
||||||
const mdxSource = await serialize(postFileContent ?? "", {
|
const mdxSource = await serialize(postFileContent ?? "", {
|
||||||
parseFrontmatter: true,
|
parseFrontmatter: true,
|
||||||
mdxOptions: {
|
mdxOptions: {
|
||||||
remarkPlugins: [remarkPrism, externalLinks, remarkMath, remarkGfm],
|
remarkPlugins: [remarkPrism, externalLinks, remarkMath, remarkGfm],
|
||||||
rehypePlugins: [rehypeMathJax, rehypeAutolinkHeadings, rehypeSlug, rehypePresetMinify as any, rehypeRaw],
|
rehypePlugins: [rehypeMathJax, rehypeAutolinkHeadings, rehypeSlug, rehypePresetMinify as any, rehypeRaw],
|
||||||
format: "md",
|
format: "md",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const htmlContent = minifyHTMLCode(renderToString(<MDXRemote {...mdxSource} />));
|
const htmlContent = minifyHTMLCode(renderToString(<MDXRemote {...mdxSource} />));
|
||||||
|
|
||||||
feed.addItem({
|
feed.addItem({
|
||||||
title: post.frontMatter.title,
|
title: post.frontMatter.title,
|
||||||
id: post.id,
|
id: post.id,
|
||||||
link: `https://${Config.SiteDomain}/blog/${post.id}`,
|
link: `https://${Config.SiteDomain}/blog/${post.id}`,
|
||||||
description: post.frontMatter.summary ?? undefined,
|
description: "feedId:68173131511981056+userId:69616630442815488",
|
||||||
content: htmlContent,
|
content: htmlContent,
|
||||||
author: [
|
author: [
|
||||||
{
|
{
|
||||||
name: Config.AuthorName,
|
name: Config.AuthorName,
|
||||||
email: Config.SocialLinks.email,
|
email: Config.SocialLinks.email,
|
||||||
link: `https://${Config.SiteDomain}/about`,
|
link: `https://${Config.SiteDomain}/about`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
category: post.frontMatter.tags?.map((tagname: string) => ({
|
category: post.frontMatter.tags?.map((tagname: string) => ({
|
||||||
name: tagname,
|
name: tagname,
|
||||||
})),
|
})),
|
||||||
date: new Date(dateNumber[0], dateNumber[1] - 1, dateNumber[2]),
|
date: new Date(dateNumber[0], dateNumber[1] - 1, dateNumber[2]),
|
||||||
image: post.frontMatter.coverURL ?? undefined,
|
image: post.frontMatter.coverURL ?? undefined,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
fs.writeFile("./public/rss.xml", feed.rss2(), "utf-8", (err) => {});
|
fs.writeFile("./public/rss.xml", feed.rss2(), "utf-8", (err) => {});
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user