# @citeproc-rs/wasm 中文文档

规范地址：https://npmcn.com/package/%40citeproc-rs/wasm/

版本：0\.2\.0
npm 元数据更新时间：2022-04-04T23:05:28.032Z
中文译文更新时间：2026-11-09T21:56:22.110Z
软件包许可：MPL-2\.0

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40citeproc-rs/wasm
原文对照：https://npmcn.com/package/%40citeproc-rs/wasm/?lang=original
项目主页：https://github.com/cormacrelf/citeproc-rs#readme
源码仓库：https://github.com/cormacrelf/citeproc-rs

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：25.2 MB，28 个文件
- 模块格式：CommonJS
- TypeScript 类型：包内自带
- 运行依赖：0 个
- 首次发布：2020-09-18T19:41:28.516Z
- 最新版本发布：2021-12-14T16:21:25.064Z
- 近 30 天下载量：3205（2026-10-10 至 2026-11-08，npm 官方下载统计）
- 已发布版本数：49（近 12 个月 0 个）

## 中文简介

引用proc-rs,编译为WebAssembly

## 安装

```sh
npm install @citeproc-rs/wasm
```

也可以使用：`pnpm add @citeproc-rs/wasm`、`yarn add @citeproc-rs/wasm`、`bun add @citeproc-rs/wasm`

## README

# `@citeproc-rs/wasm`

这是一个前端 [`citeproc-rs`](https://github.com/cormacrelf/citeproc-rs),引用 处理器用 Rust 写成并编译到 Web Assembly .

它包含适合于下列目的的建筑物:

-   节点.js
-   浏览器,使用 Webpack.js 等捆绑器
-   浏览器直接从网络服务器导入 ES 模块

## 安装/ 释放通道

有两个发布频道:

**稳定** 每个版本的发布。 ()_在编写本报告时,没有 版本发布._安装方式:

```sh
yarn add @citeproc-rs/wasm
```

**加那利语Name** 跟踪主分支 [打开 GitHub 图像](https://github.com/cormacrelf/citeproc-rs)。其版本编号随同 格式 `0.0.0-canary-GIT_COMMIT_SHA`因此,版本范围在您的 `package.json` 没有意义。 但是,你可以安装最新的一个有:

```sh
yarn add @citeproc-rs/wasm@canary
# alternatively, a specific commit
yarn add @citeproc-rs/wasm@0.0.0-canary-COMMIT_SHA
```

如果使用国家预防机制,则替换 `yarn add` 与 `npm install`。 。 。 .

### 包括你的项目

对于Node.js,只需将软件包导入为普通. 字体定义为 ,尽管API中不能自动生成类型的部分 定义在文档注释中被提及,并附带您可以使用的类型 导入.

```
// Node.js
const { Driver } = require("@citeproc-rs/wasm");
```

##### 微软边缘

注意微软 Edge 的文本编码器/文本解码器支持中的提醒 [原子弹 教程](https://rustwasm.github.io/docs/wasm-bindgen/examples/hello-world.html)。 。 。 .

#### 使用 Web 软件包

在网络上加载时,由于技术原因和编译原因 Web Assembly 是大型的, 你必须同步装入软件包 。 网包来了 具有这样同步导入包的能力:

```javascript
// Webpack
import("@citeproc-rs/wasm")
    .then(go)
    .catch(console.error);

function go(wasm) {
    const { Driver } = wasm;
    // use Driver
}
```

当你这样做时,你的代码会触发下载(和流出剖析) 当二进制完成时,您 `go` 函数将调用。 这个 如果您的网络服务器设置正确, 下载当然可以缓存 整个过程很快.

您可以在任何地方使用正则导入驱动程序作为类型Script类型, 只是不要 用它调用 `new Driver()`。 。 。 .

##### 反应

如果你正在写 React app,你可能希望使用 `React.lazy` 像这样:

```typescript
// App.tsx
import React, { Suspense } from "react";
const AsyncCiteprocEnabledComponent = React.lazy(async () => {
    await import("@citeproc-rs/wasm");
    return await import("./CiteprocEnabledComponent");
});
const App = () => (
    <Suspense
        fallback={<div>Loading citation formatting engine...</div>}>
        <AsyncCiteprocEnabledComponent />
    </Suspense>
);

// CiteprocEnabledComponent
import { Driver } from "@citeproc-rs/wasm";
// ...
```

#### 以脚本标记导入( I)`web` 目标)

用 ES 在(现代)网页浏览器中不带捆绑器直接导入 模块支持,程序不同。 你必须:

1.  做一个 `_web` 已出版的国家预防机制成套材料的子目录,载于 在您的网络服务器上的内容目录, 或者像 CDN 那样使用 CDN [(单位:公斤)](https://npmcn.com/package/%40citeproc-rs/wasm/unpkg.com)。 。 。 .
2.  包含 a `<script type="module">` 在您的页面中标记 `<body>`,像这样:

```html
<script type="module">
    import init, { Driver } from './path/to/_web/citeproc_rs_wasm.js';
    async function run() {
        await init();
        // use Driver
    }
    run()
</script>
```

**小心点**:此方法不能保证包只装入一次. 若为 您再次调用它, 它会取消您以前创建的驱动程序 .

#### 以脚本标记导入( I)`no-modules` 目标)

这是 _基于_ 页:1 [边框引导 条目](https://rustwasm.github.io/docs/wasm-bindgen/examples/without-a-bundler.html?highlight=no-modules#using-the-older---target-no-modules), (中文(简体) ), 注意这些警告。 你会,类似地 `web` 目标,需要使 一、导 言 `_no_modules` 已出版的国家预防机制成套材料的子目录 可通过网络服务器或通过CDN获取。 但它已经 **一个附加符号** 改为 通过脚本标记导入.

**小心点**:此方法不能保证包只装入一次. 若为 您再次调用它, 它会取消您以前创建的驱动程序 .

```
<html>
  <head>
    <meta content="text/html;charset=utf-8" http-equiv="Content-Type"/>
  </head>
  <body>
    <!-- Include these TWO JS files -->
    <script src='path/to/@citeproc-rs/wasm/_no_modules/citeproc_rs_wasm_include.js'></script>
    <script src='path/to/@citeproc-rs/wasm/_no_modules/citeproc_rs_wasm.js'></script>

    <script>
      // Like with the `--target web` output the exports are immediately
      // available but they won't work until we initialize the module. Unlike
      // `--target web`, however, the globals are all stored on a
      // `wasm_bindgen` global. The global itself is the initialization
      // function and then the properties of the global are all the exported
      // functions.
      //
      // Note that the name `wasm_bindgen` will at some point be configurable with the
      // `--no-modules-global` CLI flag (https://github.com/rustwasm/wasm-pack/issues/729)
      const { Driver } = wasm_bindgen;

      async function run() {
        // Note the _bg.wasm ending
        await wasm_bindgen('path/to/@citeproc-rs/wasm/_no_modules/citeproc_rs_wasm_bg.wasm');

        // Use Driver
      }

      run();

    </script>
  </body>
</html>
```

#### 在Zotero的使用

Zotero有一个特别的建筑 和遗留的Firefox ESR扩展API, 它需要一个通用JS模块格式,但没有节点.js `fs` API,以及 `no-modules`' 装载装置,但不使用 `window` 作为全球 它不存在。 档案在 `_zotero` 国家防范机制一揽子计划目录. 用法与无模块基本相同;您需要所有三个文件:

-   `@citeproc-rs/wasm/_zotero/citeproc_rs_wasm_include.js`
-   `@citeproc-rs/wasm/_zotero/citeproc_rs_wasm.js`
-   `@citeproc-rs/wasm/_zotero/citeproc_rs_wasm_bg.wasm`

除了"共同JS shims"之外,主要区别在于API将会是 装入 `Zotero.CiteprocRs` 对象,以便将其全部链接 一起来.

**小心点**:此方法不能保证包只装入一次. 若为 你打电话 `initWasmModule` 再说一次,这会使你之前的司机无效 创建.

```javascript
require("citeproc_rs_wasm_include");
const initWasmModule = require("citeproc_rs_wasm");
const wasmBinaryPromise = Zotero.HTTP
    .request('GET',
             'resource://zotero/citeproc_rs_wasm_bg.wasm',
             { responseType: "arraybuffer" })
    .then(xhr => xhr.response);
await initWasmModule(wasmBinaryPromise);

let driver;
try {
    driver = new Zotero.CiteprocRs.Driver({...});
} catch (e) {
    if (e instanceof Zotero.CiteprocRs.CslStyleError) {
        // ...
    }
}
```

## 使用量

### 概览

交互式使用的基本模式是:

1.  用您的风格创建驱动程序实例
2.  任意编辑引用或引用组
3.  **打电话 `driver.batchedUpdates()`**
4.  对文档应用更新(例如图形界面)
5.  用户更改时跳入步骤 2

第三步是重要的一步。 每次编辑一个组或一个引用, 通常只有一两个可见的修改才能产生结果。 因此, 驱动程序只给您那些有 更改,或由其他地方的编辑导致更改。 您可以提交任何 每个调用之间的编辑次数.

API也允许非交互使用. 见下文.

### 处理错误

许多驱动方法可以抛出错误.

如果您想专门处理这个库的错误,你可以,并且 这主要用于显示样式解析或验证错误。 错误 类型有附着的结构数据.

```typescript
try {
    let driver = new Driver({ ... });
    // do stuff with driver
} catch (error) {
    if (error instanceof CslStyleError) {
        console.error("Could not parse CSL, error:", error);
    } else if (error instanceof CiteprocRsDriverError) {
        console.error("Error in usage of Driver", error);
    } else if (error instanceof CiteprocRsError) {
        // CslStyleError and CiteprocRsDriverError are both subclasses of
        // CiteprocRsError, so this branch would catch them too had they not
        // been checked already.
        //
        // There may be errors that are not a subclass, but directly an
        // instance of CitprocRsError, so for completeness one should test for
        // this too.
        console.error("Catch-all error", error);
    } else {
        throw error;
    }
} finally {
    // Driver is only undefined if `new Driver` threw an error.
    if (driver) {
        driver.free()
    }
}
```

不幸的是,错误类型必须是全球出口,在窗口/全球/本身.

### 1\. 创建驱动实例

首先,创建驱动程序. 请注意,现在,你还必须打电话 `.free()` 编辑 当你用完它的时候, 驱动器可以处理它的内存, 但是 [有一个TC39 建议](https://rustwasm.github.io/docs/wasm-bindgen/reference/weak-references.html) 在执行阶段,将没有必要这样做.

驱动程序至少需要 XML 样式字符串、 获取器( 下方) 和输出 格式(其中一种为 `"html"`, (中文(简体) ), `"rtf"` 或者说 `"plain"`) (中文(简体) ).

```javascript
let fetcher =  ...; // see below
let driver = new Driver({
    style: "<style version=\"1.0\" class=\"note\" ... > ... </style>",
    format: "html", // optional, html is the default
    formatOptions: { // optional
        linkAnchors: true, // optional, default true
    },
    localeOverride: "de-DE", // optional, like setting default-locale on the style
    // bibliographyNoSort: true // disables sorting on the bibliography
    fetcher,
});
// Fetch the chain of locale files required to use the specified locale
await driver.fetchLocales();
// ... use the driver ...
driver.free()
```

库解析并验证了 CSL 样式输入. 任何验证错误都是 报告,用字节相抵以发现CSL碎片的责任 和有用的信息(英语),有时甚至提示如何修复. 见 [处理错误](https://npmcn.com/package/%40citeproc-rs/wasm/#readme-error-handling) 如何访问这个.

#### 获取器

有上百个地方 你需要的地方取决于风格 默认, 定义了任何覆盖和任何倒置的地块, 因此 获取一个是同步的, 允许从 HTTP 上获取一个 。 没有 远不止于此:

```javascript
class Fetcher {
    async fetchLocale(lang) {
        return await fetch("https://some-cdn-with-locales.com/locales-${lang}.xml")
            .then(res => res.text());

        // or just
        // return "<locale> ... </locale>";
        // return LOCALES_PRELOADED[lang];

        // or if you don't support locales other than the bundled en-US!
        // return null;
    }
}

let fetcher = new Fetcher();
let driver = new Driver({ ..., fetcher });
// Make sure you actually fetch them!
await driver.fetchLocales();
```

除非你没有 `async` 语法,在这种情况下,返回 a `Promise` 直接,例如:. `return Promise.resolve("<locale> ... </locale>")`。 。 。 .

拒绝在 `new Driver` 或者忘记打电话 `await driver.fetchLocales()` 使用捆绑结果 `en-US` 语言。 你个 也不应该试图在获取本地地址时使用驱动程序实例.

### 2\. 编辑参考文献或引文集

#### 参考资料

您可以插入这样的引用 。 这是一个 [CSL - 简森](https://github.com/citation-style-language/schema) 对象.

```javascript
driver.insertReference({ id: "citekey", type: "book", title: "Title" });
driver.insertReferences([ ... many references ... ]);
driver.resetReferences([ ... deletes any others ... ]);
driver.removeReference("citekey");
```

#### 引用组及其锡类

文件由一系列集群组成,每个集群都有一系列引用. 每个 组有 `id`,这是任何旧的字符串.

```javascript
// initClusters is like booting up an existing document and getting up to speed
driver.initClusters([
    { id: "one", cites: [ {id: "citekey"} ] },
    { id: "two", cites: [ {id: "citekey", locator: "56", label: "page" } ] },
]);
// Update or insert any one of them like so
driver.insertCluster({ id: "one", cites: [ { id: "updated_citekey" } ] });
// (You can use `driver.randomClusterId()` to generate a new one at random.)
let three = driver.randomClusterId();
driver.insertCluster({ id: three, cites: [ { id: "new_cluster_here" } ] });
```

这些集群不包含位置信息,所以重排是单独的 程序. **不拨打SetCluster命令,驱动程序会考虑文档 以入为空.**

这么说吧, `setClusterOrder` 表示在 文档。 文件内的每一份都应列入本清单。 你可以跳过 注释号,表示两者之间没有引用脚注。 选择 `note` 意思是它是内文参考. 注意号必须是单调的 但你 可以在同一个脚注中有一个以上的组.

```javascript
driver.setClusterOrder([ { id: "one", note: 1 }, { id: "two", note: 4 } ]);
```

您将注意到,如果一个交互式用户剪切并粘贴一段 ,可以表示整个重排序操作 在两次呼叫中,一次在剪接后(略去一些分组),一次在 粘贴(在别处放置相同的组)。 没有打电话 `insertCluster` 需要这样做.

#### 未引用项目

有时用户希望在书目中列入参考文献,尽管 这些文件的任何引用中都没有提及.

```javascript
driver.includeUncited("None"); // Default
driver.includeUncited("All");
driver.includeUncited({ Specific: ["citekeyA", "citekeyB"] });
```

"All"是参考车手知道的 如果你有的话 此集为"All",只是调用 `driver.insertReference()` 带有新的 参考ID将导致在书目中添加一个条目。 条目 在特定模式中,当它们在这里提供时,不必存在;它们可以是, 例如,参考图书馆收集参考文献的引用 之后将全部提供给司机 列入书目,但不包括图书馆其他地方的项目.

### 3\. 电话 `driver.batchedUpdates()` 并应用 diff

这样您就可以申请到您的文档 UI 。 它包括两个组 和文献目录条目.

```javascript
// Get the diff since last time batchedUpdates, fullRender or drain was called.
let diff = driver.batchedUpdates();

// apply cluster changes to the UI.

// ("myDocument" is an imaginary API.)

for (let changedCluster of diff.clusters) {
    let [id, html] = changedCluster;
    myDocument.updateCluster(id, html);
}

// Null? No change to the bibliography.
if (diff.bibliography != null) {
    let bib = diff.bibliography;
    // Save the entries that have actually changed
    for (let key of Object.keys(bib.updatedEntries)) {
        let rendered = bib.updatedEntries[key];
        myDocument.updateBibEntry(key, rendered);
    }
    // entryIds is the full list of entries in the bibliography.
    // If a citekey isn't in there, it should be removed.
    // It is non-null when it has changed.
    if (bib.entryIds != null) {
        myDocument.setBibliographyOrder(bib.entryIds);
    }
}
```

注意,一些直觉,如果你打电话 `batchedUpdates()` 再次立即 diff会是空的.

### 文献目录

除了交互式批量更新方法之外,还有两种功能用于 以静态编制参考书目.

```javascript
// returns BibliographyMeta, with information about how a library consumer should
// lay out the bibliography. There is a similar API in citeproc-js.
let meta = driver.bibliographyMeta();

// This is an array of BibEntry
let bibliography = driver.makeBibliography();
for (let entry of bibliography) {
    console.log(entry.id, entry.value);
}
```

### 预览引用群集

有时,一个用户想要在编辑时看到集群的外观 在确认变化之前.

```javascript
let cluster = { cites: [ { id: "citekey", locator: "45" }, { ... } ] };
let positions = [ ... before, { note: 34 }, ... after ];
let preview = driver.previewCluster(cluster, positions);
let plainPreview = driver.previewCluster(cluster, positions, "plain");
```

集群论点只是一个集群,没有 `id` 田间,因为它是 麻黄. 缺乏 `id` 字段在 `positions` 参数为 不错.

位置阵列就像呼叫 `setClusterOrder`,除了准确的 其中一个位置省略了 id 字段。 这可以:

-   替换现有集群的位置并预览集群替换;或
-   假设插入一个集群的位置.

如果你只通过一个位置, 它会像预览一个操作像 "删除整个文档,取而代之的是这个集群". **那会 意味着你永远不会在预览中看到"同上".** 因此,为了最大效用, 组装位置阵列,如您要调用 `setClusterOrder` 与 正是您正在预览的操作.

格式参数是可选的,其作用方式类似传递到的格式 `new Driver`: 一个 `"html"`, (中文(简体) ), `"rtf"` 或者说 `"plain"`。驱动程序将使用 而不是它的正常输出格式.

### `AuthorOnly`, (中文(简体) ), `SuppressAuthor` 打开 `Composite`

`@citeproc-rs/wasm` 支持集群上的这些旗帜(所有3个)并引用(但 `Composite`),以类似方式 `citeproc-js`见 [`citeproc-js` 关于特别引用的文件 表单](https://citeproc-js.readthedocs.io/en/latest/running.html#special-citation-forms) 供参考.

```javascript
// only two modes for cites
let citeAO = { id: "jones2006", mode: "AuthorOnly" };
let citeSA = { id: "jones2006", mode: "SuppressAuthor" };

// additional options for clusters
let clusterAO       = { id: "one", cites: [...], mode: "AuthorOnly" };
let clusterSA       = { id: "one", cites: [...], mode: "SuppressAuthor" };
let clusterSA_First = { id: "one", cites: [...], mode: "SuppressAuthor", suppressFirst: 3 };
let clusterC        = { id: "one", cites: [...], mode: "Composite" };
let clusterC_Infix  = { id: "one", cites: [...], mode: "Composite", infix: ", whose book" };
let clusterC_Full   = { id: "one", cites: [...], mode: "Composite", infix: ", whose books", suppressFirst: 0 };
```

它确实支持一个额外的选项 : `SuppressAuthor` 财务报告和审定财务报表 `Composite` 打开 集群 : `suppressFirst`,将效果限制在第一个 N 名称组 (或者如果引用分组被禁用,第一个N名). 设定为0 无限.

#### `<intext>` 元素为 `AuthorOnly` 包括:.

`citeproc-rs` 支持 `<intext>` 中描述的元素 `citeproc-js` 上面链接的文档, 但默认无法启用 。 它还支持 `<intext and="symbol">` 或者说 `and="text"`,将交换最后的文本布局 分隔符( e)`<layout delimiter="; ">`) 用于水肿或 `and` 术语.

如果你想用这个 `<intext>` 在 CML 中,您可以选择:

##### 选项 1: 在样式中添加要使用的特征标志

```xml
<style class="in-text">
    <features>
        <feature name="custom-intext" />
    </features>
    ...
</style>
```

AFAIK 还没有其他处理器支持此语法 .

##### 备选案文2:启用 `custom-intext` 所有样式的特性通过 `new Driver`

```javascript
let driver = new Driver({ ..., cslFeatures: ["custom-intext"] });
// ... driver.free();
```

### 非交互使用, 或重水化先前创建的文档

如果您是在非互动工作, 或重新给先前创建的系统水分 文档供交互使用,您可能想要对所有分组进行一个通过 在文档中,使每组和书目条目反映 正确值.

```javascript
// Get the clusters from your document (example)
let allNotes = myDocument.footnotes.map(fn => {
    return { cluster: getCluster(fn), number: fn.number }
});

// Re-hydrate the entire document based on the reference library and your
// document's clusters
driver.resetReferences(myDocument.allReferences);
driver.initClusters(allNotes.map(fn => fn.cluster));
driver.setClusterOrder(allNotes.map(fn => { id: fn.cluster.id, note: fn.number }));

// Render every cluster and bibliography item.
// It then drains the update queue, leaving the diff empty for the next edit.
// see the FullRender typescript type
let render = driver.fullRender();

// Write out the rendered clusters into the doc
for (let fn of allNotes) {
    fn.renderedHtml = render.allClusters[fn.cluster.id];
}

// Write out the bibliography entries as well
let allBibKeys = render.bibEntries.map(entry => entry.id);
for (let bibEntry of render.bibEntries) {
    myDocument.bibliographyMap[entry.id] = entry.value;
}

// Update your (example) UI
updateUserInterface(allNotes, myDocument, whatever);
```

### `parseStyleMetadata`

有时你想要关于 CSL 风格的信息而不实际启动 a 整个司机。 一种重要的用法是依赖式,不能使用 与 `new Driver()` 因为它没有能力 引用在 它本身,基本上只是三件信息的容器:

-   一个日记名称
-   独立父样式
-   可能的默认本地覆盖

`@citeproc-rs/wasm` 提供API,用于查找CSL样式文件中的内容.

```typescript
let styleMeta = parseStyleMetadata("<style ...> ... </style>");
```

此函数仍然可以丢出 `CslStyleError`,但这比 使用新的驱动程序( ), 因为它不会真正试图解析和验证所有 样式的部分。 如果 XML 变形或 `<info>` 块太无效,无法保存.

这是如何使用 `parseStyleMetadata` 来分析并使用依赖的样式.

```typescript
let dependentStyle = "<style ...> ... </style>";
let meta = parseStyleMetadata(dependentStyle);
let isDependent = meta.info.parent != null;
let parentStyleId = isDependent && meta.info.parent.href;
let localeOverride = meta.defaultLocale;

// ...
let parentStyle = await downloadStyleWithId(parentStyleId);
let driver = new Driver({
    style: parentStyle,
    localeOverride,
    ...
});
await driver.fetchLocales();

// Here you might also want to know if the style can render a bibliography or not
let parentMeta = parseStyleMetadata(parentStyle);
if (parentMeta.independentMeta.hasBibliography) {
    let bib = driver.makeBibliography();
    // ...
}

// ...
driver.free();
```

### `setOutputFormat` 财务报告和审定财务报表 `setStyle`

如果您想要更改整个驱动程序的输出格式, 您可以使用 `setOutputFormat(format, formatOptions)`。格式为字符串,其中之一 `"html" | "rtf" | "plain"` 就像一个 `new Driver` 方法。 选项是可选的 参数,其数值与 `formatOptions` 内 `new Driver`。 。 。 .

`setStyle(xmlString)` 将更改驱动程序使用的 SSL 样式.

这两种方法都要求放弃几乎所有缓存计算, 所以请少用.

如果您需要以不同格式进行预览,则在 `previewCluster` 做这些。 它不会扔掉所有的 计算. `citeproc-rs`'混淆程序确实将格式化为: 账户,所以 `<i>Title</i>` 可区别于 `<b>Title</b>` 在HTML和RTF中, 但如果整个驱动程序输出格式是 `"plain"`因为他们都看 纯文本相同. `previewCluster` 将简单地翻译格式 以另一种格式,而不重新计算所有混淆.

## 常见问题

### @citeproc-rs/wasm 是什么？

引用proc-rs,编译为WebAssembly

### 如何安装 @citeproc-rs/wasm？

在项目目录运行 npm install @citeproc-rs/wasm，或使用 pnpm add / yarn add / bun add。

### @citeproc-rs/wasm 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @citeproc-rs/wasm 支持 ESM 还是 CommonJS？

以 CommonJS 形式发布，可以直接 require\(\)；在 ES Module 项目中也可以用 import 引入（Node\.js 会把 module\.exports 作为默认导出）。

### @citeproc-rs/wasm 可以商用吗？

@citeproc-rs/wasm 使用 MPL-2\.0 许可。弱 Copyleft：可以商用，也可以和闭源代码一起使用；但如果分发时修改了 MPL 授权的文件，这些文件的修改需以 MPL 开源。以上为概括，不构成法律意见，请以许可原文为准。

### @citeproc-rs/wasm 的下载量有多少？

根据 npm 官方下载统计，@citeproc-rs/wasm 在 2026/10/10 – 2026/11/08 这 30 天内被下载 3,205 次，日均约 107 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @citeproc-rs/wasm 还在维护吗？

最新版本 0\.2\.0 发布于 2021/12/15（4 年前）；至今共发布 49 个版本，其中过去 12 个月发布了 0 个；首次发布于 2020/09/19。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

