Skip to content

流程与钩子

本文介绍了 Paperlib 中重要的流程,以及在这些流程中,可用的钩子。

钩子介绍

在 Paperlib 中,我们在不同的地方,放置了不同名字的钩子点。一个钩子插件可以注册到对应的钩子点来介入 Paperlib 的运行流程。一共有两种类型的钩子点。

Modify 钩子点

  • 目的:这种类型的钩子点,用于修改钩子点传来的参数,或者参数内的变量,而不能改变类型,最后返回修改后的参数。

  • 回调返回值类型:该类钩子要求回调函数的返回值必须是一个数组,数组的每个元素,对应着传入的参数数组。比如,钩子点传入的参数为 (arg1: string, arg2: {value: number}),在钩子的回调函数中可以修改 arg1 为别的字符串,修改 arg2.value 为别的数字,但是不能修改 arg1 的类型为数字,或者修改 arg2 的类型为别的类型。回调函数的返回值必须为修改后的参数组成的数组:[arg1, arg2]

    注意,即使传入参数仅为一个,也需要返回元素数量为1的数组。因为传入参数永远被视作一个数组。在接下来的文章中,我们使用 参数数组<...> 来表示。

Transform 钩子点

  • 目的:这种类型的钩子点,可以修改 Paperlib 的运行流程中的数据流。用于把传入参数转换为其他形式的数据,然后返回。
  • 回调返回值类型:可以为其他类型,但是通常不同钩子点有期望的返回值类型。比如,scrapeEntry 钩子点,期望的返回值类型为 PaperEntity 数组。

关于如何注册钩子,以及如何编写钩子插件,请参考 钩子插件

论文导入流程

无论是从文件拖动导入,还是从浏览器插件导入,在组成相应的 source payload 后,都会进入到论文导入流程。论文导入流程的图示如下:

该流程中,主要的钩子点都在 ScrapeServicescrapeEntry()scrapeMetadata() 方法中。


scrapeEntry()

scrapeEntry() 的主要任务就是把这些来自不同类型的源的数据,转换为 Paperlib 内部的数据结构 PaperEntity,并尽可能填充 PaperEntity 的重要字段(例如:title, doi, arxivID 等),以便之后的 scrapeMetadata() 方法搜寻补全其论文 metadata。

在接受到论文源的导入之后,我们首先调用 scrapeEntry()。他的主要参数是 SourcePayload 的数组,即论文源的数据。source payload 包含指示源的类型的 type 字段,以及源的数据:

typescript
interface SourcePayload {
  type: "file" | "webcontent";
  // 对于 file 类型,value 为文件路径的字符串
  // 对于 webcontent 类型,value 为 WebContentSourcePayload
  value: string | WebContentSourcePayload;
}

interface WebContentSourcePayload {
  url: string;             // 源网页的 url
  document: string;        // 源网页的 html              
  cookies?: string;        // 有的网页包含 cookies
}

scrapeEntry() 的返回值类型为 PaperEntity 的数组,因为即使传入的 SourcePayload 数组只包含一个 source payload,它也可能包含多个论文。例如,从文件拖动导入,可能拖入的是一个 BibTex 文件,其中包含多个论文的信息。


scrapeMetadata()

scrapeEntry() 的返回值,会被传入到 scrapeMetadata() 方法中。scrapeMetadata() 的主要任务是从网络各种数据库上搜寻论文的 metadata,并补全 PaperEntity 中所有字段。scrapeMetadata() 的返回值类型也是 PaperEntity的数组。


如图中所示,在这个流程中,有六个钩子点可以,五个 Modify 类型的钩子点,以及一个 Transform 类型的钩子点。

beforeScrapeEntry

参数
类型Modify
位置scrapeEntry() 方法的最开始,还未转换为 PaperEntity 之前
Callback 参数SourcePayload[]
Callback 返回值参数数组<SourcePayload[]>

scrapeEntry

参数
类型Transform
位置scrapeEntry() 的主要钩子点,接受 SourcePayload 数组 转换为 PaperEntity 数组输出
Callback 参数SourcePayload[]
Callback 返回值PaperEntity[]

afterScrapeEntry

参数
类型Modify
位置scrapeEntry() 方法的最后,已经转换为 PaperEntity 之后
Callback 参数PaperEntity[]
Callback 返回值参数数组<PaperEntity[]>

beforeScrapeMetadata

参数
类型Modify
位置scrapeMetadata() 方法的最开始,还未搜寻 metadata 之前
Callback 参数paperEntities: PaperEntity[], scrapers: string[], force: boolean
Callback 返回值参数数组<paperEntities: PaperEntity[], scrapers: string[], force: boolean>

其中,scrapers 是一个字符串数组,如果不为空,则代表用户选择用特定的搜寻器进行搜寻。force 表示是否强制搜寻,如果为 true,则会忽略 PaperEntity 中已经存在的 metadata,强制搜寻。

scrapeMetadata

参数
类型Modify
位置scrapeMetadata() 的主要钩子点,接受 PaperEntity 数组,可修改每一个的属性后返回
Callback 参数paperEntities: PaperEntity[], scrapers: string[], force: boolean
Callback 返回值参数数组<paperEntities: PaperEntity[], scrapers: string[], force: boolean>

