开发者

基于Python实现Markdown编辑器的示例详解

目录
  • 故事开场
  • 完整代码速览
  • 代码解析
    • 功能块 1:搭一个左右分栏的窗口
    • 功能块 2:左边写 Markdown
    • 功能块 3:右边实时预览
    • 功能块 4:一键打开/保存
  • 如果还想更厉害
    • 扩展点子 1:命令行批量转换
    • 扩展点子 2:加主题切换按钮
  • 知识延展
    • 总结

      故事开场

      深夜 11 点,你要给项目写一份 README。

      Typora 突然收费、VS Code 插件又卡顿,每次改一行都得 Ctrl+S → 切浏览器 → F5,循环十次,心态爆炸。

      这时,你从桌面角落掏出“小白瑞士军刀”——markdown_editor.py

      双击,弹出迷你双栏窗口:左边写 Markdown,右边实时变成漂亮网页;写完直接 Ctrl+S 导出 .md,三秒搞定。

      痛点解决:再也不用“写-保存-刷新”三连,所见即所得,熬夜少一点。

      完整代码速览

      #!/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 HTMLLabel
      
      class Window(tk.Frame):
          def __init__(self, master=None):
              super().__init__(master)
              self.master = master
              self.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)
      
            android  self.outputbox = HTMLLabel(self, width=1, background="white",
                                 javascript        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:右边实时预览

      markdown2pythonMarkdown 秒变 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 current
          current = "dark" if current == "light" else "light"
          outputbox.cpythononfig(background=themes[current])
      tk.Button(root, text="换肤", command=toggle_theme).pack(side="bottom")
      

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

      知识延展

      Python Markdown转PDF

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

      import markdown
      import pdfkit
      import sys
      
      args = sys.argv[1:]  # 收集命令行参数
      assert args, "No file/dir was provided"
      
      html_texts = []
      for arg in args:
          with open(arg, "r", encoding="utf-8") as f:
              md = f.read()
          html_texts.append(markdown.markdown(md))
      
      # 指向 wkhtmltopdf 可执行文件(Windows 示例)
      config = pdfkit.configuration(
          wkhtmltopdf=r"C:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe")
      
      for idx, html in enumerate(html_texts):
          filename = args[idx].r编程客栈split('.', 1)[0]  # 去掉扩展名
          pdfkit.from_string(html, f'{filename}.pdf', configuration=config)
      

      代码解析

      功能块 1:命令行接收文件

      像快递小哥一样,脚本在门口等你把 .md 文件扔进来。

      args = sys.argv[1:]
      assert args, "No file/dir was provided"
      

      支持一次拖多个文件:python markdown_to_pdf.py readme.md blog.md

      功能块 2:Markdown 秒变 HTML

      把 Markdown 语法翻译成浏览器能看懂的 HTML,就像把方言翻译成普通话。

      html_texts.append(markdown.markdown(md))
      

      表格、代码块、标题样式一次性到位。

      功能块 3:HTML 秒变 PDF

      用 wkhtmltopdf 把网页“打印”成 PDF,排版 100% 还原。

      pdfkit.from_string(html, f'{filename}.pdf', configuration=config)
      

      只要路径正确,Windows、MACOS、linux 都能用。

      如果还想更厉害

      扩展点子 1:命令行加参数,一键换主题

      加 --theme 参数,用不同 css 模板。

      import argparse
      parser = argparse.ArgumentParser()
      parser.add_argument("--theme", default="github.css")
      args = parser.parse_args()
      css = open(args.theme).read()
      html = f"<style>{css}</style>" + markdown.markdown(md)
      

      运行:

      python markdown_to_pdf.py readme.md --theme dark.css
      

      扩展点子 2:批量文件夹

      把某个文件夹所有 .md 一键转 PDF。

      import glob
      for md_path in glob.glob("docs/*.md"):
          with open(md_path, encoding="utf-8") as f:
              html = markdown.markdown(f.read())
          pdfkit.from_string(html, md_path.replace(".md", ".pdf"), configuration=config)

      总结

      markdown_editor.py 这把瑞士军刀只有 60 行,却把“写作 + 预览 + 导出”三件事装进了一个轻量级窗口。

      你双击即可写 README、写博客、写笔记,再也不用来回切换软件。

      再加两行代码,就能批量转网页或一键换主题,小白也能玩出花。

      下次写文档,记得先打开它,写完即发布,效率翻倍。

      到此这篇关于基于Python实现Markdown编辑器的示例详解的文章就介绍到这了,更多相关Python Markdown编辑器内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

      0

      上一篇:

      下一篇:

      精彩评论

      暂无评论...
      验证码 换一张
      取 消

      最新开发

      开发排行榜