Pandoc / unstructured / unified 文本处理

本文共2043字。
版权声明: 署名-非商业性使用-相同方式共享 | CC BY-NC-SA 2.5 CN
展开

简介

Pandoc、unstructured 和 unified 都是用于文本转换的工具,但各自有不同的特点和应用场景。

  1. Pandoc Pandoc 是一个开源的文档转换器,可以将多种标记语言(如 Markdown、HTML、LaTeX 等)之间相互转换,支持多种输出格式(如 PDF、Word、HTML、ePub 等)。Pandoc 可以通过命令行或 API 调用进行使用。

  2. Unstructured Unstructured 是一个基于 Python 的文本处理库,主要用于从非结构化文本中提取出结构化信息。它可以帮助用户识别文本中的实体、事件、关系等,并将其转换为易于分析的结构化数据。 Unstructured 适用于大数据挖掘、自然语言处理、情感分析等领域。

  3. Unified Unified 是一个通用的 AST 转换库,可以将不同的文本格式转换为抽象语法树(AST),并在这个层次上执行转换操作。Unified 支持多种标记语言(如 HTML、Markdown、XML、CSS 等),可以通过插件机制扩展功能。

比较

特性 Pandoc unstructured Unified
编程语言 haskell Python Javascript
输入格式转换 ×
输出格式转换 ×
自定义输入格式 ×
自定义输出格式 ×
输入文件多样化
输出文件多样化
API支持 ×
文档可扩展性 ×
支持插件系统 × ×

注:√表示该库或工具具备该特性,×表示该库或工具不具备该特性。

Pandoc的过滤器

Pandoc 的工作原理和编译器没啥区别,都是做语法解析,变成抽象语法树,再转换成目标文件。

$2 原文件 AST 目标文件

Pandoc是可编程的。在AST级别,可通过编程修改AST节点,然后转换成目标文件。两种方式,

  1. AST由Json表示,通过filter修改json文件。
  2. AST是内部数据结构,通过lua-filter来修改AST的节点。

例子

lua filter用于去掉 <span> </span> 的外层标签。

1
2
3
function Span(elem)
return elem.content
end

只保留http(s)的链接,其余去掉 <a> </a> 外层标签

1
2
3
4
5
6
7
function Link(elem)
if elem.target:match("^https?://") then
return elem
else
return elem.content
end
end

表格样式简化

这是一个实际的例子,功能是

  • 去掉了表格的各种样式。
  • 把宽度为0的格子去掉。
  • 把非head的可能是表头的第一行变成head。

这样做的目的,主要是从docx转换成markdown,能得到简单的表格。否则,pandoc会直接输出html的表格,比较冗余。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
logging = require "logging"
tb_cnt = 0

function Table (tbl)
--logging.temp(tbl.bodies[1].body)
local nspecs = tbl.colspecs:filter(function (colspec)
local width = colspec[2]
return width == nil or width > 0.003
end)
if tbl.colspecs ~= nspecs then
logging.warning("table has unexpected column widths")
tbl.colspecs = nspecs
tbl.bodies = tbl.bodies:map( function(b)
--logging.temp(b.body)
b.body = b.body:map( function(row)
row.cells = row.cells:filter( function(cell)
return cell.contents ~= nil
end
)
return row
end)
end)
end
tbl.bodies = tbl.bodies:map( function (b)
b.body = b.body:map( function(row)
row.cells = row.cells:map (function(cell)
cell.contents = pandoc.utils.stringify(cell.contents):gsub('\n', '')
return cell
end)
row.attr = nil

return row
end)
local first_row = b.body[1]
if first_row ~= nil and #first_row.cells == 1 then
if #tbl.caption.long == 0 then
tbl.caption.long = first_row.cells[1].contents
tbl.caption.short = pandoc.utils.stringify(first_row.cells[1].contents)
b.body:remove(1)
end
end
if #tbl.head.rows == 0 and #b.body > 0 then
tbl.head.rows:insert( b.body:remove(1))
end
return b
end)
if tb_cnt == 0 then
logging.debug(tbl.caption)
end
tb_cnt = tb_cnt + 1
-- filter out the column widths that are too small
return tbl
end


unstrctured

