重要

此文档涵盖 IPython 6.0 及更高版本。从 6.0 版本开始,IPython 不再支持与低于 3.3 的 Python 版本(包括所有版本的 Python 2.7)的兼容性。

如果你正在寻找与 Python 2.7 兼容的 IPython 版本,请使用 IPython 5.x LTS 版本并参阅其文档(LTS 是长期支持版本)。

Mime 渲染器扩展

就像它的表亲 Jupyter Notebooks 和 JupyterLab 一样,终端 IPython 可以被认为在 shell 中渲染了许多 mimetype。这可以用来显示内联图像(如果你的终端仿真器支持的话);或者使用外部文件查看器打开一些显示结果。

到目前为止,注册新的 mimetype 处理程序只能通过扩展来完成,需要 4 个步骤

  • 定义一个可调用对象,它需要 2 个参数:datametadata;可调用对象的返回值到目前为止被忽略。此可调用对象负责“显示”给定的 mimetype。它可以向当前终端发送正确的转义序列和字节;或者打开一个外部程序。-

  • 将正确的 mimetype 追加到 ipython.display_formatter.active_types,以便 IPython 知道它不应该忽略这些 mimetype。

  • 启用给定的 mimetype:ipython.display_formatter.formatters[mime].enabled = True

  • 使用 mimetype 处理程序注册上述可调用对象:ipython.mime_renderers[mime] = handler

以下是一个完整的 IPython 扩展,用于在 macOS 上为 iterm2 内联显示图像并将数学转换为 png,然后再内联显示。

from base64 import encodebytes
from IPython.lib.latextools import latex_to_png


def mathcat(data, meta):
    png = latex_to_png(f'$${data}$$'.replace('\displaystyle', '').replace('$$$', '$$'))
    imcat(png, meta)

IMAGE_CODE = '\033]1337;File=name=name;inline=true;:{}\a'

def imcat(image_data, metadata):
    try:
        print(IMAGE_CODE.format(encodebytes(image_data).decode()))
    # bug workaround
    except:
        print(IMAGE_CODE.format(image_data))

def register_mimerenderer(ipython, mime, handler):
    ipython.display_formatter.active_types.append(mime)
    ipython.display_formatter.formatters[mime].enabled = True
    ipython.mime_renderers[mime] = handler

def load_ipython_extension(ipython):
    register_mimerenderer(ipython, 'image/png', imcat)
    register_mimerenderer(ipython, 'image/jpeg', imcat)
    register_mimerenderer(ipython, 'text/latex', mathcat)

此示例仅适用于 macOS 上的 iterm2,并且为了简洁起见,跳过了错误处理。你还可以使用 subprocess.run() 和一个临时文件调用外部查看器,这留作练习。