refkit 0.1.1__cp310-abi3-win_amd64.whl
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/__init__.py +138 -0
- refkit/__init__.pyi +91 -0
- refkit/_native.pyd +0 -0
- refkit/_native.pyi +272 -0
- refkit/agent.py +97 -0
- refkit/py.typed +1 -0
- refkit/types.py +172 -0
- refkit-0.1.1.agent-plugin/plugin.json +13 -0
- refkit-0.1.1.agent-plugin/skills/refkit/SKILL.md +24 -0
- refkit-0.1.1.agent-plugin/skills/refkit/agents/openai.yaml +4 -0
- refkit-0.1.1.agent-plugin/skills/refkit/references/contracts.md +62 -0
- refkit-0.1.1.agent-plugin/skills/refkit/references/edit.md +29 -0
- refkit-0.1.1.agent-plugin/skills/refkit/references/inspect.md +48 -0
- refkit-0.1.1.agent-plugin/skills/refkit/references/render.md +53 -0
- refkit-0.1.1.agent-plugin/skills/refkit/references/tidy.md +35 -0
- refkit-0.1.1.dist-info/METADATA +94 -0
- refkit-0.1.1.dist-info/RECORD +23 -0
- refkit-0.1.1.dist-info/WHEEL +4 -0
- refkit-0.1.1.dist-info/agent_plugins.json +1 -0
- refkit-0.1.1.dist-info/entry_points.txt +2 -0
- refkit-0.1.1.dist-info/licenses/LICENSE +201 -0
- refkit-0.1.1.dist-info/licenses/NOTICE +11 -0
- refkit-0.1.1.dist-info/sboms/refkit-native.cyclonedx.json +3416 -0
refkit/__init__.py
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"""Citation parsing, rendering, and BibTeX editing."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from importlib.metadata import version as _metadata_version
|
|
6
|
+
from os import PathLike
|
|
7
|
+
|
|
8
|
+
from . import _native as _core
|
|
9
|
+
from . import types as types
|
|
10
|
+
|
|
11
|
+
__version__ = _metadata_version("refkit")
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _ensure_native_version() -> None:
|
|
15
|
+
if _core.__version__ == __version__:
|
|
16
|
+
return
|
|
17
|
+
raise SystemError(
|
|
18
|
+
f"The installed refkit extension version ({_core.__version__}) is incompatible "
|
|
19
|
+
f"with refkit {__version__}. Reinstall refkit from one release."
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
_ensure_native_version()
|
|
24
|
+
|
|
25
|
+
BibDocument = _core.BibDocument
|
|
26
|
+
BibEntry = _core.BibEntry
|
|
27
|
+
BibEntryMap = _core.BibEntryMap
|
|
28
|
+
BibField = _core.BibField
|
|
29
|
+
BibFieldMap = _core.BibFieldMap
|
|
30
|
+
Citation = _core.Citation
|
|
31
|
+
CitationGroup = _core.CitationGroup
|
|
32
|
+
Cite = _core.Cite
|
|
33
|
+
Document = _core.Document
|
|
34
|
+
Entry = _core.Entry
|
|
35
|
+
Library = _core.Library
|
|
36
|
+
Locale = _core.Locale
|
|
37
|
+
MissingReferenceError = _core.MissingReferenceError
|
|
38
|
+
RefkitError = _core.RefkitError
|
|
39
|
+
ParseError = _core.ParseError
|
|
40
|
+
Rendered = _core.Rendered
|
|
41
|
+
RenderedDocument = _core.RenderedDocument
|
|
42
|
+
Style = _core.Style
|
|
43
|
+
TidyError = _core.TidyError
|
|
44
|
+
TidyOptions = _core.TidyOptions
|
|
45
|
+
TidyResult = _core.TidyResult
|
|
46
|
+
TidySyntaxError = _core.TidySyntaxError
|
|
47
|
+
TidyWarning = _core.TidyWarning
|
|
48
|
+
build_info = _core.build_info
|
|
49
|
+
build_mode = _core.build_mode
|
|
50
|
+
|
|
51
|
+
__all__ = [
|
|
52
|
+
"BibDocument",
|
|
53
|
+
"BibEntry",
|
|
54
|
+
"BibEntryMap",
|
|
55
|
+
"BibField",
|
|
56
|
+
"BibFieldMap",
|
|
57
|
+
"Citation",
|
|
58
|
+
"Cite",
|
|
59
|
+
"CitationGroup",
|
|
60
|
+
"RefkitError",
|
|
61
|
+
"ParseError",
|
|
62
|
+
"Document",
|
|
63
|
+
"Entry",
|
|
64
|
+
"Library",
|
|
65
|
+
"Locale",
|
|
66
|
+
"MissingReferenceError",
|
|
67
|
+
"Rendered",
|
|
68
|
+
"RenderedDocument",
|
|
69
|
+
"Style",
|
|
70
|
+
"TidyError",
|
|
71
|
+
"TidyOptions",
|
|
72
|
+
"TidyResult",
|
|
73
|
+
"TidySyntaxError",
|
|
74
|
+
"TidyWarning",
|
|
75
|
+
"build_info",
|
|
76
|
+
"build_mode",
|
|
77
|
+
"cite",
|
|
78
|
+
"full_bibliography",
|
|
79
|
+
"tidy_bibtex",
|
|
80
|
+
"tidy_file",
|
|
81
|
+
"__version__",
|
|
82
|
+
"types",
|
|
83
|
+
]
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def tidy_bibtex(
|
|
87
|
+
source: str,
|
|
88
|
+
*,
|
|
89
|
+
options: TidyOptions | None = None,
|
|
90
|
+
) -> TidyResult:
|
|
91
|
+
"""Format BibTeX text and return the formatted source plus warnings."""
|
|
92
|
+
|
|
93
|
+
return _core.tidy_bibtex(source, options=options)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def tidy_file(
|
|
97
|
+
path: str | PathLike[str],
|
|
98
|
+
*,
|
|
99
|
+
output: str | PathLike[str] | None = None,
|
|
100
|
+
options: TidyOptions | None = None,
|
|
101
|
+
) -> TidyResult:
|
|
102
|
+
"""Read a BibTeX file, format it, and write the result when `output` is set."""
|
|
103
|
+
|
|
104
|
+
result = BibDocument.read(path).tidy(options=options)
|
|
105
|
+
if output is not None:
|
|
106
|
+
_core._write_bibtex(output, result.bibtex)
|
|
107
|
+
return result
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def cite(
|
|
111
|
+
source: str | PathLike[str],
|
|
112
|
+
citation: str | Cite | CitationGroup,
|
|
113
|
+
*,
|
|
114
|
+
style: str | Style = "apa",
|
|
115
|
+
locale: str | Locale | None = "en-US",
|
|
116
|
+
) -> Rendered:
|
|
117
|
+
"""Read `source` and render one citation."""
|
|
118
|
+
|
|
119
|
+
library = Library.read(source)
|
|
120
|
+
loaded_style = Style.load(style) if isinstance(style, str) else style
|
|
121
|
+
rendered = Document(library, loaded_style, locale=locale).render(
|
|
122
|
+
[Citation("citation", citation)]
|
|
123
|
+
)
|
|
124
|
+
return rendered["citation"]
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def full_bibliography(
|
|
128
|
+
source: str | PathLike[str],
|
|
129
|
+
*,
|
|
130
|
+
style: str | Style = "apa",
|
|
131
|
+
locale: str | Locale | None = "en-US",
|
|
132
|
+
) -> Rendered:
|
|
133
|
+
"""Read `source` and render every entry as a bibliography."""
|
|
134
|
+
|
|
135
|
+
library = Library.read(source)
|
|
136
|
+
loaded_style = Style.load(style) if isinstance(style, str) else style
|
|
137
|
+
document = Document(library, loaded_style, locale=locale)
|
|
138
|
+
return document.full_bibliography()
|
refkit/__init__.pyi
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
from os import PathLike
|
|
2
|
+
|
|
3
|
+
from . import types as types
|
|
4
|
+
from ._native import (
|
|
5
|
+
BibDocument,
|
|
6
|
+
BibEntry,
|
|
7
|
+
BibEntryMap,
|
|
8
|
+
BibField,
|
|
9
|
+
BibFieldMap,
|
|
10
|
+
Citation,
|
|
11
|
+
CitationGroup,
|
|
12
|
+
Cite,
|
|
13
|
+
Document,
|
|
14
|
+
Entry,
|
|
15
|
+
Library,
|
|
16
|
+
Locale,
|
|
17
|
+
MissingReferenceError,
|
|
18
|
+
ParseError,
|
|
19
|
+
RefkitError,
|
|
20
|
+
Rendered,
|
|
21
|
+
RenderedDocument,
|
|
22
|
+
Style,
|
|
23
|
+
TidyError,
|
|
24
|
+
TidyOptions,
|
|
25
|
+
TidyResult,
|
|
26
|
+
TidySyntaxError,
|
|
27
|
+
TidyWarning,
|
|
28
|
+
build_info,
|
|
29
|
+
build_mode,
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
__all__ = [
|
|
33
|
+
"BibDocument",
|
|
34
|
+
"BibEntry",
|
|
35
|
+
"BibEntryMap",
|
|
36
|
+
"BibField",
|
|
37
|
+
"BibFieldMap",
|
|
38
|
+
"Citation",
|
|
39
|
+
"Cite",
|
|
40
|
+
"CitationGroup",
|
|
41
|
+
"RefkitError",
|
|
42
|
+
"ParseError",
|
|
43
|
+
"Document",
|
|
44
|
+
"Entry",
|
|
45
|
+
"Library",
|
|
46
|
+
"Locale",
|
|
47
|
+
"MissingReferenceError",
|
|
48
|
+
"Rendered",
|
|
49
|
+
"RenderedDocument",
|
|
50
|
+
"Style",
|
|
51
|
+
"TidyError",
|
|
52
|
+
"TidyOptions",
|
|
53
|
+
"TidyResult",
|
|
54
|
+
"TidySyntaxError",
|
|
55
|
+
"TidyWarning",
|
|
56
|
+
"build_info",
|
|
57
|
+
"build_mode",
|
|
58
|
+
"cite",
|
|
59
|
+
"full_bibliography",
|
|
60
|
+
"tidy_bibtex",
|
|
61
|
+
"tidy_file",
|
|
62
|
+
"__version__",
|
|
63
|
+
"types",
|
|
64
|
+
]
|
|
65
|
+
|
|
66
|
+
__version__: str
|
|
67
|
+
|
|
68
|
+
def tidy_bibtex(
|
|
69
|
+
source: str,
|
|
70
|
+
*,
|
|
71
|
+
options: TidyOptions | None = None,
|
|
72
|
+
) -> TidyResult: ...
|
|
73
|
+
def tidy_file(
|
|
74
|
+
path: str | PathLike[str],
|
|
75
|
+
*,
|
|
76
|
+
output: str | PathLike[str] | None = None,
|
|
77
|
+
options: TidyOptions | None = None,
|
|
78
|
+
) -> TidyResult: ...
|
|
79
|
+
def cite(
|
|
80
|
+
source: str | PathLike[str],
|
|
81
|
+
citation: str | Cite | CitationGroup,
|
|
82
|
+
*,
|
|
83
|
+
style: str | Style = "apa",
|
|
84
|
+
locale: str | Locale | None = "en-US",
|
|
85
|
+
) -> Rendered: ...
|
|
86
|
+
def full_bibliography(
|
|
87
|
+
source: str | PathLike[str],
|
|
88
|
+
*,
|
|
89
|
+
style: str | Style = "apa",
|
|
90
|
+
locale: str | Locale | None = "en-US",
|
|
91
|
+
) -> Rendered: ...
|
refkit/_native.pyd
ADDED
|
Binary file
|
refkit/_native.pyi
ADDED
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
from collections.abc import Iterable
|
|
2
|
+
from os import PathLike
|
|
3
|
+
from typing import Literal, TypeAlias
|
|
4
|
+
|
|
5
|
+
from .types import (
|
|
6
|
+
BibliographyLayout,
|
|
7
|
+
Diagnostic,
|
|
8
|
+
ProjectionRow,
|
|
9
|
+
RawBlock,
|
|
10
|
+
RawFailedBlock,
|
|
11
|
+
RenderedTree,
|
|
12
|
+
TidyRename,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
__version__: str
|
|
16
|
+
build_info: str
|
|
17
|
+
build_mode: Literal["debug", "release"]
|
|
18
|
+
_RecoveryPolicy: TypeAlias = Literal["error", "report"]
|
|
19
|
+
_DuplicateRule: TypeAlias = Literal["doi", "key", "abstract", "citation"]
|
|
20
|
+
_MergeStrategy: TypeAlias = Literal["first", "last", "combine", "overwrite"]
|
|
21
|
+
|
|
22
|
+
class RefkitError(Exception): ...
|
|
23
|
+
|
|
24
|
+
class ParseError(RefkitError):
|
|
25
|
+
diagnostics: list[Diagnostic]
|
|
26
|
+
|
|
27
|
+
class MissingReferenceError(RefkitError): ...
|
|
28
|
+
class TidyError(RefkitError): ...
|
|
29
|
+
|
|
30
|
+
class TidySyntaxError(TidyError):
|
|
31
|
+
line: int
|
|
32
|
+
column: int
|
|
33
|
+
byte: int
|
|
34
|
+
character: str | None
|
|
35
|
+
message: str
|
|
36
|
+
|
|
37
|
+
class TidyOptions:
|
|
38
|
+
def __init__(
|
|
39
|
+
self,
|
|
40
|
+
*,
|
|
41
|
+
omit: Iterable[str] | None = None,
|
|
42
|
+
curly: bool = False,
|
|
43
|
+
numeric: bool = False,
|
|
44
|
+
months: bool = False,
|
|
45
|
+
space: int = 2,
|
|
46
|
+
tab: bool = False,
|
|
47
|
+
align: bool | int | None = 14,
|
|
48
|
+
blank_lines: bool = False,
|
|
49
|
+
sort: bool | Iterable[str] | None = None,
|
|
50
|
+
duplicates: Iterable[_DuplicateRule] | None = None,
|
|
51
|
+
merge: _MergeStrategy | None = None,
|
|
52
|
+
strip_enclosing_braces: bool = False,
|
|
53
|
+
drop_all_caps: bool = False,
|
|
54
|
+
escape: bool = True,
|
|
55
|
+
sort_fields: bool | Iterable[str] | None = None,
|
|
56
|
+
strip_comments: bool = False,
|
|
57
|
+
trailing_commas: bool = False,
|
|
58
|
+
encode_urls: bool = False,
|
|
59
|
+
tidy_comments: bool = True,
|
|
60
|
+
remove_empty_fields: bool = False,
|
|
61
|
+
remove_duplicate_fields: bool = True,
|
|
62
|
+
generate_keys: bool | str | None = None,
|
|
63
|
+
max_authors: int | None = None,
|
|
64
|
+
lowercase: bool = True,
|
|
65
|
+
enclosing_braces: bool | Iterable[str] | None = None,
|
|
66
|
+
remove_braces: bool | Iterable[str] | None = None,
|
|
67
|
+
wrap: bool | int | None = None,
|
|
68
|
+
) -> None: ...
|
|
69
|
+
|
|
70
|
+
class TidyWarning:
|
|
71
|
+
@property
|
|
72
|
+
def code(self) -> Literal["missing_key", "duplicate_entry"]: ...
|
|
73
|
+
@property
|
|
74
|
+
def rule(self) -> _DuplicateRule | None: ...
|
|
75
|
+
@property
|
|
76
|
+
def message(self) -> str: ...
|
|
77
|
+
|
|
78
|
+
class TidyResult:
|
|
79
|
+
@property
|
|
80
|
+
def bibtex(self) -> str: ...
|
|
81
|
+
@property
|
|
82
|
+
def warnings(self) -> list[TidyWarning]: ...
|
|
83
|
+
@property
|
|
84
|
+
def renames(self) -> list[TidyRename]: ...
|
|
85
|
+
@property
|
|
86
|
+
def count(self) -> int: ...
|
|
87
|
+
|
|
88
|
+
def tidy_bibtex(source: str, *, options: TidyOptions | None = None) -> TidyResult: ...
|
|
89
|
+
def _write_bibtex(path: str | PathLike[str], source: str) -> None: ...
|
|
90
|
+
|
|
91
|
+
class Entry:
|
|
92
|
+
@property
|
|
93
|
+
def key(self) -> str: ...
|
|
94
|
+
@property
|
|
95
|
+
def entry_type(self) -> str: ...
|
|
96
|
+
@property
|
|
97
|
+
def title(self) -> str | None: ...
|
|
98
|
+
@property
|
|
99
|
+
def date(self) -> str | None: ...
|
|
100
|
+
@property
|
|
101
|
+
def parents(self) -> list[Entry]: ...
|
|
102
|
+
@property
|
|
103
|
+
def volume(self) -> str | None: ...
|
|
104
|
+
@property
|
|
105
|
+
def doi(self) -> str | None: ...
|
|
106
|
+
|
|
107
|
+
class Library:
|
|
108
|
+
@staticmethod
|
|
109
|
+
def read(path: str | PathLike[str], *, recovery: _RecoveryPolicy = "error") -> Library: ...
|
|
110
|
+
@staticmethod
|
|
111
|
+
def parse_bibtex(
|
|
112
|
+
source: str,
|
|
113
|
+
*,
|
|
114
|
+
recovery: _RecoveryPolicy = "error",
|
|
115
|
+
) -> Library: ...
|
|
116
|
+
@staticmethod
|
|
117
|
+
def parse_yaml(source: str) -> Library: ...
|
|
118
|
+
@property
|
|
119
|
+
def diagnostics(self) -> list[Diagnostic]: ...
|
|
120
|
+
def keys(self) -> list[str]: ...
|
|
121
|
+
def get_many(self, keys: Iterable[str]) -> list[Entry]: ...
|
|
122
|
+
def values(self) -> list[Entry]: ...
|
|
123
|
+
def get(self, key: str) -> Entry | None: ...
|
|
124
|
+
def is_empty(self) -> bool: ...
|
|
125
|
+
def select(self, selector: str) -> list[Entry]: ...
|
|
126
|
+
def project(
|
|
127
|
+
self, fields: Iterable[str] | None = None, *, keys: Iterable[str] | None = None
|
|
128
|
+
) -> list[ProjectionRow]: ...
|
|
129
|
+
def __len__(self) -> int: ...
|
|
130
|
+
def __bool__(self) -> bool: ...
|
|
131
|
+
def __contains__(self, key: str) -> bool: ...
|
|
132
|
+
def __getitem__(self, key: str) -> Entry: ...
|
|
133
|
+
|
|
134
|
+
class Style:
|
|
135
|
+
@staticmethod
|
|
136
|
+
def load(name: str) -> Style: ...
|
|
137
|
+
@staticmethod
|
|
138
|
+
def from_xml(xml: str) -> Style: ...
|
|
139
|
+
@staticmethod
|
|
140
|
+
def from_path(path: str | PathLike[str]) -> Style: ...
|
|
141
|
+
@property
|
|
142
|
+
def id(self) -> str: ...
|
|
143
|
+
@property
|
|
144
|
+
def title(self) -> str: ...
|
|
145
|
+
|
|
146
|
+
class Locale:
|
|
147
|
+
@staticmethod
|
|
148
|
+
def load(code: str) -> Locale: ...
|
|
149
|
+
@property
|
|
150
|
+
def code(self) -> str: ...
|
|
151
|
+
|
|
152
|
+
class Cite:
|
|
153
|
+
def __init__(
|
|
154
|
+
self, key: str, *, locator: str | None = None, label: str | None = None
|
|
155
|
+
) -> None: ...
|
|
156
|
+
@property
|
|
157
|
+
def key(self) -> str: ...
|
|
158
|
+
@property
|
|
159
|
+
def locator(self) -> str | None: ...
|
|
160
|
+
@property
|
|
161
|
+
def label(self) -> str | None: ...
|
|
162
|
+
|
|
163
|
+
class CitationGroup:
|
|
164
|
+
def __init__(self, items: Iterable[str | Cite]) -> None: ...
|
|
165
|
+
@property
|
|
166
|
+
def items(self) -> list[Cite]: ...
|
|
167
|
+
def __len__(self) -> int: ...
|
|
168
|
+
|
|
169
|
+
class Citation:
|
|
170
|
+
def __init__(
|
|
171
|
+
self, id: str, citation: str | Cite | CitationGroup, *, note_number: int | None = None
|
|
172
|
+
) -> None: ...
|
|
173
|
+
@property
|
|
174
|
+
def note_number(self) -> int | None: ...
|
|
175
|
+
@property
|
|
176
|
+
def id(self) -> str: ...
|
|
177
|
+
@property
|
|
178
|
+
def group(self) -> CitationGroup: ...
|
|
179
|
+
|
|
180
|
+
class Rendered:
|
|
181
|
+
@property
|
|
182
|
+
def layout(self) -> BibliographyLayout | None: ...
|
|
183
|
+
@property
|
|
184
|
+
def text(self) -> str: ...
|
|
185
|
+
@property
|
|
186
|
+
def html(self) -> str: ...
|
|
187
|
+
@property
|
|
188
|
+
def tree(self) -> RenderedTree: ...
|
|
189
|
+
|
|
190
|
+
class RenderedDocument:
|
|
191
|
+
@property
|
|
192
|
+
def citation_order(self) -> list[str]: ...
|
|
193
|
+
@property
|
|
194
|
+
def citations(self) -> dict[str, Rendered]: ...
|
|
195
|
+
@property
|
|
196
|
+
def bibliography(self) -> Rendered: ...
|
|
197
|
+
def __getitem__(self, id: str) -> Rendered: ...
|
|
198
|
+
|
|
199
|
+
class Document:
|
|
200
|
+
def __init__(
|
|
201
|
+
self, library: Library, style: Style, *, locale: str | Locale | None = None
|
|
202
|
+
) -> None: ...
|
|
203
|
+
def render(self, citations: Iterable[Citation]) -> RenderedDocument: ...
|
|
204
|
+
def cited_bibliography(self, citations: Iterable[Citation]) -> Rendered: ...
|
|
205
|
+
def full_bibliography(self) -> Rendered: ...
|
|
206
|
+
|
|
207
|
+
class BibField:
|
|
208
|
+
@property
|
|
209
|
+
def name(self) -> str: ...
|
|
210
|
+
@property
|
|
211
|
+
def value(self) -> str: ...
|
|
212
|
+
@value.setter
|
|
213
|
+
def value(self, value: str) -> None: ...
|
|
214
|
+
@property
|
|
215
|
+
def span(self) -> tuple[int, int]: ...
|
|
216
|
+
|
|
217
|
+
class BibFieldMap:
|
|
218
|
+
def unique_keys(self) -> list[str]: ...
|
|
219
|
+
def occurrence_keys(self) -> list[str]: ...
|
|
220
|
+
def occurrences(self) -> list[BibField]: ...
|
|
221
|
+
def get_all(self, key: str) -> list[BibField]: ...
|
|
222
|
+
def is_empty(self) -> bool: ...
|
|
223
|
+
def get_unique(self, key: str) -> BibField | None: ...
|
|
224
|
+
def __len__(self) -> int: ...
|
|
225
|
+
def __bool__(self) -> bool: ...
|
|
226
|
+
def __contains__(self, key: str) -> bool: ...
|
|
227
|
+
def __getitem__(self, key: str) -> BibField: ...
|
|
228
|
+
|
|
229
|
+
class BibEntry:
|
|
230
|
+
@property
|
|
231
|
+
def key(self) -> str: ...
|
|
232
|
+
@property
|
|
233
|
+
def kind(self) -> str: ...
|
|
234
|
+
@property
|
|
235
|
+
def fields(self) -> BibFieldMap: ...
|
|
236
|
+
@property
|
|
237
|
+
def span(self) -> tuple[int, int]: ...
|
|
238
|
+
|
|
239
|
+
class BibEntryMap:
|
|
240
|
+
def unique_keys(self) -> list[str]: ...
|
|
241
|
+
def occurrence_keys(self) -> list[str]: ...
|
|
242
|
+
def occurrences(self) -> list[BibEntry]: ...
|
|
243
|
+
def get_all(self, key: str) -> list[BibEntry]: ...
|
|
244
|
+
def is_empty(self) -> bool: ...
|
|
245
|
+
def get_unique(self, key: str) -> BibEntry | None: ...
|
|
246
|
+
def __len__(self) -> int: ...
|
|
247
|
+
def __bool__(self) -> bool: ...
|
|
248
|
+
def __contains__(self, key: str) -> bool: ...
|
|
249
|
+
def __getitem__(self, key: str) -> BibEntry: ...
|
|
250
|
+
|
|
251
|
+
class BibDocument:
|
|
252
|
+
@property
|
|
253
|
+
def diagnostics(self) -> list[Diagnostic]: ...
|
|
254
|
+
@staticmethod
|
|
255
|
+
def read(path: str | PathLike[str]) -> BibDocument: ...
|
|
256
|
+
@staticmethod
|
|
257
|
+
def parse(source: str) -> BibDocument: ...
|
|
258
|
+
@property
|
|
259
|
+
def entries(self) -> BibEntryMap: ...
|
|
260
|
+
@property
|
|
261
|
+
def comments(self) -> list[str]: ...
|
|
262
|
+
@property
|
|
263
|
+
def preamble(self) -> str: ...
|
|
264
|
+
@property
|
|
265
|
+
def strings(self) -> dict[str, str]: ...
|
|
266
|
+
@property
|
|
267
|
+
def failed_blocks(self) -> list[RawFailedBlock]: ...
|
|
268
|
+
@property
|
|
269
|
+
def blocks(self) -> list[RawBlock]: ...
|
|
270
|
+
def to_bibtex(self) -> str: ...
|
|
271
|
+
def tidy(self, *, options: TidyOptions | None = None) -> TidyResult: ...
|
|
272
|
+
def write(self, path: str | PathLike[str]) -> None: ...
|
refkit/agent.py
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"""Use RefKit from code-mode agents."""
|
|
2
|
+
|
|
3
|
+
import sys as _sys
|
|
4
|
+
from importlib.metadata import version as _version
|
|
5
|
+
from pathlib import Path as _Path
|
|
6
|
+
from textwrap import indent as _indent
|
|
7
|
+
from types import ModuleType as _ModuleType
|
|
8
|
+
|
|
9
|
+
import agent_plugins as _agent_plugins
|
|
10
|
+
|
|
11
|
+
_DISTRIBUTION_NAME = "refkit"
|
|
12
|
+
_SKILL_NAME = "refkit"
|
|
13
|
+
|
|
14
|
+
AgentPluginError = _agent_plugins.AgentPluginError
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def agent_plugin() -> _agent_plugins.Plugin:
|
|
18
|
+
"""Return the Agent Plugin installed with this RefKit version.
|
|
19
|
+
|
|
20
|
+
Raises:
|
|
21
|
+
AgentPluginError: The installed distribution has no usable plugin marker.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
return _agent_plugins.locate(_DISTRIBUTION_NAME)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def agent_skill() -> _agent_plugins.Skill:
|
|
28
|
+
"""Return the packaged RefKit Agent Skill.
|
|
29
|
+
|
|
30
|
+
Raises:
|
|
31
|
+
AgentPluginError: The installed plugin or its RefKit skill cannot be resolved.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
return agent_plugin().skill(_SKILL_NAME)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def instructions() -> str:
|
|
38
|
+
"""Return the installed RefKit Agent Skill instructions as Markdown."""
|
|
39
|
+
|
|
40
|
+
return agent_skill().body.lstrip("\n")
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def resources() -> dict[str, _Path]:
|
|
44
|
+
"""Return installed skill files keyed by skill-relative path."""
|
|
45
|
+
|
|
46
|
+
skill = agent_skill()
|
|
47
|
+
return {path.relative_to(skill.path).as_posix(): path for path in skill.files}
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def _module_help(summary: str) -> str:
|
|
51
|
+
introduction = f"""{summary}
|
|
52
|
+
|
|
53
|
+
Installed refkit version: {_version(_DISTRIBUTION_NAME)}.
|
|
54
|
+
|
|
55
|
+
Use `refkit.Library` to inspect normalized bibliography data, `refkit.Document`
|
|
56
|
+
to render ordered citations, and `refkit.BibDocument` to edit raw BibTeX.
|
|
57
|
+
|
|
58
|
+
import refkit.agent as agent
|
|
59
|
+
|
|
60
|
+
print(agent.instructions())
|
|
61
|
+
print(agent.resources()["references/inspect.md"].read_text(encoding="utf-8"))
|
|
62
|
+
|
|
63
|
+
Packaged instructions describe the installed API. Read the task resource before
|
|
64
|
+
executing its example. The website at https://peter-gy.github.io/refkit/ describes
|
|
65
|
+
the current published API and can differ from this installed version.
|
|
66
|
+
"""
|
|
67
|
+
try:
|
|
68
|
+
skill = agent_skill()
|
|
69
|
+
tree = _indent(skill.tree(), " ")
|
|
70
|
+
except AgentPluginError as error:
|
|
71
|
+
return f"{introduction}\nAgent Plugin unavailable: {error}\nReinstall refkit.\n"
|
|
72
|
+
return f"{introduction}\nInstalled task resources:\n\n{tree}\n"
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
__all__ = [
|
|
76
|
+
"AgentPluginError",
|
|
77
|
+
"agent_plugin",
|
|
78
|
+
"agent_skill",
|
|
79
|
+
"instructions",
|
|
80
|
+
"resources",
|
|
81
|
+
]
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class _AgentModule(_ModuleType):
|
|
85
|
+
@property
|
|
86
|
+
def __doc__(self) -> str | None: # pyrefly: ignore [bad-override]
|
|
87
|
+
summary = self.__dict__.get("__doc__")
|
|
88
|
+
if not isinstance(summary, str): # pragma: no cover - interpreter module state
|
|
89
|
+
return None
|
|
90
|
+
return _module_help(summary)
|
|
91
|
+
|
|
92
|
+
@__doc__.setter
|
|
93
|
+
def __doc__(self, value: str | None) -> None: # pragma: no cover - interpreter hook
|
|
94
|
+
self.__dict__["__doc__"] = value
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
_sys.modules[__name__].__class__ = _AgentModule
|
refkit/py.typed
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|