优化模版样式
This commit is contained in:
		
							parent
							
								
									6db55b4dd9
								
							
						
					
					
						commit
						d6806b2757
					
				| @ -20,7 +20,7 @@ export const templates: Template[] = [ | |||||||
|             themeColor: '#166534', |             themeColor: '#166534', | ||||||
|             fontFamily: '-apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif', |             fontFamily: '-apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif', | ||||||
|             textAlign: 'left', |             textAlign: 'left', | ||||||
|             lineHeight: '1.75', |             lineHeight: '2', | ||||||
|             padding: '1rem 1.5rem', |             padding: '1rem 1.5rem', | ||||||
|             maxWidth: '100%', |             maxWidth: '100%', | ||||||
|             margin: '0 auto', |             margin: '0 auto', | ||||||
|  | |||||||
| @ -38,23 +38,27 @@ function preprocessMarkdown(markdown: string): string { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Initialize marked instance
 | // Initialize marked instance
 | ||||||
| const marked = new Marked() | const marked = new Marked({ | ||||||
| 
 |  | ||||||
| // 创建基础渲染器
 |  | ||||||
| const baseRenderer = new marked.Renderer() |  | ||||||
| 
 |  | ||||||
| // 重写 strong 渲染器
 |  | ||||||
| baseRenderer.strong = function(text) { |  | ||||||
|   return `<strong>${text}</strong>` |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // 应用配置和渲染器
 |  | ||||||
| marked.setOptions({ |  | ||||||
|   gfm: true, |   gfm: true, | ||||||
|   breaks: true, |   breaks: true, | ||||||
|   async: false, |   async: false, | ||||||
|   pedantic: false, |   pedantic: false | ||||||
|   renderer: baseRenderer | }) | ||||||
|  | 
 | ||||||
|  | // 应用配置
 | ||||||
|  | marked.use({ | ||||||
|  |   breaks: true, | ||||||
|  |   gfm: true, | ||||||
|  |   walkTokens(token: Tokens.Generic) { | ||||||
|  |     // 确保列表项被正确处理
 | ||||||
|  |     if (token.type === 'list') { | ||||||
|  |       (token as Tokens.List).items.forEach(item => { | ||||||
|  |         if (item.task) { | ||||||
|  |           item.checked = !!item.checked | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     } | ||||||
|  |   } | ||||||
| }) | }) | ||||||
| 
 | 
 | ||||||
| const defaultOptions: RendererOptions = { | const defaultOptions: RendererOptions = { | ||||||
| @ -83,9 +87,6 @@ const defaultOptions: RendererOptions = { | |||||||
| export function convertToWechat(markdown: string, options: RendererOptions = defaultOptions): string { | export function convertToWechat(markdown: string, options: RendererOptions = defaultOptions): string { | ||||||
|   const renderer = new marked.Renderer() |   const renderer = new marked.Renderer() | ||||||
|    |    | ||||||
|   // 继承基础渲染器
 |  | ||||||
|   Object.setPrototypeOf(renderer, baseRenderer) |  | ||||||
| 
 |  | ||||||
|   // 合并选项
 |   // 合并选项
 | ||||||
|   const mergedOptions = { |   const mergedOptions = { | ||||||
|     base: { ...defaultOptions.base, ...options.base }, |     base: { ...defaultOptions.base, ...options.base }, | ||||||
| @ -156,14 +157,28 @@ export function convertToWechat(markdown: string, options: RendererOptions = def | |||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| // 重写 list 方法
 | // 重写 list 方法
 | ||||||
| renderer.list = function(token: Tokens.List): string { | renderer.list = function(token: Tokens.List) { | ||||||
|     const tag = token.ordered ? 'ol' : 'ul' |     const tag = token.ordered ? 'ol' : 'ul' | ||||||
|     try { |     try { | ||||||
|       const style = mergedOptions.block?.[token.ordered ? 'ol' : 'ul'] |       const style = { | ||||||
|  |         ...(mergedOptions.block?.[token.ordered ? 'ol' : 'ul'] || {}), | ||||||
|  |         listStyle: token.ordered ? 'decimal' : 'disc', | ||||||
|  |         paddingLeft: '2em', | ||||||
|  |         marginBottom: '16px' | ||||||
|  |       } | ||||||
|       const styleStr = cssPropertiesToString(style) |       const styleStr = cssPropertiesToString(style) | ||||||
|       const startAttr = token.ordered && token.start !== 1 ? ` start="${token.start}"` : '' |       const startAttr = token.ordered && token.start !== 1 ? ` start="${token.start}"` : '' | ||||||
|        |        | ||||||
|       return `<${tag}${startAttr}${styleStr ? ` style="${styleStr}"` : ''}>${token.items.map(item => renderer.listitem(item)).join('')}</${tag}>` |       const items = token.items.map(item => { | ||||||
|  |         let itemText = item.text | ||||||
|  |         if (item.task) { | ||||||
|  |           const checkbox = `<input type="checkbox"${item.checked ? ' checked=""' : ''} disabled="" /> ` | ||||||
|  |           itemText = checkbox + itemText | ||||||
|  |         } | ||||||
|  |         return renderer.listitem({ ...item, text: itemText }) | ||||||
|  |       }).join('') | ||||||
|  |        | ||||||
|  |       return `<${tag}${startAttr}${styleStr ? ` style="${styleStr}"` : ''}>${items}</${tag}>` | ||||||
|     } catch (error) { |     } catch (error) { | ||||||
|       console.error(`Error rendering list: ${error}`) |       console.error(`Error rendering list: ${error}`) | ||||||
|       return `<${tag}>${token.items.map(item => renderer.listitem(item)).join('')}</${tag}>` |       return `<${tag}>${token.items.map(item => renderer.listitem(item)).join('')}</${tag}>` | ||||||
| @ -173,28 +188,38 @@ renderer.list = function(token: Tokens.List): string { | |||||||
| // 重写 listitem 方法
 | // 重写 listitem 方法
 | ||||||
| renderer.listitem = function(item: Tokens.ListItem) { | renderer.listitem = function(item: Tokens.ListItem) { | ||||||
|     try { |     try { | ||||||
|       const style = mergedOptions.inline?.listitem |       const style = { | ||||||
|  |         ...(mergedOptions.inline?.listitem || {}), | ||||||
|  |         marginBottom: '8px', | ||||||
|  |         display: 'list-item' | ||||||
|  |       } | ||||||
|       const styleStr = cssPropertiesToString(style) |       const styleStr = cssPropertiesToString(style) | ||||||
|        |        | ||||||
|       // 移除列表项开头的破折号和空格
 |       // 处理嵌套列表
 | ||||||
|       let itemText = item.text.replace(/^- /, '') |       let content = item.text | ||||||
|        |       if (item.tokens) { | ||||||
|       // 处理任务列表项
 |         content = item.tokens.map(token => { | ||||||
|       if (item.task) { |           if (token.type === 'list') { | ||||||
|         const checkbox = `<input type="checkbox"${item.checked ? ' checked=""' : ''} disabled="" /> ` |             // 递归处理嵌套列表
 | ||||||
|         itemText = checkbox + itemText |             return renderer.list(token as Tokens.List) | ||||||
|  |           } else { | ||||||
|  |             // 处理其他类型的 token
 | ||||||
|  |             const tokens = marked.Lexer.lexInline(token.raw) | ||||||
|  |             return marked.Parser.parseInline(tokens, { renderer }) | ||||||
|  |           } | ||||||
|  |         }).join('') | ||||||
|  |       } else { | ||||||
|  |         // 如果没有 tokens,则按普通文本处理
 | ||||||
|  |         const tokens = marked.Lexer.lexInline(content) | ||||||
|  |         content = marked.Parser.parseInline(tokens, { renderer }) | ||||||
|       } |       } | ||||||
|        |        | ||||||
|       // 使用 Lexer 和 Parser 处理剩余的内联标记
 |  | ||||||
|       const tokens = marked.Lexer.lexInline(itemText) |  | ||||||
|       const content = marked.Parser.parseInline(tokens, { renderer }) |  | ||||||
|        |  | ||||||
|       return `<li${styleStr ? ` style="${styleStr}"` : ''}>${content}</li>` |       return `<li${styleStr ? ` style="${styleStr}"` : ''}>${content}</li>` | ||||||
|     } catch (error) { |     } catch (error) { | ||||||
|       console.error(`Error rendering list item: ${error}`) |       console.error(`Error rendering list item: ${error}`) | ||||||
|       return `<li>${item.text}</li>` |       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 }) as string |   const html = marked.parse(markdown, { renderer }) as string | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 tianyaxiang
						tianyaxiang