我自己关注unstructured是因为要解析 pdf文档。解析pdf文档的目的在于切成文本串,放到数据库里以便查询。pdf文档是输出类型的文档,不像word专注编辑,也不像markdown那样专注于文本,因而解析pdf并不容易。pdf的类别比较多,主要分为图像类的和文本类。

如果是图像类,得做OCR才能进一步处理。

如果是文本类或者经过OCR处理之后,有以下难点:

  • 页头页脚各个文档不一致
  • 表格不容易识别
  • 公式不容以识别
  • 插图如何提取并在恰当的地方引用
  • 双栏不容易识别

如果一股脑的提取所有文本,则显然质量不够好。对人类来说容易理解的PDF输出文档,对计算机来说却并不容易。unstructured 库可利用机器学习算法进行内容分段,算是有所进步。这块没深入研究,在此仅仅做个记录。

关于图像中的公式识别,倒是有一个非常好的第三方工具,Mathpix,可以把图像的公式变成Latex文本。并且这个工具还可以整片的转换pdf文档为 Mathpix 的Markdown格式,我测试了一下,效果非常不错。

unified

UnifiedJS 是一个用于处理和转换文本的 JavaScript 库。它提供了一种统一的方式来解析、转换和序列化各种不同格式的文本,如 > Markdown、HTML、JSON、CSS 等。 UnifiedJS 的核心思想是使用抽象语法树(AST)作为中间表示形式,通过将文本解析为 AST,再对 AST 进行处理和转换,最后将其转回文本形式。这种方式使得开发者能够灵活地操作和处理文本内容,而无需关心具体的输入和输出格式。

UnifiedJS 采用模块化设计,提供了一系列插件,每个插件负责处理特定的任务,例如解析、转换、序列化等。开发者可以根据自己的需求选择合适的插件进行组合,从而构建出符合自己需求的文本处理流程。

UnifiedJS 还提供了一些附加工具,如 lint 工具用于检查文本内容的规范性,remark-cli 命令行工具用于在命令行中使用 UnifiedJS。

总之,UnifiedJS 是一个功能强大、灵活易用的文本处理库,它可以帮助开发者处理和转换各种不同格式的文本内容,提高开发效率。

以上简介来自ChatGPT。我看没啥问题,直接拷贝过来了。因此,unified和pandoc是非常类似的,也是以AST为核心。unified项目立项较晚,比Pandoc晚了10年。

Unified 项目始于 2016 年。它最初由 John-David Dalton 发起,旨在创建一个通用的 JavaScript 工具链,用于处理和转换各种不同格式的文本。

最初的版本是由 John-David Dalton 独立开发的,并在 GitHub 上进行开源发布。随着时间的推移,越来越多的开发者对该项目感兴趣并加入了贡献。Unified 逐渐成为一个活跃的开源社区,拥有众多的贡献者和用户。

Pandoc 项目始于 2006 年。它由约翰·麦克唐纳(John MacFarlane)创立,最初是作为他在哈佛大学的博士论文工具的一部分而开发的。

约翰·麦克唐纳当时需要一个通用的文档转换工具,可以将他的 Markdown 格式的论文转换为其他格式,例如 HTML、PDF 等。然而,当时可用的工具并没有满足他的需求,于是他决定自己开发一个更灵活和强大的文档转换工具,这就是 Pandoc 诞生的原因。

最初的版本是使用 Haskell 编程语言开发的,并在 GitHub 上进行开源发布。随着时间的推移,Pandoc 在全球范围内得到了广泛的认可和应用,成为了一种流行的文档转换工具。它支持多种输入和输出格式,包括 Markdown、HTML、PDF、DOCX 等,具有强大的功能和灵活的配置选项。

小结

文本预处理和数据清洗是非常重要的工作,需要好的工具。本文记录一些好工具和编程方法,备忘。另外,我发现好的项目都下面这个特点:

  • 模块化的设计,围绕一个核心来组织各种代码模块往往更有生命力。

例如 Pandoc和 unified,都围绕AST组织代码。又如 fastify,围绕HTTP的插件组织代码。

另外的趋势就是AI会植入各种工具和流程。例如unstructured会用AI做布局分析。