杰瑞科技汇

Python Markdown中如何插入与显示图片?

  1. Markdown 语法本身:如何用 Markdown 语法插入图片。
  2. Python Markdown 库:如何使用 Python 库来解析 Markdown 文件,并处理其中的图片(将相对路径的图片转换为 HTML 能正确显示的格式)。

Part 1: Markdown 图片语法

Markdown 语法非常简洁,插入图片的基本语法如下:

Python Markdown中如何插入与显示图片?-图1
(图片来源网络,侵删)
![替代文本](图片的URL或路径)

语法详解:

  • ![替代文本] (Alt Text):

    • 这是一个固定的符号,告诉解析器这是一个图片。
    • [替代文本]:这是图片的描述性文本,如果图片因为某种原因无法加载(比如网络错误、文件丢失),浏览器会显示这段文字,屏幕阅读器会朗读这段文字,帮助视障用户了解图片内容。强烈建议始终填写有意义的替代文本。
  • (图片的URL或路径):

    • 包裹图片的路径或 URL。
    • 图片 URL:可以是网络上的图片地址。
      ![Python Logo](https://www.python.org/static/community_logos/python-logo-master-v3-TM.png)
    • 本地图片路径:可以是相对路径或绝对路径。
      ![本地图片](./images/my_image.png)

本地图片路径的注意事项

  • 相对路径:推荐使用相对路径,因为它让你的 Markdown 文件和图片可以一起移动,而不会失效。
    • ./images/cat.jpg:当前目录下的 images 文件夹。
    • ../photos/dog.jpg:上一级目录下的 photos 文件夹。
    • logo.png:与 Markdown 文件在同一目录。
  • 空格和特殊字符:如果文件名或路径中包含空格或特殊字符,最好用引号括起来,或者用 %20 等 URL 编码字符代替空格。
    ![my cat](./images/my cat.jpg)  // 这样写可能有问题
    ![my cat](./images/my%20cat.jpg) // 推荐写法

Part 2: 使用 Python Markdown 库处理图片

当你用 Python 读取一个 Markdown 文件并想将其转换为 HTML 时,会遇到一个问题:Markdown 中的本地图片路径(如 ./images/cat.jpg)在最终的 HTML 文件中可能无法正确显示,因为 HTML 文件和图片的最终位置关系已经改变。

Python Markdown 库提供了扩展功能来解决这个问题,最常用的是 Extension

Python Markdown中如何插入与显示图片?-图2
(图片来源网络,侵删)

安装 Python Markdown 库

如果你还没有安装,请先安装:

pip install markdown

核心问题:相对路径的处理

假设你的项目结构如下:

/my_project
|-- /docs
|   |-- report.md
|-- /images
|   |-- logo.png

report.md 中,你这样写:

# 我的报告
![项目Logo](../images/logo.png)

当你把 report.md 转换为 HTML 后,如果直接打开 HTML 文件,浏览器会从 report.html 所在的位置(即 /docs/)去寻找 ../images/logo.png,这显然是找不到的。

Python Markdown中如何插入与显示图片?-图3
(图片来源网络,侵删)

解决方案:使用 AbsoluteLinkExtension

Python Markdown 官方提供了一个非常方便的扩展 AbsoluteLinkExtension,它的作用是:将 Markdown 中的所有相对链接(包括图片链接)转换为绝对链接

工作原理:你告诉这个扩展一个“基础路径”(base path),它会将所有相对路径都基于这个基础路径进行解析,生成一个绝对路径。

示例代码:

import markdown
import os
# 1. 定义你的项目根目录(所有路径的基准)
#    在这个例子中,我们假设 /my_project 是根目录
project_root = '/my_project'
# 2. 定义 Markdown 文件和输出 HTML 文件的路径
md_file_path = os.path.join(project_root, 'docs', 'report.md')
html_file_path = os.path.join(project_root, 'docs', 'report.html')
# 3. 读取 Markdown 文件内容
with open(md_file_path, 'r', encoding='utf-8') as f:
    md_content = f.read()
# 4. 配置 Markdown 转换器,并启用 AbsoluteLinkExtension
#    - extensions: 启用扩展
#    - extension_configs: 为扩展配置参数
#      'markdown.extensions.absolut_url': {'base_url': project_root}
#      告诉扩展,将所有相对路径都基于 /my_project 这个绝对路径来解析
html_content = markdown.markdown(
    md_content,
    extensions=[
        'markdown.extensions.absolut_url', # 核心扩展
        'markdown.extensions.extra',       # 推荐启用,包含表格、脚注等
        'markdown.extensions.codehilite'  # 代码高亮
    ],
    extension_configs={
        'markdown.extensions.absolut_url': {
            'base_url': project_root
        }
    }
)
# 5. 将转换后的 HTML 写入文件
#    我们可以添加一个完整的 HTML 框架
full_html_content = f"""<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">我的报告</title>
</head>
<body>
{html_content}
</body>
</html>
"""
with open(html_file_path, 'w', encoding='utf-8') as f:
    f.write(full_html_content)
print(f"成功转换 Markdown 文件: {md_file_path} -> {html_file_path}")

执行后会发生什么?

AbsoluteLinkExtension 会将 report.md 中的 ![项目Logo](../images/logo.png) 解析为: ![项目Logo](/my_project/images/logo.png)

这样,无论你的 HTML 文件被移动到哪里,只要图片的最终位置是 /my_project/images/logo.png,浏览器就能正确找到它。


Part 3: 完整的最佳实践示例

这是一个更完整的脚本,它会递归地查找一个目录下的所有 .md 文件,并将它们转换为带有完整 HTML 框架的 .html 文件,同时使用 AbsoluteLinkExtension 来处理图片和链接。

import markdown
import os
import shutil
def convert_md_to_html(md_file_path, output_dir, base_url):
    """
    将单个 Markdown 文件转换为 HTML 文件。
    :param md_file_path: Markdown 文件的绝对路径
    :param output_dir: HTML 文件的输出目录
    :param base_url: 用于解析绝对链接的基础路径
    """
    # 确保输出目录存在
    os.makedirs(output_dir, exist_ok=True)
    # 生成输出 HTML 文件的路径
    md_filename = os.path.basename(md_file_path)
    html_filename = os.path.splitext(md_filename)[0] + '.html'
    html_file_path = os.path.join(output_dir, html_filename)
    # 读取 Markdown 内容
    with open(md_file_path, 'r', encoding='utf-8') as f:
        md_content = f.read()
    # 转换 Markdown 为 HTML
    html_body = markdown.markdown(
        md_content,
        extensions=[
            'markdown.extensions.absolut_url',
            'markdown.extensions.extra',
            'markdown.extensions.codehilite',
            'markdown.extensions.toc' # 自动生成目录
        ],
        extension_configs={
            'markdown.extensions.absolut_url': {'base_url': base_url}
        }
    )
    # 构建完整的 HTML 页面
    full_html = f"""<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">{os.path.splitext(md_filename)[0]}</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css">
    <style>
        body {{ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; line-height: 1.6; margin: 2em; }}
        pre {{ background-color: #f4f4f4; padding: 1em; border-radius: 5px; }}
        code {{ background-color: #f4f4f4; padding: 0.2em 0.4em; border-radius: 3px; }}
        img {{ max-width: 100%; height: auto; }}
    </style>
</head>
<body>
{html_body}
</body>
</html>
    """
    # 写入 HTML 文件
    with open(html_file_path, 'w', encoding='utf-8') as f:
        f.write(full_html)
    print(f"已转换: {md_file_path} -> {html_file_path}")
def convert_directory(source_dir, output_dir):
    """
    转换一个目录下的所有 Markdown 文件。
    :param source_dir: 源 Markdown 文件所在的目录
    :param output_dir: 转换后的 HTML 文件存放的目录
    """
    # base_url 应该是源目录的绝对路径,这样相对路径才能被正确解析
    base_url = os.path.abspath(source_dir)
    # 遍历源目录
    for root, _, files in os.walk(source_dir):
        for file in files:
            if file.lower().endswith('.md'):
                md_file_path = os.path.join(root, file)
                # 输出路径保持与源文件相同的相对目录结构
                relative_path = os.path.relpath(root, source_dir)
                current_output_dir = os.path.join(output_dir, relative_path)
                convert_md_to_html(md_file_path, current_output_dir, base_url)
if __name__ == '__main__':
    # --- 配置你的输入和输出目录 ---
    # 假设你的 Markdown 文件都在 'docs' 文件夹下
    # 你希望生成的 HTML 文件放在 'site' 文件夹下
    markdown_source_dir = 'docs'
    html_output_dir = 'site'
    # 清空旧的输出目录(可选)
    if os.path.exists(html_output_dir):
        shutil.rmtree(html_output_dir)
    # 开始转换
    convert_directory(markdown_source_dir, html_output_dir)
    print("\n所有 Markdown 文件转换完成!")
  1. Markdown 语法:使用 ![alt text](path) 插入图片。
  2. 路径问题:在 Python 环境中,本地相对路径在转换后可能失效。
  3. Python Markdown 解决方案:使用 markdown.extensions.absolut_url 扩展。
  4. 核心配置:为扩展提供 base_url,即你的项目根目录的绝对路径。
  5. 最佳实践:编写一个脚本来批量处理整个目录,并保持原有的文件结构,这能大大提高效率。
分享:
扫描分享到社交APP
上一篇
下一篇