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.4rc2.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.4rc2-py3-none-any.whl (10.7 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: refkit-0.0.4rc2.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.4rc2.tar.gz
Algorithm Hash digest
SHA256 ff5f0335abcbc6af00f9c9b7b01e59ceed7c21abff726709bd53118540c9cf45
MD5 ec0ce585191a8157b635939241672a89
BLAKE2b-256 5e056573761fa7877040c95b072f047a28234f0e807c61aa400bbeaa66966d7d

See more details on using hashes here.

File details

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

File metadata

  • Download URL: refkit-0.0.4rc2-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.4rc2-py3-none-any.whl
Algorithm Hash digest
SHA256 a9fd470046051b8f1e51cdb5af6eb857a007712a715f1e7426db1518af5600fa
MD5 0ca83d2ea6c0f4be1092fdf12de3ec5d
BLAKE2b-256 8613a7a0b3f0d4760f85bbc840187243592e0a6bebc0ffaf0b5691f538ee2f80

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