python 实现markdown编辑器-9

python 实现markdown编辑器

      • 表格

表格

# 1号标题
## 2号标题
### 3号标题
#### 4号标题
##### 5号标题
###### 6号标题
- 无序列表第一种
* 无序列表第二种
+ 无序列表第三种
1. test
2. test
3. test
- [ ] unchecked
- [x] checked
` ` `
import this
` ` `
test
: test1
: test2
$$\sin x$$
----
第一列|第二列
-----|-----
第一条|第二条
第三条|第四条

这个语法比较复杂,所以需要一行一行分析:
一个简单点的示例:

col1 col2
item item
 col1|col2
 ----|----
 item|item

第一行:

col1|col2

格式是A|B
第二行:

----|----

格式是 任意个-  +  |  +  任意个-
第三行:

 item|item

格式同第一行
一个复杂点的示例:

col1 col2 col3
item item item
item item item
col1|col2|col3
----|----|----
item|item|item
item|item|item

不难发现表格的格式是:

  • 第一行:用|隔开的列标题
  • 第二行:用|隔开多个-
  • 第三行及以后:用|隔开的每一项

所以可以给出代码:

from tkinter.filedialog import askopenfilename as aof,asksaveasfilename as asf
from tkinter.messagebox import askyesno as askyn
from PIL import Image,ImageDraw,ImageTk
from tkinter import ttk
import tkinter as tk
import requests
import io
fontname = ...
display = tk.Tk()
writer = tk.Toplevel()
widgets = []
text = tk.Text(writer)
text.grid(row=0,column=0)
cont = ''
def read_md(file):
 	with open(file) as f:
 			return f.read()
def write_md(file,cont):
 	with open(file,'w') as f:
 		f.write(cont)
def clear():
	for i in widgets:
		i.grid_forget()
def get_KaTeX_io(katex):
	resp = requests.get('https://latex.codecogs.com/png.image?\dpi{110} ' + katex)
	return io.BytesIO(resp.content)
def get_KaTeX(katex):
	img_io = get_KaTeX_io(katex)
	img = Image.open(img_io)
	return ImageTk.PhotoImage(img)
def get_spliter():
	w = max(1,display.winfo_width() - 6)
	img = Image.new('RGB',(w,1),(221,221,221))
	return ImageTk.PhotoImage(img)
def render_md():
	display.update()
	clear()
	l = 0
	code = False
	buf = ''
	n = 0
	for i in cont.split('\n'):
		if(n):
			n -= 1
			continue
		if(code and i != '```'):
			buf += i + '\n'
			continue
		if(i.startswith('# ')):
			lb = tk.Label(display,text=i[2:],font=(fontname,40,'bold'))
		elif(i.startswith('## ')):
			lb = tk.Label(display,text=i[3:],font=(fontname,35,'bold'))
		elif(i.startswith('### ')):
			lb = tk.Label(display,text=i[4:],font=(fontname,30,'bold'))
		elif(i.startswith('#### ')):
			lb = tk.Label(display,text=i[5:],font=(fontname,25,'bold'))
		elif(i.startswith('##### ')):
			lb = tk.Label(display,text=i[6:],font=(fontname,20,'bold'))
		elif(i.startswith('###### ')):
			lb = tk.Label(display,text=i[7:],font=(fontname,15,'bold'))
		elif(i.startswith('- [ ] ')):
			lb = tk.Checkbutton(display,text=i[6:],state=tk.DISABLED)
		elif(i.startswith('- [x] ')):
			lb = tk.Checkbutton(display,text=i[6:],state=tk.DISABLED)
			lb.select()
		elif(i.startswith('- ') or i.startswith('* ') or i.startswith('+ ')):
			i = '● ' + i[2:]
			lb = tk.Label(display,text=i,font=(fontname,15,''))
		elif(i.startswith(': ')):
			lb = tk.Label(display,text='\t'+i[2:])
		elif(i.startswith('$$') and i.endswith('$$') and i not in ('$$','$$$')):
			imgTk = get_KaTeX(i[2:-2])
			lb = tk.Label(display,image=imgTk)
			lb.image = imgTk
			lb.grid(row=l,column=0)
			l += 1
			continue
		elif(set(i) in ({
     '-'},{
     '*'}) and len(i) >= 3):
			imgTk = get_spliter()
			lb = tk.Label(display,image=imgTk)
			lb.image = imgTk
		elif(i == '```'):
			if(code):
				lb = tk.Text(display)
				lb.insert(0.0,buf)
				h = float(lb.index(tk.END)) - 2
				lb.config(height=h)
				buf = ''
				code = False
			else:
				code = True
				continue
		else:
			try:
				head = i.split('|')
				check = cont.split('\n')[l + 1].split('|')
				assert len(head) == len(check)
				assert set(''.join(check)) == {
     '-'}
				assert all(check)
				assert len(head) > 1
				body = []
				after = cont.split('\n')[l + 2:]
				n = 1
				for j in after:
					if(len(j.split('|')) == len(head)):
						body.append(j.split('|'))
					else:
						break
					l += 1
					n += 1
				assert body
				lb = ttk.Treeview(display,columns=[i for i in range(len(head))],show='headings')
				for j in range(len(head)):
					lb.heading(j,text=head[j])
				for j in body:
					lb.insert('','end',value=j)
			except:
				n = 0
				lb = tk.Label(display,text=i,font=(fontname,15,''))
		lb.grid(row=l,column=0,sticky='w')
		widgets.append(lb)
		l += 1
def update_writer():
	global cont
	writer.update()
	cont = text.get(0.0,tk.END)
def main():
	global cont
	writer.title('writer')
	display.title('displayer')
	file = aof(title='open a markdown file')
	if(file):
		cont = read_md(file)
	text.insert(0.0,cont)
	while(1):
		try:
			update_writer()
			render_md()
		except:
			try:
				writer.destroy()
			except:
				pass
			try:
				display.destroy()
			except:
				pass
			if(file):
				write_md(file,cont)
			else:
				tk.Tk().withdraw()
				while(1):
					file = asf(title='save as ...')
					if(not file):
						if(not askyn('Do you want to keep this new document?','Do you want to keep this new document?')):
							exit()
					write_md(file)
if(__name__ == '__main__'):
	main()

这里使用ttk中的Treeview表格控件完成。
效果:
python 实现markdown编辑器-9_第1张图片

>> 《python 实现markdown编辑器-10》

你可能感兴趣的:(python,markdown)