linkml-reference-validator 0.2.1rc2__tar.gz → 0.3.0rc1__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.
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/PKG-INFO +2 -2
- linkml_reference_validator-0.3.0rc1/docs/assets/zotero-find-full-text.png +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/docs/concepts/editorial-conventions.md +9 -4
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/docs/concepts/how-it-works.md +45 -0
- linkml_reference_validator-0.3.0rc1/docs/how-to/export-cache-to-zotero.md +114 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/docs/how-to/fetch-full-text-and-pdfs.md +145 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/docs/how-to/repair-validation-errors.md +43 -1
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/docs/how-to/validate-clinical-trials.md +4 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/docs/reference/cli.md +144 -24
- linkml_reference_validator-0.3.0rc1/docs/reference/splitting.md +69 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/docs/setup-guide.md +4 -0
- linkml_reference_validator-0.3.0rc1/docs/superpowers/plans/2026-08-05-private-library-full-text.md +190 -0
- linkml_reference_validator-0.3.0rc1/docs/superpowers/specs/2026-08-05-private-library-full-text-design.md +309 -0
- linkml_reference_validator-0.3.0rc1/docs/troubleshooting.md +968 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/docs/tutorials/complete-workflow.md +1 -1
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/mkdocs.yml +2 -0
- linkml_reference_validator-0.3.0rc1/src/linkml_reference_validator/cli/cache.py +410 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/src/linkml_reference_validator/cli/lookup.py +3 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/src/linkml_reference_validator/cli/repair.py +66 -12
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/src/linkml_reference_validator/cli/validate.py +53 -21
- linkml_reference_validator-0.3.0rc1/src/linkml_reference_validator/etl/__init__.py +12 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/src/linkml_reference_validator/etl/acquire.py +80 -1
- linkml_reference_validator-0.3.0rc1/src/linkml_reference_validator/etl/csl_export.py +73 -0
- linkml_reference_validator-0.3.0rc1/src/linkml_reference_validator/etl/extract/__init__.py +31 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/src/linkml_reference_validator/etl/extract/base.py +11 -3
- linkml_reference_validator-0.3.0rc1/src/linkml_reference_validator/etl/extract/html.py +245 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/src/linkml_reference_validator/etl/extract/pdf.py +9 -2
- linkml_reference_validator-0.3.0rc1/src/linkml_reference_validator/etl/extract/xml.py +264 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/src/linkml_reference_validator/etl/fulltext/__init__.py +2 -0
- linkml_reference_validator-0.3.0rc1/src/linkml_reference_validator/etl/fulltext/base.py +200 -0
- linkml_reference_validator-0.3.0rc1/src/linkml_reference_validator/etl/fulltext/openalex.py +106 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/src/linkml_reference_validator/etl/fulltext/pmc.py +58 -20
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/src/linkml_reference_validator/etl/fulltext/unpaywall.py +25 -9
- linkml_reference_validator-0.3.0rc1/src/linkml_reference_validator/etl/fulltext/zotero.py +252 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/src/linkml_reference_validator/etl/identifiers.py +19 -0
- linkml_reference_validator-0.3.0rc1/src/linkml_reference_validator/etl/reference_fetcher.py +1890 -0
- linkml_reference_validator-0.3.0rc1/src/linkml_reference_validator/etl/sources/pmid.py +595 -0
- linkml_reference_validator-0.3.0rc1/src/linkml_reference_validator/matching.py +75 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/src/linkml_reference_validator/models.py +123 -18
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/src/linkml_reference_validator/plugins/reference_validation_plugin.py +50 -1
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/src/linkml_reference_validator/validation/repairer.py +83 -1
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/src/linkml_reference_validator/validation/supporting_text_validator.py +191 -21
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/fixtures/GEO_GSE12345.md +1 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/fixtures/PMC_TEST001.md +1 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/fixtures/PMC_TEST002.md +2 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/fixtures/PMID_TEST001.md +1 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/fixtures/PMID_TEST002.md +1 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/fixtures/PMID_TEST003.md +2 -0
- linkml_reference_validator-0.2.1rc2/tests/fixtures/CLINICALTRIALS_NCT00000001.md → linkml_reference_validator-0.3.0rc1/tests/fixtures/clinicaltrials_NCT00000001.md +1 -0
- linkml_reference_validator-0.3.0rc1/tests/fixtures/fulltext_html/README.md +22 -0
- linkml_reference_validator-0.3.0rc1/tests/fixtures/fulltext_html/dspace-32894695.html +1 -0
- linkml_reference_validator-0.3.0rc1/tests/fixtures/fulltext_html/iris-19049553.html +359 -0
- linkml_reference_validator-0.3.0rc1/tests/fixtures/fulltext_html/plos-0000308.html +78 -0
- linkml_reference_validator-0.3.0rc1/tests/fixtures/jats/PMC5593426.xml +5 -0
- linkml_reference_validator-0.3.0rc1/tests/fixtures/jats/README.md +21 -0
- linkml_reference_validator-0.3.0rc1/tests/test_absent_abstract_recovery.py +140 -0
- linkml_reference_validator-0.3.0rc1/tests/test_acquire.py +224 -0
- linkml_reference_validator-0.3.0rc1/tests/test_cache_author_recovery.py +102 -0
- linkml_reference_validator-0.3.0rc1/tests/test_cli_cache_enrich.py +227 -0
- linkml_reference_validator-0.3.0rc1/tests/test_cli_cache_export.py +246 -0
- linkml_reference_validator-0.3.0rc1/tests/test_cli_cache_reference.py +271 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/test_cli_repair.py +134 -0
- linkml_reference_validator-0.3.0rc1/tests/test_clinicaltrials_cache.py +234 -0
- linkml_reference_validator-0.3.0rc1/tests/test_empty_snippets.py +794 -0
- linkml_reference_validator-0.3.0rc1/tests/test_extractor_fidelity.py +665 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/test_extractors.py +13 -0
- linkml_reference_validator-0.3.0rc1/tests/test_frontmatter_and_doi_case.py +334 -0
- linkml_reference_validator-0.3.0rc1/tests/test_fulltext_providers.py +356 -0
- linkml_reference_validator-0.3.0rc1/tests/test_html_fulltext_acceptance.py +432 -0
- linkml_reference_validator-0.3.0rc1/tests/test_jats_tables.py +344 -0
- linkml_reference_validator-0.3.0rc1/tests/test_ligature_normalization.py +91 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/test_models.py +13 -0
- linkml_reference_validator-0.3.0rc1/tests/test_no_cache_downgrade.py +526 -0
- linkml_reference_validator-0.3.0rc1/tests/test_open_access_policy.py +686 -0
- linkml_reference_validator-0.3.0rc1/tests/test_pmid_network.py +327 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/test_reference_fetcher.py +692 -3
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/test_sources.py +300 -0
- linkml_reference_validator-0.3.0rc1/tests/test_split_supporting_text.py +75 -0
- linkml_reference_validator-0.3.0rc1/tests/test_validation_counts.py +407 -0
- linkml_reference_validator-0.3.0rc1/tests/test_zotero_provider.py +277 -0
- linkml_reference_validator-0.2.1rc2/docs/troubleshooting.md +0 -706
- linkml_reference_validator-0.2.1rc2/src/linkml_reference_validator/cli/cache.py +0 -143
- linkml_reference_validator-0.2.1rc2/src/linkml_reference_validator/etl/__init__.py +0 -9
- linkml_reference_validator-0.2.1rc2/src/linkml_reference_validator/etl/extract/__init__.py +0 -16
- linkml_reference_validator-0.2.1rc2/src/linkml_reference_validator/etl/extract/html.py +0 -46
- linkml_reference_validator-0.2.1rc2/src/linkml_reference_validator/etl/extract/xml.py +0 -46
- linkml_reference_validator-0.2.1rc2/src/linkml_reference_validator/etl/fulltext/base.py +0 -70
- linkml_reference_validator-0.2.1rc2/src/linkml_reference_validator/etl/fulltext/openalex.py +0 -70
- linkml_reference_validator-0.2.1rc2/src/linkml_reference_validator/etl/reference_fetcher.py +0 -786
- linkml_reference_validator-0.2.1rc2/src/linkml_reference_validator/etl/sources/pmid.py +0 -390
- linkml_reference_validator-0.2.1rc2/tests/test_acquire.py +0 -116
- linkml_reference_validator-0.2.1rc2/tests/test_fulltext_providers.py +0 -175
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/.claude/.mcp.json +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/.claude/settings.json +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/.copier-answers.yml +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/.devcontainer/devcontainer.json +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/.devcontainer/post_create.sh +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/.editorconfig +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/.github/actions/claude-code-action/action.yml +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/.github/actions/claude-issue-summarize-action/action.yml +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/.github/actions/claude-issue-triage-action/action.yml +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/.github/ai-controllers.json +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/.github/copilot-instructions.md +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/.github/copilot-setup-steps.yml +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/.github/dependabot.yml +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/.github/workflows/claude-code-review.yml +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/.github/workflows/claude-issue-summarize.yml +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/.github/workflows/claude-issue-triage.yml +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/.github/workflows/claude-ontology-review.yml +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/.github/workflows/claude.yml +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/.github/workflows/deploy-docs.yaml +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/.github/workflows/dragon-ai.yml +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/.github/workflows/main.yaml +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/.github/workflows/pypi-publish.yaml +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/.gitignore +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/.goosehints +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/.pre-commit-config.yaml +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/.yamllint.yaml +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/AGENTS.md +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/BUG_GEO_ACCESSION_TO_UID.md +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/BUG_ZENODO_DOI_AND_URL_HANDLING.md +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/CLAUDE.md +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/CLI-ISSUES.md +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/CODE_OF_CONDUCT.md +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/CONTRIBUTING.md +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/FEATURE_REQUEST_REPAIR.md +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/LICENSE +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/README.md +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/REVIEW2.md +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/REVIEW3.md +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/ai.just +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/copilot-instructions.md +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/docs/about.md +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/docs/concepts/content-types.md +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/docs/elements/.gitkeep +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/docs/how-to/add-reference-source.md +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/docs/how-to/skip-unsupported-references.md +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/docs/how-to/use-local-files-and-urls.md +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/docs/how-to/validate-dois.md +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/docs/how-to/validate-entrez.md +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/docs/how-to/validate-obo-files.md +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/docs/how-to/validate-titles.md +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/docs/how-to/validate-urls.md +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/docs/index.md +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/docs/notebooks/01_getting_started.ipynb +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/docs/notebooks/02_advanced_usage.ipynb +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/docs/notebooks/03_python_api.ipynb +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/docs/notebooks/04_obo_validation.ipynb +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/docs/notebooks/05_geo_validation.ipynb +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/docs/quickstart.md +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/docs/superpowers/plans/2026-06-12-modular-pdf-fulltext-fetching.md +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/docs/superpowers/specs/2026-06-12-modular-pdf-fulltext-fetching-design.md +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/docs/templates-linkml/README.md +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/docs/todo.md +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/examples/README.md +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/justfile +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/mypy.ini +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/notebooks/01_getting_started.ipynb +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/notebooks/02_advanced_usage.ipynb +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/notebooks/03_python_api.ipynb +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/notebooks/README.md +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/project/README.md +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/project.justfile +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/pyproject.toml +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/pytest.ini +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/src/linkml_reference_validator/__init__.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/src/linkml_reference_validator/_version.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/src/linkml_reference_validator/cli/__init__.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/src/linkml_reference_validator/cli/shared.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/src/linkml_reference_validator/etl/fulltext/epmc_preprint.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/src/linkml_reference_validator/etl/fulltext/json_api.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/src/linkml_reference_validator/etl/fulltext/loader.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/src/linkml_reference_validator/etl/sources/__init__.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/src/linkml_reference_validator/etl/sources/base.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/src/linkml_reference_validator/etl/sources/clinicaltrials.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/src/linkml_reference_validator/etl/sources/doi.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/src/linkml_reference_validator/etl/sources/entrez.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/src/linkml_reference_validator/etl/sources/file.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/src/linkml_reference_validator/etl/sources/json_api.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/src/linkml_reference_validator/etl/sources/loader.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/src/linkml_reference_validator/etl/sources/ppr.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/src/linkml_reference_validator/etl/sources/url.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/src/linkml_reference_validator/etl/sources/utils.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/src/linkml_reference_validator/etl/text_extractor.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/src/linkml_reference_validator/field_detection.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/src/linkml_reference_validator/plugins/REVIEW.md +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/src/linkml_reference_validator/plugins/__init__.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/src/linkml_reference_validator/validation/__init__.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/src/linkml_reference_validator/validation/fuzzy_text_utils.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/__init__.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/conftest.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/data/test_data_deep_nesting_invalid.yaml +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/data/test_data_deep_nesting_valid.yaml +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/data/test_data_invalid.yaml +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/data/test_data_valid.yaml +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/data/test_schema.yaml +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/data/test_schema_deep_nesting.yaml +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/fixtures/PMC_TEST001.txt +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/fixtures/PMC_TEST002.txt +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/fixtures/PMID_TEST001.txt +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/fixtures/PMID_TEST002.txt +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/fixtures/PMID_TEST003.txt +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/fixtures/sample.obo +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/test_cli.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/test_cli_lookup.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/test_clinicaltrials_integration.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/test_deep_nesting.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/test_doi_preprint.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/test_e2e_integration.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/test_epmc_preprint_provider.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/test_field_detection.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/test_fulltext_loader.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/test_fuzzy_suggestions.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/test_geo_integration.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/test_identifiers.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/test_json_api_source.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/test_optional_linkml_dependency.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/test_plugin_integration.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/test_pmc_fulltext.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/test_ppr_source.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/test_real_validation.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/test_repair.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/test_source_utils.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/test_supporting_text_validator.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/test_text_extractor.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/test_title_validation.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/test_unknown_slot_traversal.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/tests/test_validation_config.py +0 -0
- {linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: linkml_reference_validator
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0rc1
|
|
4
4
|
Summary: Validation of supporting text from references and publications
|
|
5
5
|
Author-email: Chris Mungall <cjmungall@lbl.gov>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -248,7 +248,7 @@ Editorial conventions work the same in data files:
|
|
|
248
248
|
|
|
249
249
|
### Normalization Order
|
|
250
250
|
|
|
251
|
-
1. Remove
|
|
251
|
+
1. Remove editorial `[...]` content unless a configured literal pattern matches
|
|
252
252
|
2. Split on `...` if present
|
|
253
253
|
3. For each part:
|
|
254
254
|
- Lowercase
|
|
@@ -258,10 +258,15 @@ Editorial conventions work the same in data files:
|
|
|
258
258
|
|
|
259
259
|
### Regular Expressions
|
|
260
260
|
|
|
261
|
-
Brackets: `\[
|
|
262
|
-
Ellipsis: `\.\.\.` (splits on three dots exactly)
|
|
261
|
+
Brackets: `\[.*?\]` (single-line, non-nested matching; literal patterns can preserve matches)
|
|
263
262
|
|
|
264
|
-
|
|
263
|
+
Ellipsis: `\s*\.{2,}\s*` (splits on two or more ASCII periods)
|
|
264
|
+
|
|
265
|
+
Both `..` (two dots) and `....` (four dots) are treated as separators. The Unicode
|
|
266
|
+
ellipsis `…` is not a separator.
|
|
267
|
+
|
|
268
|
+
Python callers can use the public [supporting text splitting helper](../reference/splitting.md)
|
|
269
|
+
without constructing a validator.
|
|
265
270
|
|
|
266
271
|
## See Also
|
|
267
272
|
|
|
@@ -36,6 +36,51 @@ reference_content = "...The MUC1 oncoprotein blocks nuclear..."
|
|
|
36
36
|
# Match: "muc1 oncoprotein" found in normalized reference
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
+
**Empty excerpts are rejected:**
|
|
40
|
+
|
|
41
|
+
An empty or whitespace-only excerpt is always an error, never a pass. The
|
|
42
|
+
empty string is a substring of every document, so a blank excerpt would
|
|
43
|
+
otherwise be reported as verified evidence while quoting nothing at all:
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
supporting_text = "" # or " ", "\n"
|
|
47
|
+
# ERROR: Supporting text is empty
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The check runs before the reference is fetched, and applies even when the
|
|
51
|
+
reference prefix is on the [skip list](../how-to/skip-unsupported-references.md):
|
|
52
|
+
a blank excerpt is a defect in the data regardless of what it cites. An
|
|
53
|
+
excerpt slot that is *absent* is a different matter — whether it is required
|
|
54
|
+
is up to your schema.
|
|
55
|
+
|
|
56
|
+
**Minimum excerpt length (optional):**
|
|
57
|
+
|
|
58
|
+
A blank excerpt is the extreme case. A two-character one is barely better: a
|
|
59
|
+
short string matches almost any paper by chance, so the match succeeds without
|
|
60
|
+
the excerpt being real evidence. Set `min_excerpt_length` to require a minimum:
|
|
61
|
+
|
|
62
|
+
```yaml
|
|
63
|
+
# .linkml-reference-validator.yaml
|
|
64
|
+
validation:
|
|
65
|
+
min_excerpt_length: 20
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Keep it under `validation:`. A config file that has a `validation:` section
|
|
69
|
+
ignores validation keys placed at the top level — silently, which for an
|
|
70
|
+
opt-in check means it looks enabled while never running.
|
|
71
|
+
|
|
72
|
+
The check is off by default (`0`), so existing data keeps validating as before.
|
|
73
|
+
Length is measured in **non-whitespace characters of quoted text**:
|
|
74
|
+
|
|
75
|
+
- Whitespace is ignored, so PDF-to-text extraction damage does not change the
|
|
76
|
+
count — `"t he pro tein"` and `"the protein"` both measure 10.
|
|
77
|
+
- No tokenizing, so chemical nomenclature and other punctuation-dense strings
|
|
78
|
+
are counted in full — `"2,3-dihydroxybenzoate"` measures 21, not 2 words.
|
|
79
|
+
- Editorial `[brackets]` and `...` separators do not count, since they are
|
|
80
|
+
never matched against the reference.
|
|
81
|
+
|
|
82
|
+
Like the blank check, this runs before the reference is fetched.
|
|
83
|
+
|
|
39
84
|
### 3. Ellipsis Handling
|
|
40
85
|
|
|
41
86
|
When supporting text contains `...`, each part is matched separately:
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# Export a Reference Cache to Zotero
|
|
2
|
+
|
|
3
|
+
This workflow turns a checked-in public reference cache into a Zotero collection,
|
|
4
|
+
asks Zotero to find available PDFs, and then inventories the resulting attachments
|
|
5
|
+
without putting closed manuscripts into the project repository.
|
|
6
|
+
|
|
7
|
+
The three stores remain separate:
|
|
8
|
+
|
|
9
|
+
| Store | Purpose | Safe to commit? |
|
|
10
|
+
|---|---|---:|
|
|
11
|
+
| Project `references_cache` | Reproducible public validation evidence | Yes |
|
|
12
|
+
| Zotero library | User-managed references and PDF attachments | No |
|
|
13
|
+
| Private research cache | Extracted user-library text for agent context | No |
|
|
14
|
+
|
|
15
|
+
Normal validation reads only the first store.
|
|
16
|
+
|
|
17
|
+
## 1. Export metadata from the public cache
|
|
18
|
+
|
|
19
|
+
Run the exporter from the `linkml-reference-validator` checkout. For dismech:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
uv run linkml-reference-validator cache export \
|
|
23
|
+
--cache-dir /Users/cjm/repos/dismech/references_cache \
|
|
24
|
+
--needs-full-text \
|
|
25
|
+
--output /Users/cjm/Downloads/dismech-zotero.json
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
`--needs-full-text` is the default. It excludes cache entries that already have
|
|
29
|
+
full text, excludes non-publication identifiers, and deduplicates by normalized
|
|
30
|
+
DOI and then PMID. The CSL JSON output uses an explicit metadata allowlist:
|
|
31
|
+
|
|
32
|
+
- title and authors;
|
|
33
|
+
- journal and year;
|
|
34
|
+
- DOI; or
|
|
35
|
+
- PMID and its public PubMed URL.
|
|
36
|
+
|
|
37
|
+
It never contains cached article text, excerpts, provenance, PDFs, local paths,
|
|
38
|
+
or private-cache data. The command refuses to replace an existing output file;
|
|
39
|
+
use `--force` only after checking the destination. Use `--all` if you explicitly
|
|
40
|
+
want eligible references that already contain full text.
|
|
41
|
+
|
|
42
|
+
## 2. Import the file into Zotero
|
|
43
|
+
|
|
44
|
+
In Zotero:
|
|
45
|
+
|
|
46
|
+
1. Choose **File → Import**.
|
|
47
|
+
2. Choose **A file**.
|
|
48
|
+
3. Select `dismech-zotero.json`.
|
|
49
|
+
4. Keep the imported records in a project-specific collection such as
|
|
50
|
+
**dismech**.
|
|
51
|
+
|
|
52
|
+
CSL JSON is a standard format supported by Zotero. Importing the file adds only
|
|
53
|
+
bibliographic records; it does not copy anything from the validator's caches.
|
|
54
|
+
|
|
55
|
+
## 3. Ask Zotero to find PDFs
|
|
56
|
+
|
|
57
|
+
Select one or more top-level journal articles in the center item list,
|
|
58
|
+
right-click the selection, and choose **Find Full Text**. It is a built-in Zotero
|
|
59
|
+
command, not a plugin.
|
|
60
|
+
|
|
61
|
+

|
|
62
|
+
|
|
63
|
+
The command appears for an eligible parent item that has a DOI and does not
|
|
64
|
+
already have a file attachment. It may also be unavailable in a group library
|
|
65
|
+
where files cannot be added. If it is absent, first test a single article in
|
|
66
|
+
your personal library and confirm that its DOI field is populated.
|
|
67
|
+
|
|
68
|
+
For a large import, start with a modest batch rather than all records at once.
|
|
69
|
+
Publishers can temporarily rate-limit repeated requests, and a later retry may
|
|
70
|
+
find additional files. Zotero reports **Full Text PDF** or **No file found** for
|
|
71
|
+
each attempted item.
|
|
72
|
+
|
|
73
|
+
## 4. Inventory the enriched Zotero library
|
|
74
|
+
|
|
75
|
+
Once Zotero finishes, scan the project cache again:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
uv run linkml-reference-validator cache enrich \
|
|
79
|
+
--provider zotero \
|
|
80
|
+
--cache-dir /Users/cjm/repos/dismech/references_cache \
|
|
81
|
+
--dry-run
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
This read-only scan matches exact DOI, PMID, or PMCID identifiers and reports
|
|
85
|
+
which cached references now have usable Zotero text or PDF attachments. It does
|
|
86
|
+
not invoke **Find Full Text** and does not modify Zotero.
|
|
87
|
+
|
|
88
|
+
After reviewing the matches, materialize them into the separate private research
|
|
89
|
+
cache:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
uv run linkml-reference-validator cache enrich \
|
|
93
|
+
--provider zotero \
|
|
94
|
+
--cache-dir /Users/cjm/repos/dismech/references_cache \
|
|
95
|
+
--apply
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Apply mode leaves `references_cache` unchanged. Private content goes to
|
|
99
|
+
`~/.cache/linkml-reference-validator/private` by default with owner-only
|
|
100
|
+
permissions. Agents may inspect it for context, but validation cannot use it as
|
|
101
|
+
evidence.
|
|
102
|
+
|
|
103
|
+
## 5. Validate reproducibly
|
|
104
|
+
|
|
105
|
+
Run validation normally. Results remain reproducible because the validator
|
|
106
|
+
reads the public project cache and accepts only public full-text provider results.
|
|
107
|
+
Neither the contents of Zotero nor the machine-specific private cache affect
|
|
108
|
+
validation.
|
|
109
|
+
|
|
110
|
+
## See also
|
|
111
|
+
|
|
112
|
+
- [Fetching Full Text and PDFs](fetch-full-text-and-pdfs.md)
|
|
113
|
+
- [Zotero: importing standardized formats](https://www.zotero.org/support/kb/importing_standardized_formats)
|
|
114
|
+
- [Zotero: adding files to a library](https://www.zotero.org/support/attaching_files)
|
|
@@ -46,9 +46,11 @@ your config YAML or on the `ReferenceValidationConfig` object):
|
|
|
46
46
|
|-----|---------|-------------|
|
|
47
47
|
| `fetch_full_text` | `true` | Attempt to obtain full text via the provider chain when a metadata source does not already return full text. |
|
|
48
48
|
| `full_text_providers` | `[pmc, epmc_preprint, unpaywall, openalex]` | Ordered list of provider names to try until one yields usable full text. |
|
|
49
|
+
| `private_cache_dir` | `~/.cache/linkml-reference-validator/private` | Separate research cache for closed/user-library full text; never read by validation. |
|
|
49
50
|
| `pdf_backend` | `pypdf` | Name of the PDF text-extraction backend. |
|
|
50
51
|
| `download_pdfs` | `true` | If true, persist downloaded PDFs to the files cache directory. |
|
|
51
52
|
| `full_text_providers_file` | `null` | Optional path to a YAML file defining custom full-text providers. |
|
|
53
|
+
| `zotero_base_url` | `http://localhost:23119/api/users/0` | Read-only Zotero local API library used by the opt-in `zotero` provider. |
|
|
52
54
|
|
|
53
55
|
Two existing keys are also reused by the full-text machinery:
|
|
54
56
|
|
|
@@ -71,6 +73,106 @@ pdf_backend: pypdf
|
|
|
71
73
|
download_pdfs: true
|
|
72
74
|
```
|
|
73
75
|
|
|
76
|
+
## Private manuscripts in Zotero
|
|
77
|
+
|
|
78
|
+
The opt-in **`zotero`** provider can find non-open manuscripts that are already
|
|
79
|
+
in your personal Zotero library. It matches exact DOI, PMID, or PMCID identifiers;
|
|
80
|
+
it does not automatically accept fuzzy title matches.
|
|
81
|
+
|
|
82
|
+
Zotero must be running, and its local API must be enabled in Zotero's advanced
|
|
83
|
+
settings. Inventory the reference cache before changing it:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
linkml-reference-validator cache enrich \
|
|
87
|
+
--provider zotero \
|
|
88
|
+
--cache-dir references_cache \
|
|
89
|
+
--dry-run
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
The report distinguishes `found`, `not_found`, `already_full_text`, and `error`.
|
|
93
|
+
Dry-run is the default and never changes cache files. After reviewing exact
|
|
94
|
+
matches, apply usable text with:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
linkml-reference-validator cache enrich \
|
|
98
|
+
--provider zotero \
|
|
99
|
+
--cache-dir references_cache \
|
|
100
|
+
--apply
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Apply mode does **not** modify `references_cache`. It writes the enriched entry
|
|
104
|
+
to a separate research cache at `~/.cache/linkml-reference-validator/private`
|
|
105
|
+
by default. Agents may inspect that cache for background context, but ordinary
|
|
106
|
+
validation never reads it and never cites it as evidence. Validation therefore
|
|
107
|
+
has the same inputs locally, in CI, and on another contributor's machine.
|
|
108
|
+
|
|
109
|
+
To keep the research cache in a private repository or another secured location:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
linkml-reference-validator cache enrich \
|
|
113
|
+
--provider zotero \
|
|
114
|
+
--cache-dir references_cache \
|
|
115
|
+
--private-cache-dir /path/to/private-reference-cache \
|
|
116
|
+
--apply
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
The same location can be configured for all commands:
|
|
120
|
+
|
|
121
|
+
```yaml
|
|
122
|
+
cache_dir: references_cache
|
|
123
|
+
private_cache_dir: /path/to/private-reference-cache
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Zotero-indexed text is preferred. If Zotero has not indexed an attachment, the
|
|
127
|
+
provider downloads it from Zotero's local PDF endpoint and sends it through the
|
|
128
|
+
normal PDF extractor. The source attachment key and `user_library` access type
|
|
129
|
+
are persisted, but the ephemeral localhost URL is not.
|
|
130
|
+
|
|
131
|
+
!!! warning "Keep research caches private"
|
|
132
|
+
|
|
133
|
+
Private cache entries contain extracted manuscript text and may contain a
|
|
134
|
+
copied PDF. Do not place this cache in a public repository or share it
|
|
135
|
+
unless you have permission to redistribute that content.
|
|
136
|
+
|
|
137
|
+
Do not add `zotero` to `full_text_providers`. Even if it is configured there,
|
|
138
|
+
ordinary validation rejects its `user_library` result and continues to public
|
|
139
|
+
providers. Use `cache enrich` when you want to search Zotero.
|
|
140
|
+
|
|
141
|
+
Support for reproducible validation backed by private manuscripts is a future,
|
|
142
|
+
separate feature. The proposed design is a trusted offline job that emits a
|
|
143
|
+
minimal signed excerpt attestation into the public cache. The validator would
|
|
144
|
+
verify the signature using a checked-in public key; neither agents nor CI would
|
|
145
|
+
have the signing key or permission to generate those files directly.
|
|
146
|
+
|
|
147
|
+
## Export a cache to a Zotero collection
|
|
148
|
+
|
|
149
|
+
Export references that still need full text as metadata-only CSL JSON:
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
linkml-reference-validator cache export \
|
|
153
|
+
--cache-dir references_cache \
|
|
154
|
+
--format csl-json \
|
|
155
|
+
--needs-full-text \
|
|
156
|
+
--output project-zotero.json
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
The default `--needs-full-text` mode excludes cache entries that already contain
|
|
160
|
+
full text. It also excludes non-publication identifiers, deduplicates by
|
|
161
|
+
normalized DOI and then PMID, and exports only an explicit metadata allowlist:
|
|
162
|
+
title, authors, journal, year, DOI, PMID, and PubMed URL. Cached article text,
|
|
163
|
+
excerpts, provenance, PDFs, and local paths are never exported. Use `--all` only
|
|
164
|
+
when you deliberately want eligible records that already have full text.
|
|
165
|
+
|
|
166
|
+
The exporter refuses to replace an existing output file unless `--force` is
|
|
167
|
+
given. Review the reported counts, then in Zotero choose **File → Import → A
|
|
168
|
+
file**, select the JSON file, and place the imported items in a project-specific
|
|
169
|
+
collection. Zotero supports CSL JSON as a standard import format. After import,
|
|
170
|
+
select the collection and run **Find Full Text**, then rerun `cache enrich`.
|
|
171
|
+
|
|
172
|
+
See [Zotero's standardized-format import instructions](https://www.zotero.org/support/kb/importing_standardized_formats).
|
|
173
|
+
For the complete workflow with screenshots, see
|
|
174
|
+
[Export a Reference Cache to Zotero](export-cache-to-zotero.md).
|
|
175
|
+
|
|
74
176
|
## Preprints
|
|
75
177
|
|
|
76
178
|
Preprints are first-class references. They are increasingly cited for early
|
|
@@ -183,3 +285,46 @@ downloaded PDF lives under the cache directory and can be located at
|
|
|
183
285
|
- [Validating DOIs](validate-dois.md) — DOI metadata sources and supplementary files
|
|
184
286
|
- [Validating Entrez Accessions](validate-entrez.md) — PubMed/PMC references
|
|
185
287
|
- [CLI Reference](../reference/cli.md) — complete command documentation
|
|
288
|
+
|
|
289
|
+
## HTML article checks and cache recovery
|
|
290
|
+
|
|
291
|
+
An OpenAlex or Unpaywall URL may lead to a repository item record containing
|
|
292
|
+
only an abstract and metadata. HTML full-text acquisition now requires an
|
|
293
|
+
identifiable research body: publisher body markup or narrative research sections
|
|
294
|
+
with paragraphs, after removing abstracts and navigation. Length and additional
|
|
295
|
+
metadata text alone do not establish full text. This also applies when a URL
|
|
296
|
+
advertised as a PDF actually returns HTML. Genuine HTML research bodies remain
|
|
297
|
+
eligible, including short bodies above the existing 500-character minimum.
|
|
298
|
+
|
|
299
|
+
Ambiguous layouts are rejected and the next configured provider is tried. The
|
|
300
|
+
fetcher does not crawl repository download links. If every provider completes
|
|
301
|
+
without usable text or an error, the reference retains its original abstract
|
|
302
|
+
and records `full_text_attempted: true`.
|
|
303
|
+
|
|
304
|
+
New `full_text_html` cache entries carry `html_full_text_version: 1`. Older
|
|
305
|
+
Markdown HTML full-text entries without this stamp are refreshed on their next
|
|
306
|
+
validation read. This migration covers all providers because cached plain text
|
|
307
|
+
cannot establish which HTML body structure was present. It does not invalidate
|
|
308
|
+
current PDF, XML, or abstract caches.
|
|
309
|
+
|
|
310
|
+
If refreshing an old HTML entry fails, validation does **not** fall back to that
|
|
311
|
+
entry: its text may be repository metadata rather than article evidence. The
|
|
312
|
+
file remains untouched for inventory/export, and the next validation run retries
|
|
313
|
+
recovery. Once the source is available, normal fetching replaces it with a
|
|
314
|
+
verified article or the available metadata/abstract. Other content types retain
|
|
315
|
+
the existing stale-cache fallback. Legacy `.txt` caches remain a separate,
|
|
316
|
+
read-only compatibility path and are not migrated by this HTML stamp.
|
|
317
|
+
|
|
318
|
+
Research headings establish body presence; they do not filter the accepted
|
|
319
|
+
article's other sections. For example, `Main`, `Case presentation`, and
|
|
320
|
+
`Limitations` remain in an accepted article. A separately marked body is also
|
|
321
|
+
preserved when an abstract heading uses a higher heading level. Without that
|
|
322
|
+
structural boundary, an unmarked structured abstract remains ambiguous and is
|
|
323
|
+
rejected conservatively.
|
|
324
|
+
|
|
325
|
+
A provider's `FullTextLocation.text` (including a custom API `text_field`) is a
|
|
326
|
+
trusted **already-extracted article body** contract. Configure it only for APIs
|
|
327
|
+
that return article text, not arbitrary page text or metadata. Plain extracted
|
|
328
|
+
text cannot be structurally rechecked; raw HTML supplied with an HTML hint still
|
|
329
|
+
passes the body classifier. The acceptance stamp records that either the HTML
|
|
330
|
+
check or this trusted provider contract was used.
|
|
@@ -13,6 +13,21 @@ After validating your data files, you may find validation errors due to:
|
|
|
13
13
|
|
|
14
14
|
The `repair` command attempts to fix these issues automatically or flags them for manual review.
|
|
15
15
|
|
|
16
|
+
### Typographic ligatures already match
|
|
17
|
+
|
|
18
|
+
Validation folds Latin compatibility ligatures on both the reference content and
|
|
19
|
+
the quote, including each part separated by `...`. For example, PDF-extracted
|
|
20
|
+
`amyloid fibrils` matches `amyloid fibrils` without a repair. The supported folds
|
|
21
|
+
are `ff → ff`, `fi → fi`, `fl → fl`, `ffi → ffi`, `ffl → ffl`, `ſt/st → st`, and
|
|
22
|
+
`IJ/ij → IJ/ij`. IJ is included because Unicode gives it a compatibility
|
|
23
|
+
decomposition into I and J; ordinary case normalization still applies.
|
|
24
|
+
|
|
25
|
+
The distinct letters `Æ/æ` and `Œ/œ` remain distinct from `AE/ae` and `OE/oe`.
|
|
26
|
+
Equating these letters would accept spelling changes beyond typographic repair.
|
|
27
|
+
Validation uses an explicit ligature table instead of broad Unicode NFKC
|
|
28
|
+
normalization so this change does not equate scientific notation such as `H₂O`
|
|
29
|
+
with `H2O`, `10⁶` with `106`, or the micro sign `µ` with Greek `μ`.
|
|
30
|
+
|
|
16
31
|
## Quick Start
|
|
17
32
|
|
|
18
33
|
### Repair a Single Quote
|
|
@@ -112,7 +127,7 @@ Flags text that appears fabricated or hallucinated:
|
|
|
112
127
|
|
|
113
128
|
```
|
|
114
129
|
RECOMMENDED REMOVALS:
|
|
115
|
-
PMID:34567890 at evidence[2]:
|
|
130
|
+
PMID:34567890 at evidence[2].supporting_text:
|
|
116
131
|
Similarity: 8%
|
|
117
132
|
Snippet: 'This completely made up text...'
|
|
118
133
|
```
|
|
@@ -290,6 +305,33 @@ The supporting text wasn't found in the reference. Possible causes:
|
|
|
290
305
|
- Wrong PMID
|
|
291
306
|
- AI-generated/hallucinated quote
|
|
292
307
|
|
|
308
|
+
### "Supporting text is empty"
|
|
309
|
+
|
|
310
|
+
The excerpt is empty or whitespace-only, so there is nothing to match against
|
|
311
|
+
the reference. This is usually a bug in whatever generated the data (for
|
|
312
|
+
example, a string slice with a backwards range yielding `""`).
|
|
313
|
+
|
|
314
|
+
Empty excerpts cannot be repaired automatically — there is no text to correct,
|
|
315
|
+
and fuzzy-matching nothing against the reference would invent a quote. They
|
|
316
|
+
appear under **INSUFFICIENT EXCERPTS (nothing to verify)** in the report, so
|
|
317
|
+
you can supply the real quote or drop the evidence item.
|
|
318
|
+
|
|
319
|
+
They are deliberately *not* counted as removals. A removal recommendation means
|
|
320
|
+
"this quote does not match the reference", a verdict reached by comparing the
|
|
321
|
+
two; here no comparison happened. So `removal_count` excludes them and the
|
|
322
|
+
action type is `INSUFFICIENT_EXCERPT`, not `REMOVAL` — worth knowing if you
|
|
323
|
+
script against the report. They do still make `repair data` exit non-zero.
|
|
324
|
+
|
|
325
|
+
### "Supporting text is too short"
|
|
326
|
+
|
|
327
|
+
The excerpt is below the `min_excerpt_length` you configured (off by default,
|
|
328
|
+
and set under `validation:`; see
|
|
329
|
+
[How It Works](../concepts/how-it-works.md)). A very short excerpt matches
|
|
330
|
+
almost any paper by chance, so it is weak evidence even when the match succeeds.
|
|
331
|
+
|
|
332
|
+
Like empty excerpts, these report under **INSUFFICIENT EXCERPTS** rather than
|
|
333
|
+
being repaired: there is no way to guess which longer passage the curator meant.
|
|
334
|
+
|
|
293
335
|
### "Reference content not available"
|
|
294
336
|
|
|
295
337
|
The reference exists but has no retrievable content:
|
|
@@ -40,6 +40,10 @@ clinicaltrials:NCT00000001
|
|
|
40
40
|
CLINICALTRIALS:NCT00000001
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
+
These forms normalize to `clinicaltrials:NCT00000001` and share the cache file
|
|
44
|
+
`clinicaltrials_NCT00000001.md`. Existing files with that canonical name are
|
|
45
|
+
reused without renaming or fetching the trial again.
|
|
46
|
+
|
|
43
47
|
## Prefix Aliases and Normalization
|
|
44
48
|
|
|
45
49
|
If your data uses alternate prefix styles (e.g., the legacy `NCT:` prefix), configure normalization in `.linkml-reference-validator.yaml`:
|
{linkml_reference_validator-0.2.1rc2 → linkml_reference_validator-0.3.0rc1}/docs/reference/cli.md
RENAMED
|
@@ -378,29 +378,57 @@ linkml-reference-validator validate data \
|
|
|
378
378
|
|
|
379
379
|
### Output Format
|
|
380
380
|
|
|
381
|
-
|
|
382
|
-
```
|
|
383
|
-
Validating data.yaml against schema schema.yaml
|
|
384
|
-
Cache directory: references_cache
|
|
381
|
+
The summary separates work performed from issues found:
|
|
385
382
|
|
|
383
|
+
```text
|
|
386
384
|
Validation Summary:
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
385
|
+
Input files: 2
|
|
386
|
+
Files validated: 2
|
|
387
|
+
Snippets checked: 3
|
|
388
|
+
Snippets skipped: 0
|
|
389
|
+
Snippets unavailable: 0
|
|
390
|
+
Titles checked: 1
|
|
391
|
+
Issues found: 1
|
|
392
|
+
Issues found in 1 file(s) (1 validation issue(s))
|
|
393
|
+
Failing files:
|
|
394
|
+
bad.yaml
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
- **Input files** counts supplied paths, including files that cannot be read.
|
|
398
|
+
- **Files validated** counts files with at least one mapping submitted to the
|
|
399
|
+
validator. An empty mapping counts; an empty list has no instances and does not.
|
|
400
|
+
A mixed list containing valid mappings and malformed entries counts once and
|
|
401
|
+
still fails. Entry diagnostics use zero-based indexes.
|
|
402
|
+
- **Snippets checked** counts executed comparisons against reference content,
|
|
403
|
+
including matches and mismatches. Multiple excerpt slots each count separately.
|
|
404
|
+
- **Snippets skipped** counts snippet/reference pairs bypassed by `skip_prefixes`.
|
|
405
|
+
- **Snippets unavailable** counts attempted snippet validations where the reference
|
|
406
|
+
could not be fetched or had no content. These are not completed comparisons.
|
|
407
|
+
- **Titles checked** counts actual title comparisons, including those performed
|
|
408
|
+
alongside snippets. Missing titles and skipped/unavailable references do not count.
|
|
409
|
+
- **Issues found** counts emitted validation issues. Blank excerpts may produce an
|
|
410
|
+
issue without any comparison; file read/parse or data-format errors appear in the
|
|
411
|
+
failing-file list without adding a fabricated validation issue.
|
|
412
|
+
|
|
413
|
+
Absent excerpts and excerpts without a usable reference perform no comparison.
|
|
414
|
+
Counters come from execution and reset for each LinkML validation call; the CLI
|
|
415
|
+
accumulates all instances and files. The public plugin exposes `snippets_checked`,
|
|
416
|
+
`snippets_skipped`, `snippets_unavailable`, and `titles_checked` after validation.
|
|
417
|
+
When using lazy `process()` or `iter_results()` APIs, exhaust the result iterator
|
|
418
|
+
before reading final counters. Unconsumed or partially consumed iterators do not
|
|
419
|
+
provide final counts; `Validator.validate()` consumes the iterator for you.
|
|
420
|
+
|
|
421
|
+
Title-only skips and unavailable titles have no separate summary counters: they
|
|
422
|
+
leave all check counters at zero. A skipped title emits no issue; an unavailable
|
|
423
|
+
standalone title emits an issue. Existing title behavior is preserved: a reference
|
|
424
|
+
missing its title is an issue for standalone title validation, but a title supplied
|
|
425
|
+
alongside an excerpt is not compared or reported when the reference has no title.
|
|
426
|
+
|
|
427
|
+
A zero-snippet run prints `No snippet comparisons were performed.` This includes
|
|
428
|
+
empty input collections and title-only runs. Exit behavior is unchanged: no issues
|
|
429
|
+
or file errors means exit 0, even when zero snippets were checked; issues or file
|
|
430
|
+
errors mean exit 1. Failed file paths are listed at the end, including unreadable
|
|
431
|
+
files, while later files continue to be processed.
|
|
404
432
|
|
|
405
433
|
---
|
|
406
434
|
|
|
@@ -585,16 +613,16 @@ Repair Report
|
|
|
585
613
|
============================================================
|
|
586
614
|
|
|
587
615
|
HIGH CONFIDENCE FIXES (auto-applicable):
|
|
588
|
-
PMID:12345678 at evidence[0]:
|
|
616
|
+
PMID:12345678 at evidence[0].supporting_text:
|
|
589
617
|
Character normalization fix
|
|
590
618
|
'CO2 levels...' → 'CO₂ levels...'
|
|
591
619
|
|
|
592
620
|
SUGGESTED FIXES (review recommended):
|
|
593
|
-
PMID:23456789 at evidence[1]:
|
|
621
|
+
PMID:23456789 at evidence[1].supporting_text:
|
|
594
622
|
Inserted ellipsis between non-contiguous parts
|
|
595
623
|
|
|
596
624
|
RECOMMENDED REMOVALS (low confidence):
|
|
597
|
-
PMID:34567890 at evidence[2]:
|
|
625
|
+
PMID:34567890 at evidence[2].supporting_text:
|
|
598
626
|
Similarity: 8%
|
|
599
627
|
Snippet: 'Fabricated text...'
|
|
600
628
|
|
|
@@ -622,6 +650,10 @@ validation:
|
|
|
622
650
|
geo: GEO
|
|
623
651
|
NCBIGeo: GEO
|
|
624
652
|
|
|
653
|
+
# Minimum non-whitespace characters an excerpt must quote.
|
|
654
|
+
# 0 disables the check; empty excerpts are rejected regardless.
|
|
655
|
+
min_excerpt_length: 0
|
|
656
|
+
|
|
625
657
|
repair:
|
|
626
658
|
# Confidence thresholds
|
|
627
659
|
auto_fix_threshold: 0.95
|
|
@@ -719,6 +751,31 @@ Successfully cached PMID:16888623
|
|
|
719
751
|
Content length: 1523 characters
|
|
720
752
|
```
|
|
721
753
|
|
|
754
|
+
### Exit Codes
|
|
755
|
+
|
|
756
|
+
- `0` - The public validation cache holds a current entry for the reference
|
|
757
|
+
- `1` - It does not
|
|
758
|
+
|
|
759
|
+
Exit `0` does not imply a download: a reference the current extractor has
|
|
760
|
+
already cached may be reported as cached without contacting the source.
|
|
761
|
+
|
|
762
|
+
Two cases satisfy the promise loosely. Content marked as non-open full text is
|
|
763
|
+
written to the private cache, which validation deliberately never reads, so that
|
|
764
|
+
run exits `0` without leaving anything in the public cache. Legacy `.txt` entries
|
|
765
|
+
are exempt from the extractor version check and so always report as current.
|
|
766
|
+
|
|
767
|
+
Conversely, a reference that could not be re-fetched is a failure even when a
|
|
768
|
+
cache entry for it exists. Validation falls back to an entry written by an older
|
|
769
|
+
extractor rather than reporting the reference as missing, but this command exists
|
|
770
|
+
to populate the cache, so leaving it without a current entry is reported as
|
|
771
|
+
failure and a script gating on the exit status does not go green through an
|
|
772
|
+
outage. The same applies when no source handles the identifier at all.
|
|
773
|
+
|
|
774
|
+
```
|
|
775
|
+
Fetching PMID:16888623...
|
|
776
|
+
Failed to cache PMID:16888623: it could not be re-fetched, so an out-of-date cache entry was served. The cache still holds no current entry for it.
|
|
777
|
+
```
|
|
778
|
+
|
|
722
779
|
---
|
|
723
780
|
|
|
724
781
|
## cache lookup
|
|
@@ -761,6 +818,69 @@ linkml-reference-validator cache lookup PMID:16888623 --content
|
|
|
761
818
|
linkml-reference-validator cache lookup PMID:16888623 --no-cache
|
|
762
819
|
```
|
|
763
820
|
|
|
821
|
+
## cache export
|
|
822
|
+
|
|
823
|
+
Export public bibliographic metadata to CSL JSON for Zotero import.
|
|
824
|
+
|
|
825
|
+
```bash
|
|
826
|
+
linkml-reference-validator cache export --output project-zotero.json [OPTIONS]
|
|
827
|
+
```
|
|
828
|
+
|
|
829
|
+
**Options:**
|
|
830
|
+
|
|
831
|
+
- `--output PATH, -o PATH` - Required destination file
|
|
832
|
+
- `--format TEXT` - Export format (default and currently supported: `csl-json`)
|
|
833
|
+
- `--needs-full-text` - Export only publication records needing full text (default)
|
|
834
|
+
- `--all` - Include eligible records that already contain full text
|
|
835
|
+
- `--cache-dir PATH, -c PATH` - Public reference cache directory
|
|
836
|
+
- `--force, -f` - Replace an existing output file
|
|
837
|
+
- `--config PATH` - Validation configuration file
|
|
838
|
+
- `--verbose, -v` - Enable detailed logging
|
|
839
|
+
|
|
840
|
+
```bash
|
|
841
|
+
linkml-reference-validator cache export \
|
|
842
|
+
--cache-dir references_cache \
|
|
843
|
+
--needs-full-text \
|
|
844
|
+
--output project-zotero.json
|
|
845
|
+
```
|
|
846
|
+
|
|
847
|
+
The output is a DOI/PMID-deduplicated metadata allowlist. It never includes
|
|
848
|
+
cached article content, excerpts, PDFs, local paths, or private-cache data.
|
|
849
|
+
|
|
850
|
+
---
|
|
851
|
+
|
|
852
|
+
## cache enrich
|
|
853
|
+
|
|
854
|
+
Inventory or enrich existing abstract-only cache entries through one full-text
|
|
855
|
+
provider. This is primarily intended for opt-in private-library providers such
|
|
856
|
+
as Zotero.
|
|
857
|
+
|
|
858
|
+
```bash
|
|
859
|
+
linkml-reference-validator cache enrich [OPTIONS]
|
|
860
|
+
```
|
|
861
|
+
|
|
862
|
+
**Options:**
|
|
863
|
+
|
|
864
|
+
- `--provider TEXT` - Registered provider name (default: `zotero`)
|
|
865
|
+
- `--cache-dir PATH, -c PATH` - Reference cache directory
|
|
866
|
+
- `--private-cache-dir PATH` - Separate private research-cache destination (default: `~/.cache/linkml-reference-validator/private`)
|
|
867
|
+
- `--dry-run` - Report matches without changing files (default)
|
|
868
|
+
- `--apply` - Materialize usable matches into the private research cache
|
|
869
|
+
- `--config PATH` - Validation configuration file
|
|
870
|
+
- `--verbose, -v` - Enable detailed logging
|
|
871
|
+
|
|
872
|
+
```bash
|
|
873
|
+
# Safe inventory
|
|
874
|
+
linkml-reference-validator cache enrich --provider zotero --dry-run
|
|
875
|
+
|
|
876
|
+
# Apply reviewed exact matches
|
|
877
|
+
linkml-reference-validator cache enrich --provider zotero --apply
|
|
878
|
+
```
|
|
879
|
+
|
|
880
|
+
The public source cache is never modified by this command, and validation never
|
|
881
|
+
reads the private destination. Private-library content may be copyrighted; keep
|
|
882
|
+
the research cache private.
|
|
883
|
+
|
|
764
884
|
---
|
|
765
885
|
|
|
766
886
|
## Reference ID Formats
|