pynakes 0.5.1__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.
- pynakes-0.5.1/.pre-commit-hooks.yaml +49 -0
- pynakes-0.5.1/LICENSE +21 -0
- pynakes-0.5.1/MANIFEST.in +4 -0
- pynakes-0.5.1/PKG-INFO +242 -0
- pynakes-0.5.1/README.md +197 -0
- pynakes-0.5.1/pyproject.toml +98 -0
- pynakes-0.5.1/setup.cfg +4 -0
- pynakes-0.5.1/src/pynakes/__init__.py +8 -0
- pynakes-0.5.1/src/pynakes/__main__.py +6 -0
- pynakes-0.5.1/src/pynakes/_calendar.py +58 -0
- pynakes-0.5.1/src/pynakes/_engine_groups.py +88 -0
- pynakes-0.5.1/src/pynakes/_engine_helpers.py +741 -0
- pynakes-0.5.1/src/pynakes/_engine_keys.py +92 -0
- pynakes-0.5.1/src/pynakes/_engine_ops.py +564 -0
- pynakes-0.5.1/src/pynakes/_identifiers.py +69 -0
- pynakes-0.5.1/src/pynakes/_text_utils.py +163 -0
- pynakes-0.5.1/src/pynakes/authors.py +270 -0
- pynakes-0.5.1/src/pynakes/batch.py +165 -0
- pynakes-0.5.1/src/pynakes/bibtex_parser.py +386 -0
- pynakes-0.5.1/src/pynakes/bibtex_writer.py +182 -0
- pynakes-0.5.1/src/pynakes/canonical.py +431 -0
- pynakes-0.5.1/src/pynakes/capabilities.py +345 -0
- pynakes-0.5.1/src/pynakes/cli.py +217 -0
- pynakes-0.5.1/src/pynakes/cli_commands/__init__.py +1 -0
- pynakes-0.5.1/src/pynakes/cli_commands/_fetch_report.py +39 -0
- pynakes-0.5.1/src/pynakes/cli_commands/_reference.py +129 -0
- pynakes-0.5.1/src/pynakes/cli_commands/add.py +150 -0
- pynakes-0.5.1/src/pynakes/cli_commands/batch.py +87 -0
- pynakes-0.5.1/src/pynakes/cli_commands/capabilities.py +34 -0
- pynakes-0.5.1/src/pynakes/cli_commands/convert.py +185 -0
- pynakes-0.5.1/src/pynakes/cli_commands/dedupe.py +116 -0
- pynakes-0.5.1/src/pynakes/cli_commands/edit.py +105 -0
- pynakes-0.5.1/src/pynakes/cli_commands/fetch.py +221 -0
- pynakes-0.5.1/src/pynakes/cli_commands/fields.py +206 -0
- pynakes-0.5.1/src/pynakes/cli_commands/files.py +110 -0
- pynakes-0.5.1/src/pynakes/cli_commands/format.py +217 -0
- pynakes-0.5.1/src/pynakes/cli_commands/groups.py +355 -0
- pynakes-0.5.1/src/pynakes/cli_commands/import_ref.py +176 -0
- pynakes-0.5.1/src/pynakes/cli_commands/init.py +302 -0
- pynakes-0.5.1/src/pynakes/cli_commands/inspect.py +115 -0
- pynakes-0.5.1/src/pynakes/cli_commands/integrity.py +173 -0
- pynakes-0.5.1/src/pynakes/cli_commands/keys.py +457 -0
- pynakes-0.5.1/src/pynakes/cli_commands/lint.py +68 -0
- pynakes-0.5.1/src/pynakes/cli_commands/metadata.py +257 -0
- pynakes-0.5.1/src/pynakes/cli_commands/normalize.py +206 -0
- pynakes-0.5.1/src/pynakes/cli_commands/remove.py +86 -0
- pynakes-0.5.1/src/pynakes/cli_commands/search.py +86 -0
- pynakes-0.5.1/src/pynakes/cli_commands/setops.py +360 -0
- pynakes-0.5.1/src/pynakes/cli_commands/show.py +48 -0
- pynakes-0.5.1/src/pynakes/cli_commands/tex.py +277 -0
- pynakes-0.5.1/src/pynakes/cli_commands/used.py +142 -0
- pynakes-0.5.1/src/pynakes/cli_common.py +543 -0
- pynakes-0.5.1/src/pynakes/cli_discovery.py +326 -0
- pynakes-0.5.1/src/pynakes/convert.py +270 -0
- pynakes-0.5.1/src/pynakes/dedupe.py +449 -0
- pynakes-0.5.1/src/pynakes/diff.py +32 -0
- pynakes-0.5.1/src/pynakes/editing.py +421 -0
- pynakes-0.5.1/src/pynakes/engine.py +449 -0
- pynakes-0.5.1/src/pynakes/fetch.py +695 -0
- pynakes-0.5.1/src/pynakes/fetch_progress.py +35 -0
- pynakes-0.5.1/src/pynakes/fields.py +280 -0
- pynakes-0.5.1/src/pynakes/files.py +222 -0
- pynakes-0.5.1/src/pynakes/filestore.py +913 -0
- pynakes-0.5.1/src/pynakes/formatters/__init__.py +91 -0
- pynakes-0.5.1/src/pynakes/formatters/_case.py +254 -0
- pynakes-0.5.1/src/pynakes/formatters/_date.py +91 -0
- pynakes-0.5.1/src/pynakes/formatters/_extra.py +130 -0
- pynakes-0.5.1/src/pynakes/formatters/_latex.py +494 -0
- pynakes-0.5.1/src/pynakes/formatters/_latex_tables.py +154 -0
- pynakes-0.5.1/src/pynakes/formatters/_pages.py +32 -0
- pynakes-0.5.1/src/pynakes/formatters/_registry.py +87 -0
- pynakes-0.5.1/src/pynakes/formatters/_units.py +53 -0
- pynakes-0.5.1/src/pynakes/group_tree.py +624 -0
- pynakes-0.5.1/src/pynakes/groups.py +73 -0
- pynakes-0.5.1/src/pynakes/importer.py +469 -0
- pynakes-0.5.1/src/pynakes/inheritance.py +155 -0
- pynakes-0.5.1/src/pynakes/initialize.py +264 -0
- pynakes-0.5.1/src/pynakes/integrity.py +679 -0
- pynakes-0.5.1/src/pynakes/interchange/__init__.py +75 -0
- pynakes-0.5.1/src/pynakes/interchange/_shared.py +262 -0
- pynakes-0.5.1/src/pynakes/interchange/csl.py +170 -0
- pynakes-0.5.1/src/pynakes/interchange/csv.py +72 -0
- pynakes-0.5.1/src/pynakes/interchange/endnote.py +171 -0
- pynakes-0.5.1/src/pynakes/interchange/mods.py +328 -0
- pynakes-0.5.1/src/pynakes/interchange/ris.py +152 -0
- pynakes-0.5.1/src/pynakes/io.py +187 -0
- pynakes-0.5.1/src/pynakes/journals.py +517 -0
- pynakes-0.5.1/src/pynakes/keys.py +363 -0
- pynakes-0.5.1/src/pynakes/lint.py +673 -0
- pynakes-0.5.1/src/pynakes/metadata/__init__.py +196 -0
- pynakes-0.5.1/src/pynakes/metadata/core.py +588 -0
- pynakes-0.5.1/src/pynakes/metadata/jabref.py +888 -0
- pynakes-0.5.1/src/pynakes/metadata/schema.py +190 -0
- pynakes-0.5.1/src/pynakes/model.py +578 -0
- pynakes-0.5.1/src/pynakes/normalize.py +540 -0
- pynakes-0.5.1/src/pynakes/providers/__init__.py +1 -0
- pynakes-0.5.1/src/pynakes/providers/_http.py +255 -0
- pynakes-0.5.1/src/pynakes/providers/arxiv.py +133 -0
- pynakes-0.5.1/src/pynakes/providers/crossref.py +78 -0
- pynakes-0.5.1/src/pynakes/providers/doi.py +31 -0
- pynakes-0.5.1/src/pynakes/providers/identity.py +48 -0
- pynakes-0.5.1/src/pynakes/providers/openalex.py +122 -0
- pynakes-0.5.1/src/pynakes/providers/pdf_overrides.json +106 -0
- pynakes-0.5.1/src/pynakes/providers/pdf_overrides.py +61 -0
- pynakes-0.5.1/src/pynakes/providers/publisher.py +111 -0
- pynakes-0.5.1/src/pynakes/providers/semantic_scholar.py +45 -0
- pynakes-0.5.1/src/pynakes/py.typed +0 -0
- pynakes-0.5.1/src/pynakes/search.py +222 -0
- pynakes-0.5.1/src/pynakes/setops.py +212 -0
- pynakes-0.5.1/src/pynakes/usage.py +378 -0
- pynakes-0.5.1/src/pynakes.egg-info/PKG-INFO +242 -0
- pynakes-0.5.1/src/pynakes.egg-info/SOURCES.txt +181 -0
- pynakes-0.5.1/src/pynakes.egg-info/dependency_links.txt +1 -0
- pynakes-0.5.1/src/pynakes.egg-info/entry_points.txt +2 -0
- pynakes-0.5.1/src/pynakes.egg-info/requires.txt +18 -0
- pynakes-0.5.1/src/pynakes.egg-info/top_level.txt +1 -0
- pynakes-0.5.1/tests/__init__.py +0 -0
- pynakes-0.5.1/tests/agent_eval/__init__.py +1 -0
- pynakes-0.5.1/tests/agent_eval/providers.py +147 -0
- pynakes-0.5.1/tests/agent_eval/runner.py +320 -0
- pynakes-0.5.1/tests/agent_eval/schemas.py +155 -0
- pynakes-0.5.1/tests/agent_eval/workspace.py +87 -0
- pynakes-0.5.1/tests/conftest.py +32 -0
- pynakes-0.5.1/tests/fixtures/biblatex_sample.bib +45 -0
- pynakes-0.5.1/tests/fixtures/bibtex_classic.bib +50 -0
- pynakes-0.5.1/tests/fixtures/conformance/biblatex-3.21-core.bib +31 -0
- pynakes-0.5.1/tests/fixtures/conformance/bibtex-0.99d-core.bib +31 -0
- pynakes-0.5.1/tests/fixtures/conformance/bibtex-regression.bib +55 -0
- pynakes-0.5.1/tests/fixtures/conformance/manifest.json +49 -0
- pynakes-0.5.1/tests/fixtures/conformance/upstream/biblatex-3.21-examples.bib +1663 -0
- pynakes-0.5.1/tests/fixtures/conformance/upstream/bibtex-0.99d-xampl.bib +362 -0
- pynakes-0.5.1/tests/fixtures/duplicate_entries.bib +51 -0
- pynakes-0.5.1/tests/fixtures/jabref_groups.bib +46 -0
- pynakes-0.5.1/tests/fixtures/linked_files.bib +43 -0
- pynakes-0.5.1/tests/fixtures/paper.aux +6 -0
- pynakes-0.5.1/tests/fixtures/paper.tex +11 -0
- pynakes-0.5.1/tests/fixtures/simple.bib +41 -0
- pynakes-0.5.1/tests/test_agent_beta_eval.py +72 -0
- pynakes-0.5.1/tests/test_batch.py +176 -0
- pynakes-0.5.1/tests/test_bibtex_parser.py +516 -0
- pynakes-0.5.1/tests/test_bibtex_writer.py +345 -0
- pynakes-0.5.1/tests/test_canonical.py +412 -0
- pynakes-0.5.1/tests/test_capabilities.py +130 -0
- pynakes-0.5.1/tests/test_cli.py +3359 -0
- pynakes-0.5.1/tests/test_conformance_corpus.py +163 -0
- pynakes-0.5.1/tests/test_convert.py +244 -0
- pynakes-0.5.1/tests/test_dedupe.py +300 -0
- pynakes-0.5.1/tests/test_diff.py +26 -0
- pynakes-0.5.1/tests/test_editing.py +133 -0
- pynakes-0.5.1/tests/test_engine.py +435 -0
- pynakes-0.5.1/tests/test_error_recovery.py +67 -0
- pynakes-0.5.1/tests/test_fetch.py +627 -0
- pynakes-0.5.1/tests/test_fields.py +224 -0
- pynakes-0.5.1/tests/test_files.py +144 -0
- pynakes-0.5.1/tests/test_filestore.py +352 -0
- pynakes-0.5.1/tests/test_gate_checks.py +177 -0
- pynakes-0.5.1/tests/test_group_tree.py +1251 -0
- pynakes-0.5.1/tests/test_groups.py +82 -0
- pynakes-0.5.1/tests/test_importer.py +435 -0
- pynakes-0.5.1/tests/test_inheritance.py +204 -0
- pynakes-0.5.1/tests/test_init.py +284 -0
- pynakes-0.5.1/tests/test_integrity.py +324 -0
- pynakes-0.5.1/tests/test_interchange.py +204 -0
- pynakes-0.5.1/tests/test_io.py +291 -0
- pynakes-0.5.1/tests/test_jabref_compatibility.py +538 -0
- pynakes-0.5.1/tests/test_jabref_metadata.py +897 -0
- pynakes-0.5.1/tests/test_jabref_parity.py +620 -0
- pynakes-0.5.1/tests/test_journals.py +165 -0
- pynakes-0.5.1/tests/test_keys.py +306 -0
- pynakes-0.5.1/tests/test_latex_utils.py +23 -0
- pynakes-0.5.1/tests/test_lint.py +515 -0
- pynakes-0.5.1/tests/test_metadata_schema.py +358 -0
- pynakes-0.5.1/tests/test_model.py +336 -0
- pynakes-0.5.1/tests/test_normalize.py +403 -0
- pynakes-0.5.1/tests/test_paren_operations.py +297 -0
- pynakes-0.5.1/tests/test_property.py +138 -0
- pynakes-0.5.1/tests/test_providers.py +210 -0
- pynakes-0.5.1/tests/test_reference_interactive.py +145 -0
- pynakes-0.5.1/tests/test_search.py +122 -0
- pynakes-0.5.1/tests/test_setops.py +526 -0
- pynakes-0.5.1/tests/test_stress.py +57 -0
- pynakes-0.5.1/tests/test_usage.py +209 -0
- pynakes-0.5.1/tests/test_workflows.py +107 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# pynakes pre-commit hooks.
|
|
2
|
+
#
|
|
3
|
+
# Add to a repository's .pre-commit-config.yaml:
|
|
4
|
+
#
|
|
5
|
+
# repos:
|
|
6
|
+
# - repo: https://github.com/maiani/pynakes
|
|
7
|
+
# rev: v0.5.0
|
|
8
|
+
# hooks:
|
|
9
|
+
# - id: pynakes-lint
|
|
10
|
+
# - id: pynakes-keys-check
|
|
11
|
+
# - id: pynakes-files-check # opt-in: validates linked-file paths
|
|
12
|
+
# - id: pynakes-dedupe-check # opt-in: flags duplicate works
|
|
13
|
+
#
|
|
14
|
+
# Every hook is read-only, offline, and deterministic. pre-commit passes the
|
|
15
|
+
# staged .bib files as arguments; --strict makes a finding fail the commit.
|
|
16
|
+
|
|
17
|
+
- id: pynakes-lint
|
|
18
|
+
name: pynakes lint
|
|
19
|
+
description: Validate BibTeX entries and fail on errors (duplicate/empty keys, missing required fields).
|
|
20
|
+
entry: pynakes lint --strict
|
|
21
|
+
language: python
|
|
22
|
+
files: \.bib$
|
|
23
|
+
types: [file]
|
|
24
|
+
|
|
25
|
+
- id: pynakes-keys-check
|
|
26
|
+
name: pynakes keys check
|
|
27
|
+
description: Fail if any citation key is duplicated.
|
|
28
|
+
entry: pynakes keys check --strict
|
|
29
|
+
language: python
|
|
30
|
+
files: \.bib$
|
|
31
|
+
types: [file]
|
|
32
|
+
|
|
33
|
+
- id: pynakes-files-check
|
|
34
|
+
name: pynakes files check
|
|
35
|
+
description: Fail if any JabRef linked file is missing or the wrong type.
|
|
36
|
+
entry: pynakes files check --strict
|
|
37
|
+
language: python
|
|
38
|
+
files: \.bib$
|
|
39
|
+
types: [file]
|
|
40
|
+
stages: [manual]
|
|
41
|
+
|
|
42
|
+
- id: pynakes-dedupe-check
|
|
43
|
+
name: pynakes dedupe check
|
|
44
|
+
description: Fail if duplicate works (same DOI/arXiv/title) are present.
|
|
45
|
+
entry: pynakes dedupe check --strict
|
|
46
|
+
language: python
|
|
47
|
+
files: \.bib$
|
|
48
|
+
types: [file]
|
|
49
|
+
stages: [manual]
|
pynakes-0.5.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Andrea Maiani
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
pynakes-0.5.1/PKG-INFO
ADDED
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pynakes
|
|
3
|
+
Version: 0.5.1
|
|
4
|
+
Summary: Agent-friendly, round-trip-faithful BibTeX/BibLaTeX maintenance toolkit
|
|
5
|
+
Author-email: Andrea Maiani <dev@andreamaiani.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/maiani/pynakes
|
|
8
|
+
Project-URL: Repository, https://github.com/maiani/pynakes
|
|
9
|
+
Project-URL: Issues, https://github.com/maiani/pynakes/issues
|
|
10
|
+
Project-URL: Changelog, https://github.com/maiani/pynakes/blob/main/CHANGELOG.md
|
|
11
|
+
Keywords: bibtex,biblatex,bibliography,citations,references,jabref,latex,doi,reference-management,cli,agent
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering
|
|
22
|
+
Classifier: Topic :: Text Processing :: Markup :: LaTeX
|
|
23
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
24
|
+
Classifier: Typing :: Typed
|
|
25
|
+
Requires-Python: >=3.11
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
License-File: LICENSE
|
|
28
|
+
Requires-Dist: click>=8.1.0
|
|
29
|
+
Requires-Dist: httpx>=0.27.0
|
|
30
|
+
Requires-Dist: typer>=0.12.0
|
|
31
|
+
Requires-Dist: rich>=13.7.0
|
|
32
|
+
Provides-Extra: dev
|
|
33
|
+
Requires-Dist: pre-commit>=3.6.0; extra == "dev"
|
|
34
|
+
Requires-Dist: pytest>=7.4.0; extra == "dev"
|
|
35
|
+
Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
|
|
36
|
+
Requires-Dist: hypothesis>=6.100.0; extra == "dev"
|
|
37
|
+
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
38
|
+
Requires-Dist: build>=1.2.0; extra == "dev"
|
|
39
|
+
Requires-Dist: twine>=5.0.0; extra == "dev"
|
|
40
|
+
Provides-Extra: docs
|
|
41
|
+
Requires-Dist: mkdocs>=1.6; extra == "docs"
|
|
42
|
+
Requires-Dist: mkdocs-material>=9.5; extra == "docs"
|
|
43
|
+
Requires-Dist: mkdocstrings[python]>=0.26; extra == "docs"
|
|
44
|
+
Dynamic: license-file
|
|
45
|
+
|
|
46
|
+
# pynakes
|
|
47
|
+
|
|
48
|
+
<p align="center">
|
|
49
|
+
<img src="https://raw.githubusercontent.com/maiani/pynakes/main/docs/assets/logo.svg" alt="pynakes logo" width="128">
|
|
50
|
+
</p>
|
|
51
|
+
|
|
52
|
+
[](https://pypi.org/project/pynakes/)
|
|
53
|
+
[](https://pypi.org/project/pynakes/)
|
|
54
|
+
[](https://github.com/maiani/pynakes/actions)
|
|
55
|
+
[](https://github.com/maiani/pynakes/blob/main/LICENSE)
|
|
56
|
+
|
|
57
|
+
> [!WARNING]
|
|
58
|
+
> `pynakes` is alpha-quality software. Interfaces and behavior may change between releases.
|
|
59
|
+
|
|
60
|
+
`pynakes` is a deterministic bibliography maintenance engine built for reliable agentic workflows, CI, and human use. Agents decide what should change; pynakes inspects, validates, previews, and applies those changes safely and reproducibly.
|
|
61
|
+
|
|
62
|
+
The Python CLI makes small, explicit, reviewable changes to `.bib` files —
|
|
63
|
+
minimal diffs, dry-run previews, and atomic writes — and reports every change
|
|
64
|
+
as structured JSON.
|
|
65
|
+
|
|
66
|
+
Requires Python 3.11+ and is packaged as an OS-independent CLI and library.
|
|
67
|
+
|
|
68
|
+
Untouched entries write back byte-for-byte — no hidden reformatting, reordering, or re-quoting. The file stays diff-friendly in git and yours for decades.
|
|
69
|
+
|
|
70
|
+
Named after the *Pinakes*, Callimachus's catalog of the Library of Alexandria — antiquity's first bibliography.
|
|
71
|
+
A `.bib` file is the index card; a **pinax** is the card together with the shelf it points at.
|
|
72
|
+
|
|
73
|
+
## Why pynakes
|
|
74
|
+
|
|
75
|
+
- **Reviewable by design.** Modifying commands support `--dry-run --diff` for review before writing. Writes are atomic and re-parse-validated; `--backup` optionally retains the previous file. Ambiguous cases — conflicting merges, duplicate DOIs — are reported with exit code `2` rather than guessed.
|
|
76
|
+
- **Round-trip fidelity.** An entry you don't touch is written back byte-for-byte. pynakes never normalizes whitespace, reorders fields, or re-quotes values behind your back — so diffs stay tiny and reviewable.
|
|
77
|
+
- **A deterministic execution layer for agents and CI.** Stable JSON output and exit codes, machine-readable `capabilities`, structured change plans, and `--strict` / pre-commit gates let an agent exercise judgment without directly rewriting bibliography text.
|
|
78
|
+
- **Deterministic and offline by default.** No hidden time, randomness, or ordering; network access is explicit (`ref import`, `asset fetch`, or `--online`) and confined to the few commands that need it.
|
|
79
|
+
- **Preservation-first interoperability.** Untouched BibTeX/BibLaTeX source and
|
|
80
|
+
JabRef metadata round-trip unchanged. `pynakes-meta` holds native settings;
|
|
81
|
+
JabRef metadata can be preserved, adopted, and projected explicitly.
|
|
82
|
+
|
|
83
|
+
## Two workflows
|
|
84
|
+
|
|
85
|
+
### 1. Bibliography engine
|
|
86
|
+
Load any `.bib` file the BibTeX/BibLaTeX toolchain produces,
|
|
87
|
+
then:
|
|
88
|
+
|
|
89
|
+
- **Inspect** — entry count, encoding, duplicates, JabRef metadata
|
|
90
|
+
- **Lint** — validate required fields, DOI shape, key conflicts (CI-gate multiple files)
|
|
91
|
+
- **Normalize** — authors, DOIs, months, journals, `saveActions` pipeline
|
|
92
|
+
- **Format** — deterministic layout-only rewrites with explicit layout flags
|
|
93
|
+
- **Import** by DOI or arXiv identifier, with configurable key generation, or add a manual entry
|
|
94
|
+
- **Dedupe & merge** — detect and resolve duplicates, with conflict reporting
|
|
95
|
+
- **Bulk-edit fields** — set, rename, move, append, clear, or protect fields on matching references
|
|
96
|
+
- **Manage groups and keys** — list, rename, repair, generate from patterns
|
|
97
|
+
- **Convert** between BibTeX/BibLaTeX dialects; import/export CSL-JSON, RIS,
|
|
98
|
+
MODS, and EndNote; export CSV
|
|
99
|
+
- **Track citation usage** — find cited, unused, and missing keys in `.tex` or
|
|
100
|
+
`.aux` sources
|
|
101
|
+
- **Remove** entries with a single command
|
|
102
|
+
|
|
103
|
+
All through the standardized lifecycle: load → stage → preview/diff → commit.
|
|
104
|
+
JabRef v5.15 interoperability covers metadata preservation and classification,
|
|
105
|
+
offline-compatible `saveActions`, all four group types, save-order configuration,
|
|
106
|
+
and common key-pattern markers and modifiers. Unsupported formatter names are
|
|
107
|
+
reported rather than silently applied. Every modifying command supports
|
|
108
|
+
`--dry-run --diff` and atomic writes; backups are opt-in.
|
|
109
|
+
|
|
110
|
+
### 2. Pinax — the corpus layer
|
|
111
|
+
|
|
112
|
+
Opt in by setting a `files-dir` in the library metadata. Now every citation key can carry materials:
|
|
113
|
+
|
|
114
|
+
- **arXiv download** — PDFs and source bundles, automatically fetched, verified, and extracted with provenance tracking (source hash, download timestamp)
|
|
115
|
+
- **Open-access published PDFs** — resolved from DOI via OpenAlex, CrossRef, and publisher-specific URL overrides; `.published.pdf` lands only for genuinely OA papers, never misidentified repository mirrors
|
|
116
|
+
- **`asset fetch`** — download configured materials for all entries or one key
|
|
117
|
+
- **`asset check`** — validate presence, detect orphans, verify checksums, optionally fix (`--fix`)
|
|
118
|
+
- **`ref remove`** — removes both the entry and its materials by default
|
|
119
|
+
- **Coordinated key edits** — renaming a key moves its materials
|
|
120
|
+
- **`corpus combine`/`corpus split`** — materials follow their entries
|
|
121
|
+
|
|
122
|
+
The `.bib` stays the source of truth; Pinax just keeps the shelf tidy.
|
|
123
|
+
|
|
124
|
+
## Installation
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
pip install pynakes
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
For development (with test/lint tools):
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
git clone https://github.com/maiani/pynakes.git
|
|
134
|
+
cd pynakes
|
|
135
|
+
pip install -e ".[dev]"
|
|
136
|
+
pre-commit install # enable ruff hooks on commit
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
See the [Installation guide](docs/guides/installation.md) for shell completion and troubleshooting.
|
|
140
|
+
|
|
141
|
+
## Quick start
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
# Create a new library, then inspect and check for issues
|
|
145
|
+
pynakes init mylib.bib
|
|
146
|
+
pynakes inspect mylib.bib
|
|
147
|
+
pynakes lint mylib.bib --json
|
|
148
|
+
|
|
149
|
+
# Import a reference by DOI or arXiv id, or add one manually
|
|
150
|
+
pynakes ref import 10.5555/example mylib.bib
|
|
151
|
+
pynakes ref import arXiv:2301.00001 mylib.bib
|
|
152
|
+
pynakes ref add Manual2026 mylib.bib --field title="Manual Reference" --field year=2026
|
|
153
|
+
pynakes ref add # interactive
|
|
154
|
+
pynakes ref show Manual2026 mylib.bib
|
|
155
|
+
pynakes ref edit Manual2026 mylib.bib --field year=2027 --clear-field note
|
|
156
|
+
pynakes ref edit Manual2026 mylib.bib # interactive
|
|
157
|
+
|
|
158
|
+
# Preview the normalization pass before committing
|
|
159
|
+
pynakes normalize mylib.bib --dry-run --diff
|
|
160
|
+
|
|
161
|
+
# Remove entries by citation key (with pinax material cleanup)
|
|
162
|
+
pynakes ref remove mylib.bib DeprecatedKey2020
|
|
163
|
+
|
|
164
|
+
# Rename a citation key across the .bib file and .tex sources
|
|
165
|
+
pynakes keys rename mylib.bib OldKey2020 NewKey2020 paper.tex chapters/
|
|
166
|
+
|
|
167
|
+
# Fetch configured materials for one entry (Pinax mode)
|
|
168
|
+
pynakes asset fetch arXivKey2024 mylib.bib
|
|
169
|
+
|
|
170
|
+
# Search entries
|
|
171
|
+
pynakes search mylib.bib "neural network" --json
|
|
172
|
+
|
|
173
|
+
# Gate a build: fail if any .bib has errors
|
|
174
|
+
pynakes lint mylib.bib chapters/*.bib --strict
|
|
175
|
+
|
|
176
|
+
# Shell completion for cite keys (bash/zsh/fish)
|
|
177
|
+
eval "$(pynakes --show-completion bash)"
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
When the current directory contains exactly one `.bib` file, its path may be omitted from commands that operate on a single library (for example, `pynakes normalize --dry-run`).
|
|
181
|
+
|
|
182
|
+
Commands still require an explicit path when there are multiple `.bib` files.
|
|
183
|
+
|
|
184
|
+
See the [Quick Start guide](docs/guides/quickstart.md) and [Usage guide](docs/guides/usage.md) for the full command surface.
|
|
185
|
+
|
|
186
|
+
## Safety model
|
|
187
|
+
|
|
188
|
+
Every modifying command:
|
|
189
|
+
|
|
190
|
+
- Validates before writing (parse errors, conflicts, missing required fields)
|
|
191
|
+
- Supports `--dry-run` and `--diff` to preview changes
|
|
192
|
+
- Writes atomically and optionally creates a `.bak` backup
|
|
193
|
+
- Reports conflicts and exits `2` rather than guessing (e.g. duplicate DOI on import)
|
|
194
|
+
- Emits structured JSON (`--json`) for programmatic use
|
|
195
|
+
|
|
196
|
+
## For scripted and LLM-assisted workflows
|
|
197
|
+
|
|
198
|
+
In an agentic workflow, the agent supplies judgment and pynakes supplies the
|
|
199
|
+
deterministic execution layer. The same interface is safe for ordinary scripts
|
|
200
|
+
and CI:
|
|
201
|
+
|
|
202
|
+
- `--json` returns machine-readable results with status, warnings, and errors
|
|
203
|
+
- `pynakes capabilities --json` describes supported operations for an agent
|
|
204
|
+
- Exit codes: `0` success, `1` error, `2` conflict (safe to retry with user input)
|
|
205
|
+
|
|
206
|
+
See the [LLM Integration guide](docs/guides/llm-integration.md) for the full JSON envelope and recommended workflows.
|
|
207
|
+
|
|
208
|
+
## Status
|
|
209
|
+
|
|
210
|
+
v0.5.0 is the first public alpha. It includes the preservation-first
|
|
211
|
+
parser/writer, the documented maintenance command surface, broad JabRef v5.15
|
|
212
|
+
interoperability, machine-readable command discovery, and the optional Pinax
|
|
213
|
+
corpus layer with arXiv and published-PDF material workflows. CI tests Python
|
|
214
|
+
3.11–3.13 and enforces a 90% coverage floor.
|
|
215
|
+
|
|
216
|
+
Until v1.0, pynakes does **not** guarantee backward compatibility for the Python
|
|
217
|
+
API, CLI syntax, or JSON envelopes. The project aims to keep automation
|
|
218
|
+
workflows predictable and documents breaking changes in the changelog, but
|
|
219
|
+
production users should pin exact `0.x` versions.
|
|
220
|
+
|
|
221
|
+
Parser conformance is verified against the TeX Live 2026 toolchain (BibTeX 0.99d,
|
|
222
|
+
BibLaTeX 3.21, Biber 2.21). The project roadmap is documented in
|
|
223
|
+
[DEVPLAN.md](DEVPLAN.md).
|
|
224
|
+
|
|
225
|
+
## Documentation
|
|
226
|
+
|
|
227
|
+
- [Quick Start](docs/guides/quickstart.md)
|
|
228
|
+
- [Usage Guide](docs/guides/usage.md)
|
|
229
|
+
- [Installation](docs/guides/installation.md)
|
|
230
|
+
- [LLM Integration](docs/guides/llm-integration.md)
|
|
231
|
+
- [Git Workflows: pre-commit & CI](docs/guides/git-workflows.md)
|
|
232
|
+
- [Architecture](docs/guides/architecture.md)
|
|
233
|
+
- [Pinax — the corpus layer](docs/guides/pinax.md)
|
|
234
|
+
- [API Reference](docs/api/reference.md)
|
|
235
|
+
|
|
236
|
+
## License
|
|
237
|
+
|
|
238
|
+
MIT — see [LICENSE](LICENSE).
|
|
239
|
+
|
|
240
|
+
## Contributing
|
|
241
|
+
|
|
242
|
+
Contributions are welcome — see [CONTRIBUTING.md](CONTRIBUTING.md).
|
pynakes-0.5.1/README.md
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
# pynakes
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<img src="https://raw.githubusercontent.com/maiani/pynakes/main/docs/assets/logo.svg" alt="pynakes logo" width="128">
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
[](https://pypi.org/project/pynakes/)
|
|
8
|
+
[](https://pypi.org/project/pynakes/)
|
|
9
|
+
[](https://github.com/maiani/pynakes/actions)
|
|
10
|
+
[](https://github.com/maiani/pynakes/blob/main/LICENSE)
|
|
11
|
+
|
|
12
|
+
> [!WARNING]
|
|
13
|
+
> `pynakes` is alpha-quality software. Interfaces and behavior may change between releases.
|
|
14
|
+
|
|
15
|
+
`pynakes` is a deterministic bibliography maintenance engine built for reliable agentic workflows, CI, and human use. Agents decide what should change; pynakes inspects, validates, previews, and applies those changes safely and reproducibly.
|
|
16
|
+
|
|
17
|
+
The Python CLI makes small, explicit, reviewable changes to `.bib` files —
|
|
18
|
+
minimal diffs, dry-run previews, and atomic writes — and reports every change
|
|
19
|
+
as structured JSON.
|
|
20
|
+
|
|
21
|
+
Requires Python 3.11+ and is packaged as an OS-independent CLI and library.
|
|
22
|
+
|
|
23
|
+
Untouched entries write back byte-for-byte — no hidden reformatting, reordering, or re-quoting. The file stays diff-friendly in git and yours for decades.
|
|
24
|
+
|
|
25
|
+
Named after the *Pinakes*, Callimachus's catalog of the Library of Alexandria — antiquity's first bibliography.
|
|
26
|
+
A `.bib` file is the index card; a **pinax** is the card together with the shelf it points at.
|
|
27
|
+
|
|
28
|
+
## Why pynakes
|
|
29
|
+
|
|
30
|
+
- **Reviewable by design.** Modifying commands support `--dry-run --diff` for review before writing. Writes are atomic and re-parse-validated; `--backup` optionally retains the previous file. Ambiguous cases — conflicting merges, duplicate DOIs — are reported with exit code `2` rather than guessed.
|
|
31
|
+
- **Round-trip fidelity.** An entry you don't touch is written back byte-for-byte. pynakes never normalizes whitespace, reorders fields, or re-quotes values behind your back — so diffs stay tiny and reviewable.
|
|
32
|
+
- **A deterministic execution layer for agents and CI.** Stable JSON output and exit codes, machine-readable `capabilities`, structured change plans, and `--strict` / pre-commit gates let an agent exercise judgment without directly rewriting bibliography text.
|
|
33
|
+
- **Deterministic and offline by default.** No hidden time, randomness, or ordering; network access is explicit (`ref import`, `asset fetch`, or `--online`) and confined to the few commands that need it.
|
|
34
|
+
- **Preservation-first interoperability.** Untouched BibTeX/BibLaTeX source and
|
|
35
|
+
JabRef metadata round-trip unchanged. `pynakes-meta` holds native settings;
|
|
36
|
+
JabRef metadata can be preserved, adopted, and projected explicitly.
|
|
37
|
+
|
|
38
|
+
## Two workflows
|
|
39
|
+
|
|
40
|
+
### 1. Bibliography engine
|
|
41
|
+
Load any `.bib` file the BibTeX/BibLaTeX toolchain produces,
|
|
42
|
+
then:
|
|
43
|
+
|
|
44
|
+
- **Inspect** — entry count, encoding, duplicates, JabRef metadata
|
|
45
|
+
- **Lint** — validate required fields, DOI shape, key conflicts (CI-gate multiple files)
|
|
46
|
+
- **Normalize** — authors, DOIs, months, journals, `saveActions` pipeline
|
|
47
|
+
- **Format** — deterministic layout-only rewrites with explicit layout flags
|
|
48
|
+
- **Import** by DOI or arXiv identifier, with configurable key generation, or add a manual entry
|
|
49
|
+
- **Dedupe & merge** — detect and resolve duplicates, with conflict reporting
|
|
50
|
+
- **Bulk-edit fields** — set, rename, move, append, clear, or protect fields on matching references
|
|
51
|
+
- **Manage groups and keys** — list, rename, repair, generate from patterns
|
|
52
|
+
- **Convert** between BibTeX/BibLaTeX dialects; import/export CSL-JSON, RIS,
|
|
53
|
+
MODS, and EndNote; export CSV
|
|
54
|
+
- **Track citation usage** — find cited, unused, and missing keys in `.tex` or
|
|
55
|
+
`.aux` sources
|
|
56
|
+
- **Remove** entries with a single command
|
|
57
|
+
|
|
58
|
+
All through the standardized lifecycle: load → stage → preview/diff → commit.
|
|
59
|
+
JabRef v5.15 interoperability covers metadata preservation and classification,
|
|
60
|
+
offline-compatible `saveActions`, all four group types, save-order configuration,
|
|
61
|
+
and common key-pattern markers and modifiers. Unsupported formatter names are
|
|
62
|
+
reported rather than silently applied. Every modifying command supports
|
|
63
|
+
`--dry-run --diff` and atomic writes; backups are opt-in.
|
|
64
|
+
|
|
65
|
+
### 2. Pinax — the corpus layer
|
|
66
|
+
|
|
67
|
+
Opt in by setting a `files-dir` in the library metadata. Now every citation key can carry materials:
|
|
68
|
+
|
|
69
|
+
- **arXiv download** — PDFs and source bundles, automatically fetched, verified, and extracted with provenance tracking (source hash, download timestamp)
|
|
70
|
+
- **Open-access published PDFs** — resolved from DOI via OpenAlex, CrossRef, and publisher-specific URL overrides; `.published.pdf` lands only for genuinely OA papers, never misidentified repository mirrors
|
|
71
|
+
- **`asset fetch`** — download configured materials for all entries or one key
|
|
72
|
+
- **`asset check`** — validate presence, detect orphans, verify checksums, optionally fix (`--fix`)
|
|
73
|
+
- **`ref remove`** — removes both the entry and its materials by default
|
|
74
|
+
- **Coordinated key edits** — renaming a key moves its materials
|
|
75
|
+
- **`corpus combine`/`corpus split`** — materials follow their entries
|
|
76
|
+
|
|
77
|
+
The `.bib` stays the source of truth; Pinax just keeps the shelf tidy.
|
|
78
|
+
|
|
79
|
+
## Installation
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
pip install pynakes
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
For development (with test/lint tools):
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
git clone https://github.com/maiani/pynakes.git
|
|
89
|
+
cd pynakes
|
|
90
|
+
pip install -e ".[dev]"
|
|
91
|
+
pre-commit install # enable ruff hooks on commit
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
See the [Installation guide](docs/guides/installation.md) for shell completion and troubleshooting.
|
|
95
|
+
|
|
96
|
+
## Quick start
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
# Create a new library, then inspect and check for issues
|
|
100
|
+
pynakes init mylib.bib
|
|
101
|
+
pynakes inspect mylib.bib
|
|
102
|
+
pynakes lint mylib.bib --json
|
|
103
|
+
|
|
104
|
+
# Import a reference by DOI or arXiv id, or add one manually
|
|
105
|
+
pynakes ref import 10.5555/example mylib.bib
|
|
106
|
+
pynakes ref import arXiv:2301.00001 mylib.bib
|
|
107
|
+
pynakes ref add Manual2026 mylib.bib --field title="Manual Reference" --field year=2026
|
|
108
|
+
pynakes ref add # interactive
|
|
109
|
+
pynakes ref show Manual2026 mylib.bib
|
|
110
|
+
pynakes ref edit Manual2026 mylib.bib --field year=2027 --clear-field note
|
|
111
|
+
pynakes ref edit Manual2026 mylib.bib # interactive
|
|
112
|
+
|
|
113
|
+
# Preview the normalization pass before committing
|
|
114
|
+
pynakes normalize mylib.bib --dry-run --diff
|
|
115
|
+
|
|
116
|
+
# Remove entries by citation key (with pinax material cleanup)
|
|
117
|
+
pynakes ref remove mylib.bib DeprecatedKey2020
|
|
118
|
+
|
|
119
|
+
# Rename a citation key across the .bib file and .tex sources
|
|
120
|
+
pynakes keys rename mylib.bib OldKey2020 NewKey2020 paper.tex chapters/
|
|
121
|
+
|
|
122
|
+
# Fetch configured materials for one entry (Pinax mode)
|
|
123
|
+
pynakes asset fetch arXivKey2024 mylib.bib
|
|
124
|
+
|
|
125
|
+
# Search entries
|
|
126
|
+
pynakes search mylib.bib "neural network" --json
|
|
127
|
+
|
|
128
|
+
# Gate a build: fail if any .bib has errors
|
|
129
|
+
pynakes lint mylib.bib chapters/*.bib --strict
|
|
130
|
+
|
|
131
|
+
# Shell completion for cite keys (bash/zsh/fish)
|
|
132
|
+
eval "$(pynakes --show-completion bash)"
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
When the current directory contains exactly one `.bib` file, its path may be omitted from commands that operate on a single library (for example, `pynakes normalize --dry-run`).
|
|
136
|
+
|
|
137
|
+
Commands still require an explicit path when there are multiple `.bib` files.
|
|
138
|
+
|
|
139
|
+
See the [Quick Start guide](docs/guides/quickstart.md) and [Usage guide](docs/guides/usage.md) for the full command surface.
|
|
140
|
+
|
|
141
|
+
## Safety model
|
|
142
|
+
|
|
143
|
+
Every modifying command:
|
|
144
|
+
|
|
145
|
+
- Validates before writing (parse errors, conflicts, missing required fields)
|
|
146
|
+
- Supports `--dry-run` and `--diff` to preview changes
|
|
147
|
+
- Writes atomically and optionally creates a `.bak` backup
|
|
148
|
+
- Reports conflicts and exits `2` rather than guessing (e.g. duplicate DOI on import)
|
|
149
|
+
- Emits structured JSON (`--json`) for programmatic use
|
|
150
|
+
|
|
151
|
+
## For scripted and LLM-assisted workflows
|
|
152
|
+
|
|
153
|
+
In an agentic workflow, the agent supplies judgment and pynakes supplies the
|
|
154
|
+
deterministic execution layer. The same interface is safe for ordinary scripts
|
|
155
|
+
and CI:
|
|
156
|
+
|
|
157
|
+
- `--json` returns machine-readable results with status, warnings, and errors
|
|
158
|
+
- `pynakes capabilities --json` describes supported operations for an agent
|
|
159
|
+
- Exit codes: `0` success, `1` error, `2` conflict (safe to retry with user input)
|
|
160
|
+
|
|
161
|
+
See the [LLM Integration guide](docs/guides/llm-integration.md) for the full JSON envelope and recommended workflows.
|
|
162
|
+
|
|
163
|
+
## Status
|
|
164
|
+
|
|
165
|
+
v0.5.0 is the first public alpha. It includes the preservation-first
|
|
166
|
+
parser/writer, the documented maintenance command surface, broad JabRef v5.15
|
|
167
|
+
interoperability, machine-readable command discovery, and the optional Pinax
|
|
168
|
+
corpus layer with arXiv and published-PDF material workflows. CI tests Python
|
|
169
|
+
3.11–3.13 and enforces a 90% coverage floor.
|
|
170
|
+
|
|
171
|
+
Until v1.0, pynakes does **not** guarantee backward compatibility for the Python
|
|
172
|
+
API, CLI syntax, or JSON envelopes. The project aims to keep automation
|
|
173
|
+
workflows predictable and documents breaking changes in the changelog, but
|
|
174
|
+
production users should pin exact `0.x` versions.
|
|
175
|
+
|
|
176
|
+
Parser conformance is verified against the TeX Live 2026 toolchain (BibTeX 0.99d,
|
|
177
|
+
BibLaTeX 3.21, Biber 2.21). The project roadmap is documented in
|
|
178
|
+
[DEVPLAN.md](DEVPLAN.md).
|
|
179
|
+
|
|
180
|
+
## Documentation
|
|
181
|
+
|
|
182
|
+
- [Quick Start](docs/guides/quickstart.md)
|
|
183
|
+
- [Usage Guide](docs/guides/usage.md)
|
|
184
|
+
- [Installation](docs/guides/installation.md)
|
|
185
|
+
- [LLM Integration](docs/guides/llm-integration.md)
|
|
186
|
+
- [Git Workflows: pre-commit & CI](docs/guides/git-workflows.md)
|
|
187
|
+
- [Architecture](docs/guides/architecture.md)
|
|
188
|
+
- [Pinax — the corpus layer](docs/guides/pinax.md)
|
|
189
|
+
- [API Reference](docs/api/reference.md)
|
|
190
|
+
|
|
191
|
+
## License
|
|
192
|
+
|
|
193
|
+
MIT — see [LICENSE](LICENSE).
|
|
194
|
+
|
|
195
|
+
## Contributing
|
|
196
|
+
|
|
197
|
+
Contributions are welcome — see [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "pynakes"
|
|
7
|
+
version = "0.5.1"
|
|
8
|
+
description = "Agent-friendly, round-trip-faithful BibTeX/BibLaTeX maintenance toolkit"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
license-files = ["LICENSE"]
|
|
12
|
+
requires-python = ">=3.11"
|
|
13
|
+
authors = [
|
|
14
|
+
{name = "Andrea Maiani", email = "dev@andreamaiani.com"}
|
|
15
|
+
]
|
|
16
|
+
keywords = [
|
|
17
|
+
"bibtex",
|
|
18
|
+
"biblatex",
|
|
19
|
+
"bibliography",
|
|
20
|
+
"citations",
|
|
21
|
+
"references",
|
|
22
|
+
"jabref",
|
|
23
|
+
"latex",
|
|
24
|
+
"doi",
|
|
25
|
+
"reference-management",
|
|
26
|
+
"cli",
|
|
27
|
+
"agent",
|
|
28
|
+
]
|
|
29
|
+
classifiers = [
|
|
30
|
+
"Development Status :: 3 - Alpha",
|
|
31
|
+
"Environment :: Console",
|
|
32
|
+
"Intended Audience :: Science/Research",
|
|
33
|
+
"Intended Audience :: Developers",
|
|
34
|
+
"Operating System :: OS Independent",
|
|
35
|
+
"Programming Language :: Python :: 3",
|
|
36
|
+
"Programming Language :: Python :: 3.11",
|
|
37
|
+
"Programming Language :: Python :: 3.12",
|
|
38
|
+
"Programming Language :: Python :: 3.13",
|
|
39
|
+
"Topic :: Scientific/Engineering",
|
|
40
|
+
"Topic :: Text Processing :: Markup :: LaTeX",
|
|
41
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
42
|
+
"Typing :: Typed",
|
|
43
|
+
]
|
|
44
|
+
dependencies = [
|
|
45
|
+
"click>=8.1.0",
|
|
46
|
+
"httpx>=0.27.0",
|
|
47
|
+
"typer>=0.12.0",
|
|
48
|
+
"rich>=13.7.0",
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
[project.optional-dependencies]
|
|
52
|
+
dev = [
|
|
53
|
+
"pre-commit>=3.6.0",
|
|
54
|
+
"pytest>=7.4.0",
|
|
55
|
+
"pytest-cov>=4.1.0",
|
|
56
|
+
"hypothesis>=6.100.0",
|
|
57
|
+
"ruff>=0.1.0",
|
|
58
|
+
"build>=1.2.0",
|
|
59
|
+
"twine>=5.0.0",
|
|
60
|
+
]
|
|
61
|
+
docs = [
|
|
62
|
+
"mkdocs>=1.6",
|
|
63
|
+
"mkdocs-material>=9.5",
|
|
64
|
+
"mkdocstrings[python]>=0.26",
|
|
65
|
+
]
|
|
66
|
+
|
|
67
|
+
[project.urls]
|
|
68
|
+
Homepage = "https://github.com/maiani/pynakes"
|
|
69
|
+
Repository = "https://github.com/maiani/pynakes"
|
|
70
|
+
Issues = "https://github.com/maiani/pynakes/issues"
|
|
71
|
+
Changelog = "https://github.com/maiani/pynakes/blob/main/CHANGELOG.md"
|
|
72
|
+
|
|
73
|
+
[project.scripts]
|
|
74
|
+
pynakes = "pynakes.cli:app"
|
|
75
|
+
|
|
76
|
+
[tool.setuptools.packages.find]
|
|
77
|
+
where = ["src"]
|
|
78
|
+
|
|
79
|
+
[tool.setuptools.package-data]
|
|
80
|
+
pynakes = ["py.typed", "providers/pdf_overrides.json"]
|
|
81
|
+
|
|
82
|
+
[tool.pytest.ini_options]
|
|
83
|
+
testpaths = ["tests"]
|
|
84
|
+
addopts = "-v --tb=short"
|
|
85
|
+
markers = [
|
|
86
|
+
"agent_eval: opt-in real-agent beta-test harness",
|
|
87
|
+
]
|
|
88
|
+
|
|
89
|
+
[tool.ruff]
|
|
90
|
+
target-version = "py311"
|
|
91
|
+
line-length = 100
|
|
92
|
+
|
|
93
|
+
[tool.ruff.lint]
|
|
94
|
+
select = ["E", "F", "W", "I"]
|
|
95
|
+
ignore = ["E501"]
|
|
96
|
+
|
|
97
|
+
[tool.coverage.run]
|
|
98
|
+
source = ["src/pynakes"]
|
pynakes-0.5.1/setup.cfg
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"""pynakes: Agent-friendly BibTeX library management."""
|
|
2
|
+
|
|
3
|
+
from importlib.metadata import PackageNotFoundError, version
|
|
4
|
+
|
|
5
|
+
try:
|
|
6
|
+
__version__ = version("pynakes")
|
|
7
|
+
except PackageNotFoundError: # running from a source tree that isn't installed
|
|
8
|
+
__version__ = "0.0.0+unknown"
|