| 
									
										
										
										
											2024-08-14 12:57:22 +08:00
										 |  |  | import fs from "fs"; | 
					
						
							| 
									
										
										
										
											2023-12-29 19:55:54 +08:00
										 |  |  | import { CopyrightAnnouncement, LatestPostCountInHomePage, WebsiteURL } from "@/consts/consts"; | 
					
						
							| 
									
										
										
										
											2023-12-25 17:21:39 +08:00
										 |  |  | import { Config } from "@/data/config"; | 
					
						
							|  |  |  | import { Feed } from "feed"; | 
					
						
							| 
									
										
										
										
											2024-01-15 11:44:48 +08:00
										 |  |  | import { JSDOM } from "jsdom"; | 
					
						
							| 
									
										
										
										
											2023-12-25 17:21:39 +08:00
										 |  |  | import { MDXRemote } from "next-mdx-remote"; | 
					
						
							|  |  |  | import { serialize } from "next-mdx-remote/serialize"; | 
					
						
							|  |  |  | import { renderToString } from "react-dom/server"; | 
					
						
							|  |  |  | import rehypeAutolinkHeadings from "rehype-autolink-headings"; | 
					
						
							|  |  |  | import rehypeMathJax from "rehype-mathjax/svg"; | 
					
						
							|  |  |  | import rehypePresetMinify from "rehype-preset-minify"; | 
					
						
							| 
									
										
										
										
											2024-04-17 12:48:35 +08:00
										 |  |  | import rehypeRaw from "rehype-raw"; | 
					
						
							| 
									
										
										
										
											2023-12-25 17:21:39 +08:00
										 |  |  | import rehypeSlug from "rehype-slug"; | 
					
						
							|  |  |  | import externalLinks from "remark-external-links"; | 
					
						
							|  |  |  | import remarkGfm from "remark-gfm"; | 
					
						
							|  |  |  | import remarkMath from "remark-math"; | 
					
						
							|  |  |  | import remarkPrism from "remark-prism"; | 
					
						
							|  |  |  | import { getPostFileContent, sortedPosts } from "./post-process"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-13 23:07:11 +08:00
										 |  |  | const NoticeForRSSReaders = (postId: string) => `
 | 
					
						
							|  |  |  | --- | 
					
						
							|  |  |  | **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
 | 
					
						
							|  |  |  | `;
 | 
					
						
							| 
									
										
										
										
											2023-12-29 19:55:54 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-15 11:44:48 +08:00
										 |  |  | function minifyHTMLCode(htmlString: string): string { | 
					
						
							|  |  |  |   const dom = new JSDOM(htmlString); | 
					
						
							|  |  |  |   const document = dom.window.document; | 
					
						
							|  |  |  |   const elements = document.querySelectorAll("*"); | 
					
						
							|  |  |  |   const unusedElements = document.querySelectorAll("script, style"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Remove all class attributes.
 | 
					
						
							|  |  |  |   elements.forEach((element) => { | 
					
						
							|  |  |  |     element.removeAttribute("class"); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Remove all script and style tags.
 | 
					
						
							|  |  |  |   unusedElements.forEach((element) => { | 
					
						
							|  |  |  |     element.parentElement?.removeChild(element); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return dom.serialize(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-25 17:21:39 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * Generate the RSS Feed File in `./public` so it could be visited by https://domain/rss.xml
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | export const generateRSSFeed = async () => { | 
					
						
							|  |  |  |   const feed = new Feed({ | 
					
						
							|  |  |  |     title: Config.SiteTitle, | 
					
						
							|  |  |  |     description: Config.Sentence, | 
					
						
							|  |  |  |     id: Config.SiteDomain, | 
					
						
							| 
									
										
										
										
											2023-12-29 19:55:54 +08:00
										 |  |  |     link: WebsiteURL, | 
					
						
							| 
									
										
										
										
											2023-12-25 17:21:39 +08:00
										 |  |  |     image: Config.PageCovers.websiteCoverURL, | 
					
						
							|  |  |  |     favicon: `https://${Config.SiteDomain}/favcion.ico`, | 
					
						
							| 
									
										
										
										
											2023-12-29 19:55:54 +08:00
										 |  |  |     copyright: CopyrightAnnouncement, | 
					
						
							| 
									
										
										
										
											2023-12-25 17:21:39 +08:00
										 |  |  |     generator: "Node.js Feed", | 
					
						
							|  |  |  |     author: { | 
					
						
							|  |  |  |       name: Config.AuthorName, | 
					
						
							|  |  |  |       email: Config.SocialLinks.email, | 
					
						
							| 
									
										
										
										
											2023-12-29 19:55:54 +08:00
										 |  |  |       link: WebsiteURL, | 
					
						
							| 
									
										
										
										
											2023-12-25 17:21:39 +08:00
										 |  |  |     }, | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-03 22:08:27 +08:00
										 |  |  |   for (let i = 0; i < Math.min(LatestPostCountInHomePage, sortedPosts.allPostList.length); i++) { | 
					
						
							| 
									
										
										
										
											2023-12-25 17:21:39 +08:00
										 |  |  |     const post = sortedPosts.allPostList[i]; | 
					
						
							| 
									
										
										
										
											2024-09-13 23:07:11 +08:00
										 |  |  |     const postFileContent = `${getPostFileContent(post.id)}${NoticeForRSSReaders(post.id)}`; | 
					
						
							| 
									
										
										
										
											2024-09-28 00:18:55 +08:00
										 |  |  |     const dateNumber = post.frontMatter.time.split("-").map((num: string) => Number.parseInt(num)); | 
					
						
							| 
									
										
										
										
											2024-04-03 22:08:27 +08:00
										 |  |  |     const mdxSource = await serialize(postFileContent ?? "", { | 
					
						
							| 
									
										
										
										
											2023-12-25 17:21:39 +08:00
										 |  |  |       parseFrontmatter: true, | 
					
						
							|  |  |  |       mdxOptions: { | 
					
						
							|  |  |  |         remarkPlugins: [remarkPrism, externalLinks, remarkMath, remarkGfm], | 
					
						
							| 
									
										
										
										
											2024-04-17 12:48:35 +08:00
										 |  |  |         rehypePlugins: [rehypeMathJax, rehypeAutolinkHeadings, rehypeSlug, rehypePresetMinify as any, rehypeRaw], | 
					
						
							| 
									
										
										
										
											2023-12-25 17:21:39 +08:00
										 |  |  |         format: "md", | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2024-01-15 11:44:48 +08:00
										 |  |  |     const htmlContent = minifyHTMLCode(renderToString(<MDXRemote {...mdxSource} />)); | 
					
						
							| 
									
										
										
										
											2023-12-25 17:21:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     feed.addItem({ | 
					
						
							|  |  |  |       title: post.frontMatter.title, | 
					
						
							|  |  |  |       id: post.id, | 
					
						
							|  |  |  |       link: `https://${Config.SiteDomain}/blog/${post.id}`, | 
					
						
							|  |  |  |       description: post.frontMatter.summary ?? undefined, | 
					
						
							|  |  |  |       content: htmlContent, | 
					
						
							|  |  |  |       author: [ | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           name: Config.AuthorName, | 
					
						
							|  |  |  |           email: Config.SocialLinks.email, | 
					
						
							| 
									
										
										
										
											2024-04-03 22:08:27 +08:00
										 |  |  |           link: `https://${Config.SiteDomain}/about`, | 
					
						
							| 
									
										
										
										
											2023-12-25 17:21:39 +08:00
										 |  |  |         }, | 
					
						
							|  |  |  |       ], | 
					
						
							| 
									
										
										
										
											2024-09-28 00:18:55 +08:00
										 |  |  |       category: post.frontMatter.tags?.map((tagname: string) => ({ | 
					
						
							|  |  |  |         name: tagname, | 
					
						
							|  |  |  |       })), | 
					
						
							| 
									
										
										
										
											2024-10-13 11:42:05 +08:00
										 |  |  |       date: new Date(dateNumber[0], dateNumber[1] - 1, dateNumber[2]), | 
					
						
							| 
									
										
										
										
											2023-12-25 17:21:39 +08:00
										 |  |  |       image: post.frontMatter.coverURL ?? undefined, | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   fs.writeFile("./public/rss.xml", feed.rss2(), "utf-8", (err) => {}); | 
					
						
							|  |  |  | }; |