[319]使用python将markdown和html互转

166 阅读9分钟

@[toc]

将markdown转换成html

markdown用法

Github地址:github.com/Python-Mark…

什么是Python-Markdown?

Python-Markdown是一个用于解析和转换Markdown文档的Python库。它可以将Markdown文本转换为HTML或其他格式,并提供了一些方便的工具和扩展来扩展Markdown的功能。Python-Markdown的目标是提供一种灵活而易于使用的方式来处理和生成Markdown文档,可以专注于内容而不必担心文档的样式和排版。

Python-Markdown的特点

  • 标准Markdown支持:它支持标准Markdown语法,包括标题、段落、列表、链接、引用等。
  • HTML转换:Python-Markdown可以将Markdown文本转换为HTML,可以在网页上轻松显示文档。
  • 自定义扩展:可以使用扩展来添加自定义的Markdown标记和功能,以满足不同的需求。
  • 多输出格式:除了HTML,Python-Markdown还支持将Markdown文档转换为其他格式,如PDF、LaTeX等。

安装Python-Markdown

要开始使用Python-Markdown,首先需要安装它。可以使用pip来安装Python-Markdown:

pip install markdown

安装完成后,就可以在Python中导入markdown模块,并开始解析和转换Markdown文档了。

使用Python-Markdown

基本用法

首先看一下如何使用Python-Markdown来解析和转换Markdown文档。

以下是一个简单的示例代码,演示了如何将Markdown文本转换为HTML:

import markdown

# Markdown文本
markdown_text = """
# 标题
这是一个Markdown文档的示例。

- 列表项1
- 列表项2

[链接](https://www.example.com)
"""

# 转换Markdown为HTML
html = markdown.markdown(markdown_text)

# 打印HTML
print(html)

运行这段代码后,将获得Markdown文本转换后的HTML内容,并将其打印出来。可以将这段HTML嵌入到网页中,以显示Markdown内容。

命令行下使用markdown_py脚本进行转换

markdown_py README.md >> README.html
自定义扩展

Python-Markdown支持自定义扩展,可以根据需求添加额外的Markdown标记和功能。

以下是一个示例,演示了如何创建一个简单的自定义扩展,以将文本中的emoji表情符号转换为图像:

import markdown
from markdown.extensions import Extension
from markdown.inlinepatterns import SimpleTagPattern

# 自定义扩展类
class EmojiExtension(Extension):
    def extendMarkdown(self, md):
        emoji_pattern = r':(\w+):'
        emoji_tag = 'img src="emojis/\g<1>.png" alt=":\g<1>:" title=":\g<1>:"'

        emoji_re = SimpleTagPattern(emoji_pattern, 'emoji')
        md.inlinePatterns.add('emoji', emoji_re, '>not_strong')

# Markdown文本
markdown_text = "这是一个示例文本,包含一些表情符号::smile: :heart: :rocket:"

# 创建Markdown实例并应用自定义扩展
md = markdown.Markdown(extensions=[EmojiExtension()])

# 转换Markdown为HTML
html = md.convert(markdown_text)

# 打印HTML
print(html)

在这个示例中,创建了一个自定义扩展EmojiExtension,它可以将文本中的:smile:等表情符号转换为对应的图像。可以根据需要编写自己的扩展来添加额外的Markdown功能。

使用样式表

如果想为生成的HTML添加自定义样式,可以使用CSS(层叠样式表)。可以创建一个CSS样式表,然后在生成的HTML中引用它,以便自定义Markdown文档的外观。

以下是一个简单的示例,展示了如何为Markdown文档添加自定义样式:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Markdown文档</title>
    <link rel="stylesheet" type="text/css" href="custom_styles.css">
</head>
<body>
    <div class="markdown-content">
        <!-- 这里插入Python-Markdown转换后的HTML -->
    </div>


</body>
</html>

在这个示例中,在HTML文档的<head>部分引用了一个名为custom_styles.css的CSS样式表。可以在custom_styles.css中定义自己的样式,例如更改字体、颜色、边框等,以自定义Markdown文档的外观。

多语言支持

Python-Markdown支持多种语言的Markdown标记。如果需要在不同语言中创建Markdown文档,可以在生成HTML时指定不同的语言扩展功能。

例如,如果要处理中文Markdown,可以使用markdown.extensions.extra扩展功能,如下所示:

import markdown
from markdown.extensions.extra import ExtraExtension

# 中文Markdown文本
markdown_text = """
# 标题
这是一个Markdown文档的示例。

- 列表项1
- 列表项2

[链接](https://www.example.com)
"""

# 创建Markdown实例并应用扩展功能
md = markdown.Markdown(extensions=[ExtraExtension()])

# 转换Markdown为HTML
html = md.convert(markdown_text)

# 打印HTML
print(html)

在这个示例中,使用了ExtraExtension扩展功能来处理中文Markdown文档。


mistune用法

好的,我来为您详细介绍 Python Mistune 库的用法。Mistune 是一个快速、功能齐全的纯 Python Markdown 解析器。

  • 安装
