显示富文本的内容

Jupyter 丰富的显示系统允许在 Jupyter 笔记本和其他前端显示富文本的内容。

这是通过向前端发送包含前端可能使用的各种数据表示的 mime bundles 来实现的。

一个 mime bundle 可能包含同一对象的多种替代表示,例如

  • 一个用于笔记本和其他网络前端的 text/html 表示。

  • 一个用于控制台的 text/plain 表示。

除了纯文本和 html,还可以使用其他的 mime 类型,如 image/png,甚至是在前端有渲染器的自定义 mime 类型。

默认的纯文本表示法

默认情况下,xeus-cling 为任何对象提供了一个纯文本表示。

如果是基本类型,如 doubleint,将显示该值。

对于序列(暴露了一个迭代器对 begin / end),序列的内容也被显示出来。

最后,对于更复杂的类型,将显示对象的地址。

为用户定义的类型提供自定义的 mime 表示法

对于一个用户定义的类 myns::foo,你可以很容易地提供一个适合你需要的 mime 表示,如一个风格化的 html 表,包括各种属性的值。

这可以通过简单地重载函数来实现

nl::json mime_bundle_repr(const foo&);

foo 在同一个命名空间 myns

xeus-cling 的丰富显示机制将通过参数依赖查询(ADL)拾取这个功能,并在显示时使用它。

例如:image/png 表示一个图像类。

在这个例子中,im::image 类持有一个从文件中读取的缓冲区。定义在同一命名空间的 mime_bundle_repr 重载只是将缓冲区转发给前端。

#include <string>
#include <fstream>

#include "xtl/xbase64.hpp"
#include "nlohmann/json.hpp"

namespace nl = nlohmann;

namespace im
{
    struct image
    {
        inline image(const std::string& filename)
        {
            std::ifstream fin(filename, std::ios::binary);
            m_buffer << fin.rdbuf();
        }

        std::stringstream m_buffer;
    };

    nl::json mime_bundle_repr(const image& i)
    {
        auto bundle = nl::json::object();
        bundle["image/png"] = xtl::base64encode(i.m_buffer.str());
        return bundle;
    }
}
_images/image.png

在前端显示内容

在前端显示一个对象的第一种方法是省略代码单元的最后一个分号。这样做时,最后一个表达式将被显示出来。

另一种实现方式,是包含 xcpp::display 函数并传递对象来显示。xcpp::display<xcpp/xdisplay.hpp> 头中定义。

_images/display.png

注解

使用 xcpp::display 和省略最后一个分号之间的一个微妙区别是,后者的结果是单元格 output 包括提示数字,而前者将只显示丰富的前端表示。

这种行为与 Python 内核的实现是一致的,1 的结果是一个输出,而 print(1) 的结果是一个显示信息。