当前位置: 首页 > news >正文

【python实用小脚本-169】『Python』所见即所得 Markdown 编辑器:写完即出网页预览——告别“写完→保存→刷新”三连

『Python』所见即所得 Markdown 编辑器:写完即出网页预览——告别“写完→保存→刷新”三连

Markdown, 实时预览, 小白编辑器, 一键导出, 瑞士军刀

故事开场:一把瑞士军刀救了熬夜写 README 的你

深夜 11 点,你要给项目写一份 README。
Typora 突然收费、VS Code 插件又卡顿,每次改一行都得 Ctrl+S → 切浏览器 → F5,循环十次,心态爆炸。
这时,你从桌面角落掏出“小白瑞士军刀”——markdown_editor.py
双击,弹出迷你双栏窗口:左边写 Markdown,右边实时变成漂亮网页;写完直接 Ctrl+S 导出 .md,三秒搞定。
痛点解决:再也不用“写-保存-刷新”三连,所见即所得,熬夜少一点。


完整代码速览(≤1000字符,直接展示)

#!/usr/bin/python
# -*- coding: utf-8 -*-
import tkinter as tk
from tkinter import font, filedialog, messagebox as mbox
from markdown2 import Markdown
from tkhtmlview import HTMLLabelclass Window(tk.Frame):def __init__(self, master=None):super().__init__(master)self.master = masterself.font = font.Font(family="Helvetica", size=14)self.init_window()def onChange(self, event):self.inputeditor.edit_modified(0)md2html = Markdown()self.outputbox.set_html(md2html.convert(self.inputeditor.get("1.0", tk.END)))def openfile(self):filename = filedialog.askopenfilename(filetypes=[("Markdown", "*.md"), ("Text", "*.txt"), ("All", "*.*")])if filename:try:self.inputeditor.delete("1.0", tk.END)self.inputeditor.insert(tk.END, open(filename, "r").read())except Exception:mbox.showerror("Error", f"{filename} cannot be opened!")def savefile(self):filedata = self.inputeditor.get("1.0", tk.END)filename = filedialog.asksaveasfilename(defaultextension=".md",filetypes=[("Markdown", "*.md"), ("Text", "*.txt")])if filename:open(filename, "w").write(filedata)def init_window(self):self.master.title("Markdown Viewer")self.pack(fill=tk.BOTH, expand=1)menu = tk.Menu(self)filemenu = tk.Menu(menu, tearoff=0)filemenu.add_command(label="Open", command=self.openfile)filemenu.add_command(label="Save as", command=self.savefile)filemenu.add_separator()filemenu.add_command(label="Exit", command=self.quit)menu.add_cascade(label="File", menu=filemenu)self.master.config(menu=menu)self.inputeditor = tk.Text(self, width=1, font=self.font)self.inputeditor.pack(fill=tk.BOTH, expand=1, side=tk.LEFT)self.inputeditor.bind("<<Modified>>", self.onChange)self.outputbox = HTMLLabel(self, width=1, background="white",html="<h1>Markdown Editor</h1>")self.outputbox.pack(fill=tk.BOTH, expand=1, side=tk.RIGHT)root = tk.Tk()
root.geometry("750x600")
Window(root)
root.mainloop()

代码解析

功能块 1:搭一个左右分栏的窗口

像搭积木一样,先放左右两块“写字板”。

root = tk.Tk()
root.geometry("750x600")

750x600 固定大小,防止小白把窗口拉得面目全非。

功能块 2:左边写 Markdown

左边就是普通的 Text 框,绑定“内容被修改”事件。

self.inputeditor = tk.Text(self, width=1, font=self.font)
self.inputeditor.bind("<<Modified>>", self.onChange)

每敲一个字,就触发 onChange,右边立刻刷新。

功能块 3:右边实时预览

markdown2 把 Markdown 秒变 HTML,再用 HTMLLabel 显示。

def onChange(self, event):md2html = Markdown()self.outputbox.set_html(md2html.convert(self.inputeditor.get("1.0", tk.END)))

