Repository navigation
Expand file tree
/
Copy pathrender.py
More file actions
138 lines (120 loc) · 4.59 KB
/
Copy pathrender.py
File metadata and controls
138 lines (120 loc) · 4.59 KB
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
import os
import re
from _global import *
from rich.markdown import Markdown
from rich.console import Console
from rich.style import Style
from rich.theme import Theme
from rich.text import Text
from rich.live import Live
# 自定义主题
custom_theme = Theme({
"markdown.block_quote": "#999999 on #1f1f1f",
"markdown.block_quote_border": "#d75f00",
"markdown.h1": "bold #7095e1 on #293140",
"markdown.h2": "bold #dbb071 on #3f362a",
"markdown.h3": "bold #9ac96a on #323b28",
"markdown.h4": "bold #1bb598 on #183731",
"markdown.h5": "bold #bba2ec on #383342",
"markdown.h6": "bold #9c7ed3 on #322c3d",
"markdown.item.bullet": "#fd9d62",
"markdown.item.number": "#fd9d62",
"markdown.link_url": "#29a3bb",
"markdown.hr": "#fd9d62",
"table.border": "#b07d62",
"table.header": "bold #8da6e1",
"table.footer": "bold #8da6e1",
# "markdown.h1": "bold #1E90FF",
# "markdown.h1.icon": "#000000 on #1E90FF",
# "markdown.h2": "bold #00BFFF",
# "markdown.h2.icon": "#000000 on #00BFFF",
# "markdown.h3": "bold #87CEFA",
# "markdown.h3.icon": "#000000 on #87CEFA",
# "markdown.h4": "bold #87CEEB",
# "markdown.h4.icon": "#000000 on #87CEEB",
# "markdown.h5": "bold #E0FFFF",
# "markdown.h5.icon": "#000000 on #E0FFFF",
# "markdown.h6": "#E0FFFF",
# "markdown.h6.icon": "#000000 on #E0FFFF",
"live.ellipsis": "#e6db74 on #242933"
})
console = Console(theme=custom_theme)
class MDStreamRenderer:
def __init__(self, code_start:int):
self.md = None
self.live = None
self.code_start = code_start
self.buffer = ""
def __enter__(self):
self._new()
self.code_list = []
return self
def _md2snippet(self):
for elem in self.md.parsed:
if elem.type == 'fence' and elem.block:
sid = self._add_snippet(elem.info, elem.content)
elem.meta.update({
"sid": sid,
"sdir": str(SNIPPETS_DIR / str(sid))
})
self.live.update(self.md, refresh=True)
def _new(self, text=''):
self.code_pose, self.code_in = -1, False
if self.md is not None:
self._md2snippet()
self.live.__exit__(None, None, None)
self.buffer = text
self.live = Live(console=console, refresh_per_second=10)
self.live.__enter__()
def _end(self):
if self.md is not None:
self._md2snippet()
self.md = None
def __exit__(self, exc_type, exc_value, traceback):
self.live.__exit__(exc_type, exc_value, traceback)
def _add_snippet(self, lang, code):
self.code_list.append({"lang": lang, "code": code})
return self.code_start+len(self.code_list)-1
def _update(self, edl:str='', reasoning:bool=False):
def _new_md(buffer:str):
return Markdown(buffer, code_theme="nord-darker", inline_code_lexer="text")
if self.buffer == '' and (edl == '' or edl == '\n\n'):
return
self.buffer += edl
# print('code', self.code_in, 'buffer', f'{self.buffer!r}')
try:
new_pose = self.buffer.rfind('```')
self.md = _new_md(self.buffer)
self.live.update(self.md, refresh=True)
if self.code_in:
if new_pose != self.code_pose:
self.code_in = False
self.code_pose = new_pose
if edl == '\n\n' or ('close' in self.md.parsed[-1].type and self.md.parsed[-1].level == 0 and reasoning):
self._new()
else:
if new_pose == self.code_pose:
if edl == '\n\n' or ('close' in self.md.parsed[-1].type and self.md.parsed[-1].level == 0 and reasoning):
self._new()
else:
self.code_pose = new_pose
self.code_in = True
except:
self.live.update(Text(self.buffer), refresh=True)
def update(self, chunk:str, reasoning:bool=False):
chunk = re.sub(r"\n{2,}", "\n\n", chunk)
length, i, newline = len(chunk), 0, False
while i < length:
if chunk[i] == '\n':
newline = False
if i+1 < length and chunk[i+1] == '\n':
self._update('\n\n')
i = i+1
else:
self._update('\n', reasoning)
else:
newline = True
self.buffer += chunk[i]
i += 1
if newline:
self._update()