mooncite

    CSL-style citation and bibliography rendering for MoonBit

    citation
    bibliography
    csl
    citeproc
    moonbit
    Download zip
    Version
    0.1.2
    License
    Apache-2.0
    Last updated
    16 days ago
    Downloads
    34

    No dependencies

    #MoonCite

    MoonCite 是 MoonBit 文献引用与参考文献排版库:输入 CSL XML 样式和 CSL-JSON 文献数据,在本地生成正文引用、文献表和 HTML 片段。适合文档生成、科研笔记、静态站点和教学工具,不提供在线文献检索服务。

    #0.1.2 的功能范围

    • 常用样式节点:text、names/name、label、date/date-part、number、group、choose、macro、sort 和 layout。
    • 姓名格式真正由样式控制:全名/姓氏/人数、缩写、连词、排序名、分隔符、et-al 截断和保留最后一位作者。支持根节点、citation、bibliography 的选项继承,以及无作者时的 substitute。
    • collapse="citation-number" 已接入正文引用流程;不必手工调用范围辅助函数。连续三个及以上编号生成范围,两个编号保持分别列出。
    • 引用簇的括号、前后缀和字体在对应层级应用;引用和文献表使用一致编号,支持排序、定位页码、逐条 prefix/suffix 和 suppress-author。
    • CSL-JSON 作者、机构作者、日期、标题、页码、URL、DOI 等字段;纯文本和 HTML 输出,HTML 内容按层级转义。
    • 英文/中文常用术语及简单的样式内术语覆盖。库本身不联网,不依赖 Node.js 或 JavaScript 引用引擎。

    交付终点:有限 CSL 子集,不是完整 CSL 1.0.2 兼容引擎,也不承诺本轮补齐整个标准。 新增按实际引用文本冲突与文献表顺序分配的 year-suffix 消歧,以及共用完整文献集合的无状态 render_document。不做 add-names/add-givenname 消歧、ibid/position/near-note 历史、完整 locale/name-part/粒子规则或文档脚注排版。未支持渲染节点/属性/枚举值在样式载入时明确报错,历史 Cite JSON 字段、日期范围/literal 渲染也拒绝,不再静默跳过。完整边界、成功与拒绝案例见 兼容范围。

    与 Typst 并非没有重叠。 Hayagriva 已能作为独立 Rust 库使用。本项目提供不依赖外部引用引擎的 MoonBit 数据/API 与多目标输出,适合受控样式的 MoonBit 应用;不是功能、兼容性或性能更强的替代品。具体复用途径与比较依据见 生态贡献及对标边界。

    #从 GitHub 获取并运行

    当前源码使用 moonc >= 0.10.15(满足比赛要求的不低于 0.10.14);建议使用官方工具链 2026-10-12 版或更新版本。本版源码为 0.1.2。以下命令可直接验证 GitHub 源码。

    git clone https://github.com/yujieMamba/mooncite.git cd mooncite moon version --all moonc -v moon fmt --check moon check --target wasm-gc --deny-warn moon build --target wasm-gc --deny-warn moon test --target wasm-gc --deny-warn moon run examples/beginners --target wasm-gc moon run examples/numeric --target wasm-gc moon run examples/document --target wasm-gc

    #从 MoonCakes 安装指定版本

    在已有 MoonBit 模块中执行:

    moon add yujieMamba/mooncite@0.1.2

    依赖该库的包在 moon.pkg 中加入:

    import {
    "yujieMamba/mooncite",
    }

    代码通过 @mooncite 调用下方接口;cmd/main 和 examples/* 提供完整可运行源码。发布版本以 MoonCakes 注册表为准;验证源码时仍可使用上面的 GitHub 克隆方式。

    #最小用法

    下面是 examples/beginners/main.mbt 中的核心代码。完整样式、包配置和入口在该目录,可直接运行。

    let item = @mooncite.Item::new("intro")
    .set_string("title", "A MoonBit introduction")
    .set_name("author", [
    @mooncite.CslName::new("Doe", given="Jane Mary"),
    @mooncite.CslName::new("Smith", given="John"),
    ])
    .set_date("issued", @mooncite.CslDate::new(2025))
    let p = @mooncite.Processor::from_style(STYLE).unwrap()
    println(p.render_citation([item], [@mooncite.Cite::new("intro")]).unwrap())
    println(p.render_bibliography([item]).unwrap())
    println(p.render_bibliography_html([item]).unwrap())

    样式在 citation 内使用 <name form="short" and="text"/>,bibliography 内使用 name-as-sort-order="first",根节点提供 initialize-with=". "。输出如下:

    (Doe and Smith 2025) Doe, J. M. and J. Smith. (2025). A MoonBit introduction. Doe, J. M. and J. Smith. (2025). <i>A MoonBit introduction</i>.

    #数字引用:完整渲染,不是独立辅助函数

    examples/numeric/main.mbt 的样式包含:

    <citation collapse="citation-number"> <sort><key variable="citation-number"/></sort> <layout prefix="[" suffix="]" delimiter=", "> <group delimiter=", "> <text variable="citation-number"/> <group delimiter=" "> <label variable="locator" form="short"/> <text variable="locator"/> </group> </group> </layout> </citation>

    运行 moon run examples/numeric --target wasm-gc,先输出引用簇,再输出编号文献表:

    [1–3, 5, 7–9] [1, 2, pp. 12-14, 3] 1. Paper 1 2. Paper 2 3. Paper 3 ... 9. Paper 9

    第二行的第 2 条引用带定位页码,因此不能吞入数字范围。重复引用、不连续/逆序编号,以及有 prefix/suffix 或 suppress-author 的引用也不参与跨条合并。没有 <sort> 时保留输入顺序,不为获得范围而擅自排序。混有标题等逐条信息的布局保持逐条渲染,避免折叠丢失内容。

    编号由本次传入的完整文献集合确定:有 bibliography 排序时按该排序分配,否则按输入顺序;合法显式编号优先保留。库不维护跨调用的引用历史。多次生成引用及文献表时请传入同一个完整集合,而非每次仅传当前引用的文献子集。渲染过程中使用副本,不改写调用者的数据。

    #示例与验证

    五个可运行入口(不是五个编译目标):

    moon run cmd/main --target wasm-gc moon run examples/beginners --target wasm-gc moon run examples/numeric --target wasm-gc moon run examples/text-extract --target wasm-gc moon run examples/document --target wasm-gc

    100 个 MoonBit 测试覆盖核心路径和回归问题;其中 26 个用例与独立的 citeproc-js 2.4.63 使用相同输入及预期输出,分别验证姓名格式、数字范围、HTML 范围端点和年后缀消歧。它们是选定行为的精确对照,不代表全部 CSL 兼容,也不是性能基准。

    对照工具仅是开发依赖,需要 Node.js 22:

    npm ci --prefix tools/reference --ignore-scripts npm test --prefix tools/reference

    CI 对 wasm-gc、wasm、js、native 分别执行格式检查、检查、显式构建、测试和五个示例;独立运行 citeproc-js 对照。本地复现记录见 质量报告,本次修复与验收步骤见 修复验证 和 验收对应说明。

    #消歧与文档上下文

    let document = processor.render_document(items, [
    [@mooncite.Cite::new("a")],
    [@mooncite.Cite::new("z")],
    [@mooncite.Cite::new("a")],
    ]).unwrap()

    完整示例在 examples/document。其中题目为 Zulu/Alpha 的两篇 Doe 2025 文献,按题目排序后依次给 a/b 后缀;引用顺序 a、z、a 输出 (Doe 2025b)、(Doe 2025a)、(Doe 2025b),文献表相应一致。26 组共享对照包含实际姓名渲染碰撞、et-al、显式/自动后缀和 z 之后的 aa/ab。

    items 必须是整篇文档的同一完整集合,含需列入文献表的未引文献。新增/删除文献或改排序数据后重渲染所有簇。这个接口没有脚注历史,不会把第三次引用变成 ibid。style_compatibility_issues 可以预检样式;Processor::from_style 同样强制门禁,见兼容范围文档。原有 assign_year_suffixes 只是会修改参数的元数据辅助函数,不是引擎消歧流程;实际渲染在副本上按基础引用文本判断。

    #源码组织

    文件职责
    xml.mbt、style.mbtXML/样式解析、选项继承、宏验证
    model.mbt、item_json.mbt文献与引用数据模型、CSL-JSON
    names_render.mbt、render.mbt姓名及节点渲染、文本/HTML
    citation.mbt、ordering.mbt、disambiguation.mbt、document.mbt引用簇、范围折叠、排序编号、年后缀与无状态整篇输出
    compatibility.mbt有限样式契约与不支持能力诊断
    locale.mbt、advanced.mbt、features.mbt术语及扩展辅助 API
    render_regression_test.mbt、reference_test.mbt回归测试与共享对照用例

    #许可证

    生产库采用 Apache License 2.0。规范文档、参考项目和可选测试引擎的许可边界见 THIRD_PARTY.md。仓库不包含上游引用引擎源文件;开发对照工具不能被理解为生产库的运行时依赖。

    #AI 使用说明

    开发中使用了 AI 代码助手参与实现、测试设计和文档整理;最终交付以可复现的源码、测试及 CI 结果为准。详见 AI_DISCLOSURE.md。

    Affix

    pub struct Affix {
    prefix : String
    suffix : String
    delimiter : String
    text_case : String
    font_style : String
    font_weight : String
    vertical_align : String
    }

    ChooseBranch

    pub struct ChooseBranch {
    conditions : Array[Condition]
    match_mode : String
    children : Array[Node]
    }

    Cite

    pub(all) struct Cite {
    id : String
    locator : String
    label : String
    prefix : String
    suffix : String
    suppress_author : Bool
    } derive(Eq,
    Debug
    )

    Cite::equal

    fn Cite::equal(Cite, Cite) -> Bool

    Cite::new

    fn Cite::new(id : String) -> Cite

    Cite::not_equal

    fn Cite::not_equal(x : Cite, y : Cite) -> Bool

    Cite::to_repr

    Condition

    pub enum Condition {
    Variable(String)
    Type(String)
    Numeric(String)
    IsUncertain(String)
    IsPlural(String)
    Position(String)
    }

    CslDate

    pub(all) struct CslDate {
    year : Int
    month : Int
    day : Int
    end_year : Int
    end_month : Int
    end_day : Int
    circa : Bool
    literal : String
    } derive(Eq,
    Debug
    )

    CslDate::equal

    fn CslDate::equal(CslDate, CslDate) -> Bool

    CslDate::new

    fn CslDate::new(year : Int, month? : Int, day? : Int) -> CslDate

    CslDate::not_equal

    fn CslDate::not_equal(x : CslDate, y : CslDate) -> Bool

    CslDate::to_repr

    CslError

    pub(all) enum CslError {
    BadXml(String)
    BadStyle(String)
    BadJson(String)
    BadItem(String)
    MissingStyle
    } derive(Eq,
    Debug
    )

    Recoverable processor errors. Messages stay stable for tests.

    CslError::equal

    fn CslError::equal(CslError, CslError) -> Bool

    CslError::message

    fn CslError::message(self : CslError) -> String

    CslError::not_equal

    fn CslError::not_equal(x : CslError, y : CslError) -> Bool

    CslError::to_repr

    CslName

    pub(all) struct CslName {
    literal : String
    family : String
    given : String
    suffix : String
    dropping_particle : String
    non_dropping_particle : String
    } derive(Eq,
    Debug
    )

    CslName::equal

    fn CslName::equal(CslName, CslName) -> Bool

    CslName::new

    fn CslName::new(family : String, given? : String) -> CslName

    CslName::not_equal

    fn CslName::not_equal(x : CslName, y : CslName) -> Bool

    CslName::to_repr

    DateNode

    pub struct DateNode {
    variable : String
    parts : Array[DatePart]
    delimiter : String
    }

    DatePart

    pub struct DatePart {
    name : String
    form : String
    prefix : String
    suffix : String
    range_delimiter : String
    text_case : String
    }

    Item

    pub(all) struct Item {
    id : String
    title : String
    container_title : String
    publisher : String
    publisher_place : String
    volume : String
    issue : String
    page : String
    edition : String
    url : String
    doi : String
    item_type : String
    abstract_text : String
    names : Map[String, Array[CslName]]
    dates : Map[String, CslDate]
    strings : Map[String, String]
    numbers : Map[String, Int]
    booleans : Map[String, Bool]
    } derive(
    Debug
    )

    Item::date

    fn Item::date(self : Item, variable : String) -> CslDate?

    Item::has

    fn Item::has(self : Item, variable : String) -> Bool

    Item::name

    fn Item::name(self : Item, variable : String) -> Array[CslName]

    Item::new

    fn Item::new(id : String) -> Item

    Item::number

    fn Item::number(self : Item, variable : String) -> Int?

    Item::set_bool

    fn Item::set_bool(self : Item, variable : String, value : Bool) -> Item

    Item::set_date

    fn Item::set_date(self : Item, variable : String, date : CslDate) -> Item

    Item::set_name

    fn Item::set_name(self : Item, variable : String, names : Array[CslName]) -> Item

    Item::set_number

    fn Item::set_number(self : Item, variable : String, value : Int) -> Item

    Item::set_string

    fn Item::set_string(self : Item, variable : String, value : String) -> Item

    Item::string

    fn Item::string(self : Item, variable : String) -> String

    Item::to_repr

    LabelNode

    pub struct LabelNode {
    variable : String
    form : String
    plural : String
    }

    Layout

    pub struct Layout {
    affix : Affix
    children : Array[Node]
    }

    Locale

    pub(all) struct Locale {
    language : String
    terms : Map[String, String]
    months : Map[Int, String]
    }

    Localized CSL terms. The table is intentionally small but extensible: user supplied locale XML can replace any term without changing style code.

    Locale::chinese

    fn Locale::chinese() -> Locale

    Locale::english

    fn Locale::english() -> Locale

    Locale::month

    fn Locale::month(self : Locale, number : Int, form? : String) -> String

    Locale::term

    fn Locale::term(self : Locale, name : String, form? : String) -> String

    NameNode

    pub struct NameNode {
    variable : String
    form : String
    and_word : String
    delimiter : String
    initialize_with : String
    initialize : Bool
    name_as_sort_order : String
    delimiter_precedes_last : String
    et_al_min : Int
    et_al_use_first : Int
    label_variable : String
    options : Map[String, String]
    name_affix : Affix
    label : XmlElem?
    substitute : Array[Node]
    }

    Node

    pub enum Node {
    Label(Affix, LabelNode)
    Text(Affix, TextNode)
    Names(Affix, NameNode)
    Number(Affix, NumberNode)
    Date(Affix, DateNode)
    Group(Affix, Array[Node])
    Choose(Affix, Array[ChooseBranch])
    }

    NumberNode

    pub struct NumberNode {
    variable : String
    form : String
    prefix : String
    suffix : String
    delimiter : String
    text_case : String
    }

    Processor

    pub(all) struct Processor {
    style : Style
    }

    Processor::from_style

    fn Processor::from_style(style_xml : String) -> Result[Processor, CslError]

    Processor::render_bibliography

    fn Processor::render_bibliography(self : Processor, items : Array[Item], format? : String) -> Result[String, CslError]

    Processor::render_bibliography_html

    fn Processor::render_bibliography_html(self : Processor, items : Array[Item]) -> Result[String, CslError]

    Processor::render_bibliography_json

    fn Processor::render_bibliography_json(self : Processor, items_json : String, format? : String) -> Result[String, CslError]

    Processor::render_citation

    fn Processor::render_citation(self : Processor, items : Array[Item], cites : Array[Cite], format? : String) -> Result[String, CslError]

    Processor::render_citation_html

    fn Processor::render_citation_html(self : Processor, items : Array[Item], cites : Array[Cite]) -> Result[String, CslError]

    Processor::render_citation_json

    fn Processor::render_citation_json(self : Processor, items_json : String, cites_json : String, format? : String) -> Result[String, CslError]

    Processor::render_document

    fn Processor::render_document(self : Processor, items : Array[Item], clusters : Array[Array[Cite]], format? : String) -> Result[RenderedDocument, CslError]

    RenderedDocument

    pub(all) struct RenderedDocument {
    citations : Array[String]
    bibliography : String
    } derive(Eq,
    Debug
    )

    Result of rendering all clusters against one complete item universe. This is deliberately stateless: no note positions, ibid or hidden history.

    RenderedDocument::equal

    RenderedDocument::not_equal

    fn RenderedDocument::not_equal(x : RenderedDocument, y : RenderedDocument) -> Bool

    SortKey

    pub struct SortKey {
    variable : String
    macro_name : String
    names_min : Int
    names_use_first : Int
    sort_order : String
    }

    Style

    pub struct Style {
    title : String
    version : String
    default_locale : String
    macros : Map[String, Array[Node]]
    citation : Layout?
    bibliography : Layout?
    citation_sort : Array[SortKey]
    bibliography_sort : Array[SortKey]
    citation_disambiguate : Bool
    citation_collapse : String
    citation_delimiter : String
    after_collapse_delimiter : String?
    name_options : Map[String, String]
    citation_name_options : Map[String, String]
    bibliography_name_options : Map[String, String]
    locale : Locale
    }

    TextNode

    pub struct TextNode {
    variable : String
    value : String
    macro_name : String
    term : String
    form : String
    }

    XmlElem

    pub(all) struct XmlElem {
    name : String
    attrs : Map[String, String]
    children : Array[XmlNode]
    } derive(
    Debug
    )

    XmlElem::attr

    fn XmlElem::attr(self : XmlElem, key : String) -> String

    XmlElem::direct_text

    fn XmlElem::direct_text(self : XmlElem) -> String

    XmlElem::first

    fn XmlElem::first(self : XmlElem, name : String) -> XmlElem?

    XmlElem::has_attr

    fn XmlElem::has_attr(self : XmlElem, key : String) -> Bool

    XmlElem::kids

    fn XmlElem::kids(self : XmlElem) -> Array[XmlElem]

    XmlElem::kids_named

    fn XmlElem::kids_named(self : XmlElem, name : String) -> Array[XmlElem]

    XmlElem::text

    fn XmlElem::text(self : XmlElem) -> String

    XmlElem::to_repr

    XmlNode

    pub(all) enum XmlNode {
    Element(XmlElem)
    Text(String)
    } derive(
    Debug
    )

    XmlNode::to_repr

    assign_year_suffixes

    fn assign_year_suffixes(items : Array[Item]) -> Unit

    Metadata-only convenience, mutates its argument and groups author/year. This is NOT CSL disambiguation. Processor uses rendered-citation collisions, bibliography order and copied items; use Processor for citation processing.

    bibliography_key

    fn bibliography_key(item : Item) -> String

    bibliography_statistics

    fn bibliography_statistics(items : Array[Item]) -> Map[String, Int]

    citation_has_locator

    fn citation_has_locator(cites : Array[Cite]) -> Bool

    cite_items

    fn cite_items(items : Array[Item], cites : Array[Cite]) -> Array[Item]

    cite_to_plain_json

    fn cite_to_plain_json(cite : Cite) -> String

    cites_to_plain_json

    fn cites_to_plain_json(cites : Array[Cite]) -> String

    collapse_numeric_ranges

    fn collapse_numeric_ranges(values : Array[Int]) -> String

    compact_whitespace

    fn compact_whitespace(value : String) -> String

    compare_items_for_bibliography

    fn compare_items_for_bibliography(a : Item, b : Item) -> Int

    date_is_range

    fn date_is_range(date : CslDate) -> Bool

    date_range_text

    fn date_range_text(date : CslDate, delimiter? : String) -> String

    date_sort_stamp

    fn date_sort_stamp(date : CslDate) -> Int64

    deduplicate_items

    fn deduplicate_items(items : Array[Item]) -> Array[Item]

    first_nonempty_render

    fn first_nonempty_render(style_xml : String, items : Array[Item]) -> String

    format_edition

    fn format_edition(item : Item) -> String

    format_identifier

    fn format_identifier(item : Item, prefer_doi? : Bool) -> String

    format_localized_date

    fn format_localized_date(locale : Locale, date : CslDate, form? : String) -> String

    format_localized_month

    fn format_localized_month(locale : Locale, date : CslDate, form : String) -> String

    format_page_variable

    fn format_page_variable(item : Item, variable? : String) -> String

    format_volume_issue

    fn format_volume_issue(item : Item) -> String

    initials_for_name

    fn initials_for_name(name : CslName, marker? : String) -> String

    invert_name

    fn invert_name(name : CslName) -> String

    item_author_key

    fn item_author_key(item : Item) -> String

    item_author_year_key

    fn item_author_year_key(item : Item) -> String

    item_by_id

    fn item_by_id(items : Array[Item], id : String) -> Item?

    item_container_label

    fn item_container_label(item : Item) -> String

    item_display_title

    fn item_display_title(item : Item) -> String

    item_has_author

    fn item_has_author(item : Item) -> Bool

    item_has_editor

    fn item_has_editor(item : Item) -> Bool

    item_is_book

    fn item_is_book(item : Item) -> Bool

    item_is_online

    fn item_is_online(item : Item) -> Bool

    item_is_periodical

    fn item_is_periodical(item : Item) -> Bool

    item_summary

    fn item_summary(item : Item) -> String

    item_to_plain_json

    fn item_to_plain_json(item : Item) -> String

    items_to_plain_json

    fn items_to_plain_json(items : Array[Item]) -> String

    locale_debug

    fn locale_debug(locale : Locale) -> String

    locale_from_language

    fn locale_from_language(language : String) -> Locale

    locale_months

    fn locale_months(locale : Locale) -> Array[String]

    locale_terms

    fn locale_terms(locale : Locale) -> Array[String]

    localize_and

    fn localize_and(locale : Locale) -> String

    localize_et_al

    fn localize_et_al(locale : Locale) -> String

    localize_label

    fn localize_label(locale : Locale, variable : String, count : Int) -> String

    localize_name_delimiter

    fn localize_name_delimiter(locale : Locale, count : Int) -> String

    merge_citation_parts

    fn merge_citation_parts(main : String, cites : Array[Cite]) -> String

    merge_locales

    fn merge_locales(base : Locale, replacement : Locale) -> Locale

    name_family_key

    fn name_family_key(name : CslName) -> String

    name_given_key

    fn name_given_key(name : CslName) -> String

    name_list_equal

    fn name_list_equal(a : Array[CslName], b : Array[CslName]) -> Bool

    names_equal

    fn names_equal(a : CslName, b : CslName) -> Bool

    normalize_page_range

    fn normalize_page_range(value : String) -> String

    Page-range and citation helpers used by numeric and author-date styles.

    normalize_range_part

    fn normalize_range_part(value : String) -> String

    normalize_title

    fn normalize_title(value : String) -> String

    number_label

    fn number_label(variable : String, count : Int, short? : Bool) -> String

    page_range_end

    fn page_range_end(value : String) -> String

    page_range_start

    fn page_range_start(value : String) -> String

    parse_cites_json

    fn parse_cites_json(json_text : String) -> Result[Array[Cite], CslError]

    parse_item_json

    fn parse_item_json(value : Json) -> Result[Item, CslError]

    parse_items_json

    fn parse_items_json(json_text : String) -> Result[Array[Item], CslError]

    parse_locale_xml

    fn parse_locale_xml(xml : String) -> Result[Locale, CslError]

    parse_xml

    fn parse_xml(input : String) -> Result[XmlElem, CslError]

    Parse a CSL/XML document and return the root element.

    processor_capabilities

    fn processor_capabilities() -> Array[String]

    processor_empty_result

    fn processor_empty_result(style_xml : String) -> Bool

    processor_is_deterministic

    fn processor_is_deterministic(style_xml : String, items : Array[Item]) -> Bool

    processor_license

    fn processor_license() -> String

    processor_upstream

    fn processor_upstream() -> String

    processor_version

    fn processor_version() -> String

    render_citation_html

    fn render_citation_html(style_xml : String, items : Array[Item], cites : Array[Cite]) -> Result[String, CslError]

    render_citation_text

    fn render_citation_text(style_xml : String, items : Array[Item], cites : Array[Cite]) -> Result[String, CslError]

    render_cite_prefix

    fn render_cite_prefix(cite : Cite) -> String

    render_each_item

    fn render_each_item(style_xml : String, items : Array[Item]) -> Array[String]

    render_html

    fn render_html(style_xml : String, items : Array[Item]) -> Result[String, CslError]

    render_int_range

    fn render_int_range(start : Int, end : Int) -> String

    render_many

    fn render_many(styles : Array[String], items : Array[Item]) -> Array[Result[String, CslError]]

    render_one

    fn render_one(style_xml : String, item : Item) -> Result[String, CslError]

    render_text

    fn render_text(style_xml : String, items : Array[Item]) -> Result[String, CslError]

    render_text_json

    fn render_text_json(style_xml : String, items_json : String) -> Result[String, CslError]

    safe_render

    fn safe_render(style_xml : String, items : Array[Item]) -> String

    safe_render_html

    fn safe_render_html(style_xml : String, items : Array[Item]) -> String

    sentence_title

    fn sentence_title(value : String) -> String

    style_compatibility_issues

    fn style_compatibility_issues(style_xml : String) -> Array[String]

    Compatibility diagnostics for the supported MoonCite profile. This is not validation against the full CSL schema; metadata below info is not rendered. Empty means accepted by this profile, not full CSL 1.0.2 conformance.

    style_complexity

    fn style_complexity(style_xml : String) -> Map[String, Int]

    style_has_macro

    fn style_has_macro(style_xml : String, name : String) -> Bool

    style_is_author_date

    fn style_is_author_date(style_xml : String) -> Bool

    style_is_numeric

    fn style_is_numeric(style_xml : String) -> Bool

    style_macro_names

    fn style_macro_names(style_xml : String) -> Array[String]

    style_metadata

    fn style_metadata(style_xml : String) -> Map[String, String]

    style_render_preview

    fn style_render_preview(style_xml : String, item : Item) -> Map[String, String]

    style_supports_bibliography

    fn style_supports_bibliography(style_xml : String) -> Bool

    style_supports_citation

    fn style_supports_citation(style_xml : String) -> Bool

    title_case_words

    fn title_case_words(value : String) -> String

    validate_item

    fn validate_item(item : Item) -> Array[String]

    validate_items

    fn validate_items(items : Array[Item]) -> Map[String, Array[String]]

    validate_style

    fn validate_style(style_xml : String) -> Array[String]

    with_citation_numbers

    fn with_citation_numbers(items : Array[Item]) -> Array[Item]