Keldos Chuan Hu MZhaovo commited on
Commit
9c7114f
·
unverified ·
1 Parent(s): 76e70d9

引入 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]>

Files changed (5) hide show
  1. ChuanhuChatbot.py +3 -0
  2. custom.css +133 -0
  3. presets.py +5 -54
  4. requirements.txt +1 -0
  5. 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 = """<div align="center" style="margin:16px 0">
 
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
- websearch_prompt = """Web search results:
 
 
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
- lines = text.split("\n")
70
- lines = [line for line in lines if line != ""]
71
- count = 0
72
- for i, line in enumerate(lines):
73
- if "```" in line:
74
- count += 1
75
- items = line.split("`")
76
- if count % 2 == 1:
77
- lines[i] = f'<pre><code class="language-{items[-1]}">'
78
- else:
79
- lines[i] = f"<br></code></pre>"
80
  else:
81
- if i > 0:
82
- if count % 2 == 1:
83
- line = line.replace("`", "\`")
84
- line = line.replace("<", "&lt;")
85
- line = line.replace(">", "&gt;")
86
- line = line.replace(" ", "&nbsp;")
87
- line = line.replace("*", "&ast;")
88
- line = line.replace("_", "&lowbar;")
89
- line = line.replace("-", "&#45;")
90
- line = line.replace(".", "&#46;")
91
- line = line.replace("!", "&#33;")
92
- line = line.replace("(", "&#40;")
93
- line = line.replace(")", "&#41;")
94
- line = line.replace("$", "&#36;")
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