pip install mistune

基础用法

1. 基本转换
import mistune

# 最简单的 Markdown 转 HTML
markdown_text = "# 标题\n\n这是**粗体**和*斜体*"
html = mistune.markdown(markdown_text)
# html = mistune.html('一段markdown')
print(html)
# 输出: <h1>标题</h1>\n<p>这是<strong>粗体</strong>和<em>斜体</em></p>
2. 创建渲染器实例
import mistune

# 创建 Markdown 渲染器
markdown = mistune.create_markdown()

text = """
# 一级标题

## 二级标题

- 列表项1
- 列表项2
- 列表项3

[链接文本](https://example.com)
"""

result = markdown(text)
print(result)

高级功能

1. 自定义渲染器
import mistune

class CustomRenderer(mistune.HTMLRenderer):
    def heading(self, text, level):
        # 为标题添加自定义 class
        return f'<h{level} class="custom-heading">{text}</h{level}>'
    
    def link(self, text, url, title=None):
        # 让所有链接在新窗口打开
        if title:
            return f'<a href="{url}" title="{title}" target="_blank">{text}</a>'
        return f'<a href="{url}" target="_blank">{text}</a>'

# 使用自定义渲染器
markdown = mistune.create_markdown(renderer=CustomRenderer())

text = "# 自定义标题\n\n[示例链接](https://example.com)"
print(markdown(text))
2. 使用插件
import mistune
from mistune.plugins import plugin_table, plugin_url, plugin_task_lists

# 启用表格、URL、任务列表插件
markdown = mistune.create_markdown(
    plugins=[plugin_table, plugin_url, plugin_task_lists]
)

text = """
## 任务列表

- [ ] 未完成任务
- [x] 已完成任务

## 表格

| 姓名 | 年龄 | 城市 |
|------|------|------|
| 张三 | 25   | 北京 |
| 李四 | 30   | 上海 |
"""

print(markdown(text))
3. 安全模式(防止 XSS)
import mistune
from mistune import create_markdown, HTMLRenderer

# 方法1:使用 escape=True
markdown = create_markdown(escape=True)

# 方法2:自定义安全渲染器
class SafeRenderer(HTMLRenderer):
    def link(self, text, url, title=None):
        # 验证 URL 协议
        if url.startswith(('http://', 'https://', 'mailto:')):
            return super().link(text, url, title)
        return text  # 不安全的链接只显示文本

safe_markdown = create_markdown(renderer=SafeRenderer())

text = '点击 <a href="javascript:alert(1)">危险链接</a>'
print(safe_markdown(text))

完整示例

import mistune
from mistune.plugins import plugin_table, plugin_footnotes, plugin_def_list

def create_advanced_markdown():
    """创建功能完整的 Markdown 处理器"""
    
    class AdvancedRenderer(mistune.HTMLRenderer):
        def block_code(self, code, info=None):
            """为代码块添加行号和语言标识"""
            language = info.split()[0] if info else ''
            if language:
                return f'<pre><code class="language-{language}">{mistune.escape(code)}</code></pre>'
            return f'<pre><code>{mistune.escape(code)}</code></pre>'
        
        def image(self, text, url, title=None):
            """为图片添加懒加载"""
            if title:
                return f'<img src="{url}" alt="{text}" title="{title}" loading="lazy">'
            return f'<img src="{url}" alt="{text}" loading="lazy">'
    
    return mistune.create_markdown(
        renderer=AdvancedRenderer(),
        plugins=[plugin_table, plugin_footnotes, plugin_def_list],
        escape=False  # 信任输入内容时才设为 False
    )

# 使用高级处理器
markdown = create_advanced_markdown()

complex_text = """
# 文档标题

这是一段包含多种格式的文本。

## 代码示例

\```python
def hello_world():
    print("Hello, World!")
    return True
\```

## 表格

| 功能 | 状态 | 说明 |
|------|------|------|
| 表格支持 | ✅ | 已实现 |
| 脚注 | ✅ | 已实现 |

## 图片

![示例图片](https://example.com/image.jpg)

这是一个脚注[^1]。

[^1]: 这里是脚注的内容。
"""

html_output = markdown(complex_text)
print(html_output)

常用配置选项

import mistune

# 完整的配置示例
markdown = mistune.create_markdown(
    renderer=mistune.HTMLRenderer(),
    plugins=None,           # 插件列表
    escape=True,           # 是否转义 HTML
    hard_wrap=False,       # 是否将换行转换为 <br>
    max_nested=20,         # 最大嵌套深度
    allow_harmful_protocols=None  # 允许的协议列表
)

性能优化

import mistune
import time

# 预编译渲染器以提高重复使用性能
markdown_parser = mistune.create_markdown()

# 批量处理多个文档
documents = ["# 文档1", "## 文档2", "### 文档3"]

start_time = time.time()
results = [markdown_parser(doc) for doc in documents]
end_time = time.time()

print(f"处理了 {len(documents)} 个文档,耗时: {end_time - start_time:.4f} 秒")

