Skip to main content

Fast Python citation parsing, rendering, and BibTeX editing backed by Rust

Project description

refkit

refkit reads BibTeX, BibLaTeX, and Hayagriva YAML, renders CSL citations, formats BibTeX, and edits raw BibTeX documents from Python.

Install

pip install refkit

refkit is pure Python and depends on the exact matching refkit-core release. refkit-core contains the Rust/PyO3 extension as refkit_core._refkit_core, including PyEmscripten wheels for Pyodide.

The supported Python versions and native wheel ABI are declared in package metadata and release workflows.

Render A Citation

import refkit as rk

library = rk.Library.parse_bibtex(
    """
@article{doe2024,
  author = {Doe, Jane},
  title = {Fast Citations},
  journal = {Journal of Citation Tests},
  year = {2024}
}
@book{roe2022,
  author = {Roe, Richard},
  title = {Batch References},
  publisher = {Example Press},
  year = {2022}
}
"""
)
style = rk.Style.load("apa")
doc = rk.Document(library, style, locale="en-US")

rendered = doc.render(
    [
        rk.Citation("intro", "doe2024"),
        rk.Citation(
            "detail",
            rk.CitationGroup([rk.Cite("doe2024", locator="12", label="page"), "roe2022"]),
        ),
    ]
)

print(rendered["intro"].text)
print(rendered["detail"].text)
print(rendered.bibliography.text)

Expected output:

(Doe, 2024)
(Doe, 2024, p. 12; Roe, 2022)
Doe, J. (2024). Fast Citations. Journal of Citation Tests.
Roe, R. (2022). Batch References. Example Press.

Document.render renders the whole citation document at once. It returns RenderedDocument, where rendered["intro"] and rendered["detail"] are named citation outputs and rendered.bibliography is the cited bibliography for those citations. Cite names one citation item. CitationGroup renders several items as one citation. Citation(id, group) gives that rendered citation a stable lookup name. Citation ids must be unique inside one Document.render call.

For one-off scripts, pass a bibliography path directly:

rk.cite("refs.bib", "doe2024", style="ieee").text
rk.full_bibliography("refs.bib", style="chicago-author-date").html

Use Library.parse_bibtex, Library.parse_yaml, and Document when the bibliography source is already in memory or when several citations share the same library and style.

Format BibTeX

tidy_bibtex formats BibTeX text and returns TidyResult with the formatted source, warnings, and entry count.

import refkit as rk

result = rk.tidy_bibtex(
    """
@ARTICLE {doe2024,
  pages={6-13},
  year={2024},}
"""
)

print(result.bibtex)
print(result.count)

Use TidyOptions for formatting choices:

options = rk.TidyOptions(sort_fields=True, wrap=88)
result = rk.tidy_bibtex(source, options=options)

Warnings are structured objects:

for warning in result.warnings:
    print(warning.code, warning.rule, warning.message)

Raw edit flows can render the current document state before formatting:

raw = rk.BibDocument.read("refs.bib")
raw.entries["doe2024"].fields["title"].value = "Corrected title"
result = raw.tidy(options=rk.TidyOptions(sort_fields=True))

Use tidy_file when the input is on disk. It writes a file when output is supplied.

rk.tidy_file("refs.bib", output="refs.tidy.bib")

Capabilities

Capability Python surface
Read normalized bibliography data Library.read, Library.parse_bibtex, Library.parse_yaml
Render citations Document.render, Citation, Cite, CitationGroup, cite
Render bibliographies Document.cited_bibliography, Document.full_bibliography, full_bibliography
Load styles and locales Style.load, Style.from_path, Style.from_xml, Locale.load
Inspect entries mapping access, keys, get, get_many, select, project, to_dicts
Format BibTeX tidy_bibtex, tidy_file, TidyOptions, TidyResult
Edit raw BibTeX BibDocument.read, BibDocument.parse, field assignment, write
Inspect rendered output Rendered.text, Rendered.html, Rendered.tree

Input Formats

API Input Result
Library.read(path) .bib Normalized citation library from BibTeX or BibLaTeX.
Library.read(path) .yaml, .yml Normalized citation library from Hayagriva YAML.
Library.parse_bibtex(source) BibTeX or BibLaTeX string Normalized citation library.
Library.parse_yaml(source) Hayagriva YAML string Normalized citation library.
BibDocument.read(path) .bib Raw document model with comments, preambles, strings, failed blocks, order, spans, and editable fields.
Style.load(name) Bundled style name such as apa CSL style for rendering.
Style.from_path(path) Independent CSL XML file CSL style for rendering.
Style.from_xml(xml) Independent CSL XML string CSL style for rendering.
Locale.load(code) Bundled locale code such as en-US Locale object for rendering.

