File size: 5,548 Bytes
97c8e77
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
from markdown_it import MarkdownIt
import html
import re

def get_style_css(style_name):
    """
    根据选择的样式名称获取对应的CSS样式文件
    
    Args:
        style_name (str): 样式名称,可选值为"Default"、"MBE"、"Glassmorphism"、"Apple"
    
    Returns:
        str: CSS样式内容
    """
    
    if style_name == "Default":
        return open("assets/demo.css", "r").read()
    elif style_name == "1":
        return open("assets/demo.1.css", "r").read()
    elif style_name == "MBE":
        return open("assets/demo_mbe.css", "r").read()
    elif style_name == "Glassmorphism":
        return open("assets/demo_glassmorphism.css", "r").read()
    elif style_name == "Apple":
        return open("assets/demo_apple.css", "r").read()
    elif style_name == "Paper":
        return open("assets/demo_paper.css", "r").read()
    else:
        return open("assets/demo.css", "r").read()

def decorate_writing(writing_result, style="Default"):
    if not writing_result:
        return writing_result
    
    cite_pattern = r'<qwen:cite\s+url=["\']([^"\']+)["\'](?:\s+[^>]*)?>(.*?)</qwen:cite>'
    takeaway_pattern = r'<qwen:takeaway(?:\s+class=["\'](?P<class>[^"\']+)["\'])?>(?P<content>[^<]*)</qwen:takeaway>'
    citation_map = {}

    def replace_cite(match):
        nonlocal citation_map
        urls = match.group(1).split(',')
        content = match.group(2)
        citation_html = []
        
        for url in urls:
            if url not in citation_map:
                citation_map[url] = len(citation_map) + 1
            current_index = citation_map[url]
            citation_html.append((f'<a href="{url}" title="点击查看引用来源: {url}">{current_index}</a>', current_index))
        
        citation_html = sorted(citation_html, key=lambda x: x[1])
        citation_html = ', '.join([x[0] for x in citation_html])

        cite_html = f'{content}<sup class="citation">[{citation_html}]</sup>'
        return cite_html
    
    decorated_result = re.sub(cite_pattern, replace_cite, writing_result, flags=re.S)

    def replace_takeaway(match):
        class_attr = match.group('class')
        content = match.group('content')
        
        if class_attr:
            return f'<div class="takeaway {class_attr}">{content}</div>'
        else:
            return f'<div class="takeaway">{content}</div>'
    
    decorated_result = re.sub(takeaway_pattern, replace_takeaway, decorated_result, flags=re.S)

    mermaid_pattern = r'```mermaid\n(.*?)\n```'
    def decorate_mermaid(match):
        return f"""
<pre class="mermaid">
{match.group(1)}
</pre>
"""
    decorated_result = re.sub(mermaid_pattern, decorate_mermaid, decorated_result, flags=re.S)

    echarts_pattern = r'```echarts\n(.*?)\n```'
    echarts_index = 0
    
    def replace_echarts(match):
        """
        将echarts代码块转换为HTML和JavaScript
        
        Args:
            match: 正则表达式匹配对象
        
        Returns:
            str: 包含HTML和JavaScript的echarts图表代码
        """
        nonlocal echarts_index 
        echarts_code = match.group(1)
        echarts_id = f'echarts-container-{echarts_index}'
        echarts_index += 1
        
        replace_code = f"""
<div class="echarts-container loading" id="{echarts_id}">Echarts Rendering...</div>
<script>
    var chartDom = document.getElementById('{echarts_id}');
    var myChart = echarts.init(chartDom);
    var option;
    option = {echarts_code};
    myChart.setOption(option);
    chartDom.classList.remove('loading');
</script>
        """
        return replace_code
    
    decorated_result = re.sub(echarts_pattern, replace_echarts, decorated_result, flags=re.S)

    md = MarkdownIt()
    body = md.render(decorated_result)
    
    selected_css = get_style_css(style)
    
    html_content = """
<html>
<head>
    <!-- KaTeX for mathematical formulas -->
    <link rel="stylesheet" href="https://s4.zstatic.net/npm/katex@0.16.0/dist/katex.min.css">
    <script src="https://s4.zstatic.net/npm/katex@0.16.0/dist/katex.min.js"></script>
    <script src="https://s4.zstatic.net/npm/katex@0.16.0/dist/contrib/auto-render.min.js"></script>
    <script src="https://s4.zstatic.net/npm/echarts@5.6.0/dist/echarts.min.js"></script>
    <style>
""" + selected_css + """
    </style>
</head>
<body>
<div class="generated-content">
""" + body + """</div>
<script type="module">
    import mermaid from 'https://unpkg.com/mermaid@11.6.0/dist/mermaid.esm.min.mjs';
</script>
<script>
    document.addEventListener('DOMContentLoaded', function() {
        renderMathInElement(document.body);
    });
</script>
</body>
</html>
"""
    # 转义HTML内容以便在iframe中安全使用
    # 这是必要的,因为HTML内容包含引号和其他特殊字符
    escaped_html_content = html.escape(html_content)
    
    # 定义iframe的样式属性
    iframe_style = "width: 100%; height: 1024px; transform-origin: top left; border-color: lightgrey; border-width: 1px; border-radius: 10px;"
    
    # 创建最终的iframe HTML,通过srcdoc属性注入转义后的HTML内容
    # 设置loading="eager"和importance="high"以优先加载
    # pointer-events="none"防止用户与iframe内容交互
    iframe_content = f'<iframe id="ai-ui-iframe" loading="eager" importance="high" pointer-events="none" style="{iframe_style}" srcdoc="{escaped_html_content}"></iframe>'

    # 返回最终的iframe HTML内容
    iframe_content = re.sub(r'\n\s*\n', '\n', iframe_content)
    return iframe_content