Mistune 的主要优势在于它的速度和灵活性。对于大多数 Markdown 处理需求,它都能提供出色的性能和可定制性。


将HTML转换为Markdown

html2text

文档:pypi.org/project/htm…

安装:

pip install html2text
OptionDescription
--versionShow program’s version number and exit
-h, --helpShow this help message and exit
--ignore-linksDon’t include any formatting for links
--escape-allEscape all special characters. Output is less readable, but avoids corner case formatting issues.
--reference-linksUse reference links instead of links to create markdown
--mark-codeMark preformatted and code blocks with [code]…[/code]

html2text模块提供了一个名为html2text的函数,可以将HTML转换为Markdown格式的文本。以下是一个示例:

import html2text

html = "<h1>Hello, World!</h1><p>This is an example.</p>"
markdown = html2text.html2text(html)
print(markdown)
自定义转换选项

html2text还提供了一些可自定义的选项,以便根据需要进行转换。以下是一些常用的选项:

  • bodywidth:指定输出的每行文本的最大宽度。
  • wrap_links:确定是否在链接周围添加方括号。
  • skip_internal_links:确定是否跳过内部链接。

这些选项可以通过在html2text函数中传递关键字参数来进行设置。例如:

markdown = html2text.html2text(html, bodywidth=80, wrap_links=True, skip_internal_links=False)

以上代码将设置最大行宽为80,对链接添加方括号,并不跳过内部链接。

处理超链接和图片

在转换HTML到Markdown格式时,还经常遇到处理超链接和图片的需求。html2text模块也提供了相应的解决方案。

超链接

通过设置aliases属性可以自定义链接的显示文本。例如:

html = '<a href="https://www.example.com">Visit our website</a>'
h = html2text.HTML2Text()
h.aliases.update({"https://www.example.com": "Example Website"})
markdown = h.handle(html)
print(markdown)

以上代码将显示为Markdown格式的超链接,并将链接指向的网站显示为自定义文本。

图片 html2text模块同样支持将HTML中的图片转换为Markdown格式。例如:

html = '<img src="image.jpg" alt="Example Image">'
markdown = html2text.html2text(html)
print(markdown)

以上代码将显示为Markdown格式的图片,并将图像文件显示为自定义文本。

示例2
import html2text
 
# 示例HTML内容
html_content = """
<h1>标题</h1>
<p>这是一个段落。</p>
<ul>
<li>列表项1</li>
<li>列表项2</li>
</ul>
"""
# 创建html2text对象
h = html2text.HTML2Text()
# 调用转换方法
markdown_text = h.handle(html_content)
print(markdown_text)
示例3
>>> import html2text
>>>
>>> h = html2text.HTML2Text()
>>> # Ignore converting links from HTML
>>> h.ignore_links = True
>>> print(h.handle("<p>Hello, <a href='http://earth.google.com/'>world</a>!"))
Hello, world!

>>> # Don't Ignore links anymore, I like links
>>> h.ignore_links = False
>>> print(h.handle("<p>Hello, <a href='http://earth.google.com/'>world</a>!"))
Hello, [world](http://earth.google.com/)!

markdownify

  • 安装
pip install markdownify
  • code
from markdownify import markdownify as md

html_content = """
<h1>标题</h1>
<p>这是一个<strong>加粗</strong>的段落。</p>
<ul>
    <li>列表项 1</li>
    <li>列表项 2</li>
</ul>
"""

# 将 HTML 转换为 Markdown
markdown_content = md(html_content)

print(markdown_content)

mistletoe 库

mistletoe 是一个快速且易于使用的 Markdown 解析器,它也能将 HTML 转换为 Markdown。你可以使用以下命令来安装:

pip install mistletoe

以下是使用 mistletoe 库进行转换的示例代码:

import mistletoe
from mistletoe import HTMLRenderer

def html_to_markdown(html):
    with HTMLRenderer() as renderer:
        document = mistletoe.Document(html)
        markdown = renderer.render(document)
    return markdown

# 示例 HTML 内容
html_content = '<h1>Hello, World!</h1><p>This is a test.</p>'
markdown_output = html_to_markdown(html_content)
print(markdown_output)

MarkItDown(微软开源工具)

  • 功能特性:支持批量转换HTML、PDF、Word等文件为Markdown,集成OCR处理图像文字。
  • 安装方法:
pip install markitdown

使用示例:

# 转换单个HTML文件
markitdown input.html output.md
# 批量转换当前目录下所有HTML文件
for file in *.html; do markitdown "$file" "${file%.html}.md"; done

E2M(多格式解析器)

  • 功能特性:支持解析HTML、PDF、EPUB等20+文件类型,集成文本/图像转换引擎(如litellm),适合复杂场景。
  • 安装方法:
pip install git+https://github.com/wisupai/e2m.git

API调用示例:

from e2m import E2MParser, E2MConverter
parser = E2MParser(parser_type="HtmlParser")
converter = E2MConverter(converter_type="TextConverter")
doc = parser.parse("input.html")
markdown = converter.convert(doc)
print(markdown)