Hayagriva YAML is a mapping from citation keys to entry mappings:

doe2024:
  type: Article
  author: Doe, Jane
  title: Refkit for Bibliographies
  date: 2024
  parent:
    type: Periodical
    title: Journal of Citation Systems
    volume: 12
library = rk.Library.parse_yaml(
    """
doe2024:
  type: Article
  title: Refkit for Bibliographies
  date: 2024
"""
)

Inspect A Library

Library is the normalized citation database. Use it for rendering, selectors, mapping access, and bulk export.

library = rk.Library.read("refs.bib")

print(library.keys())
print(library.project(["key", "title", "doi", "volume"]))
print(library.to_dicts())

Library.select accepts Hayagriva selector strings:

for entry in library.select("article > periodical[volume]"):
    print(entry.key, entry.title, entry.parents[0].title)

Edit Raw BibTeX

BibDocument preserves raw .bib comments, preambles, string definitions, failed blocks, order, and source spans.

raw = rk.BibDocument.read("refs.bib")
raw.entries["doe2024"].fields["title"].value = "Corrected title"
raw.write("refs.bib")

Direct map lookup requires one matching entry key and one matching field name. unique_keys() returns one key per name. occurrence_keys() returns keys in source order, including duplicates. When a file contains duplicates, choose the source-order occurrence explicitly:

raw = rk.BibDocument.read("refs.bib")

second_entry = raw.entries.get_all("doe2024")[1]
second_entry.fields.get_all("title")[0].value = "Corrected title"
raw.write("refs.bib")

Inspect Rendered Output

Document.render, Document.cited_bibliography, Document.full_bibliography, cite, and full_bibliography return rendered values.

rendered = doc.render([rk.Citation("intro", "doe2024")])
citation = rendered["intro"]

print(citation.text)
print(citation.html)
print(citation.tree)

Rendered.tree returns structured nodes for text, links, element metadata, transparent citation fragments, and bibliography entries.

Use With Polars

Install polars-refkit when BibTeX source lives in a dataframe and the result should stay in a Polars query plan.

import polars as pl
import polars_refkit as prk

df = pl.DataFrame(
    {
        "bibtex": ["@article{doe2024, title={Fast Citations}, year={2024}}"],
        "key": ["doe2024"],
        "keys": [["doe2024"]],
    }
)

out = df.select(
    citation=pl.col("bibtex").refkit.cite(pl.col("key")),
    each_citation=pl.col("bibtex").refkit.cite_each(pl.col("keys")),
    grouped_citation=pl.col("bibtex").refkit.cite_group(pl.col("keys")),
    count=pl.col("bibtex").refkit.entry_count(),
    keys=pl.col("bibtex").refkit.keys(),
    entries=pl.col("bibtex").refkit.entries(),
)

Development

uv sync --locked --all-packages --group dev
(cd packages/refkit-core && uv run maturin develop)
uv run --locked --all-packages --group dev python -m pytest packages/refkit/tests --no-cov

Run every workspace gate from the repository root:

make check

License

refkit is licensed under the Apache License, Version 2.0, available in LICENSE. See NOTICE for upstream citation and bibliography component acknowledgements.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

refkit-0.0.4rc4.tar.gz (26.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

refkit-0.0.4rc4-py3-none-any.whl (10.7 kB view details)

Uploaded Python 3

File details

Details for the file refkit-0.0.4rc4.tar.gz.

File metadata

  • Download URL: refkit-0.0.4rc4.tar.gz
  • Upload date:
  • Size: 26.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for refkit-0.0.4rc4.tar.gz
Algorithm Hash digest
SHA256 4cb1dbb39af0635f68fc2dde8859bf8692cccf6af946da22a8760bcec7e8f246
MD5 54265f1a2884ba37f83a4cd47460195e
BLAKE2b-256 bfe57ce3979c8849de683ca782d1ea600ae5f90c09b4b9d9ec4e32aa5b66e7c1

See more details on using hashes here.

File details

Details for the file refkit-0.0.4rc4-py3-none-any.whl.

File metadata

  • Download URL: refkit-0.0.4rc4-py3-none-any.whl
  • Upload date:
  • Size: 10.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for refkit-0.0.4rc4-py3-none-any.whl
Algorithm Hash digest
SHA256 94666d1ac807c041e4d3fc4052c8e037b802886b7ba041fae4b5b9775e85360d
MD5 9a826c3d3e1777a1637aad6a202a1a00
BLAKE2b-256 e4af2f55f60f2495f120e2822486307e848472831ef1046f471523c6ef17d2a3

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page