afterScrapeMetadata

参数
类型Modify
位置scrapeMetadata() 方法的最后,已经搜寻 metadata 之后
Callback 参数paperEntities: PaperEntity[], scrapers: string[], force: boolean
Callback 返回值参数数组<paperEntities: PaperEntity[], scrapers: string[], force: boolean>

论文 PDF 搜寻流程

当一个论文没有对应的 PDF 文件时,Paperlib 会在详情面板显示一个按钮用于在网络资源搜索可用的 PDF 并下载。这个按钮点击后,会进入到论文 PDF 搜寻流程。论文 PDF 搜寻流程的主要函数是 FileServicelocateFileOnWeb() 方法。在这个流程里可用的钩子有一个。

locateFile

参数
类型Modify
位置locateFileOnWeb() 方法中
Callback 参数PaperEntity[]
Callback 返回值参数数组<PaperEntity[]>

引用导出流程

总的来说,引用导出时,我们首先得到需要导出的 PaperEntity 数组,然后将其转换为 citation.jsCite 对象。最后,我们将 Cite 对象转化为对应格式的字符串,例如 BibTex 字符串。详情可见 GitHub 代码中,ReferenceService 的各个函数。

beforeExportBibItem

参数
类型Modify
位置exportBibItem() 方法的最开始
Callback 参数PaperEntity[]
Callback 返回值参数数组<PaperEntity[]>

citeObjCreatedInExportBibItem

参数
类型Modify
位置exportBibItem() 方法中,Cite 对象已经创建
Callback 参数cite: Cite, paperEntities: PaperEntity[]
Callback 返回值参数数组<cite: Cite, paperEntities: PaperEntity[]>

afterExportBibItem

参数
类型Modify
位置exportBibItem() 方法的最后
Callback 参数string
Callback 返回值参数数组<string>

beforeExportBibTexKey

参数
类型Modify
位置exportBibTexKey() 方法的最开始
Callback 参数PaperEntity[]
Callback 返回值参数数组<PaperEntity[]>

citeObjCreatedInExportBibTexKey

参数
类型Modify
位置exportBibTexKey() 方法中,Cite 对象已经创建
Callback 参数cite: Cite, paperEntities: PaperEntity[]
Callback 返回值参数数组<cite: Cite, paperEntities: PaperEntity[]>

afterExportBibTexKey

参数
类型Modify
位置exportBibTexKey() 方法的最后
Callback 参数string
Callback 返回值参数数组<string>

beforeExportBibTexBody

参数
类型Modify
位置exportBibTexBody() 方法的最开始
Callback 参数PaperEntity[]
Callback 返回值参数数组<PaperEntity[]>

citeObjCreatedInExportBibTexBody

参数
类型Modify
位置exportBibTexBody() 方法中,Cite 对象已经创建
Callback 参数cite: Cite, paperEntities: PaperEntity[]
Callback 返回值参数数组<cite: Cite, paperEntities: PaperEntity[]>

afterExportBibTexBody

参数
类型Modify
位置exportBibTexBody() 方法的最后
Callback 参数string
Callback 返回值参数数组<string>

beforeExportPlainText

参数
类型Modify
位置exportPlainText() 方法的最开始
Callback 参数PaperEntity[]
Callback 返回值参数数组<PaperEntity[]>

citeObjCreatedInExportPlainText

参数
类型Modify
位置exportPlainText() 方法中,Cite 对象已经创建
Callback 参数cite: Cite, paperEntities: PaperEntity[]
Callback 返回值参数数组<cite: Cite, paperEntities: PaperEntity[]>

afterExportPlainText

参数
类型Modify
位置exportPlainText() 方法的最后
Callback 参数string
Callback 返回值参数数组<string>

模糊元数据搜刮流程

在用户点击模糊搜索之后,用户选中的论文,会经过这个流程,得到模糊搜索的元数据。

该流程中,主要的钩子点都在 ScrapeServicefuzzyScrape() 方法中。

fuzzyScrape() 接受 Array<PaperEntity>, 输出 Record<string, Array<PaperEntity>>,即每个论文的 id 于候选 metadata 的映射。

可用的钩子如下:

`beforeFuzzyScrape

参数
类型Modify
位置fuzzyScrape() 方法的最开始,还未搜寻 metadata 之前
Callback 参数paperEntities: PaperEntity[]
Callback 返回值参数数组<paperEntities: PaperEntity[]>

fuzzyScrape

参数
类型Transform
位置fuzzyScrape() 的主要钩子点,接受 PaperEntity 数组,返回一个数组,每个元素是对应论文的候选匹配数组,即类型为 PaperEntity[][]
Callback 参数paperEntities: PaperEntity[]
Callback 返回值PaperEntity[][]

afterFuzzyScrape

参数
类型Modify
位置fuzzyScrape() 方法的最后,已经搜寻 metadata 之后
Callback 参数paperEntityDraftCandidates: PaperEntity[][]
Callback 返回值参数数组<paperEntityDraftCandidates: PaperEntity[][]>

Created by Future Scholars. Contact: hi@paperlib.app