moonfolio

    MoonBit-native Markdown metadata contract and content folio toolkit.

    markdown
    metadata-contract
    content-folio
    manifest
    wasm
    Download zip
    Author
    Version
    0.1.0
    License
    MIT
    Last updated
    2 months ago
    Downloads
    30

    No dependencies

    #MoonFolio

    MoonFolio 是一个 MoonBit 原生的 Markdown 元数据契约与内容卷宗工具库。它不是通用 Markdown 解析器,也不是普通 front matter 读取器;它把 Markdown 顶部元数据转换成可校验的内容契约、稳定的内容指纹、slug/permalink、registry、diff 和报告,适合文档发布、资源管线、CI 报告和 Wasm 内容工具使用。

    #独特定位

    Mooncakes 上已有 Markdown parser、静态站点生成器和文档工具。MoonFolio 避开这些方向,只处理“文档元数据编目”这一层:

    • 不渲染 Markdown;
    • 不生成站点;
    • 不替代 YAML/TOML/JSON 完整解析器;
    • 专注字段契约、内容画像、registry、diff、编辑修复、稳定 fingerprint 和 manifest 生成;
    • 让内容文件在进入站点、索引、资源包或 Wasm 应用前先通过 MoonBit 校验。

    2026-08-21 的 Mooncakes API 关键词查重结果:moonfolio、content folio、metadata contract、frontmatter contract、markdown inventory 均为 0 个直接命中;相邻项目集中在 Markdown parser/renderer、静态站点生成器、slug 工具和通用 fingerprint/manifest 工具。MoonFolio 因此继续坚持“Markdown 内容元数据编目与 folio manifest”边界,不进入 Markdown 渲染、站点生成、Mooncakes 发布审计、来源证明、评审补证、robots 解析或能力轨迹校验方向。

    #相邻项目披露与区别

    公开查重还发现了几个需要主动避开的方向:

    • ZBZ-ai-nb/cakecheck:面向 Mooncakes 发布准备度;MoonFolio 不检查 MoonBit 包发布资格,只处理 Markdown 内容文件的 front matter。
    • EJJ-ai-nb/harborcheck、WB-ai-nb/reviewproof-kit:面向 README 示例验证、来源证明或补证材料;MoonFolio 不生成来源证明,不处理报名审核材料。
    • JQ-ai-nb/robopolicy、moon-robots:面向 robots.txt 解析和访问决策;MoonFolio 不解析 robots.txt。
    • SHX-ai-nb/capsuletrace-upload:面向能力边界和验收轨迹;MoonFolio 不记录能力调用轨迹,不做验收流程校验。
    • Markdown parser/SSG 类项目:MoonFolio 不解析 Markdown AST、不渲染 HTML、不生成站点。

    #解决的问题

    Markdown 内容通常散落在文档仓库中,标题、标签、草稿状态、权重、slug 等字段容易缺失或类型不一致。MoonFolio 提供一个纯 MoonBit 的轻量编目层,让工具作者可以:

    • 读取 YAML/TOML/JSON 风格 front matter;
    • 声明字段契约,例如 title 必须为文本、tags 必须为列表;
    • 配置内容画像,例如草稿是否允许、标签 taxonomy、日期范围、permalink 前缀;
    • 建立 registry,对多篇文档做筛选、统计、重复 slug/fingerprint 检查;
    • 比较两次 registry/manifest,发现新增、删除、变更和重命名;
    • 用编辑器 API 补 slug/permalink/fingerprint,规范字段顺序;
    • 为每篇文档生成稳定 slug、permalink 和 fingerprint;
    • 输出 Markdown/JSON-ish 报告和 line-based manifest,便于 CI、缓存、资源索引和增量构建使用。

    #适用场景

    • 文档站或静态站点的内容入库检查;
    • MoonBit/Wasm 应用内置 Markdown 资源索引;
    • 教程、博客、包文档的字段规范校验;
    • 资源管线中的内容 fingerprint、manifest 和 release diff;
    • 内容仓库的批量质量报告;
    • 不需要完整 Markdown 渲染、只需要元数据编目的工具。

    #安装方式

    moon add JM-ai-n/moonfolio

    当前包名:

    JM-ai-n/moonfolio

    当前 moon.mod 配置为 JM-ai-n/moonfolio。正式发布时,Mooncakes 登录用户必须与包名 owner 一致;如果最终参赛账号不同,需要同步修改包名 owner 和 repository 为实际公开仓库。

    #最小使用示例

    let input =
    #|---
    #|title: MoonFolio demo
    #|draft: false
    #|tags: [moonbit, docs]
    #|---
    #|# Hello

    let output = @moonfolio.parse(input)
    let report = @moonfolio.validate_contract(output.document, [
    { key: "title", kind: @moonfolio.TextType, required: true },
    { key: "draft", kind: @moonfolio.BoolType, required: true },
    { key: "tags", kind: @moonfolio.ListType, required: true },
    ])
    let folio = @moonfolio.build_folio(output.document, "/docs")
    let profile = @moonfolio.profile_with_allowed_tags(
    @moonfolio.profile_with_permalink_prefix(
    @moonfolio.default_content_profile(),
    "/docs",
    ),
    ["moonbit", "docs"],
    )
    let profile_report = @moonfolio.evaluate_profile(output.document, profile)

    println(report.ok.to_string())
    println(profile_report.score.to_string())
    println(folio.manifest_line)

    #本地运行

    moon check moon check --deny-warn moon build moon test --deny-warn moon run cmd/main moon run examples/basic moon publish --dry-run

    #API 与核心功能

    • parse(input):解析 Markdown 元数据块;
    • parse_with_required(input, required):解析并检查必填字段;
    • validate_contract(document, rules):按字段契约检查必填性和类型;
    • default_content_profile/strict_content_profile:创建内容画像;
    • evaluate_profile(document, profile):检查标签、草稿、日期、permalink 等发布规则;
    • build_folio(document, base_path):生成 title、slug、permalink、fingerprint 和 manifest line;
    • folio_manifest(documents, base_path):为多篇文档生成 line-based manifest;
    • registry_from_sources/registry_summary/registry_filter:建立和查询 folio registry;
    • diff_registries/diff_manifests:比较两次内容清单;
    • apply_metadata_edit/canonicalize_document:安全编辑和规范化元数据;
    • registry_report_markdown/registry_report_json:输出 CI 可读报告;
    • slugify(text):生成稳定 ASCII slug;
    • fingerprint_document(document):生成稳定 8 位内容 fingerprint;
    • strip_front_matter(input):返回正文;
    • get_text/get_bool/get_int/get_list:类型化读取字段;
    • to_yaml/to_toml/to_json_front_matter:导出规范化元数据。

    #支持范围

    • YAML 风格边界:---;
    • TOML 风格边界:+++;
    • JSON 风格边界:;;;;
    • 字符串、布尔值、整数、字符串数组;
    • 字段契约与类型校验;
    • 内容画像:必填字段、禁用字段、标签 taxonomy、草稿状态、日期范围、permalink 前缀;
    • 多文档 registry:查找、筛选、排序、统计、重复值检测;
    • registry/manifest diff:新增、删除、变更、重命名;
    • 元数据编辑器:增删改字段、列表项编辑、slug/permalink/fingerprint 补全、字段顺序规范化;
    • Markdown 与 JSON-ish 报告导出;
    • 稳定 slug/permalink;
    • 文档 fingerprint;
    • manifest line;
    • 重复 key、非法 key、缺少结束边界、缺少契约字段等诊断;
    • YAML/TOML 规范化导出。

    #暂不支持范围

    • 完整 Markdown AST 或 HTML 渲染;
    • 完整 YAML/TOML/JSON 语法;
    • 多行字符串、嵌套对象和数组对象;
    • 直接文件系统扫描;
    • 加密级哈希;
    • 自动推断日期、浮点数或时间类型。

    这些边界保证 MoonFolio 是一个聚焦、可复现、可维护的 MoonBit 基础库,而不是和现有 Markdown/SSG 项目重复。

    #测试与验收

    当前 MoonBit 源码规模超过 4k 行。测试覆盖正常输入、错误输入、无元数据输入、边界情况、数据结构转换、导出结果、字段契约、内容画像、registry、diff、编辑器、报告导出、内容卷宗、manifest 和示例 smoke test。

    moon check --deny-warn moon build moon test --deny-warn moon run cmd/main moon run examples/basic moon package

    #Mooncakes

    • 包名:JM-ai-n/moonfolio
    • 文档地址:https://mooncakes.io/docs/JM-ai-n/moonfolio
    • Manifest:https://mooncakes.io/api/v0/manifest/JM-ai-n/moonfolio

    发布流程:

    moon login moon publish --dry-run moon publish

    正式发布前需要确认 GitHub 公开仓库已创建、当前代码已推送,并使用与 JM-ai-n/moonfolio owner 一致的 Mooncakes 账号执行 moon publish --dry-run 与 moon publish。

    #开源许可证与第三方说明

    本项目使用 MIT License。核心代码为原创 MoonBit 实现,不移植第三方源码,不包含图片、音频、字体或来源不明测试数据。

    ContentFolio

    pub(all) struct ContentFolio {
    title : String
    slug : String
    permalink : String
    fingerprint : String
    format : MatterFormat
    manifest_line : String
    } derive(Eq,
    Debug
    )

    ContentProfile

    pub(all) struct ContentProfile {
    required_fields : Array[String]
    forbidden_fields : Array[String]
    title_key : String
    max_title_length : Int
    summary_key : String
    require_summary : Bool
    max_summary_length : Int
    draft_key : String
    allow_draft : Bool
    require_approval_for_draft : Bool
    approval_key : String
    tag_key : String
    allowed_tags : Array[String]
    required_tags : Array[String]
    max_tags : Int
    permalink_key : String
    require_permalink : Bool
    permalink_prefix : String
    date_key : String
    require_date : Bool
    min_year : Int
    max_year : Int
    } derive(Eq,
    Debug
    )

    ContractReport

    pub(all) struct ContractReport {
    ok : Bool
    checked : Array[String]
    diagnostics : Array[Diagnostic]
    } derive(Eq,
    Debug
    )

    Diagnostic

    pub(all) struct Diagnostic {
    severity : Severity
    line : Int
    code : String
    message : String
    } derive(Eq,
    Debug
    )

    DiffReport

    pub(all) struct DiffReport {
    has_changes : Bool
    added : Int
    removed : Int
    changed : Int
    renamed : Int
    unchanged : Int
    changes : Array[FolioChange]
    } derive(Eq,
    Debug
    )

    Document

    pub(all) struct Document {
    format : MatterFormat
    fields : Map[String, MetaValue]
    order : Array[String]
    raw : String
    body : String
    start_line : Int
    end_line : Int
    } derive(Eq,
    Debug
    )

    DocumentSource

    pub(all) struct DocumentSource {
    path : String
    text : String
    } derive(Eq,
    Debug
    )

    DuplicateValue

    pub(all) struct DuplicateValue {
    value : String
    paths : Array[String]
    } derive(Eq,
    Debug
    )

    EditAction

    pub(all) enum EditAction {
    SetMeta
    RemoveMeta
    RenameMeta
    AppendListItem
    RemoveListItem
    NormalizeOrder
    EnsureSlug
    EnsurePermalink
    EnsureFingerprint
    } derive(Eq,
    Debug
    )

    EditPreview

    pub(all) struct EditPreview {
    changed : Bool
    before_fingerprint : String
    after_fingerprint : String
    before_yaml : String
    after_yaml : String
    document : Document
    } derive(Eq,
    Debug
    )

    FieldRule

    pub(all) struct FieldRule {
    key : String
    kind : FieldType
    required : Bool
    } derive(Eq,
    Debug
    )

    FieldType

    pub(all) enum FieldType {
    Any
    TextType
    BoolType
    IntType
    ListType
    } derive(Eq,
    Debug
    )

    FolioChange

    pub(all) struct FolioChange {
    kind : FolioChangeKind
    before_path : String
    after_path : String
    slug : String
    before_fingerprint : String
    after_fingerprint : String
    title : String
    message : String
    } derive(Eq,
    Debug
    )

    FolioChangeKind

    pub(all) enum FolioChangeKind {
    Added
    Removed
    Changed
    Renamed
    Unchanged
    } derive(Eq,
    Debug
    )

    FolioRecord

    pub(all) struct FolioRecord {
    path : String
    document : Document
    folio : ContentFolio
    diagnostics : Array[Diagnostic]
    labels : Array[String]
    } derive(Eq,
    Debug
    )

    FolioRegistry

    pub(all) struct FolioRegistry {
    base_path : String
    records : Array[FolioRecord]
    } derive(Eq,
    Debug
    )

    FolioSnapshot

    pub(all) struct FolioSnapshot {
    items : Array[FolioSnapshotItem]
    } derive(Eq,
    Debug
    )

    FolioSnapshotItem

    pub(all) struct FolioSnapshotItem {
    path : String
    slug : String
    fingerprint : String
    title : String
    permalink : String
    format : MatterFormat
    } derive(Eq,
    Debug
    )

    FormatBucket

    pub(all) struct FormatBucket {
    format : MatterFormat
    records : Array[FolioRecord]
    } derive(Eq,
    Debug
    )

    FormatCount

    pub(all) struct FormatCount {
    format : MatterFormat
    count : Int
    } derive(Eq,
    Debug
    )

    MatterFormat

    pub(all) enum MatterFormat {
    None
    Yaml
    Toml
    Json
    } derive(Eq,
    Debug
    )

    MetaValue

    pub(all) enum MetaValue {
    Text(String)
    Bool(Bool)
    Int(Int)
    List(Array[String])
    } derive(Eq,
    Debug
    )

    MetadataEdit

    pub(all) struct MetadataEdit {
    action : EditAction
    key : String
    new_key : String
    value : MetaValue
    list_item : String
    preferred_order : Array[String]
    base_path : String
    } derive(Eq,
    Debug
    )

    ParseOutput

    pub(all) struct ParseOutput {
    document : Document
    diagnostics : Array[Diagnostic]
    } derive(Eq,
    Debug
    )

    ProfileFinding

    pub(all) struct ProfileFinding {
    kind : ProfileFindingKind
    key : String
    value : String
    message : String
    severity : Severity
    } derive(Eq,
    Debug
    )

    ProfileFindingKind

    pub(all) enum ProfileFindingKind {
    MissingRequired
    ForbiddenField
    BlankText
    TextTooLong
    TagNotAllowed
    TagRequired
    TooManyTags
    DraftBlocked
    DraftNeedsApproval
    PermalinkMissing
    PermalinkPrefixMismatch
    DateMissing
    DateInvalid
    DateOutOfRange
    } derive(Eq,
    Debug
    )

    ProfileReport

    pub(all) struct ProfileReport {
    ok : Bool
    score : Int
    checked : Array[String]
    findings : Array[ProfileFinding]
    diagnostics : Array[Diagnostic]
    suggestions : Array[String]
    } derive(Eq,
    Debug
    )

    RegistryFilter

    pub(all) struct RegistryFilter {
    tag : String
    path_prefix : String
    use_format : Bool
    format : MatterFormat
    use_draft : Bool
    draft : Bool
    valid_only : Bool
    } derive(Eq,
    Debug
    )

    RegistrySummary

    pub(all) struct RegistrySummary {
    total : Int
    valid : Int
    invalid : Int
    errors : Int
    warnings : Int
    drafts : Int
    published : Int
    unique_slugs : Int
    unique_fingerprints : Int
    duplicate_slugs : Array[DuplicateValue]
    duplicate_fingerprints : Array[DuplicateValue]
    formats : Array[FormatCount]
    tags : Array[TagCount]
    health_score : Int
    } derive(Eq,
    Debug
    )

    ReportOptions

    pub(all) struct ReportOptions {
    include_manifest : Bool
    include_diagnostics : Bool
    include_suggestions : Bool
    include_unchanged_diff : Bool
    max_items : Int
    } derive(Eq,
    Debug
    )

    Severity

    pub(all) enum Severity {
    Warning
    Error
    } derive(Eq,
    Debug
    )

    TagBucket

    pub(all) struct TagBucket {
    tag : String
    records : Array[FolioRecord]
    } derive(Eq,
    Debug
    )

    TagCount

    pub(all) struct TagCount {
    tag : String
    count : Int
    } derive(Eq,
    Debug
    )

    ValidationReport

    pub(all) struct ValidationReport {
    ok : Bool
    missing : Array[String]
    present : Array[String]
    diagnostics : Array[Diagnostic]
    } derive(Eq,
    Debug
    )

    append_unique_string

    fn append_unique_string(values : Array[String], value : String) -> Array[String]

    apply_metadata_edit

    fn apply_metadata_edit(doc : Document, edit : MetadataEdit) -> Document

    apply_metadata_edits

    fn apply_metadata_edits(doc : Document, edits : Array[MetadataEdit]) -> Document

    build_folio

    fn build_folio(doc : Document, base_path : String) -> ContentFolio

    canonical_yaml

    fn canonical_yaml(doc : Document) -> String

    canonicalize_document

    fn canonicalize_document(doc : Document) -> Document

    compact_report_options

    fn compact_report_options() -> ReportOptions

    contains_string

    fn contains_string(values : Array[String], value : String) -> Bool

    copy_strings

    fn copy_strings(values : Array[String]) -> Array[String]

    count_error_diagnostics

    fn count_error_diagnostics(diagnostics : Array[Diagnostic]) -> Int

    count_error_findings

    fn count_error_findings(findings : Array[ProfileFinding]) -> Int

    count_warning_diagnostics

    fn count_warning_diagnostics(diagnostics : Array[Diagnostic]) -> Int

    count_warning_findings

    fn count_warning_findings(findings : Array[ProfileFinding]) -> Int

    dedupe_strings

    fn dedupe_strings(values : Array[String]) -> Array[String]

    default_content_profile

    fn default_content_profile() -> ContentProfile

    default_report_options

    fn default_report_options() -> ReportOptions

    diagnostic_severity_name

    fn diagnostic_severity_name(severity : Severity) -> String

    diagnostic_to_markdown

    fn diagnostic_to_markdown(diagnostic : Diagnostic) -> String

    diagnostics_have_errors

    fn diagnostics_have_errors(diagnostics : Array[Diagnostic]) -> Bool

    diagnostics_to_markdown

    fn diagnostics_to_markdown(diagnostics : Array[Diagnostic]) -> String

    diff_added

    fn diff_added(report : DiffReport) -> Array[FolioChange]

    diff_change_kind_name

    fn diff_change_kind_name(kind : FolioChangeKind) -> String

    diff_change_lines

    fn diff_change_lines(report : DiffReport) -> Array[String]

    diff_changed

    fn diff_changed(report : DiffReport) -> Array[FolioChange]

    diff_is_release_safe

    fn diff_is_release_safe(report : DiffReport) -> Bool

    diff_manifests

    fn diff_manifests(before : String, after : String) -> DiffReport

    diff_paths

    fn diff_paths(report : DiffReport) -> Array[String]

    diff_registries

    fn diff_registries(before : FolioRegistry, after : FolioRegistry) -> DiffReport

    diff_removed

    fn diff_removed(report : DiffReport) -> Array[FolioChange]

    diff_renamed

    fn diff_renamed(report : DiffReport) -> Array[FolioChange]

    diff_report_json

    fn diff_report_json(report : DiffReport) -> String

    diff_report_markdown

    fn diff_report_markdown(report : DiffReport, options : ReportOptions) -> String

    diff_snapshots

    fn diff_snapshots(before : FolioSnapshot, after : FolioSnapshot) -> DiffReport

    diff_summary_line

    fn diff_summary_line(report : DiffReport) -> String

    diff_unchanged

    fn diff_unchanged(report : DiffReport) -> Array[FolioChange]

    difference_strings

    fn difference_strings(left : Array[String], right : Array[String]) -> Array[String]

    document_append_list_item

    fn document_append_list_item(doc : Document, key : String, item : String) -> Document

    document_ensure_fingerprint

    fn document_ensure_fingerprint(doc : Document) -> Document

    fn document_ensure_permalink(doc : Document, base_path : String) -> Document

    document_ensure_slug

    fn document_ensure_slug(doc : Document) -> Document

    document_field_count

    fn document_field_count(doc : Document) -> Int

    document_has_blank_text

    fn document_has_blank_text(doc : Document, key : String) -> Bool

    document_metadata_line_count

    fn document_metadata_line_count(doc : Document) -> Int

    document_missing_fields

    fn document_missing_fields(doc : Document, keys : Array[String]) -> Array[String]

    document_normalize_order

    fn document_normalize_order(doc : Document, preferred_order : Array[String]) -> Document

    document_present_fields

    fn document_present_fields(doc : Document, keys : Array[String]) -> Array[String]

    document_remove_field

    fn document_remove_field(doc : Document, key : String) -> Document

    document_remove_list_item

    fn document_remove_list_item(doc : Document, key : String, item : String) -> Document

    document_rename_field

    fn document_rename_field(doc : Document, key : String, new_key : String) -> Document

    document_report_json

    fn document_report_json(output : ParseOutput) -> String

    document_report_markdown

    fn document_report_markdown(output : ParseOutput) -> String

    document_set_bool

    fn document_set_bool(doc : Document, key : String, value : Bool) -> Document

    document_set_field

    fn document_set_field(doc : Document, key : String, value : MetaValue) -> Document

    document_set_int

    fn document_set_int(doc : Document, key : String, value : Int) -> Document

    document_set_list

    fn document_set_list(doc : Document, key : String, values : Array[String]) -> Document

    document_set_text

    fn document_set_text(doc : Document, key : String, value : String) -> Document

    document_sort_fields

    fn document_sort_fields(doc : Document) -> Document

    document_with_format

    fn document_with_format(doc : Document, format : MatterFormat) -> Document

    edit_action_name

    fn edit_action_name(action : EditAction) -> String

    edit_plan_summary

    fn edit_plan_summary(edits : Array[MetadataEdit]) -> String

    evaluate_profile

    fn evaluate_profile(doc : Document, profile : ContentProfile) -> ProfileReport

    fingerprint_document

    fn fingerprint_document(doc : Document) -> String

    folio_manifest

    fn folio_manifest(docs : Array[Document], base_path : String) -> String

    format_name

    fn format_name(format : MatterFormat) -> String

    get_bool

    fn get_bool(doc : Document, key : String) -> Bool?

    get_int

    fn get_int(doc : Document, key : String) -> Int?

    get_list

    fn get_list(doc : Document, key : String) -> Array[String]?

    get_text

    fn get_text(doc : Document, key : String) -> String?

    get_value

    fn get_value(doc : Document, key : String) -> MetaValue?

    has_field

    fn has_field(doc : Document, key : String) -> Bool

    intersect_strings

    fn intersect_strings(left : Array[String], right : Array[String]) -> Array[String]

    is_valid

    fn is_valid(output : ParseOutput) -> Bool

    join_backticked

    fn join_backticked(values : Array[String]) -> String

    meta_value_display

    fn meta_value_display(value : MetaValue) -> String

    metadata_append_list_item

    fn metadata_append_list_item(key : String, item : String) -> MetadataEdit

    metadata_ensure_fingerprint

    fn metadata_ensure_fingerprint() -> MetadataEdit

    fn metadata_ensure_permalink(base_path : String) -> MetadataEdit

    metadata_ensure_slug

    fn metadata_ensure_slug() -> MetadataEdit

    metadata_normalize_order

    fn metadata_normalize_order(order : Array[String]) -> MetadataEdit

    metadata_remove

    fn metadata_remove(key : String) -> MetadataEdit

    metadata_remove_list_item

    fn metadata_remove_list_item(key : String, item : String) -> MetadataEdit

    metadata_rename

    fn metadata_rename(key : String, new_key : String) -> MetadataEdit

    metadata_set_bool

    fn metadata_set_bool(key : String, value : Bool) -> MetadataEdit

    metadata_set_int

    fn metadata_set_int(key : String, value : Int) -> MetadataEdit

    metadata_set_list

    fn metadata_set_list(key : String, values : Array[String]) -> MetadataEdit

    metadata_set_text

    fn metadata_set_text(key : String, value : String) -> MetadataEdit

    normalize_tag

    fn normalize_tag(tag : String) -> String

    normalize_tags

    fn normalize_tags(tags : Array[String]) -> Array[String]

    parse

    fn parse(input : String) -> ParseOutput

    parse_with_required

    fn parse_with_required(input : String, required : Array[String]) -> ParseOutput

    preview_metadata_edit

    fn preview_metadata_edit(doc : Document, edit : MetadataEdit) -> EditPreview

    preview_metadata_edits

    fn preview_metadata_edits(doc : Document, edits : Array[MetadataEdit]) -> EditPreview

    profile_contract_rules

    fn profile_contract_rules(profile : ContentProfile) -> Array[FieldRule]

    profile_findings_to_diagnostics

    fn profile_findings_to_diagnostics(findings : Array[ProfileFinding], line : Int) -> Array[Diagnostic]

    profile_kind_code

    fn profile_kind_code(kind : ProfileFindingKind) -> String

    profile_ok

    fn profile_ok(doc : Document, profile : ContentProfile) -> Bool

    profile_report_json

    fn profile_report_json(report : ProfileReport) -> String

    profile_report_markdown

    fn profile_report_markdown(report : ProfileReport) -> String

    profile_score

    fn profile_score(findings : Array[ProfileFinding], checked_count : Int) -> Int

    profile_suggestions

    fn profile_suggestions(findings : Array[ProfileFinding]) -> Array[String]

    profile_with_allowed_tags

    fn profile_with_allowed_tags(profile : ContentProfile, tags : Array[String]) -> ContentProfile

    profile_with_date_range

    fn profile_with_date_range(profile : ContentProfile, min_year : Int, max_year : Int) -> ContentProfile

    fn profile_with_permalink_prefix(profile : ContentProfile, prefix : String) -> ContentProfile

    profile_with_required_field

    fn profile_with_required_field(profile : ContentProfile, key : String) -> ContentProfile

    profile_with_required_tags

    fn profile_with_required_tags(profile : ContentProfile, tags : Array[String]) -> ContentProfile

    profile_without_drafts

    fn profile_without_drafts(profile : ContentProfile) -> ContentProfile

    record_from_document

    fn record_from_document(path : String, doc : Document, diagnostics : Array[Diagnostic], base_path : String) -> FolioRecord

    record_from_parse_output

    fn record_from_parse_output(path : String, output : ParseOutput, base_path : String) -> FolioRecord

    record_from_source

    fn record_from_source(source : DocumentSource, base_path : String, required : Array[String]) -> FolioRecord

    record_has_errors

    fn record_has_errors(record : FolioRecord) -> Bool

    record_has_warnings

    fn record_has_warnings(record : FolioRecord) -> Bool

    record_is_draft

    fn record_is_draft(record : FolioRecord) -> Bool

    record_label_line

    fn record_label_line(record : FolioRecord) -> String

    record_report_markdown

    fn record_report_markdown(record : FolioRecord) -> String

    record_stable_id

    fn record_stable_id(record : FolioRecord) -> String

    record_status

    fn record_status(record : FolioRecord) -> String

    registry_add_record

    fn registry_add_record(registry : FolioRegistry, record : FolioRecord) -> FolioRegistry

    registry_add_source

    fn registry_add_source(registry : FolioRegistry, source : DocumentSource, required : Array[String]) -> FolioRegistry

    registry_by_format

    fn registry_by_format(registry : FolioRegistry, format : MatterFormat) -> FolioRegistry

    registry_by_path_prefix

    fn registry_by_path_prefix(registry : FolioRegistry, prefix : String) -> FolioRegistry

    registry_by_tag

    fn registry_by_tag(registry : FolioRegistry, tag : String) -> FolioRegistry

    registry_contains_path

    fn registry_contains_path(registry : FolioRegistry, path : String) -> Bool

    registry_drafts

    fn registry_drafts(registry : FolioRegistry) -> FolioRegistry

    registry_duplicate_fingerprints

    fn registry_duplicate_fingerprints(registry : FolioRegistry) -> Array[DuplicateValue]

    registry_duplicate_slugs

    fn registry_duplicate_slugs(registry : FolioRegistry) -> Array[DuplicateValue]

    registry_empty

    fn registry_empty(base_path : String) -> FolioRegistry

    registry_filter

    fn registry_filter(registry : FolioRegistry, filter : RegistryFilter) -> FolioRegistry

    registry_filter_all

    fn registry_filter_all() -> RegistryFilter

    registry_find_by_fingerprint

    fn registry_find_by_fingerprint(registry : FolioRegistry, fingerprint : String) -> FolioRecord?

    registry_find_by_path

    fn registry_find_by_path(registry : FolioRegistry, path : String) -> FolioRecord?

    fn registry_find_by_permalink(registry : FolioRegistry, permalink : String) -> FolioRecord?

    registry_find_by_slug

    fn registry_find_by_slug(registry : FolioRegistry, slug : String) -> FolioRecord?

    registry_format_counts

    fn registry_format_counts(registry : FolioRegistry) -> Array[FormatCount]

    registry_from_documents

    fn registry_from_documents(docs : Array[Document], base_path : String) -> FolioRegistry

    registry_from_sources

    fn registry_from_sources(sources : Array[DocumentSource], base_path : String, required : Array[String]) -> FolioRegistry

    registry_group_by_format

    fn registry_group_by_format(registry : FolioRegistry) -> Array[FormatBucket]

    registry_group_by_tag

    fn registry_group_by_tag(registry : FolioRegistry) -> Array[TagBucket]

    registry_health_score

    fn registry_health_score(registry : FolioRegistry) -> Int

    registry_invalid

    fn registry_invalid(registry : FolioRegistry) -> FolioRegistry

    registry_manifest

    fn registry_manifest(registry : FolioRegistry) -> String

    registry_manifest_sorted

    fn registry_manifest_sorted(registry : FolioRegistry) -> String

    registry_merge

    fn registry_merge(left : FolioRegistry, right : FolioRegistry) -> FolioRegistry

    registry_paths

    fn registry_paths(registry : FolioRegistry) -> Array[String]

    fn registry_permalinks(registry : FolioRegistry) -> Array[String]

    registry_published

    fn registry_published(registry : FolioRegistry) -> FolioRegistry

    registry_rebase

    fn registry_rebase(registry : FolioRegistry, base_path : String) -> FolioRegistry

    registry_remove_path

    fn registry_remove_path(registry : FolioRegistry, path : String) -> FolioRegistry

    registry_replace_record

    fn registry_replace_record(registry : FolioRegistry, record : FolioRecord) -> FolioRegistry

    registry_report_json

    fn registry_report_json(registry : FolioRegistry) -> String

    registry_report_markdown

    fn registry_report_markdown(registry : FolioRegistry, options : ReportOptions) -> String

    registry_slugs

    fn registry_slugs(registry : FolioRegistry) -> Array[String]

    registry_sort_by_path

    fn registry_sort_by_path(registry : FolioRegistry) -> FolioRegistry

    registry_sort_by_slug

    fn registry_sort_by_slug(registry : FolioRegistry) -> FolioRegistry

    registry_sort_by_title

    fn registry_sort_by_title(registry : FolioRegistry) -> FolioRegistry

    registry_stable_ids

    fn registry_stable_ids(registry : FolioRegistry) -> Array[String]

    registry_summary

    fn registry_summary(registry : FolioRegistry) -> RegistrySummary

    registry_table

    fn registry_table(registry : FolioRegistry) -> String

    registry_tag_counts

    fn registry_tag_counts(registry : FolioRegistry) -> Array[TagCount]

    registry_titles

    fn registry_titles(registry : FolioRegistry) -> Array[String]

    registry_unique_fingerprints

    fn registry_unique_fingerprints(registry : FolioRegistry) -> Array[String]

    registry_unique_slugs

    fn registry_unique_slugs(registry : FolioRegistry) -> Array[String]

    registry_unique_tags

    fn registry_unique_tags(registry : FolioRegistry) -> Array[String]

    registry_valid

    fn registry_valid(registry : FolioRegistry) -> FolioRegistry

    registry_with_warnings

    fn registry_with_warnings(registry : FolioRegistry) -> FolioRegistry

    render_document

    fn render_document(doc : Document, format : MatterFormat) -> String

    slugify

    fn slugify(text : String) -> String

    snapshot_find_by_fingerprint

    fn snapshot_find_by_fingerprint(snapshot : FolioSnapshot, fingerprint : String) -> FolioSnapshotItem?

    snapshot_find_by_path

    fn snapshot_find_by_path(snapshot : FolioSnapshot, path : String) -> FolioSnapshotItem?

    snapshot_find_by_slug

    fn snapshot_find_by_slug(snapshot : FolioSnapshot, slug : String) -> FolioSnapshotItem?

    snapshot_fingerprints

    fn snapshot_fingerprints(snapshot : FolioSnapshot) -> Array[String]

    snapshot_from_manifest

    fn snapshot_from_manifest(manifest : String) -> FolioSnapshot

    snapshot_from_registry

    fn snapshot_from_registry(registry : FolioRegistry) -> FolioSnapshot

    snapshot_item_from_manifest_line

    fn snapshot_item_from_manifest_line(line : String) -> FolioSnapshotItem?

    snapshot_item_from_record

    fn snapshot_item_from_record(record : FolioRecord) -> FolioSnapshotItem

    snapshot_manifest

    fn snapshot_manifest(snapshot : FolioSnapshot) -> String

    snapshot_paths

    fn snapshot_paths(snapshot : FolioSnapshot) -> Array[String]

    snapshot_slugs

    fn snapshot_slugs(snapshot : FolioSnapshot) -> Array[String]

    snapshot_sorted

    fn snapshot_sorted(snapshot : FolioSnapshot) -> FolioSnapshot

    snapshot_without_unchanged

    fn snapshot_without_unchanged(report : DiffReport) -> DiffReport

    sorted_strings

    fn sorted_strings(values : Array[String]) -> Array[String]

    strict_content_profile

    fn strict_content_profile() -> ContentProfile

    strip_front_matter

    fn strip_front_matter(input : String) -> String

    summary

    fn summary(output : ParseOutput) -> String

    to_json_front_matter

    fn to_json_front_matter(doc : Document) -> String

    to_toml

    fn to_toml(doc : Document) -> String

    to_yaml

    fn to_yaml(doc : Document) -> String

    validate_contract

    fn validate_contract(doc : Document, rules : Array[FieldRule]) -> ContractReport

    validate_required

    fn validate_required(doc : Document, required : Array[String]) -> ValidationReport