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

如何用Python开发一个功能全面的Markdown编辑工具

在这篇博客中,我将详细分析和讲解一段用Python开发的Markdown编辑工具代码。这款工具支持Markdown内容的编辑、HTML预览、导出为PDF和保存为图片的功能,同时还可以实现代码高亮。
C:\pythoncode\new\MarkdownToPdfJpegPreview.py


功能介绍

这款Markdown编辑工具基于wxPython开发,核心功能包括:

  1. Markdown编辑与HTML实时预览

    • 提供编辑区域(Memo)供用户录入Markdown内容。
    • 使用wx.html2.WebView组件将Markdown内容转为HTML并实时预览。
  2. 代码高亮

    • 使用Highlight.js实现Markdown代码段的语法高亮。
  3. 导出功能

    • 支持将Markdown保存为.md文件。
    • 将HTML预览内容导出为PDF文件。
    • 将HTML内容保存为JPEG格式的图片。

环境准备

所需的依赖库:
  • wxPython:构建图形界面
  • markdown:将Markdown解析为HTML
  • pdfkit:将HTML转换为PDF文件
  • imgkit:将HTML保存为图片
  • Pillow:处理图像

可以通过以下命令安装:

pip install wxPython markdown pdfkit imgkit pillow
安装wkhtmltopdfwkhtmltoimage工具:

pdfkitimgkit需要wkhtmltopdfwkhtmltoimage工具的支持。

  • 下载地址:wkhtmltopdf
  • 安装后,将工具路径(如C:\Program Files\wkhtmltopdf\bin)加入环境变量,或在代码中显式指定路径。

代码分析

下面是实现Markdown编辑工具的完整代码:

import wx
import wx.html2  # HTML浏览器控件
import markdown  # Markdown解析模块
import pdfkit    # HTML转PDF模块
from PIL import Image
from io import BytesIO
import imgkit


def markdown_to_html_with_highlight(md_content):
    """将Markdown转换为HTML并添加代码高亮支持"""
    html_content = markdown.markdown(md_content, extensions=['fenced_code'])
    # 添加Highlight.js脚本和样式
    highlight_js = '''
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/default.min.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js"></script>
    <script>hljs.highlightAll();</script>
    '''
    return f"{highlight_js}<body>{html_content}</body>"


class MarkdownApp(wx.Frame):
    def __init__(self):
        super().__init__(None, title="Markdown编辑工具", size=(1000, 700))
        self.InitUI()

    def InitUI(self):
        # 工具栏
        toolbar = self.CreateToolBar()
        toolbar.AddTool(wx.ID_SAVE, "保存 Markdown", wx.ArtProvider.GetBitmap(wx.ART_FILE_SAVE))
        toolbar.AddTool(wx.ID_PREVIEW, "预览", wx.ArtProvider.GetBitmap(wx.ART_FIND))
        toolbar.AddTool(wx.ID_PRINT, "生成 PDF", wx.ArtProvider.GetBitmap(wx.ART_PRINT))
        toolbar.AddTool(wx.ID_SAVEAS, "保存为图片", wx.ArtProvider.GetBitmap(wx.ART_PASTE))
        toolbar.Realize()

        # 绑定工具栏按钮事件
        self.Bind(wx.EVT_TOOL, self.OnSaveMarkdown, id=wx.ID_SAVE)
        self.Bind(wx.EVT_TOOL, self.OnPreview, id=wx.ID_PREVIEW)
        self.Bind(wx.EVT_TOOL, self.OnGeneratePDF, id=wx.ID_PRINT)
        self.Bind(wx.EVT_TOOL, self.OnSaveImage, id=wx.ID_SAVEAS)

        # 布局
        panel = wx.Panel(self)
        vbox = wx.BoxSizer(wx.VERTICAL)

        self.memo = wx.TextCtrl(panel, style=wx.TE_MULTILINE)
        self.browser = wx.html2.WebView.New(panel)

        vbox.Add(self.memo, 1, wx.EXPAND)
        vbox.Add(self.browser, 1, wx.EXPAND)

        panel.SetSizer(vbox)
        self.Show()

    def OnPreview(self, event):
        """预览Markdown内容为HTML"""
        md_content = self.memo.GetValue()
        html_content = markdown_to_html_with_highlight(md_content)
        self.browser.SetPage(html_content, "")

    def OnSaveMarkdown(self, event):
        """保存Markdown为.md文件"""
        with wx.FileDialog(self, "保存 Markdown", wildcard="Markdown 文件 (*.md)|*.md",
                           style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT) as dialog:
            if dialog.ShowModal() == wx.ID_CANCEL:
                return
            path = dialog.GetPath()
            with open(path, 'w', encoding='utf-8') as file:
                file.write(self.memo.GetValue())

    def OnGeneratePDF(self, event):
        """生成PDF文件"""
        md_content = self.memo.GetValue()
        html_content = markdown.markdown(md_content)
        with wx.FileDialog(self, "保存 PDF 文件", wildcard="PDF 文件 (*.pdf)|*.pdf",
                           style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT) as dialog:
            if dialog.ShowModal() == wx.ID_CANCEL:
                return
            path = dialog.GetPath()
            config = pdfkit.configuration(wkhtmltopdf='C:/Program Files/wkhtmltopdf/bin/wkhtmltopdf.exe')
            pdfkit.from_string(html_content, path, configuration=config)

    def OnSaveImage(self, event):
        """保存HTML内容为JPEG图片"""
        md_content = self.memo.GetValue()
        html_content = markdown.markdown(md_content)
        with wx.FileDialog(self, "保存图片", wildcard="JPEG 文件 (*.jpeg)|*.jpeg",
                           style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT) as dialog:
            if dialog.ShowModal() == wx.ID_CANCEL:
                return
            path = dialog.GetPath()
            config = imgkit.config(wkhtmltoimage='C:/Program Files/wkhtmltopdf/bin/wkhtmltoimage.exe')
            img_data = imgkit.from_string(html_content, False, config=config)
            image = Image.open(BytesIO(img_data))
            image.save(path, format="JPEG")


