fix: escape encoding for titles in rss
This commit is contained in:
		
							parent
							
								
									ef1ead31dc
								
							
						
					
					
						commit
						828aa71fe3
					
				
					 3 changed files with 15 additions and 14 deletions
				
			
		| 
						 | 
					@ -1,5 +1,6 @@
 | 
				
			||||||
import { GlobalConfiguration } from "../../cfg"
 | 
					import { GlobalConfiguration } from "../../cfg"
 | 
				
			||||||
import { getDate } from "../../components/Date"
 | 
					import { getDate } from "../../components/Date"
 | 
				
			||||||
 | 
					import { escapeHTML } from "../../util/escape"
 | 
				
			||||||
import { FilePath, FullSlug, SimpleSlug, simplifySlug } from "../../util/path"
 | 
					import { FilePath, FullSlug, SimpleSlug, simplifySlug } from "../../util/path"
 | 
				
			||||||
import { QuartzEmitterPlugin } from "../types"
 | 
					import { QuartzEmitterPlugin } from "../types"
 | 
				
			||||||
import path from "path"
 | 
					import path from "path"
 | 
				
			||||||
| 
						 | 
					@ -29,7 +30,7 @@ const defaultOptions: Options = {
 | 
				
			||||||
function generateSiteMap(cfg: GlobalConfiguration, idx: ContentIndex): string {
 | 
					function generateSiteMap(cfg: GlobalConfiguration, idx: ContentIndex): string {
 | 
				
			||||||
  const base = cfg.baseUrl ?? ""
 | 
					  const base = cfg.baseUrl ?? ""
 | 
				
			||||||
  const createURLEntry = (slug: SimpleSlug, content: ContentDetails): string => `<url>
 | 
					  const createURLEntry = (slug: SimpleSlug, content: ContentDetails): string => `<url>
 | 
				
			||||||
    <loc>https://${base}/${encodeURIComponent(slug)}</loc>
 | 
					    <loc>https://${base}/${encodeURI(slug)}</loc>
 | 
				
			||||||
    <lastmod>${content.date?.toISOString()}</lastmod>
 | 
					    <lastmod>${content.date?.toISOString()}</lastmod>
 | 
				
			||||||
  </url>`
 | 
					  </url>`
 | 
				
			||||||
  const urls = Array.from(idx)
 | 
					  const urls = Array.from(idx)
 | 
				
			||||||
| 
						 | 
					@ -43,9 +44,9 @@ function generateRSSFeed(cfg: GlobalConfiguration, idx: ContentIndex): string {
 | 
				
			||||||
  const root = `https://${base}`
 | 
					  const root = `https://${base}`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const createURLEntry = (slug: SimpleSlug, content: ContentDetails): string => `<item>
 | 
					  const createURLEntry = (slug: SimpleSlug, content: ContentDetails): string => `<item>
 | 
				
			||||||
    <title>${content.title}</title>
 | 
					    <title>${escapeHTML(content.title)}</title>
 | 
				
			||||||
    <link>${root}/${encodeURIComponent(slug)}</link>
 | 
					    <link>${root}/${encodeURI(slug)}</link>
 | 
				
			||||||
    <guid>${root}/${encodeURIComponent(slug)}</guid>
 | 
					    <guid>${root}/${encodeURI(slug)}</guid>
 | 
				
			||||||
    <description>${content.description}</description>
 | 
					    <description>${content.description}</description>
 | 
				
			||||||
    <pubDate>${content.date?.toUTCString()}</pubDate>
 | 
					    <pubDate>${content.date?.toUTCString()}</pubDate>
 | 
				
			||||||
  </item>`
 | 
					  </item>`
 | 
				
			||||||
| 
						 | 
					@ -56,7 +57,7 @@ function generateRSSFeed(cfg: GlobalConfiguration, idx: ContentIndex): string {
 | 
				
			||||||
  return `<?xml version="1.0" encoding="UTF-8" ?>
 | 
					  return `<?xml version="1.0" encoding="UTF-8" ?>
 | 
				
			||||||
<rss version="2.0">
 | 
					<rss version="2.0">
 | 
				
			||||||
    <channel>
 | 
					    <channel>
 | 
				
			||||||
      <title>${cfg.pageTitle}</title>
 | 
					      <title>${escapeHTML(cfg.pageTitle)}</title>
 | 
				
			||||||
      <link>${root}</link>
 | 
					      <link>${root}</link>
 | 
				
			||||||
      <description>Recent content on ${cfg.pageTitle}</description>
 | 
					      <description>Recent content on ${cfg.pageTitle}</description>
 | 
				
			||||||
      <generator>Quartz -- quartz.jzhao.xyz</generator>
 | 
					      <generator>Quartz -- quartz.jzhao.xyz</generator>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,7 @@
 | 
				
			||||||
import { Root as HTMLRoot } from "hast"
 | 
					import { Root as HTMLRoot } from "hast"
 | 
				
			||||||
import { toString } from "hast-util-to-string"
 | 
					import { toString } from "hast-util-to-string"
 | 
				
			||||||
import { QuartzTransformerPlugin } from "../types"
 | 
					import { QuartzTransformerPlugin } from "../types"
 | 
				
			||||||
 | 
					import { escapeHTML } from "../../util/escape"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface Options {
 | 
					export interface Options {
 | 
				
			||||||
  descriptionLength: number
 | 
					  descriptionLength: number
 | 
				
			||||||
| 
						 | 
					@ -10,15 +11,6 @@ const defaultOptions: Options = {
 | 
				
			||||||
  descriptionLength: 150,
 | 
					  descriptionLength: 150,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const escapeHTML = (unsafe: string) => {
 | 
					 | 
				
			||||||
  return unsafe
 | 
					 | 
				
			||||||
    .replaceAll("&", "&")
 | 
					 | 
				
			||||||
    .replaceAll("<", "<")
 | 
					 | 
				
			||||||
    .replaceAll(">", ">")
 | 
					 | 
				
			||||||
    .replaceAll('"', """)
 | 
					 | 
				
			||||||
    .replaceAll("'", "'")
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export const Description: QuartzTransformerPlugin<Partial<Options> | undefined> = (userOpts) => {
 | 
					export const Description: QuartzTransformerPlugin<Partial<Options> | undefined> = (userOpts) => {
 | 
				
			||||||
  const opts = { ...defaultOptions, ...userOpts }
 | 
					  const opts = { ...defaultOptions, ...userOpts }
 | 
				
			||||||
  return {
 | 
					  return {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										8
									
								
								quartz/util/escape.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								quartz/util/escape.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,8 @@
 | 
				
			||||||
 | 
					export const escapeHTML = (unsafe: string) => {
 | 
				
			||||||
 | 
					  return unsafe
 | 
				
			||||||
 | 
					    .replaceAll("&", "&")
 | 
				
			||||||
 | 
					    .replaceAll("<", "<")
 | 
				
			||||||
 | 
					    .replaceAll(">", ">")
 | 
				
			||||||
 | 
					    .replaceAll('"', """)
 | 
				
			||||||
 | 
					    .replaceAll("'", "'")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue