跳到主要内容

如何在 Gitea 上渲染 Jupyter Notebooks

· 阅读需 4 分钟
本文由 AI 翻译,如有歧义请以 英文原文 为准。

本指南将展示如何配置外部渲染器以显示 Jupyter Notebooks。不过,本指南也适用于其他类型的文件,甚至二进制文件!只有想不到,没有做不到。

Gitea 如何原生显示 .ipynb 文件​

让我们在 Gitea 实例上创建一个新仓库,并向其中推送一个 示例 notebook:

20200721 外部渲染器之前

如我们所见,Gitea 只是渲染文件的原始内容——高效但难以阅读。

如何生成用于显示的 HTML​

为了向用户显示更有吸引力的内容,我们需要一些 HTML,幸运的是 Jupyter 有一个名为 nbconvert 的模块:

在 Gitea 机器上安装我们选择的转换软件:

sudo apt install python3-pip
pip3 install nbconvert

如果需要,我们可以通过运行测试命令来测试:

jupyter nbconvert --to html --template full path/to/some/test/notebook.ipynb

如果我们在浏览器中打开生成的 .html 文件,会看到类似这样的内容: image

看起来很有希望……

配置 Gitea 使用转换器​

与大多数选项一样,我们只需使用 app.ini 配置 Gitea 实例。

将其添加到 custom/conf/app.ini 中:

; Gitea looks for markup.xxxxx and will apply both "markup" and "xxxxx" as a class to the parent <div>
[markup.jupyter]
ENABLED = true
; all the file extensions we want to convert, comma separated.
FILE_EXTENSIONS = .ipynb
; Lets use out nbconvert command from earlier - making to sure to convert to HTML and to output to stdout
RENDER_COMMAND = "jupyter nbconvert --stdout --to html --template full "
; nbconvert accepts a path to a file and not stdin
IS_INPUT_FILE = true

; the name after sanitizer doesn't really matter
[markup.sanitizer.jupyter0]
; Jupyter chiefly uses divs
ELEMENT = div
; we will need access to html classes later
ALLOW_ATTR = class
; we don't mind which classes we keep, so let's keep all of them
REGEXP =

现在让我们看看重启 Gitea 后会得到什么。

20200721 安装 nbconvert 之后

如你所见,这更好了,但与之前打开 HTML 文件时不一样。这是因为 Gitea 出于安全需要移除了内联样式表。现有的样式继承自包裹代码的 <div> 中的 markup 类。

找回我们的样式​

如果我们查看之前创建的 HTML 文件的内容,可以看到几个内联样式表

<style type="text/css">
/*!
*
* Twitter Bootstrap
*
*/
/*!
* Bootstrap v3.3.7 (http://getbootstrap.com)
* Copyright 2011-2016 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
html {
font-family: sans-serif;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
}
body {
margin: 0;
}

[...]

</stlye>

那么,让我们把所有样式表剥离出来,合并到一个 jupyter.less 中,确保删除所有类似 <style></style> 的 HTML 标签。现在我们有了一个包含所有漂亮样式的样式表。但它有很多通用选择器,例如:

body {
margin: 0;
}

这肯定与 Gitea 的默认样式冲突。所以我们需要确保限制样式的范围。幸运的是,Gitea 和 Less 可以帮助我们。

在 Less 中

.someclass {
body {
margin: 0;
}
summary {
display: block;
}
}

等价于 CSS:

.someclass body {
margin: 0;
}

.someclass summary {
display: block;
}

并且 Gitea 已经将 app.ini 中的 markup 和 jupyter 类赋予了包裹代码的 <div>。 image

那么,让我们把 jupyter.less 的全部内容包裹在 .markup.jupyter {} 中,生成类似 这样 的内容。

现在,让我们把这个文件放到我们的 'custom' 目录中,在我的例子中是 /root/custom/public/css/jupyter.less。

然后我添加到 /root/custom/templates/header.tmpl 中

<!-- lets import the less stylesheet {{AppSubUrl}} is a variable that gitea will autofill -->
<link rel="stylesheet/less" type="text/css" href="{{AppSubUrl}}/css/jupyter.less" />
<!-- we need the javascript to compile the less into css -->
<script src="//cdn.jsdelivr.net/npm/less" ></script>

现在让我们重启 Gitea,看看会得到什么。

使用 .markup.jupyter 自定义样式后的最终效果 20200721 添加 CSS 之后

看起来不错,但我们遇到了一些文本溢出边框边缘的问题。这是由一些麻烦的 CSS at-rules 引起的,所以让我们从 jupyter.less 中删除以下内容

@media (min-width: 768px) {
.container {
width: 768px;
}
}
@media (min-width: 992px) {
.container {
width: 940px;
}
}
@media (min-width: 1200px) {
.container {
width: 1140px;
}
}

image

大功告成!样式完美的 Jupyter Notebooks。