if __name__ == "__main__":
    app = wx.App()
    MarkdownApp()
    app.MainLoop()

功能解析

  1. Markdown解析与HTML预览

    • markdown.markdown()方法将Markdown内容转为HTML。
    • 通过Highlight.js实现代码块的语法高亮。
  2. 生成PDF

    • 使用pdfkit模块的from_string()方法将HTML内容保存为PDF。
    • 需要确保wkhtmltopdf工具正确安装并指定路径。
      需要安装wkhtmltopdf应用程序
      https://wkhtmltopdf.org/downloads.html
  3. 保存为图片

    • 使用imgkit模块生成HTML内容的图片。
    • 使用Pillow库将生成的图像数据保存为JPEG格式。
  4. 界面交互

    • 使用wxPython的工具栏和对话框实现文件保存等功能。
    • 提供预览功能让用户直观地查看Markdown效果。

运行结果

在这里插入图片描述

相关文章:

  • 小罗资源网:网络资源聚集地
  • C++变量声明、作用域与内存管理
  • GitHub上传项目
  • 开发vue小游戏:数字华龙道
  • 2025 docker安装TiDB数据库
  • 嵌入式人工智能应用-第6章 人脸检测
  • 华为鸿蒙系统全景解读:从内核设计到生态落地的技术革命
  • Java中的栈的实现
  • css 文本属性-第五章
  • 利用Deepseek+即梦,3分钟做出疗愈风禅意小院视频(含sop)
  • 网站应用-电脑PC微信快速登录-微信开发平台
  • 在Uniapp中实现特殊字符弹出框并插入输入框
  • 第本章:go 切片
  • win11 Visual Studio 17 2022源码编译 opencv4.11.0 + cuda12.6.3 启用GPU加速
  • Java链接redis
  • react 和 react-dom
  • VUE3项目的文档结构分析
  • JVM、JDK、JRE三者的关系
  • 【linux网络编程】字节序
  • 第七章 二叉树
  • 网站注册系统用什么做/如何提高网站排名
  • 企业网站建设哪家好/站长统计app软件大全
  • 做网站在阿里云上面买哪个服务/快速排名优化
  • 注册公司具体费用/长春seo优化
  • 建立问答类的网站/seo代理
  • 设计室内效果图设计/微博关键词排名优化