import { marked, type Tokens } from 'marked'
import type { CSSProperties } from 'react'
// 配置 marked 选项
marked.setOptions({
gfm: true,
breaks: true
})
// 将 React CSSProperties 转换为 CSS 字符串
function cssPropertiesToString(style: React.CSSProperties = {}): string {
return Object.entries(style)
.map(([key, value]) => {
// 转换驼峰命名为连字符命名
const cssKey = key.replace(/([A-Z])/g, '-$1').toLowerCase()
// 处理对象类型的值
if (value && typeof value === 'object') {
if ('toString' in value) {
return `${cssKey}: ${value.toString()}`
}
return `${cssKey}: ${JSON.stringify(value)}`
}
return `${cssKey}: ${value}`
})
.filter(Boolean)
.join(';')
}
// 将基础样式选项转换为 CSS 字符串
function baseStylesToString(base: RendererOptions['base'] = {}): string {
const styles: string[] = []
if (base.primaryColor) {
styles.push(`--md-primary-color: ${base.primaryColor}`)
}
if (base.textAlign) {
styles.push(`text-align: ${base.textAlign}`)
}
if (base.lineHeight) {
styles.push(`line-height: ${base.lineHeight}`)
}
return styles.join(';')
}
export function convertToWechat(markdown: string, options: RendererOptions = {}): string {
const renderer = new marked.Renderer()
// 标题渲染
renderer.heading = ({ text, depth }: Tokens.Heading) => {
const style = options.block?.[`h${depth}` as keyof typeof options.block]
const styleStr = cssPropertiesToString(style)
return `
${content}
` } // 引用渲染 renderer.blockquote = (quote) => { const style = options.block?.blockquote const styleStr = cssPropertiesToString(style) const content = typeof quote === 'object' ? (quote.text || quote.toString()) : quote return `${content}` } // 代码块渲染 renderer.code = ({ text, lang = '' }: { text: string; lang?: string }) => { const style = options.block?.code_pre const styleStr = cssPropertiesToString(style) return `
${text}
`
}
// 行内代码渲染
renderer.codespan = (code) => {
const style = options.inline?.codespan
const styleStr = cssPropertiesToString(style)
return `${code}
`
}
// 强调(斜体)渲染
renderer.em = (text) => {
const style = options.inline?.em
const styleStr = cssPropertiesToString(style)
return `${text}`
}
// 加粗渲染
renderer.strong = (text) => {
const style = options.inline?.strong
const styleStr = cssPropertiesToString(style)
return `${text}`
}
// 链接渲染
renderer.link = ({ href, title, tokens }: Tokens.Link) => {
const style = options.inline?.link
const styleStr = cssPropertiesToString(style)
const text = tokens?.map(t => 'text' in t ? t.text : '').join('') || ''
return `${text}`
}
// 图片渲染
renderer.image = ({ href, title, text }: Tokens.Image) => {
const style = options.block?.image
const styleStr = cssPropertiesToString(style)
return `${text}
` } marked.setOptions({ renderer: xiaohongshuRenderer }) let html = marked(markdown) html = `