import React, { useMemo } from 'react' import { View, RichText, Video } from '@tarojs/components' import { marked, Renderer } from 'marked' import CodeBlock from './CodeBlock' import './index.scss' interface Props { content: string themeColor?: string } const MarkdownReader: React.FC = ({ content, themeColor = '#00b96b' }) => { const elements = useMemo(() => { if (!content) return [] const tokens = marked.lexer(content) const result: React.ReactNode[] = [] let currentTokens: any[] = [] // Configure renderer const renderer = new Renderer() renderer.table = (header, body) => { return `
${header}${body}
` } renderer.tablecell = (content, flags) => { const type = flags.header ? 'th' : 'td' const style = [ 'border: 1px solid rgba(255,255,255,0.1)', 'padding: 10px', flags.header ? 'background-color: rgba(255,255,255,0.05); font-weight: 700; color: #fff;' : 'color: #ddd;', flags.align ? `text-align: ${flags.align}` : 'text-align: left' ].join(';') return `<${type} style="${style}">${content}` } renderer.image = (href, title, text) => { return `${text || ''}` } renderer.link = (href, title, text) => { return `${text}` } // Process tokens tokens.forEach((token, index) => { if (token.type === 'code') { // Skip css blocks that look like the video component styles if ((token.lang === 'css' || !token.lang) && token.text.includes('.simple-tech-video')) { return } // Flush accumulated tokens if (currentTokens.length > 0) { // preserve links if any (currentTokens as any).links = (tokens as any).links const html = marked.parser(currentTokens as any, { renderer, breaks: true }) result.push() currentTokens = [] } // Add code block result.push( ) } else if (token.type === 'html') { // Check for video tag const videoRegex = /]*>[\s\S]*?]*src=["'](.*?)["'][^>]*>[\s\S]*?<\/video>/i const simpleVideoRegex = /]*src=["'](.*?)["'][^>]*>/i const match = token.text.match(videoRegex) || token.text.match(simpleVideoRegex) if (match) { // Flush accumulated tokens if (currentTokens.length > 0) { (currentTokens as any).links = (tokens as any).links const html = marked.parser(currentTokens as any, { renderer, breaks: true }) result.push() currentTokens = [] } const src = match[1] // Try to extract caption const captionRegex = /class=["']video-caption["'][^>]*>(.*?)<\/div>/i const captionMatch = token.text.match(captionRegex) const caption = captionMatch ? captionMatch[1] : null result.push( ) } else { // Filter out style tags for video component if they are parsed as HTML if (token.text.includes('