优化模版
This commit is contained in:
parent
cdca9d4d3f
commit
c2a8ebbd01
@ -1,63 +0,0 @@
|
|||||||
import { Template } from '@/types/template'
|
|
||||||
|
|
||||||
export const templates: Template[] = [
|
|
||||||
{
|
|
||||||
id: 'wechat',
|
|
||||||
name: '微信公众号',
|
|
||||||
styles: 'wechat-template',
|
|
||||||
subTemplates: [
|
|
||||||
{
|
|
||||||
id: 'default',
|
|
||||||
name: '默认样式',
|
|
||||||
styles: 'wechat-default',
|
|
||||||
transform: (content: string) => {
|
|
||||||
return content
|
|
||||||
.replace(/<h1>/g, '<h1 style="font-size: 24px; font-weight: bold; margin-bottom: 1em;">')
|
|
||||||
.replace(/<p>/g, '<p style="margin-bottom: 1em; color: #333; line-height: 1.75;">')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'elegant',
|
|
||||||
name: '优雅简约',
|
|
||||||
styles: 'wechat-elegant',
|
|
||||||
transform: (content: string) => {
|
|
||||||
return content
|
|
||||||
.replace(/<h1>/g, '<h1 style="font-size: 26px; font-weight: 600; margin-bottom: 1.2em; color: #2c3e50;">')
|
|
||||||
.replace(/<p>/g, '<p style="margin-bottom: 1.2em; color: #34495e; line-height: 1.8; letter-spacing: 0.05em;">')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'modern',
|
|
||||||
name: '现代商务',
|
|
||||||
styles: 'wechat-modern',
|
|
||||||
transform: (content: string) => {
|
|
||||||
return content
|
|
||||||
.replace(/<h1>/g, '<h1 style="font-size: 28px; font-weight: bold; margin-bottom: 1em; color: #1a202c; border-bottom: 2px solid #e2e8f0; padding-bottom: 0.5em;">')
|
|
||||||
.replace(/<p>/g, '<p style="margin-bottom: 1.1em; color: #4a5568; line-height: 1.85; font-size: 16px;">')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'creative',
|
|
||||||
name: '创意活力',
|
|
||||||
styles: 'wechat-creative',
|
|
||||||
transform: (content: string) => {
|
|
||||||
return content
|
|
||||||
.replace(/<h1>/g, '<h1 style="font-size: 24px; font-weight: bold; margin-bottom: 1em; color: #2d3748; background: linear-gradient(to right, #4299e1, #667eea); -webkit-background-clip: text; -webkit-text-fill-color: transparent;">')
|
|
||||||
.replace(/<p>/g, '<p style="margin-bottom: 1em; color: #4a5568; line-height: 1.75; border-left: 3px solid #4299e1; padding-left: 1em;">')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
transform: (content: string) => content // 默认转换
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'xiaohongshu',
|
|
||||||
name: '小红书',
|
|
||||||
styles: 'xiaohongshu-template',
|
|
||||||
transform: (content: string) => {
|
|
||||||
// 小红书特定的转换逻辑
|
|
||||||
return content
|
|
||||||
.replace(/<h1>/g, '<h1 style="font-size: 20px; font-weight: bold; margin-bottom: 0.5em;">')
|
|
||||||
.replace(/<p>/g, '<p style="margin-bottom: 0.8em; color: #222; line-height: 1.6;">')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
@ -158,14 +158,7 @@ export const templates: Template[] = [
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
transform: (html) => `
|
transform: (html) => html
|
||||||
<section style="font-family: 'Georgia', serif;">
|
|
||||||
<style>
|
|
||||||
:root { --md-primary-color: #16a34a; }
|
|
||||||
</style>
|
|
||||||
${html}
|
|
||||||
</section>
|
|
||||||
`
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'modern',
|
id: 'modern',
|
||||||
@ -233,13 +226,8 @@ export const templates: Template[] = [
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
transform: (html) => `
|
transform: (html) => html
|
||||||
<section style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;">
|
|
||||||
<div style="max-width: 100%; margin: 0 auto; color: #374151;">
|
|
||||||
${html}
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
`
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'creative',
|
id: 'creative',
|
||||||
@ -376,10 +364,98 @@ export const templates: Template[] = [
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
transform: (html) => `
|
transform: (html) => html
|
||||||
<section style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;">
|
|
||||||
${html}
|
},
|
||||||
</section>
|
{
|
||||||
`
|
id: 'ios-notes',
|
||||||
|
name: '备忘录风格',
|
||||||
|
description: '仿 iOS 备忘录风格',
|
||||||
|
styles: 'prose-ios-notes',
|
||||||
|
options: {
|
||||||
|
base: {
|
||||||
|
primaryColor: '#FF9500',
|
||||||
|
textAlign: 'left',
|
||||||
|
lineHeight: '1.6'
|
||||||
|
},
|
||||||
|
block: {
|
||||||
|
h1: {
|
||||||
|
fontSize: '24px',
|
||||||
|
color: '#1C1C1E',
|
||||||
|
margin: '32px 0 16px',
|
||||||
|
fontWeight: '600',
|
||||||
|
fontFamily: '-apple-system, BlinkMacSystemFont, "SF Pro Text"'
|
||||||
|
},
|
||||||
|
h2: {
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#1C1C1E',
|
||||||
|
margin: '24px 0 12px',
|
||||||
|
fontWeight: '600',
|
||||||
|
fontFamily: '-apple-system, BlinkMacSystemFont, "SF Pro Text"'
|
||||||
|
},
|
||||||
|
h3: {
|
||||||
|
fontSize: '18px',
|
||||||
|
color: '#1C1C1E',
|
||||||
|
margin: '20px 0 10px',
|
||||||
|
fontWeight: '600',
|
||||||
|
fontFamily: '-apple-system, BlinkMacSystemFont, "SF Pro Text"'
|
||||||
|
},
|
||||||
|
p: {
|
||||||
|
fontSize: '17px',
|
||||||
|
color: '#333333',
|
||||||
|
margin: '16px 0',
|
||||||
|
lineHeight: 1.6,
|
||||||
|
fontFamily: '-apple-system, BlinkMacSystemFont, "SF Pro Text"'
|
||||||
|
},
|
||||||
|
blockquote: {
|
||||||
|
fontSize: '17px',
|
||||||
|
color: '#666666',
|
||||||
|
borderLeft: '4px solid #FF9500',
|
||||||
|
background: '#FAFAFA',
|
||||||
|
padding: '12px 16px',
|
||||||
|
margin: '16px 0',
|
||||||
|
borderRadius: '4px'
|
||||||
|
},
|
||||||
|
code_pre: {
|
||||||
|
fontSize: '15px',
|
||||||
|
background: '#F2F2F7',
|
||||||
|
padding: '12px 16px',
|
||||||
|
borderRadius: '8px',
|
||||||
|
margin: '16px 0',
|
||||||
|
fontFamily: 'Menlo, Monaco, "SF Mono", monospace'
|
||||||
|
},
|
||||||
|
ul: {
|
||||||
|
paddingLeft: '24px',
|
||||||
|
margin: '16px 0'
|
||||||
|
},
|
||||||
|
ol: {
|
||||||
|
paddingLeft: '24px',
|
||||||
|
margin: '16px 0'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
inline: {
|
||||||
|
strong: {
|
||||||
|
color: '#1C1C1E',
|
||||||
|
fontWeight: '600'
|
||||||
|
},
|
||||||
|
em: {
|
||||||
|
color: '#666666',
|
||||||
|
fontStyle: 'italic'
|
||||||
|
},
|
||||||
|
link: {
|
||||||
|
color: '#007AFF',
|
||||||
|
textDecoration: 'none'
|
||||||
|
},
|
||||||
|
codespan: {
|
||||||
|
color: '#E73C3E',
|
||||||
|
background: '#F2F2F7',
|
||||||
|
padding: '2px 6px',
|
||||||
|
borderRadius: '4px',
|
||||||
|
fontSize: '90%',
|
||||||
|
fontFamily: 'Menlo, Monaco, "SF Mono", monospace'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
transform: (html) => html
|
||||||
}
|
}
|
||||||
]
|
]
|
@ -40,8 +40,11 @@ function baseStylesToString(base: RendererOptions['base'] = {}): string {
|
|||||||
|
|
||||||
// 预处理函数
|
// 预处理函数
|
||||||
function preprocessMarkdown(markdown: string): string {
|
function preprocessMarkdown(markdown: string): string {
|
||||||
|
return markdown
|
||||||
// 处理 ** 语法,但排除已经是 HTML 的部分
|
// 处理 ** 语法,但排除已经是 HTML 的部分
|
||||||
return markdown.replace(/(?<!<[^>]*)\*\*([^*]+)\*\*(?![^<]*>)/g, '<strong>$1</strong>')
|
.replace(/(?<!<[^>]*)\*\*([^*]+)\*\*(?![^<]*>)/g, '<strong>$1</strong>')
|
||||||
|
// 处理无序列表的 - 标记,但排除代码块内的部分
|
||||||
|
.replace(/^(?!\s*```)([ \t]*)-\s+/gm, '$1• ')
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize marked instance
|
// Initialize marked instance
|
||||||
@ -129,24 +132,50 @@ export function convertToWechat(markdown: string, options: RendererOptions = {})
|
|||||||
return `<img src="${href}"${title ? ` title="${title}"` : ''} alt="${text}"${styleStr ? ` style="${styleStr}"` : ''} />`
|
return `<img src="${href}"${title ? ` title="${title}"` : ''} alt="${text}"${styleStr ? ` style="${styleStr}"` : ''} />`
|
||||||
}
|
}
|
||||||
|
|
||||||
customRenderer.list = function(body: Tokens.List) {
|
// 重写 list 方法
|
||||||
const ordered = body.ordered
|
customRenderer.list = function(token: Tokens.List): string {
|
||||||
const tag = ordered ? 'ol' : 'ul'
|
const tag = token.ordered ? 'ol' : 'ul'
|
||||||
const style = options.block?.[ordered ? 'ol' : 'ul']
|
try {
|
||||||
|
const style = options.block?.[token.ordered ? 'ol' : 'ul']
|
||||||
const styleStr = cssPropertiesToString(style)
|
const styleStr = cssPropertiesToString(style)
|
||||||
const tokens = marked.Lexer.lexInline(body.raw)
|
const startAttr = token.ordered && token.start !== 1 ? ` start="${token.start}"` : ''
|
||||||
const content = marked.Parser.parseInline(tokens, { renderer: customRenderer })
|
|
||||||
return `<${tag}${styleStr ? ` style="${styleStr}"` : ''}>${content}</${tag}>`
|
return `<${tag}${startAttr}${styleStr ? ` style="${styleStr}"` : ''}>${token.items.map(item => customRenderer.listitem(item)).join('')}</${tag}>`
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error rendering list: ${error}`)
|
||||||
|
return `<${tag}>${token.items.map(item => customRenderer.listitem(item)).join('')}</${tag}>`
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 重写 listitem 方法
|
||||||
customRenderer.listitem = function(item: Tokens.ListItem) {
|
customRenderer.listitem = function(item: Tokens.ListItem) {
|
||||||
|
try {
|
||||||
const style = options.inline?.listitem
|
const style = options.inline?.listitem
|
||||||
const styleStr = cssPropertiesToString(style)
|
const styleStr = cssPropertiesToString(style)
|
||||||
const tokens = marked.Lexer.lexInline(item.text)
|
|
||||||
const content = marked.Parser.parseInline(tokens, { renderer: customRenderer })
|
// 移除列表项开头的破折号和空格
|
||||||
return `<li${styleStr ? ` style="${styleStr}"` : ''}>${content}</li>`
|
let itemText = item.text.replace(/^- /, '')
|
||||||
|
|
||||||
|
// 处理任务列表项
|
||||||
|
if (item.task) {
|
||||||
|
const checkbox = `<input type="checkbox"${item.checked ? ' checked=""' : ''} disabled="" /> `
|
||||||
|
itemText = checkbox + itemText
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 使用 Lexer 和 Parser 处理剩余的内联标记
|
||||||
|
const tokens = marked.Lexer.lexInline(itemText)
|
||||||
|
const content = marked.Parser.parseInline(tokens, { renderer: customRenderer })
|
||||||
|
|
||||||
|
return `<li${styleStr ? ` style="${styleStr}"` : ''}>${content}</li>`
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error rendering list item: ${error}`)
|
||||||
|
return `<li>${item.text}</li>`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Convert Markdown to HTML using the custom renderer
|
// Convert Markdown to HTML using the custom renderer
|
||||||
const html = marked.parse(markdown, { renderer: customRenderer }) as string
|
const html = marked.parse(markdown, { renderer: customRenderer }) as string
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user