9 个版本
0.2.2 | 2019 年 2 月 20 日 |
---|---|
0.2.0 | 2018 年 6 月 13 日 |
0.1.6 | 2018 年 4 月 4 日 |
0.1.5 | 2018 年 2 月 23 日 |
0.1.2 | 2017 年 9 月 14 日 |
在 文本处理 中排名第 825
每月下载量 29
115KB
2K SLoC
mathematica-notebook-filter
mathematica-notebook-filter
是一个用 Rust 编写的程序,用于解析 Mathematica 笔记本文件,并移除冗余信息,以便更容易地将它们提交到版本控制系统中。有关将此程序集成到版本控制系统的说明,请参阅以下内容,并且可以设置透明地完成所有操作,而无需修改磁盘上的文件。
在 GPLv3 许可下授权。
此程序尚未经过严格测试。它在我的笔记本上运行正常,但可能仍有一些情况尚未考虑。如果您使用此程序,请告知我(无论是正面还是负面的反馈)。
简介
版本控制系统(如 git 和 mercurial 等)提供了一种跟踪文件更改的绝佳方式,允许多个人协作工作而不会意外覆盖他人的更改。版本控制系统主要跟踪源代码,如果两个人修改了相同的文件,则可以并排比较这两个文件,以便合并更改。
尽管二进制文件(如编译输出、图像、PDF等)也可以包含在版本控制系统中,但通常无法或没有意义去比较一个二进制文件的两个版本的更改。因此,二进制文件对版本控制系统来说非常不透明,如果它们将经常更改,不建议将二进制文件存储在版本控制系统中。
这对于Mathematica笔记本来说尤其是一个问题,因为它们将输入和输出都存储在同一个文件中。一个相当典型的例子是简单的输入
Plot[Sin[x] / x, {x, -4 Pi, 4 Pi}]
当绘制时,它以以下方式存储在笔记本文件中
GraphicsBox[{{{{}, {},
TagBox[
{RGBColor[0.368417, 0.506779, 0.709798], AbsoluteThickness[1.6],
Opacity[1.], LineBox[CompressedData["<omitted>"]],
LineBox[CompressedData["<omitted>"]]},
Annotation[#,
"Charting`Private`Tag$5185#1"]& ], {}}, {{}, {}, {}}}, {}, {}},
AspectRatio->NCache[GoldenRatio^(-1), 0.6180339887498948],
Axes->{True, True},
AxesLabel->{None, None},
AxesOrigin->{0, 0},
DisplayFunction->Identity,
Frame->{{False, False}, {False, False}},
FrameLabel->{{None, None}, {None, None}},
FrameTicks->{{Automatic,
Charting`ScaledFrameTicks[{Identity, Identity}]}, {Automatic,
Charting`ScaledFrameTicks[{Identity, Identity}]}},
GridLines->{None, None},
GridLinesStyle->Directive[
GrayLevel[0.5, 0.4]],
ImagePadding->All,
Method->{
"DefaultBoundaryStyle" -> Automatic, "DefaultMeshStyle" ->
AbsolutePointSize[6], "ScalingFunctions" -> None,
"CoordinatesToolOptions" -> {"DisplayFunction" -> ({
(Identity[#]& )[
Part[#, 1]],
(Identity[#]& )[
Part[#, 2]]}& ), "CopiedValueFunction" -> ({
(Identity[#]& )[
Part[#, 1]],
(Identity[#]& )[
Part[#, 2]]}& )}},
PlotRange->
NCache[{{(-4) Pi, 4 Pi}, {-0.21723358083481298`,
0.9999892952885239}}, {{-12.566370614359172`,
12.566370614359172`}, {-0.21723358083481298`, 0.9999892952885239}}],
PlotRangeClipping->True,
PlotRangePadding->{{
Scaled[0.02],
Scaled[0.02]}, {
Scaled[0.05],
Scaled[0.05]}},
Ticks->{Automatic, Automatic}]
请注意,上面的代码片段被显著缩减,因为压缩后的base-64编码数据有大约300行左右。
对于版本控制系统来说,如此大的输出极为繁琐,因为输入中微小的更改(例如将Sin[x]
替换为Sin[2 x]
)将产生300+行的差异。mathematica-notebook-filter
的目的就是特别避免这样大的差异,并试图使它们更有意义。它通过解析Mathematica笔记本文件格式并删除所有输出单元和元数据来实现这一点。该程序是用Rust编写的,并在crates.io上分发。
然而,应该指出的是,不幸的是,Mathematica没有以非常简单的方式存储输入,因为它不仅存储了纯Mathematica表达式,还存储了格式化信息。具体来说,带有上述绘图函数的输入单元将存储在笔记本文件中,如下所示
Cell[BoxData[
RowBox[{"Plot", "[",
RowBox[{
FractionBox[
RowBox[{"Sin", "[", "x", "]"}], "x"], ",",
RowBox[{"{",
RowBox[{"x", ",",
RowBox[{
RowBox[{"-", "4"}], "Pi"}], ",",
RowBox[{"4", "Pi"}]}], "}"}]}], "]"}]], "Input"]
将Sin[x]
更改为Sin[2 x]
会导致单元现在存储为
Cell[BoxData[
RowBox[{"Plot", "[",
RowBox[{
FractionBox[
RowBox[{"Sin", "[",
RowBox[{"2", "x"}], "]"}], "x"], ",",
RowBox[{"{",
RowBox[{"x", ",",
RowBox[{
RowBox[{"-", "4"}], "Pi"}], ",",
RowBox[{"4", "Pi"}]}], "}"}]}], "]"}]], "Input"]
至少在这个阶段,该程序不会删除额外的格式化信息。如果您想避免这种情况,则应将笔记本保存为脚本文件(扩展名为.wl
或.m
)。
使用说明
mathematica-notebook-filter
解析Mathematica笔记本文件(通常以.nb
扩展名存储)并删除所有生成的输出和其他元数据。默认情况下,程序从标准输入读取并输出到标准输出。更多使用信息可以从
mathematica-notebook-filter --help
尽管可以使用mathematica-notebook-filter
手动,但它被设计为与版本控制系统集成(有关说明,请参阅下面),以便在生成差异之前,笔记本首先通过过滤器。这样设计是为了确保原始文件保持不变,保留所有输出和元数据,过滤器使版本控制系统对额外内容视而不见。
如果您想手动运行它,一个简单的调用将是
mathematica-notebook-filter -i my_notebook.nb -o my_notebook_cleaned.nb
如果输入和输出文件相同,程序将首先输出到临时文件,只有成功解析整个输入后,才会替换原始文件。
该程序通常不解析 Wolfram 语言,并且仅针对 完整 Mathematica 笔记本,因此它对将要找到的函数及其顺序做出了一些相当强烈的假设。它一次只解析一个笔记本,并在解析完第一个笔记本后停止。如果在解析过程中遇到错误,mathematica-notebook-filter
将以非零代码退出,并且输出将是不完整的。
还应重申,将 Mathematica 代码提交给版本控制系统最好的方式是将代码保存为脚本文件(.wl
或 .m
)。这样做时,Mathematica 会以一个非常简单的格式(本质上是一个纯文本文件)保存文件,没有多余的格式化信息,也没有输出。不幸的是,这有一个缺点,即笔记本界面不可用。
另外,请注意,Mathematica 笔记本允许您复制粘贴图形(例如生成的图表)并将它们用作输入。如果您这样做,版本控制系统将不得不将整个图表包含在 diff 中,从而违背了 mathematica-notebook-filter
的目的。复制粘贴输出的替代方法是存储输出到一个变量中,或使用 %
(以及 %%
、%%%
等)来引用上一个输出(但请确保仅在单个单元格内使用 %
,而不是跨单元格,因为 %
指的是最后一个生成的输出,而不是笔记本顺序中的上一个输出)。
安装
该程序是用 Rust 编写的。最简单安装 Rust 的方法可能是使用 rustup.rs 脚本。一旦设置好,只需运行
cargo install mathematica-notebook-filter
这将下载、编译并安装 mathematica-notebook-filter
到您的 Cargo 家目录(默认情况下,Linux 上的 ~/.cargo
)。假设您已正确设置您的 PATH 变量(rustup.rs 应该会自动完成),那么您可以通过键入 mathematica-notebook-filter
来执行程序。
集成
Git
可以根据模式 glob 设置 属性。在这个例子中,我们想确保在提交之前,所有 *.nb
文件都经过此过滤器处理。要全局设置属性,请向 ~/.gitattributes
添加以下内容
*.nb filter=dropoutput_nb
以及到您的 ~/.gitconfig
[filter "dropoutput_nb"]
clean = mathematica-notebook-filter
smudge = cat
其他
欢迎提交添加其他版本控制系统说明的拉取请求。
免责声明
遗憾的是,Wolfram Research 组织似乎没有提供其语言或其文件格式的任何规范。因此,此过滤器完全是在检查 Mathematica 生成的输出后开发的。具体来说,这是使用 Mathematica 11.1 开发的,因此无法保证此过滤器与过去或未来的 Notebook 文件格式版本兼容。
如果您发现任何错误,请随时打开一个问题,但请提供足够的信息来重现错误或一个 Notebook 文件的最小示例,该文件导致问题。
贡献
欢迎提交改进与其他版本兼容性(或修复错误)的拉取请求。如果您发现任何错误,请随时打开一个问题,并确保提供足够的信息来重现错误或一个 Notebook 文件的最小示例,该文件导致问题。
依赖关系
~3–13MB
~140K SLoC