linkml-reference-validator 0.2.1rc3__tar.gz → 0.3.0__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.1rc3 → linkml_reference_validator-0.3.0}/PKG-INFO +2 -2
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/docs/concepts/editorial-conventions.md +9 -4
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/docs/concepts/how-it-works.md +45 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/docs/how-to/fetch-full-text-and-pdfs.md +43 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/docs/how-to/repair-validation-errors.md +43 -1
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/docs/how-to/use-local-files-and-urls.md +2 -2
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/docs/how-to/validate-clinical-trials.md +4 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/docs/how-to/validate-urls.md +47 -15
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/docs/reference/cli.md +81 -24
- linkml_reference_validator-0.3.0/docs/reference/splitting.md +69 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/docs/setup-guide.md +4 -0
- linkml_reference_validator-0.3.0/docs/troubleshooting.md +986 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/docs/tutorials/complete-workflow.md +1 -1
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/mkdocs.yml +1 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/src/linkml_reference_validator/cli/cache.py +38 -1
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/src/linkml_reference_validator/cli/repair.py +66 -12
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/src/linkml_reference_validator/cli/validate.py +53 -21
- linkml_reference_validator-0.3.0/src/linkml_reference_validator/etl/__init__.py +12 -0
- linkml_reference_validator-0.3.0/src/linkml_reference_validator/etl/extract/__init__.py +31 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/src/linkml_reference_validator/etl/extract/base.py +11 -3
- linkml_reference_validator-0.3.0/src/linkml_reference_validator/etl/extract/html.py +287 -0
- linkml_reference_validator-0.3.0/src/linkml_reference_validator/etl/extract/pdf.py +136 -0
- linkml_reference_validator-0.3.0/src/linkml_reference_validator/etl/extract/xml.py +253 -0
- linkml_reference_validator-0.3.0/src/linkml_reference_validator/etl/fulltext/base.py +200 -0
- linkml_reference_validator-0.3.0/src/linkml_reference_validator/etl/fulltext/openalex.py +106 -0
- linkml_reference_validator-0.3.0/src/linkml_reference_validator/etl/fulltext/pmc.py +198 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/src/linkml_reference_validator/etl/fulltext/unpaywall.py +25 -9
- linkml_reference_validator-0.3.0/src/linkml_reference_validator/etl/reference_fetcher.py +1941 -0
- linkml_reference_validator-0.3.0/src/linkml_reference_validator/etl/rules.py +195 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/src/linkml_reference_validator/etl/sources/pmid.py +177 -55
- linkml_reference_validator-0.3.0/src/linkml_reference_validator/etl/sources/url.py +273 -0
- linkml_reference_validator-0.3.0/src/linkml_reference_validator/matching.py +75 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/src/linkml_reference_validator/models.py +105 -19
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/src/linkml_reference_validator/plugins/reference_validation_plugin.py +50 -1
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/src/linkml_reference_validator/validation/repairer.py +83 -1
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/src/linkml_reference_validator/validation/supporting_text_validator.py +191 -21
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/fixtures/GEO_GSE12345.md +1 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/fixtures/PMC_TEST001.md +1 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/fixtures/PMC_TEST002.md +2 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/fixtures/PMID_TEST001.md +1 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/fixtures/PMID_TEST002.md +1 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/fixtures/PMID_TEST003.md +2 -0
- linkml_reference_validator-0.2.1rc3/tests/fixtures/CLINICALTRIALS_NCT00000001.md → linkml_reference_validator-0.3.0/tests/fixtures/clinicaltrials_NCT00000001.md +1 -0
- linkml_reference_validator-0.3.0/tests/fixtures/fulltext_html/README.md +22 -0
- linkml_reference_validator-0.3.0/tests/fixtures/fulltext_html/dspace-32894695.html +1 -0
- linkml_reference_validator-0.3.0/tests/fixtures/fulltext_html/iris-19049553.html +359 -0
- linkml_reference_validator-0.3.0/tests/fixtures/fulltext_html/plos-0000308.html +78 -0
- linkml_reference_validator-0.3.0/tests/fixtures/jats/PMC5593426.xml +5 -0
- linkml_reference_validator-0.3.0/tests/fixtures/jats/README.md +21 -0
- linkml_reference_validator-0.3.0/tests/test_absent_abstract_recovery.py +140 -0
- linkml_reference_validator-0.3.0/tests/test_cache_author_recovery.py +102 -0
- linkml_reference_validator-0.3.0/tests/test_cli_cache_reference.py +271 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/test_cli_repair.py +134 -0
- linkml_reference_validator-0.3.0/tests/test_clinicaltrials_cache.py +234 -0
- linkml_reference_validator-0.3.0/tests/test_empty_snippets.py +794 -0
- linkml_reference_validator-0.3.0/tests/test_extractor_fidelity.py +656 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/test_extractors.py +13 -0
- linkml_reference_validator-0.3.0/tests/test_frontmatter_and_doi_case.py +334 -0
- linkml_reference_validator-0.3.0/tests/test_fulltext_providers.py +356 -0
- linkml_reference_validator-0.3.0/tests/test_html_fulltext_acceptance.py +432 -0
- linkml_reference_validator-0.3.0/tests/test_jats_tables.py +346 -0
- linkml_reference_validator-0.3.0/tests/test_ligature_normalization.py +91 -0
- linkml_reference_validator-0.3.0/tests/test_no_cache_downgrade.py +540 -0
- linkml_reference_validator-0.3.0/tests/test_open_access_policy.py +686 -0
- linkml_reference_validator-0.3.0/tests/test_pdf_url_title.py +228 -0
- linkml_reference_validator-0.3.0/tests/test_pmid_network.py +327 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/test_reference_fetcher.py +485 -2
- linkml_reference_validator-0.3.0/tests/test_rules.py +129 -0
- linkml_reference_validator-0.3.0/tests/test_serve_stale_html_optin.py +134 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/test_sources.py +151 -0
- linkml_reference_validator-0.3.0/tests/test_split_supporting_text.py +75 -0
- linkml_reference_validator-0.3.0/tests/test_trust_cached_entries.py +81 -0
- linkml_reference_validator-0.3.0/tests/test_url_html_sanitize.py +161 -0
- linkml_reference_validator-0.3.0/tests/test_url_source_cache_version.py +141 -0
- linkml_reference_validator-0.3.0/tests/test_validation_counts.py +407 -0
- linkml_reference_validator-0.2.1rc3/docs/troubleshooting.md +0 -706
- linkml_reference_validator-0.2.1rc3/src/linkml_reference_validator/etl/__init__.py +0 -9
- linkml_reference_validator-0.2.1rc3/src/linkml_reference_validator/etl/extract/__init__.py +0 -16
- linkml_reference_validator-0.2.1rc3/src/linkml_reference_validator/etl/extract/html.py +0 -46
- linkml_reference_validator-0.2.1rc3/src/linkml_reference_validator/etl/extract/pdf.py +0 -67
- linkml_reference_validator-0.2.1rc3/src/linkml_reference_validator/etl/extract/xml.py +0 -46
- linkml_reference_validator-0.2.1rc3/src/linkml_reference_validator/etl/fulltext/base.py +0 -70
- linkml_reference_validator-0.2.1rc3/src/linkml_reference_validator/etl/fulltext/openalex.py +0 -70
- linkml_reference_validator-0.2.1rc3/src/linkml_reference_validator/etl/fulltext/pmc.py +0 -124
- linkml_reference_validator-0.2.1rc3/src/linkml_reference_validator/etl/reference_fetcher.py +0 -932
- linkml_reference_validator-0.2.1rc3/src/linkml_reference_validator/etl/sources/url.py +0 -148
- linkml_reference_validator-0.2.1rc3/tests/test_fulltext_providers.py +0 -175
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/.claude/.mcp.json +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/.claude/settings.json +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/.copier-answers.yml +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/.devcontainer/devcontainer.json +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/.devcontainer/post_create.sh +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/.editorconfig +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/.github/actions/claude-code-action/action.yml +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/.github/actions/claude-issue-summarize-action/action.yml +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/.github/actions/claude-issue-triage-action/action.yml +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/.github/ai-controllers.json +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/.github/copilot-instructions.md +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/.github/copilot-setup-steps.yml +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/.github/dependabot.yml +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/.github/workflows/claude-code-review.yml +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/.github/workflows/claude-issue-summarize.yml +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/.github/workflows/claude-issue-triage.yml +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/.github/workflows/claude-ontology-review.yml +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/.github/workflows/claude.yml +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/.github/workflows/deploy-docs.yaml +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/.github/workflows/dragon-ai.yml +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/.github/workflows/main.yaml +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/.github/workflows/pypi-publish.yaml +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/.gitignore +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/.goosehints +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/.pre-commit-config.yaml +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/.yamllint.yaml +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/AGENTS.md +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/BUG_GEO_ACCESSION_TO_UID.md +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/BUG_ZENODO_DOI_AND_URL_HANDLING.md +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/CLAUDE.md +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/CLI-ISSUES.md +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/CODE_OF_CONDUCT.md +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/CONTRIBUTING.md +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/FEATURE_REQUEST_REPAIR.md +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/LICENSE +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/README.md +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/REVIEW2.md +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/REVIEW3.md +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/ai.just +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/copilot-instructions.md +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/docs/about.md +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/docs/assets/zotero-find-full-text.png +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/docs/concepts/content-types.md +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/docs/elements/.gitkeep +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/docs/how-to/add-reference-source.md +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/docs/how-to/export-cache-to-zotero.md +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/docs/how-to/skip-unsupported-references.md +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/docs/how-to/validate-dois.md +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/docs/how-to/validate-entrez.md +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/docs/how-to/validate-obo-files.md +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/docs/how-to/validate-titles.md +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/docs/index.md +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/docs/notebooks/01_getting_started.ipynb +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/docs/notebooks/02_advanced_usage.ipynb +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/docs/notebooks/03_python_api.ipynb +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/docs/notebooks/04_obo_validation.ipynb +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/docs/notebooks/05_geo_validation.ipynb +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/docs/quickstart.md +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/docs/superpowers/plans/2026-06-12-modular-pdf-fulltext-fetching.md +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/docs/superpowers/plans/2026-08-05-private-library-full-text.md +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/docs/superpowers/specs/2026-06-12-modular-pdf-fulltext-fetching-design.md +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/docs/superpowers/specs/2026-08-05-private-library-full-text-design.md +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/docs/templates-linkml/README.md +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/docs/todo.md +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/examples/README.md +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/justfile +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/mypy.ini +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/notebooks/01_getting_started.ipynb +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/notebooks/02_advanced_usage.ipynb +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/notebooks/03_python_api.ipynb +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/notebooks/README.md +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/project/README.md +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/project.justfile +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/pyproject.toml +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/pytest.ini +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/src/linkml_reference_validator/__init__.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/src/linkml_reference_validator/_version.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/src/linkml_reference_validator/cli/__init__.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/src/linkml_reference_validator/cli/lookup.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/src/linkml_reference_validator/cli/shared.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/src/linkml_reference_validator/etl/acquire.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/src/linkml_reference_validator/etl/csl_export.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/src/linkml_reference_validator/etl/fulltext/__init__.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/src/linkml_reference_validator/etl/fulltext/epmc_preprint.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/src/linkml_reference_validator/etl/fulltext/json_api.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/src/linkml_reference_validator/etl/fulltext/loader.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/src/linkml_reference_validator/etl/fulltext/zotero.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/src/linkml_reference_validator/etl/identifiers.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/src/linkml_reference_validator/etl/sources/__init__.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/src/linkml_reference_validator/etl/sources/base.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/src/linkml_reference_validator/etl/sources/clinicaltrials.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/src/linkml_reference_validator/etl/sources/doi.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/src/linkml_reference_validator/etl/sources/entrez.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/src/linkml_reference_validator/etl/sources/file.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/src/linkml_reference_validator/etl/sources/json_api.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/src/linkml_reference_validator/etl/sources/loader.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/src/linkml_reference_validator/etl/sources/ppr.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/src/linkml_reference_validator/etl/sources/utils.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/src/linkml_reference_validator/etl/text_extractor.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/src/linkml_reference_validator/field_detection.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/src/linkml_reference_validator/plugins/REVIEW.md +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/src/linkml_reference_validator/plugins/__init__.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/src/linkml_reference_validator/validation/__init__.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/src/linkml_reference_validator/validation/fuzzy_text_utils.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/__init__.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/conftest.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/data/test_data_deep_nesting_invalid.yaml +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/data/test_data_deep_nesting_valid.yaml +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/data/test_data_invalid.yaml +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/data/test_data_valid.yaml +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/data/test_schema.yaml +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/data/test_schema_deep_nesting.yaml +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/fixtures/PMC_TEST001.txt +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/fixtures/PMC_TEST002.txt +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/fixtures/PMID_TEST001.txt +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/fixtures/PMID_TEST002.txt +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/fixtures/PMID_TEST003.txt +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/fixtures/sample.obo +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/test_acquire.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/test_cli.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/test_cli_cache_enrich.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/test_cli_cache_export.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/test_cli_lookup.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/test_clinicaltrials_integration.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/test_deep_nesting.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/test_doi_preprint.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/test_e2e_integration.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/test_epmc_preprint_provider.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/test_field_detection.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/test_fulltext_loader.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/test_fuzzy_suggestions.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/test_geo_integration.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/test_identifiers.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/test_json_api_source.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/test_models.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/test_optional_linkml_dependency.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/test_plugin_integration.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/test_pmc_fulltext.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/test_ppr_source.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/test_real_validation.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/test_repair.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/test_source_utils.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/test_supporting_text_validator.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/test_text_extractor.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/test_title_validation.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/test_unknown_slot_traversal.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/test_validation_config.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/tests/test_zotero_provider.py +0 -0
- {linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/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.0
|
|
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:
|
|
@@ -285,3 +285,46 @@ downloaded PDF lives under the cache directory and can be located at
|
|
|
285
285
|
- [Validating DOIs](validate-dois.md) — DOI metadata sources and supplementary files
|
|
286
286
|
- [Validating Entrez Accessions](validate-entrez.md) — PubMed/PMC references
|
|
287
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:
|
|
@@ -89,7 +89,7 @@ URLs are cached the same way as PMID and DOI references:
|
|
|
89
89
|
|
|
90
90
|
### Title Extraction
|
|
91
91
|
|
|
92
|
-
For HTML pages, the title is
|
|
92
|
+
For HTML pages, the title is the `citation_title` meta tag when present, then the `<title>` tag. For PDFs, the validator tries a publisher landing page's `citation_title` and then the PDF's embedded title. When neither is found, and for other content types, the URL itself is used as the title. See [Validating URLs](validate-urls.md#titles).
|
|
93
93
|
|
|
94
94
|
### Example: Validating Against a Web Page
|
|
95
95
|
|
|
@@ -145,6 +145,6 @@ Both file and URL references work in LinkML data files:
|
|
|
145
145
|
|
|
146
146
|
## Limitations
|
|
147
147
|
|
|
148
|
-
- **PDF files**: Not yet supported
|
|
148
|
+
- **Local PDF files**: Not yet supported as `file:` references. PDFs fetched by `url:` are supported.
|
|
149
149
|
- **Authentication**: URLs requiring login are not supported
|
|
150
150
|
- **Dynamic content**: JavaScript-rendered pages may not work
|
|
@@ -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`:
|
|
@@ -15,8 +15,8 @@ The linkml-reference-validator supports validating references that point to web
|
|
|
15
15
|
When a reference field contains a URL, the validator:
|
|
16
16
|
|
|
17
17
|
1. Fetches the web page content
|
|
18
|
-
2. Extracts the page title
|
|
19
|
-
3.
|
|
18
|
+
2. Extracts the page title (see [Titles](#titles))
|
|
19
|
+
3. Sanitizes HTML and caches the content for future validations
|
|
20
20
|
4. Validates your supporting text against the page content
|
|
21
21
|
|
|
22
22
|
## URL Format
|
|
@@ -79,14 +79,45 @@ When the validator encounters a URL reference, it:
|
|
|
79
79
|
|
|
80
80
|
The fetcher stores:
|
|
81
81
|
|
|
82
|
-
- **Title**:
|
|
83
|
-
- **Content**:
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
HTML
|
|
88
|
-
|
|
89
|
-
|
|
82
|
+
- **Title**: See [Titles](#titles)
|
|
83
|
+
- **Content**: Sanitized HTML for HTML pages; plain text and XML as received;
|
|
84
|
+
extracted text for PDFs
|
|
85
|
+
- **Content type**: `url` for pages, `full_text_pdf` for PDFs with text
|
|
86
|
+
|
|
87
|
+
HTML is sanitized before it is cached, because caches are often committed to
|
|
88
|
+
public repositories and page scripts routinely carry signed asset URLs and API
|
|
89
|
+
keys. `<script>`, `<style>`, `<noscript>` and `<template>` elements and HTML
|
|
90
|
+
comments are removed. So are `<meta>`, `<link>` and `<base>`, which hold nothing
|
|
91
|
+
but attributes. Every other tag attribute is removed except `rowspan`,
|
|
92
|
+
`colspan` and `scope`, which carry table structure. Body markup and text are
|
|
93
|
+
kept. There is no HTML-to-text conversion, so tag names can still surface
|
|
94
|
+
during normalization. If validation fails because tags interrupt the text,
|
|
95
|
+
consider extracting plain text and validating against a local `file:`
|
|
96
|
+
reference instead.
|
|
97
|
+
|
|
98
|
+
#### Titles
|
|
99
|
+
|
|
100
|
+
For HTML pages the title is the `citation_title` meta tag when present (the
|
|
101
|
+
Highwire / Google Scholar convention, which names the article rather than the
|
|
102
|
+
site), then the `<title>` tag.
|
|
103
|
+
|
|
104
|
+
For PDFs the validator tries, in order:
|
|
105
|
+
|
|
106
|
+
1. The `citation_title` of the publisher's landing page, where a known rule
|
|
107
|
+
maps the PDF URL to it. Currently J-STAGE: `.../_pdf` becomes
|
|
108
|
+
`.../_article`.
|
|
109
|
+
2. The PDF's embedded `/Title` metadata, ignoring placeholders such as
|
|
110
|
+
`Microsoft Word - draft.doc`, bare filenames and `Untitled`.
|
|
111
|
+
3. The URL itself.
|
|
112
|
+
|
|
113
|
+
So a PDF entry whose `title` equals its URL is one for which no title was
|
|
114
|
+
found.
|
|
115
|
+
|
|
116
|
+
The landing-page rules and the placeholder titles are kept in
|
|
117
|
+
`src/linkml_reference_validator/etl/rules.py`, with the other publisher and
|
|
118
|
+
site rules. Each rule sits beside examples of what it must and must not match.
|
|
119
|
+
To support another publisher, add a rule there with at least one example;
|
|
120
|
+
`tests/test_rules.py` fails for a rule without one.
|
|
90
121
|
|
|
91
122
|
### 3. Caching
|
|
92
123
|
|
|
@@ -104,9 +135,9 @@ content_type: url
|
|
|
104
135
|
## Content
|
|
105
136
|
|
|
106
137
|
<html>
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
138
|
+
<head>
|
|
139
|
+
<title>Chapter 3: Cell Structure and Function</title>
|
|
140
|
+
</head>
|
|
110
141
|
...
|
|
111
142
|
```
|
|
112
143
|
|
|
@@ -145,9 +176,10 @@ URL validation is designed for static web pages. It may not work well with:
|
|
|
145
176
|
|
|
146
177
|
### Raw Content
|
|
147
178
|
|
|
148
|
-
The validator stores
|
|
179
|
+
The validator stores sanitized page markup, not extracted text. For HTML pages:
|
|
149
180
|
|
|
150
|
-
- HTML tags are preserved in the cache
|
|
181
|
+
- HTML tags are preserved in the cache, without attributes other than
|
|
182
|
+
`rowspan`, `colspan` and `scope`
|
|
151
183
|
- The text normalization during validation handles most cases
|
|
152
184
|
- Complex HTML layouts may require careful text extraction
|
|
153
185
|
|
{linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/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
|
|
385
|
-
|
|
386
|
-
Validation Summary:
|
|
387
|
-
Total checks: 3
|
|
388
|
-
All validations passed!
|
|
389
|
-
```
|
|
390
|
-
|
|
391
|
-
**Failure:**
|
|
392
|
-
```
|
|
393
|
-
Validating data.yaml against schema schema.yaml
|
|
394
|
-
Cache directory: references_cache
|
|
395
|
-
|
|
396
|
-
Validation Issues (2):
|
|
397
|
-
[ERROR] Text part not found as substring: 'MUC1 activates JAK-STAT'
|
|
398
|
-
Location: Statement
|
|
381
|
+
The summary separates work performed from issues found:
|
|
399
382
|
|
|
383
|
+
```text
|
|
400
384
|
Validation Summary:
|
|
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
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Splitting supporting text in Python
|
|
2
|
+
|
|
3
|
+
The public import is:
|
|
4
|
+
|
|
5
|
+
```python
|
|
6
|
+
from linkml_reference_validator.matching import split_supporting_text
|
|
7
|
+
|
|
8
|
+
parts = split_supporting_text("protein [important] functions ... in cells")
|
|
9
|
+
assert parts == ["protein functions", "in cells"]
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
This pure helper needs no validator, fetcher, cache, or network access. The
|
|
13
|
+
validator's existing `_split_query` method delegates to it, so offline snippet
|
|
14
|
+
reports and validation share the same splitting implementation.
|
|
15
|
+
|
|
16
|
+
## Contract
|
|
17
|
+
|
|
18
|
+
`split_supporting_text(text, literal_bracket_patterns=()) -> list[str]`
|
|
19
|
+
|
|
20
|
+
- Replace editorial bracketed text with a space.
|
|
21
|
+
- Split on runs of **two or more ASCII periods**, including `..`, `...`, and
|
|
22
|
+
`....`. A single period and the Unicode ellipsis `…` remain literal.
|
|
23
|
+
- Collapse whitespace within each part, trim it, and discard empty parts.
|
|
24
|
+
- Return parts in input order; empty text or only editorial notes/separators
|
|
25
|
+
produces `[]`.
|
|
26
|
+
|
|
27
|
+
The helper performs splitting only; it does not normalize case or punctuation,
|
|
28
|
+
check a reference, or enforce validation policies such as minimum excerpt length.
|
|
29
|
+
An empty list contains no quoted evidence and should not be treated as a verified
|
|
30
|
+
snippet.
|
|
31
|
+
|
|
32
|
+
Bracket parsing retains the existing non-nested, single-line regex behavior:
|
|
33
|
+
`[` matches through the next `]` on the same line. Unmatched brackets remain.
|
|
34
|
+
Periods inside preserved brackets still act as separators.
|
|
35
|
+
|
|
36
|
+
## Literal scientific notation and configuration
|
|
37
|
+
|
|
38
|
+
The default is an empty pattern sequence, matching
|
|
39
|
+
`ReferenceValidationConfig.literal_bracket_patterns`. **No scientific notation is
|
|
40
|
+
preserved automatically.** Each supplied regex is searched against the content
|
|
41
|
+
inside brackets, without the brackets themselves. Any match preserves the whole
|
|
42
|
+
bracketed text; otherwise it is removed. Supplied patterns are the complete set
|
|
43
|
+
of exceptions, with no implicit patterns added.
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
from linkml_reference_validator.models import ReferenceValidationConfig
|
|
47
|
+
|
|
48
|
+
config = ReferenceValidationConfig(literal_bracket_patterns=[r"\d", r"[()+]"])
|
|
49
|
+
parts = split_supporting_text(
|
|
50
|
+
"binds [2Fe-2S] [important] ... exports [poly(A)+] RNA",
|
|
51
|
+
literal_bracket_patterns=config.literal_bracket_patterns,
|
|
52
|
+
)
|
|
53
|
+
assert parts == ["binds [2Fe-2S]", "exports [poly(A)+] RNA"]
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
For repeated calls, pass a sequence of compiled string regexes to reuse them.
|
|
57
|
+
Compiled flags are preserved; invalid regex strings raise `re.error`.
|
|
58
|
+
|
|
59
|
+
```python
|
|
60
|
+
import re
|
|
61
|
+
|
|
62
|
+
patterns = tuple(re.compile(p) for p in config.literal_bracket_patterns)
|
|
63
|
+
assert split_supporting_text("[2Fe-2S] ... [poly(A)+]", patterns) == [
|
|
64
|
+
"[2Fe-2S]", "[poly(A)+]"
|
|
65
|
+
]
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
See [Editorial Conventions](../concepts/editorial-conventions.md) for authoring
|
|
69
|
+
examples.
|
{linkml_reference_validator-0.2.1rc3 → linkml_reference_validator-0.3.0}/docs/setup-guide.md
RENAMED
|
@@ -385,6 +385,10 @@ validation:
|
|
|
385
385
|
# Cache directory (relative to config file or absolute)
|
|
386
386
|
cache_dir: ./references_cache
|
|
387
387
|
|
|
388
|
+
# Reject excerpts quoting fewer than this many non-whitespace
|
|
389
|
+
# characters (0 disables; empty excerpts are always rejected)
|
|
390
|
+
min_excerpt_length: 0
|
|
391
|
+
|
|
388
392
|
# Custom reference prefix mappings
|
|
389
393
|
reference_prefix_map:
|
|
390
394
|
geo: GEO
|