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

Uploaded Python 3

File details

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

File metadata

  • Download URL: refkit-0.0.4rc3.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.4rc3.tar.gz
Algorithm Hash digest
SHA256 93aa5fdb3001172e1d116da27413e76df03d3ca59d25dfee36305f2f9b8b9b10
MD5 b343eded1dc19089cf44957be00ed529
BLAKE2b-256 6e7c6015c53233d955de069186dd4a5cd4cca890b62b4260972ced8c0328ae8f

See more details on using hashes here.

File details

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

File metadata

  • Download URL: refkit-0.0.4rc3-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.4rc3-py3-none-any.whl
Algorithm Hash digest
SHA256 59b562595f979e63f929fbecf9eba1e798de33e7f37c86878a192d29fda064e7
MD5 2fb303037669245ec7dcac998c2407ca
BLAKE2b-256 29784794939519b2a0fdb0f33965a461a1142f4d7930d5eb55affde7427cdb82

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