refkit 0.0.4rc4__tar.gz → 0.0.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- refkit-0.0.5/.agent-plugin/plugin.json +13 -0
- refkit-0.0.5/.agent-plugin/skills/refkit/SKILL.md +45 -0
- refkit-0.0.5/.agent-plugin/skills/refkit/agents/openai.yaml +4 -0
- refkit-0.0.5/.agent-plugin/skills/refkit/references/contracts.md +61 -0
- refkit-0.0.5/.agent-plugin/skills/refkit/references/workflows.md +112 -0
- refkit-0.0.5/Cargo.lock +936 -0
- refkit-0.0.5/Cargo.toml +21 -0
- {refkit-0.0.4rc4 → refkit-0.0.5}/NOTICE +1 -0
- refkit-0.0.5/PKG-INFO +115 -0
- refkit-0.0.5/README.md +91 -0
- refkit-0.0.5/build_backend.py +21 -0
- refkit-0.0.5/crates/refkit-core/Cargo.toml +22 -0
- refkit-0.0.5/crates/refkit-core/src/document.rs +242 -0
- refkit-0.0.5/crates/refkit-core/src/lib.rs +32 -0
- refkit-0.0.5/crates/refkit-core/src/library/mod.rs +351 -0
- refkit-0.0.5/crates/refkit-core/src/library/parse.rs +83 -0
- refkit-0.0.5/crates/refkit-core/src/library/recovery.rs +324 -0
- refkit-0.0.5/crates/refkit-core/src/raw/edit.rs +231 -0
- refkit-0.0.5/crates/refkit-core/src/raw/parse.rs +823 -0
- refkit-0.0.5/crates/refkit-core/src/raw/sanitize.rs +292 -0
- refkit-0.0.5/crates/refkit-core/src/raw/tests.rs +728 -0
- refkit-0.0.5/crates/refkit-core/src/raw.rs +679 -0
- refkit-0.0.5/crates/refkit-core/src/render/bibliography.rs +108 -0
- refkit-0.0.5/crates/refkit-core/src/render/citation.rs +167 -0
- refkit-0.0.5/crates/refkit-core/src/render/html.rs +154 -0
- refkit-0.0.5/crates/refkit-core/src/render/mod.rs +209 -0
- refkit-0.0.5/crates/refkit-core/src/render/text.rs +12 -0
- refkit-0.0.5/crates/refkit-core/src/render_tree.rs +278 -0
- refkit-0.0.5/crates/refkit-core/src/source.rs +88 -0
- refkit-0.0.5/crates/refkit-core/src/strings.rs +182 -0
- refkit-0.0.5/crates/refkit-core/src/style.rs +131 -0
- refkit-0.0.5/crates/refkit-core/src/style_analysis.rs +276 -0
- refkit-0.0.5/crates/refkit-core/src/tidy/duplicates.rs +282 -0
- refkit-0.0.5/crates/refkit-core/src/tidy/keys.rs +540 -0
- refkit-0.0.5/crates/refkit-core/src/tidy/latex.rs +138 -0
- refkit-0.0.5/crates/refkit-core/src/tidy/mod.rs +435 -0
- refkit-0.0.5/crates/refkit-core/src/tidy/options.rs +174 -0
- refkit-0.0.5/crates/refkit-core/src/tidy/render/sort.rs +224 -0
- refkit-0.0.5/crates/refkit-core/src/tidy/render/value.rs +415 -0
- refkit-0.0.5/crates/refkit-core/src/tidy/render.rs +366 -0
- refkit-0.0.5/crates/refkit-core/src/tidy/unicode.rs +78 -0
- refkit-0.0.5/packages/refkit/rust/Cargo.toml +28 -0
- refkit-0.0.5/packages/refkit/rust/src/citation.rs +200 -0
- refkit-0.0.5/packages/refkit/rust/src/conversion.rs +122 -0
- refkit-0.0.5/packages/refkit/rust/src/document.rs +130 -0
- refkit-0.0.5/packages/refkit/rust/src/entry.rs +83 -0
- refkit-0.0.5/packages/refkit/rust/src/errors.rs +39 -0
- refkit-0.0.5/packages/refkit/rust/src/filesystem.rs +79 -0
- refkit-0.0.5/packages/refkit/rust/src/lib.rs +21 -0
- refkit-0.0.5/packages/refkit/rust/src/library.rs +197 -0
- refkit-0.0.5/packages/refkit/rust/src/module.rs +86 -0
- refkit-0.0.5/packages/refkit/rust/src/raw.rs +490 -0
- refkit-0.0.5/packages/refkit/rust/src/rendered.rs +151 -0
- refkit-0.0.5/packages/refkit/rust/src/repr.rs +21 -0
- refkit-0.0.5/packages/refkit/rust/src/style.rs +124 -0
- refkit-0.0.5/packages/refkit/rust/src/tidy.rs +465 -0
- {refkit-0.0.4rc4 → refkit-0.0.5}/pyproject.toml +28 -15
- {refkit-0.0.4rc4 → refkit-0.0.5}/src/refkit/__init__.py +7 -16
- {refkit-0.0.4rc4 → refkit-0.0.5}/src/refkit/__init__.pyi +1 -3
- refkit-0.0.5/src/refkit/_native.pyi +352 -0
- refkit-0.0.5/src/refkit/agent.py +167 -0
- refkit-0.0.4rc4/.gitignore +0 -18
- refkit-0.0.4rc4/PKG-INFO +0 -293
- refkit-0.0.4rc4/README.md +0 -271
- refkit-0.0.4rc4/tests/conftest.py +0 -68
- refkit-0.0.4rc4/tests/fixtures/basic.bib +0 -17
- refkit-0.0.4rc4/tests/fixtures/hayagriva-rich.yaml +0 -55
- refkit-0.0.4rc4/tests/fixtures/parent.yaml +0 -12
- refkit-0.0.4rc4/tests/fixtures/parent.yml +0 -9
- refkit-0.0.4rc4/tests/fixtures/raw-duplicates.bib +0 -25
- refkit-0.0.4rc4/tests/fixtures/raw.bib +0 -15
- refkit-0.0.4rc4/tests/fixtures/refkit-note.csl +0 -43
- refkit-0.0.4rc4/tests/fixtures/typst-biblatex.bib +0 -51
- refkit-0.0.4rc4/tests/fixtures/typst-raw.bib +0 -31
- refkit-0.0.4rc4/tests/test_properties.py +0 -50
- refkit-0.0.4rc4/tests/test_public_api.py +0 -1962
- refkit-0.0.4rc4/tests/test_pyodide.py +0 -115
- refkit-0.0.4rc4/tests/test_tidy_options.py +0 -152
- refkit-0.0.4rc4/tests/test_type_contracts.py +0 -52
- {refkit-0.0.4rc4 → refkit-0.0.5}/LICENSE +0 -0
- {refkit-0.0.4rc4 → refkit-0.0.5}/src/refkit/py.typed +0 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
|
|
3
|
+
"name": "refkit",
|
|
4
|
+
"description": "Parse, inspect, render, format, and edit bibliography data from Python and Polars.",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"author": {
|
|
7
|
+
"name": "Péter Ferenc Gyarmati",
|
|
8
|
+
"email": "dev.petergy@gmail.com"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://peter-gy.github.io/refkit/",
|
|
11
|
+
"repository": "https://github.com/peter-gy/refkit",
|
|
12
|
+
"keywords": ["bibliography", "bibtex", "citations", "python", "polars"]
|
|
13
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: refkit
|
|
3
|
+
description: Use RefKit to parse, inspect, render, format, or safely edit BibTeX, BibLaTeX, and Hayagriva bibliography data from Python or Polars.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# RefKit
|
|
7
|
+
|
|
8
|
+
RefKit exposes one portable bibliography core through Python objects and Polars expressions. Work through the public package APIs so notebook code, scripts, and applications share the same parsing, rendering, formatting, and error contracts.
|
|
9
|
+
|
|
10
|
+
## Choose the data model
|
|
11
|
+
|
|
12
|
+
- Use `refkit.Library` for normalized entries, diagnostics, selection, projection, citation rendering, and bibliography rendering.
|
|
13
|
+
- Use `refkit.BibDocument` for source-order BibTeX blocks, duplicate occurrences, existing-field edits, and preserving writes.
|
|
14
|
+
- Use `polars_refkit` when bibliography source already lives in eager or lazy Polars queries.
|
|
15
|
+
|
|
16
|
+
Do not flatten these models into one generic dictionary workflow. Their ownership and failure behavior differ.
|
|
17
|
+
|
|
18
|
+
## Working rules
|
|
19
|
+
|
|
20
|
+
1. Prefer in-memory APIs inside the active Python process. Use `Library.parse_bibtex`, `Library.parse_yaml`, `BibDocument.parse`, and `tidy_bibtex` when source text is already available.
|
|
21
|
+
2. Use `recovery="report"` when the task should retain recoverable entries. Always inspect and report `library.diagnostics` before consuming those entries. Use `recovery="error"` when malformed input must stop the operation.
|
|
22
|
+
3. Project the fields needed for inspection with `Library.project`. Avoid dumping complete large libraries or render trees into notebook output.
|
|
23
|
+
4. Build one `Document` from a prepared `Library`, `Style`, and locale. Pass the complete ordered citation sequence to one `render` call because order can affect numbering, disambiguation, position-sensitive formatting, and the cited bibliography.
|
|
24
|
+
5. Choose `Rendered.text`, `Rendered.html`, or `Rendered.tree` at the consumer boundary. Treat HTML as rendered output and tree nodes as structured data.
|
|
25
|
+
6. Select duplicate raw entry or field occurrences with `get_all` before editing an existing field. `BibEntry.key` is read-only. Preview `BibDocument.to_bibtex()` before writing a file.
|
|
26
|
+
7. Inspect `TidyResult.warnings` before accepting canonical formatting, key generation, duplicate detection, or merges.
|
|
27
|
+
8. Compare requested citation keys with `Library.keys()` before a batch render. A missing key aborts the complete render call, so return the requested, missing, and available keys and ask the user to resolve the mismatch.
|
|
28
|
+
9. Let RefKit exceptions reach the agent runtime while diagnosing. Catch a specific error only when the workflow has a concrete recovery path.
|
|
29
|
+
|
|
30
|
+
## Start with a bounded inspection
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
import refkit as rk
|
|
34
|
+
|
|
35
|
+
source = "@article{doe2024, title={Fast Citations}, year={2024}}"
|
|
36
|
+
library = rk.Library.parse_bibtex(source, recovery="report")
|
|
37
|
+
rows = library.project(["key", "entry_type", "title", "date", "doi"])
|
|
38
|
+
diagnostics = list(library.diagnostics)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Return `rows` and `diagnostics` together when report recovery retains partial input.
|
|
42
|
+
|
|
43
|
+
Read [references/workflows.md](references/workflows.md) for complete normalized, rendering, raw-edit, formatting, and Polars workflows. Read [references/contracts.md](references/contracts.md) when the task depends on lifecycle, duplicate, error, or output-shape details.
|
|
44
|
+
|
|
45
|
+
The installed documentation map is available at `https://peter-gy.github.io/refkit/llms.txt`.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# RefKit Contracts
|
|
2
|
+
|
|
3
|
+
## State owners
|
|
4
|
+
|
|
5
|
+
| Object | Owns |
|
|
6
|
+
| --- | --- |
|
|
7
|
+
| `Library` | Normalized entries and parser diagnostics. |
|
|
8
|
+
| `BibDocument` | Source-order raw BibTeX, occurrence identity, and preserving writeback. |
|
|
9
|
+
| `Style` | A prepared Citation Style Language style. |
|
|
10
|
+
| `Document` | Prepared library, style, and locale inputs. |
|
|
11
|
+
| One render call | Fresh ordered citation processor state and its cited bibliography. |
|
|
12
|
+
| `Rendered` | Text, HTML, and a structured render tree for one result. |
|
|
13
|
+
|
|
14
|
+
## Input boundaries
|
|
15
|
+
|
|
16
|
+
- `Library.read` infers BibTeX, BibLaTeX, or Hayagriva YAML from a filesystem extension.
|
|
17
|
+
- `Library.parse_bibtex` accepts BibTeX or BibLaTeX text.
|
|
18
|
+
- `recovery="error"` raises on malformed input. `recovery="report"` retains recoverable entries and records ignored blocks or duplicate keys in `Library.diagnostics`. Report recovery still raises `RefkitError` when no entry survives.
|
|
19
|
+
- `Library.parse_yaml` accepts Hayagriva bibliography YAML.
|
|
20
|
+
- `BibDocument` accepts raw BibTeX and preserves blocks that normalized parsing does not expose.
|
|
21
|
+
- `tidy_bibtex` accepts raw BibTeX text and rejects the first malformed block with `TidySyntaxError`.
|
|
22
|
+
|
|
23
|
+
## Projection boundaries
|
|
24
|
+
|
|
25
|
+
`Library.project` and the Polars `entries` expression accept `key`, `entry_type`, `type`, `title`, `date`, `doi`, and `volume`. `type` is an output-name alias for `entry_type`. The default projection contains `key`, `title`, `doi`, and `volume`.
|
|
26
|
+
|
|
27
|
+
## Duplicate boundaries
|
|
28
|
+
|
|
29
|
+
Normalized `Library` keys are unique. Report recovery retains the first recoverable entry for a duplicate key and records a diagnostic.
|
|
30
|
+
|
|
31
|
+
Raw `BibDocument` entries and fields preserve duplicate occurrences. Direct lookup requires one match. Use `get_all` to select a source-order occurrence before editing.
|
|
32
|
+
|
|
33
|
+
`BibEntry.key` is read-only. Canonical formatting can generate new keys, but accepting generated keys also requires updating downstream citations that refer to the old keys.
|
|
34
|
+
|
|
35
|
+
## Render boundaries
|
|
36
|
+
|
|
37
|
+
A `Cite` identifies one bibliography key with an optional locator and label. A `CitationGroup` combines cite items into one rendered citation. A `Citation` gives the rendered occurrence an ID used to retrieve it from `RenderedDocument`.
|
|
38
|
+
|
|
39
|
+
Citation order can affect numbering, disambiguation, position-sensitive formatting, subsequent-name rules, and the cited bibliography. Separate render calls have independent processor state.
|
|
40
|
+
|
|
41
|
+
A missing reference aborts the complete render call with `MissingReferenceError`. When citation keys come from user or external input, compare them with `Library.keys()` before rendering and ask the user to resolve missing keys.
|
|
42
|
+
|
|
43
|
+
## Error boundaries
|
|
44
|
+
|
|
45
|
+
| Error | Use |
|
|
46
|
+
| --- | --- |
|
|
47
|
+
| `RefkitError` | Filesystem, parser, raw ambiguity, and renderer failures. |
|
|
48
|
+
| `MissingReferenceError` | A render request names a key absent from the `Library`. |
|
|
49
|
+
| `TidyError` | Key generation or another formatting operation fails. |
|
|
50
|
+
| `TidySyntaxError` | Raw BibTeX contains a malformed block. Inspect its line, column, byte, character, and message fields. |
|
|
51
|
+
| `TypeError`, `ValueError`, `KeyError` | Python shape, option, label, lookup, and identifier failures. |
|
|
52
|
+
|
|
53
|
+
## Output discipline for code-mode agents
|
|
54
|
+
|
|
55
|
+
- Show a bounded projection before printing complete source.
|
|
56
|
+
- Prefer `Rendered.text` for inspection and `Rendered.html` for an HTML consumer.
|
|
57
|
+
- Traverse `Rendered.tree` when structured formatting or link metadata is required.
|
|
58
|
+
- Report diagnostics and tidy warnings beside the affected input.
|
|
59
|
+
- When report recovery retains partial input, return projected entries and diagnostics together.
|
|
60
|
+
- When citation keys are missing, return the requested, missing, and available keys before asking the user to resolve the mismatch.
|
|
61
|
+
- Preview preserving writes and generated keys before committing filesystem changes.
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# RefKit Workflows
|
|
2
|
+
|
|
3
|
+
## Parse and inspect normalized data
|
|
4
|
+
|
|
5
|
+
```python
|
|
6
|
+
import refkit as rk
|
|
7
|
+
|
|
8
|
+
source = """
|
|
9
|
+
@article{doe2024,
|
|
10
|
+
author = {Doe, Jane},
|
|
11
|
+
title = {Fast Citations},
|
|
12
|
+
year = {2024}
|
|
13
|
+
}
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
library = rk.Library.parse_bibtex(source, recovery="report")
|
|
17
|
+
rows = library.project(["key", "entry_type", "title", "date", "doi"])
|
|
18
|
+
diagnostics = list(library.diagnostics)
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
`Library` preserves normalized entry order. Recovery diagnostics describe repairs applied before typed entries were accepted.
|
|
22
|
+
|
|
23
|
+
## Render an ordered citation document
|
|
24
|
+
|
|
25
|
+
```python
|
|
26
|
+
document = rk.Document(library, rk.Style.load("apa"), locale="en-US")
|
|
27
|
+
rendered = document.render(
|
|
28
|
+
[
|
|
29
|
+
rk.Citation(id="introduction", citation="doe2024"),
|
|
30
|
+
rk.Citation(
|
|
31
|
+
id="detail",
|
|
32
|
+
citation=rk.CitationGroup([rk.Cite("doe2024", locator="12", label="page")]),
|
|
33
|
+
),
|
|
34
|
+
]
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
citation_text = rendered["detail"].text
|
|
38
|
+
bibliography_html = rendered.bibliography.html
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Each `render` call creates fresh citation processor state. Keep related citations in one ordered call.
|
|
42
|
+
|
|
43
|
+
## Edit raw BibTeX while preserving surrounding source
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
duplicate_source = """% Keep this comment.
|
|
47
|
+
@article{doe2024, TITLE={First title}, year={2024}}
|
|
48
|
+
@article{doe2024, tItLe={Second title}, year={2025}}
|
|
49
|
+
"""
|
|
50
|
+
raw = rk.BibDocument.parse(duplicate_source)
|
|
51
|
+
entries = raw.entries.get_all("doe2024")
|
|
52
|
+
if len(entries) != 2:
|
|
53
|
+
raise ValueError(f"expected two doe2024 entries, found {len(entries)}")
|
|
54
|
+
|
|
55
|
+
entry = entries[1]
|
|
56
|
+
field = entry.fields.get_all("title")[0]
|
|
57
|
+
field.value = "Corrected title"
|
|
58
|
+
|
|
59
|
+
preview = raw.to_bibtex()
|
|
60
|
+
print(preview)
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Entry keys are case-sensitive. Field lookup is case-insensitive and preserves the source spelling of the field name. `get_all` makes duplicate occurrence selection explicit. `to_bibtex()` returns preview text and performs no filesystem write.
|
|
64
|
+
|
|
65
|
+
After inspecting `preview`, commit the preserving write to the intended path:
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
raw.write("references.bib")
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Format and inspect warnings
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
duplicate_source = """
|
|
75
|
+
@article{same, title={First}}
|
|
76
|
+
@book{same, title={Second}}
|
|
77
|
+
"""
|
|
78
|
+
result = rk.tidy_bibtex(
|
|
79
|
+
duplicate_source,
|
|
80
|
+
options=rk.TidyOptions(
|
|
81
|
+
duplicates=["key"],
|
|
82
|
+
sort_fields=True,
|
|
83
|
+
wrap=88,
|
|
84
|
+
),
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
formatted = result.bibtex
|
|
88
|
+
warnings = [
|
|
89
|
+
{"code": warning.code, "rule": warning.rule, "message": warning.message}
|
|
90
|
+
for warning in result.warnings
|
|
91
|
+
]
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
`duplicates=None` skips duplicate detection. `duplicates=["key"]` emits a `duplicate_entry` warning for repeated citation keys. `TidyResult.count` records parsed entry occurrences before duplicate merges.
|
|
95
|
+
|
|
96
|
+
## Process bibliography columns with Polars
|
|
97
|
+
|
|
98
|
+
Install `polars-refkit` separately, then import it once to register the expression namespace:
|
|
99
|
+
|
|
100
|
+
```python
|
|
101
|
+
import polars as pl
|
|
102
|
+
import polars_refkit
|
|
103
|
+
|
|
104
|
+
frame = pl.DataFrame({"bibtex": [source], "key": ["doe2024"]})
|
|
105
|
+
result = frame.select(
|
|
106
|
+
citation_from_column=pl.col("bibtex").refkit.cite("key"),
|
|
107
|
+
citation_from_literal=pl.col("bibtex").refkit.cite(pl.lit("doe2024")),
|
|
108
|
+
entries=pl.col("bibtex").refkit.entries(fields=["key", "entry_type", "title"]),
|
|
109
|
+
)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
A plain string argument names a column. Wrap literal source or citation keys with `pl.lit(...)`. Importing `polars_refkit` registers `pl.Expr.refkit`. Citation expressions return null for row-local parse failures, missing keys, or rendering failures.
|