所见即所得,连表格、代码高亮都能实时渲染。

功能块 4:一键打开/保存

菜单栏放两个按钮,“Open” 读取现有 .md,“Save as” 导出成 .md.txt

filemenu.add_command(label="Open", command=self.openfile)
filemenu.add_command(label="Save as", command=self.savefile)

文件对话框自带过滤,小白不会选错格式。


如果还想更厉害

扩展点子 1:命令行批量转换

把当前目录所有 .md 一键转 .html,适合批量发布博客。

import glob, pathlib, markdown2
for md in glob.glob("*.md"):html = markdown2.markdown_path(md)pathlib.Path(md.replace(".md", ".html")).write_text(html, encoding="utf-8")

一行命令,整站静态页生成完毕。

扩展点子 2:加主题切换按钮

给预览区加“深色/浅色”按钮,夜间护眼。

themes = {"light": "white", "dark": "#1e1e1e"}
current = "light"
def toggle_theme():global currentcurrent = "dark" if current == "light" else "light"outputbox.config(background=themes[current])
tk.Button(root, text="换肤", command=toggle_theme).pack(side="bottom")

点一下,整个右边窗口立刻变暗,熬夜更舒服。


总结

markdown_editor.py 这把瑞士军刀只有 60 行,却把“写作 + 预览 + 导出”三件事装进了一个轻量级窗口。
你双击即可写 README、写博客、写笔记,再也不用来回切换软件。
再加两行代码,就能批量转网页或一键换主题,小白也能玩出花。
下次写文档,记得先打开它,写完即发布,效率翻倍。

源码获取

完整代码已开源,包含详细的注释文档:
🔗 [GitCode仓库] https://gitcode.com/laonong-1024/python-automation-scripts
📥 [备用下载] https://pan.quark.cn/s/654cf649e5a6 提取码:f5VG

http://www.xdnf.cn/news/1235539.html

相关文章:

  • Rustdesk中继服务器搭建(windows 服务器)
  • SQL注入SQLi-LABS 靶场less31-38详细通关攻略
  • Python篇--- Python 的加载、缓存、覆盖机制
  • (FD Conv)Frequency Dynamic Convolution for Dense Image Prediction论文精读(逐段解析)
  • vscode的Remote-SSH插件配置SSH主机方法
  • 构造类型--结构体,共同体联合体,枚举
  • 知识蒸馏 - 基于KL散度的知识蒸馏 HelloWorld 示例 采用PyTorch 内置函数F.kl_div的实现方式
  • 标记-清除算法中的可达性判定与Chrome DevTools内存分析实践
  • Rust: 获取 MAC 地址方法大全
  • webrtv弱网-QualityScalerResource 源码分析及算法原理
  • 集成电路学习:什么是USB HID人机接口设备
  • Hertzbeat如何配置redis?保存在redis的数据是可读数据
  • PostgreSQL面试题及详细答案120道(21-40)
  • 腾讯人脸识别
  • 14.Redis 哨兵 Sentinel
  • C++中多线程和互斥锁的基本使用
  • [硬件电路-148]:数字电路 - 什么是CMOS电平、TTL电平?还有哪些其他电平标准?发展历史?
  • 本地环境vue与springboot联调
  • 2025年6月电子学会青少年软件编程(C语言)等级考试试卷(四级)
  • [硬件电路-143]:模拟电路 - 开关电源与线性稳压电源的详细比较
  • Ubuntu22.4部署大模型前置安装
  • webrtc弱网-QualityScaler 源码分析与算法原理
  • ubuntu apt安装与dpkg安装相互之间的关系
  • (一)全栈(react配置/https支持/useState多组件传递/表单提交/React Query/axois封装/Router)
  • 自动驾驶中的传感器技术18——Camera(9)
  • GitLab 代码管理平台部署及使用
  • Java基本技术讲解
  • PPT自动化 python-pptx - 9: 图表(chart)
  • 决策树学习全解析:从理论到实战
  • 【LeetCode刷题指南】--二叉树的后序遍历,二叉树遍历