Spaces:
Sleeping
Sleeping
引入 mdtex2html 更多拓展完善markdown渲染显示, resolve #134, resolve #193 (#135)
Browse files* 增加代码高亮功能
* 引入了Pygments库用以高亮,但我不确定是不是真的必要;
* 可以从此处挑选喜欢的样式告诉我: https://pygments.org/styles/ ,目前选用了monokai.
* 是否可以完全剔除parse_text有待商榷.
* 增加表格markdown渲染
* 增加基本表格CSS
* 调整parse_text函数
* refractor: 重写了parse_text
但是我真的好久没写代码了,不清楚这样有没有问题。
update utils
* 根据新的对话框样式调整了代码框样式
* 重写parse_text
现在是挤压连续多个`\n`为单个`\n`
* 将css代码从`presets.py`中分离出来,方便修改
* 再重写 parse_text
现在是真的只替换代码块中的多余空行了。。。
这下总可以了吧QAQ
* 修复实时代码块
---------
Co-authored-by: Chuan Hu <[email protected]>
Co-authored-by: mzlegion <[email protected]>
- ChuanhuChatbot.py +3 -0
- custom.css +133 -0
- presets.py +5 -54
- requirements.txt +1 -0
- utils.py +13 -28
ChuanhuChatbot.py
CHANGED
@@ -50,6 +50,9 @@ else:
|
|
50 |
|
51 |
gr.Chatbot.postprocess = postprocess
|
52 |
|
|
|
|
|
|
|
53 |
with gr.Blocks(css=customCSS) as demo:
|
54 |
history = gr.State([])
|
55 |
token_count = gr.State([])
|
|
|
50 |
|
51 |
gr.Chatbot.postprocess = postprocess
|
52 |
|
53 |
+
with open("custom.css", "r") as f:
|
54 |
+
customCSS = f.read()
|
55 |
+
|
56 |
with gr.Blocks(css=customCSS) as demo:
|
57 |
history = gr.State([])
|
58 |
token_count = gr.State([])
|
custom.css
ADDED
@@ -0,0 +1,133 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#status_display {
|
2 |
+
display: flex;
|
3 |
+
min-height: 2.5em;
|
4 |
+
align-items: flex-end;
|
5 |
+
justify-content: flex-end;
|
6 |
+
}
|
7 |
+
#status_display p {
|
8 |
+
font-size: .85em;
|
9 |
+
font-family: monospace;
|
10 |
+
color: var(--text-color-subdued) !important;
|
11 |
+
}
|
12 |
+
[class *= "message"] {
|
13 |
+
border-radius: var(--radius-xl) !important;
|
14 |
+
border: none;
|
15 |
+
padding: var(--spacing-xl) !important;
|
16 |
+
font-size: var(--text-md) !important;
|
17 |
+
line-height: var(--line-md) !important;
|
18 |
+
}
|
19 |
+
[data-testid = "bot"] {
|
20 |
+
max-width: 85%;
|
21 |
+
border-bottom-left-radius: 0 !important;
|
22 |
+
}
|
23 |
+
[data-testid = "user"] {
|
24 |
+
max-width: 85%;
|
25 |
+
width: auto !important;
|
26 |
+
border-bottom-right-radius: 0 !important;
|
27 |
+
}
|
28 |
+
table {
|
29 |
+
margin: 1em 0;
|
30 |
+
border-collapse: collapse;
|
31 |
+
empty-cells: show;
|
32 |
+
}
|
33 |
+
td,th {
|
34 |
+
border: 1.2px solid var(--color-border-primary) !important;
|
35 |
+
padding: 0.2em;
|
36 |
+
}
|
37 |
+
thead {
|
38 |
+
background-color: rgba(175,184,193,0.2);
|
39 |
+
}
|
40 |
+
thead th {
|
41 |
+
padding: .5em .2em;
|
42 |
+
}
|
43 |
+
code {
|
44 |
+
display: inline;
|
45 |
+
white-space: break-spaces;
|
46 |
+
border-radius: 6px;
|
47 |
+
margin: 0 2px 0 2px;
|
48 |
+
padding: .2em .4em .1em .4em;
|
49 |
+
background-color: rgba(175,184,193,0.2);
|
50 |
+
}
|
51 |
+
pre code {
|
52 |
+
display: block;
|
53 |
+
white-space: pre;
|
54 |
+
background-color: hsla(0, 0%, 0%, 80%)!important;
|
55 |
+
border-radius: 10px;
|
56 |
+
padding: 1rem 1.2rem 1rem;
|
57 |
+
margin: 1.2em 2em 1.2em 0.5em;
|
58 |
+
color: #FFF;
|
59 |
+
box-shadow: 6px 6px 16px hsla(0, 0%, 0%, 0.2);
|
60 |
+
}
|
61 |
+
.codehilite .hll { background-color: #49483e }
|
62 |
+
.codehilite .c { color: #75715e } /* Comment */
|
63 |
+
.codehilite .err { color: #960050; background-color: #1e0010 } /* Error */
|
64 |
+
.codehilite .k { color: #66d9ef } /* Keyword */
|
65 |
+
.codehilite .l { color: #ae81ff } /* Literal */
|
66 |
+
.codehilite .n { color: #f8f8f2 } /* Name */
|
67 |
+
.codehilite .o { color: #f92672 } /* Operator */
|
68 |
+
.codehilite .p { color: #f8f8f2 } /* Punctuation */
|
69 |
+
.codehilite .ch { color: #75715e } /* Comment.Hashbang */
|
70 |
+
.codehilite .cm { color: #75715e } /* Comment.Multiline */
|
71 |
+
.codehilite .cp { color: #75715e } /* Comment.Preproc */
|
72 |
+
.codehilite .cpf { color: #75715e } /* Comment.PreprocFile */
|
73 |
+
.codehilite .c1 { color: #75715e } /* Comment.Single */
|
74 |
+
.codehilite .cs { color: #75715e } /* Comment.Special */
|
75 |
+
.codehilite .gd { color: #f92672 } /* Generic.Deleted */
|
76 |
+
.codehilite .ge { font-style: italic } /* Generic.Emph */
|
77 |
+
.codehilite .gi { color: #a6e22e } /* Generic.Inserted */
|
78 |
+
.codehilite .gs { font-weight: bold } /* Generic.Strong */
|
79 |
+
.codehilite .gu { color: #75715e } /* Generic.Subheading */
|
80 |
+
.codehilite .kc { color: #66d9ef } /* Keyword.Constant */
|
81 |
+
.codehilite .kd { color: #66d9ef } /* Keyword.Declaration */
|
82 |
+
.codehilite .kn { color: #f92672 } /* Keyword.Namespace */
|
83 |
+
.codehilite .kp { color: #66d9ef } /* Keyword.Pseudo */
|
84 |
+
.codehilite .kr { color: #66d9ef } /* Keyword.Reserved */
|
85 |
+
.codehilite .kt { color: #66d9ef } /* Keyword.Type */
|
86 |
+
.codehilite .ld { color: #e6db74 } /* Literal.Date */
|
87 |
+
.codehilite .m { color: #ae81ff } /* Literal.Number */
|
88 |
+
.codehilite .s { color: #e6db74 } /* Literal.String */
|
89 |
+
.codehilite .na { color: #a6e22e } /* Name.Attribute */
|
90 |
+
.codehilite .nb { color: #f8f8f2 } /* Name.Builtin */
|
91 |
+
.codehilite .nc { color: #a6e22e } /* Name.Class */
|
92 |
+
.codehilite .no { color: #66d9ef } /* Name.Constant */
|
93 |
+
.codehilite .nd { color: #a6e22e } /* Name.Decorator */
|
94 |
+
.codehilite .ni { color: #f8f8f2 } /* Name.Entity */
|
95 |
+
.codehilite .ne { color: #a6e22e } /* Name.Exception */
|
96 |
+
.codehilite .nf { color: #a6e22e } /* Name.Function */
|
97 |
+
.codehilite .nl { color: #f8f8f2 } /* Name.Label */
|
98 |
+
.codehilite .nn { color: #f8f8f2 } /* Name.Namespace */
|
99 |
+
.codehilite .nx { color: #a6e22e } /* Name.Other */
|
100 |
+
.codehilite .py { color: #f8f8f2 } /* Name.Property */
|
101 |
+
.codehilite .nt { color: #f92672 } /* Name.Tag */
|
102 |
+
.codehilite .nv { color: #f8f8f2 } /* Name.Variable */
|
103 |
+
.codehilite .ow { color: #f92672 } /* Operator.Word */
|
104 |
+
.codehilite .w { color: #f8f8f2 } /* Text.Whitespace */
|
105 |
+
.codehilite .mb { color: #ae81ff } /* Literal.Number.Bin */
|
106 |
+
.codehilite .mf { color: #ae81ff } /* Literal.Number.Float */
|
107 |
+
.codehilite .mh { color: #ae81ff } /* Literal.Number.Hex */
|
108 |
+
.codehilite .mi { color: #ae81ff } /* Literal.Number.Integer */
|
109 |
+
.codehilite .mo { color: #ae81ff } /* Literal.Number.Oct */
|
110 |
+
.codehilite .sa { color: #e6db74 } /* Literal.String.Affix */
|
111 |
+
.codehilite .sb { color: #e6db74 } /* Literal.String.Backtick */
|
112 |
+
.codehilite .sc { color: #e6db74 } /* Literal.String.Char */
|
113 |
+
.codehilite .dl { color: #e6db74 } /* Literal.String.Delimiter */
|
114 |
+
.codehilite .sd { color: #e6db74 } /* Literal.String.Doc */
|
115 |
+
.codehilite .s2 { color: #e6db74 } /* Literal.String.Double */
|
116 |
+
.codehilite .se { color: #ae81ff } /* Literal.String.Escape */
|
117 |
+
.codehilite .sh { color: #e6db74 } /* Literal.String.Heredoc */
|
118 |
+
.codehilite .si { color: #e6db74 } /* Literal.String.Interpol */
|
119 |
+
.codehilite .sx { color: #e6db74 } /* Literal.String.Other */
|
120 |
+
.codehilite .sr { color: #e6db74 } /* Literal.String.Regex */
|
121 |
+
.codehilite .s1 { color: #e6db74 } /* Literal.String.Single */
|
122 |
+
.codehilite .ss { color: #e6db74 } /* Literal.String.Symbol */
|
123 |
+
.codehilite .bp { color: #f8f8f2 } /* Name.Builtin.Pseudo */
|
124 |
+
.codehilite .fm { color: #a6e22e } /* Name.Function.Magic */
|
125 |
+
.codehilite .vc { color: #f8f8f2 } /* Name.Variable.Class */
|
126 |
+
.codehilite .vg { color: #f8f8f2 } /* Name.Variable.Global */
|
127 |
+
.codehilite .vi { color: #f8f8f2 } /* Name.Variable.Instance */
|
128 |
+
.codehilite .vm { color: #f8f8f2 } /* Name.Variable.Magic */
|
129 |
+
.codehilite .il { color: #ae81ff } /* Literal.Number.Integer.Long */
|
130 |
+
|
131 |
+
* {
|
132 |
+
transition: all 0.6s;
|
133 |
+
}
|
presets.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1 |
# -*- coding:utf-8 -*-
|
2 |
title = """<h1 align="left" style="min-width:200px; margin-top:0;">川虎ChatGPT 🚀</h1>"""
|
3 |
-
description = """
|
|
|
4 |
|
5 |
由Bilibili [土川虎虎虎](https://space.bilibili.com/29125536) 和 [明昭MZhao](https://space.bilibili.com/24807452)开发
|
6 |
|
@@ -9,58 +10,6 @@ description = """<div align="center" style="margin:16px 0">
|
|
9 |
此App使用 `gpt-3.5-turbo` 大语言模型
|
10 |
</div>
|
11 |
"""
|
12 |
-
customCSS = """
|
13 |
-
#status_display {
|
14 |
-
display: flex;
|
15 |
-
min-height: 2.5em;
|
16 |
-
align-items: flex-end;
|
17 |
-
justify-content: flex-end;
|
18 |
-
}
|
19 |
-
#status_display p {
|
20 |
-
font-size: .85em;
|
21 |
-
font-family: monospace;
|
22 |
-
color: var(--text-color-subdued) !important;
|
23 |
-
}
|
24 |
-
[class *= "message"] {
|
25 |
-
border-radius: var(--radius-xl) !important;
|
26 |
-
border: none;
|
27 |
-
padding: var(--spacing-xl) !important;
|
28 |
-
font-size: var(--text-md) !important;
|
29 |
-
line-height: var(--line-md) !important;
|
30 |
-
}
|
31 |
-
[data-testid = "bot"] {
|
32 |
-
max-width: 85%;
|
33 |
-
border-bottom-left-radius: 0 !important;
|
34 |
-
}
|
35 |
-
[data-testid = "user"] {
|
36 |
-
max-width: 85%;
|
37 |
-
width: auto !important;
|
38 |
-
border-bottom-right-radius: 0 !important;
|
39 |
-
}
|
40 |
-
code {
|
41 |
-
display: inline;
|
42 |
-
white-space: break-spaces;
|
43 |
-
border-radius: 6px;
|
44 |
-
margin: 0 2px 0 2px;
|
45 |
-
padding: .2em .4em .1em .4em;
|
46 |
-
background-color: rgba(175,184,193,0.2);
|
47 |
-
}
|
48 |
-
pre code {
|
49 |
-
display: block;
|
50 |
-
white-space: pre;
|
51 |
-
background-color: hsla(0, 0%, 0%, 72%);
|
52 |
-
border: solid 5px var(--color-border-primary) !important;
|
53 |
-
border-radius: 10px;
|
54 |
-
padding: 0 1.2rem 1.2rem;
|
55 |
-
margin-top: 1em !important;
|
56 |
-
color: #FFF;
|
57 |
-
box-shadow: inset 0px 8px 16px hsla(0, 0%, 0%, .2)
|
58 |
-
}
|
59 |
-
|
60 |
-
* {
|
61 |
-
transition: all 0.6s;
|
62 |
-
}
|
63 |
-
"""
|
64 |
|
65 |
summarize_prompt = "你是谁?我们刚才聊了什么?" # 总结对话时的 prompt
|
66 |
MODELS = [
|
@@ -71,7 +20,9 @@ MODELS = [
|
|
71 |
"gpt-4-32k",
|
72 |
"gpt-4-32k-0314",
|
73 |
] # 可选的模型
|
74 |
-
|
|
|
|
|
75 |
|
76 |
{web_results}
|
77 |
Current date: {current_date}
|
|
|
1 |
# -*- coding:utf-8 -*-
|
2 |
title = """<h1 align="left" style="min-width:200px; margin-top:0;">川虎ChatGPT 🚀</h1>"""
|
3 |
+
description = """\
|
4 |
+
<div align="center" style="margin:16px 0">
|
5 |
|
6 |
由Bilibili [土川虎虎虎](https://space.bilibili.com/29125536) 和 [明昭MZhao](https://space.bilibili.com/24807452)开发
|
7 |
|
|
|
10 |
此App使用 `gpt-3.5-turbo` 大语言模型
|
11 |
</div>
|
12 |
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
|
14 |
summarize_prompt = "你是谁?我们刚才聊了什么?" # 总结对话时的 prompt
|
15 |
MODELS = [
|
|
|
20 |
"gpt-4-32k",
|
21 |
"gpt-4-32k-0314",
|
22 |
] # 可选的模型
|
23 |
+
|
24 |
+
websearch_prompt = """\
|
25 |
+
Web search results:
|
26 |
|
27 |
{web_results}
|
28 |
Current date: {current_date}
|
requirements.txt
CHANGED
@@ -6,3 +6,4 @@ socksio
|
|
6 |
tqdm
|
7 |
colorama
|
8 |
duckduckgo_search
|
|
|
|
6 |
tqdm
|
7 |
colorama
|
8 |
duckduckgo_search
|
9 |
+
Pygments
|
utils.py
CHANGED
@@ -53,7 +53,7 @@ def postprocess(
|
|
53 |
# None if message is None else markdown.markdown(message),
|
54 |
# None if response is None else markdown.markdown(response),
|
55 |
None if message is None else message,
|
56 |
-
None if response is None else mdtex2html.convert(response),
|
57 |
)
|
58 |
return y
|
59 |
|
@@ -66,34 +66,19 @@ def count_token(message):
|
|
66 |
|
67 |
|
68 |
def parse_text(text):
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
lines[i] = f'<pre><code class="language-{items[-1]}">'
|
78 |
-
else:
|
79 |
-
lines[i] = f"<br></code></pre>"
|
80 |
else:
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
line = line.replace(">", ">")
|
86 |
-
line = line.replace(" ", " ")
|
87 |
-
line = line.replace("*", "*")
|
88 |
-
line = line.replace("_", "_")
|
89 |
-
line = line.replace("-", "-")
|
90 |
-
line = line.replace(".", ".")
|
91 |
-
line = line.replace("!", "!")
|
92 |
-
line = line.replace("(", "(")
|
93 |
-
line = line.replace(")", ")")
|
94 |
-
line = line.replace("$", "$")
|
95 |
-
lines[i] = "<br>" + line
|
96 |
-
text = "".join(lines)
|
97 |
return text
|
98 |
|
99 |
|
|
|
53 |
# None if message is None else markdown.markdown(message),
|
54 |
# None if response is None else markdown.markdown(response),
|
55 |
None if message is None else message,
|
56 |
+
None if response is None else mdtex2html.convert(response, extensions=['fenced_code','codehilite','tables']),
|
57 |
)
|
58 |
return y
|
59 |
|
|
|
66 |
|
67 |
|
68 |
def parse_text(text):
|
69 |
+
in_code_block = False
|
70 |
+
new_lines = []
|
71 |
+
for i,line in enumerate(text.split("\n")):
|
72 |
+
if line.strip().startswith("```"):
|
73 |
+
in_code_block = not in_code_block
|
74 |
+
if in_code_block:
|
75 |
+
if line.strip() != "":
|
76 |
+
new_lines.append(line)
|
|
|
|
|
|
|
77 |
else:
|
78 |
+
new_lines.append(line)
|
79 |
+
if in_code_block:
|
80 |
+
new_lines.append("```")
|
81 |
+
text = "\n".join(new_lines)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
82 |
return text
|
83 |
|
84 |
|