docpluck 2.4.3__tar.gz → 2.4.4__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.
- {docpluck-2.4.3 → docpluck-2.4.4}/CHANGELOG.md +20 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/PKG-INFO +1 -1
- {docpluck-2.4.3 → docpluck-2.4.4}/docpluck/__init__.py +1 -1
- {docpluck-2.4.3 → docpluck-2.4.4}/docpluck/extract_structured.py +46 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docpluck/figures/detect.py +23 -9
- {docpluck-2.4.3 → docpluck-2.4.4}/pyproject.toml +1 -1
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_figure_detect.py +59 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/.claude/skills/_project/lessons.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/.claude/skills/docpluck-cleanup/SKILL.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/.claude/skills/docpluck-deploy/SKILL.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/.claude/skills/docpluck-qa/SKILL.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/.claude/skills/docpluck-qa/references/benchmark-mode.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/.claude/skills/docpluck-qa/references/check-11-hard-rules.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/.claude/skills/docpluck-qa/references/check-13-escicheck-production.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/.claude/skills/docpluck-qa/references/check-5-escicheck-library.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/.claude/skills/docpluck-qa/references/check-6-escicheck-local-webapp.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/.claude/skills/docpluck-qa/references/check-7-batch-smoke.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/.claude/skills/docpluck-review/SKILL.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/.github/workflows/publish.yml +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/.github/workflows/test.yml +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/.gitignore +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/CLAUDE.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/HANDOFF_SECTIONS_APP_INTEGRATION.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/LESSONS.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/LICENSE +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/REPLY_FROM_DOCPLUCK_v1.4.5.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/REPLY_FROM_DOCPLUCK_v1.5.0.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/REQUEST_08_CHUNKING_ENDPOINT.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/REQUEST_09_REFERENCE_LIST_NORMALIZATION.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/TODO.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docpluck/__main__.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docpluck/batch.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docpluck/cli.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docpluck/extract.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docpluck/extract_docx.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docpluck/extract_html.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docpluck/extract_layout.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docpluck/figures/__init__.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docpluck/normalize.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docpluck/quality.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docpluck/render.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docpluck/sections/__init__.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docpluck/sections/annotators/__init__.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docpluck/sections/annotators/docx.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docpluck/sections/annotators/html.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docpluck/sections/annotators/pdf.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docpluck/sections/annotators/text.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docpluck/sections/blocks.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docpluck/sections/boundaries.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docpluck/sections/core.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docpluck/sections/taxonomy.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docpluck/sections/types.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docpluck/tables/__init__.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docpluck/tables/bbox_utils.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docpluck/tables/camelot_extract.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docpluck/tables/captions.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docpluck/tables/cell_cleaning.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docpluck/tables/cluster.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docpluck/tables/confidence.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docpluck/tables/detect.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docpluck/tables/render.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docpluck/tables/whitespace.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docpluck/version.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/BENCHMARKS.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/DESIGN.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/HANDOFF_2026-05-07_sections_strict_iteration.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/HANDOFF_2026-05-09_session_state_and_followups.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/HANDOFF_2026-05-09_unified_extraction_brainstorm.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/HANDOFF_2026-05-10_table_rendering_iteration.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/HANDOFF_2026-05-10_table_rendering_iteration_2.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/HANDOFF_2026-05-10_table_rendering_iteration_3.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/HANDOFF_2026-05-10_table_rendering_iteration_4.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/HANDOFF_2026-05-10_table_rendering_iteration_5.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/HANDOFF_2026-05-10_table_rendering_iteration_6.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/HANDOFF_2026-05-10_table_rendering_iteration_7.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/HANDOFF_2026-05-11_PROMOTE_SPIKE_TO_LIBRARY.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/HANDOFF_2026-05-11_table_rendering_iteration_8.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/HANDOFF_2026-05-11_visual_review_findings.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/HANDOFF_2026-05-12_phase2_101pdf_corpus.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/HANDOFF_2026-05-12_remaining_ui_and_chrome_verification.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/HANDOFF_2026-05-12_visual_verify_results.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/NORMALIZATION.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/README.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/TRIAGE_2026-05-10_corpus_assessment.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/2026-05-06-section-identification.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/2026-05-06-table-extraction.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/2026-05-07-sections-strict-iteration-progress.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/2026-05-08-unified-extraction-phase-0-splice-spike.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/sections-deferred-items.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/sections-issues-backlog.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/2026-05-07_spot-01_apa.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/2026-05-07_spot-02_pattern-A-shipped.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/2026-05-08_spot-final_all-styles.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/experiments/COMPARISON.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/experiments/option-a/korbmacher_table1.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/experiments/option-a/option-a.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/experiments/option-a/ziano_table1.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/experiments/option-b/korbmacher_notes_raw.txt +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/experiments/option-b/korbmacher_table1.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/experiments/option-b/notes.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/experiments/option-b/option-b.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/experiments/option-b/ziano_notes_raw.txt +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/experiments/option-b/ziano_table1.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/experiments/option-c/korbmacher_table1.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/experiments/option-c/notes.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/experiments/option-c/option-c.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/experiments/option-c/sample-pdftotext-bbox.html +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/experiments/option-c/ziano_table1.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/experiments/option-d/korbmacher_table1.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/experiments/option-d/notes.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/experiments/option-d/option-d.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/experiments/option-d/ziano_table1.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/experiments/option-e/korbmacher_2022_kruger_bbox.html +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/experiments/option-e/korbmacher_bbox.html +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/experiments/option-e/korbmacher_table1.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/experiments/option-e/option-e.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/experiments/option-e/sample-bbox.html +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/experiments/option-e/ziano_2021_joep_bbox.html +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/experiments/option-e/ziano_bbox.html +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/experiments/option-e/ziano_table1.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/html-fallback-demo.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs/chandrashekar_2023_mp.err +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs/chandrashekar_2023_mp.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs/efendic_2022_affect.err +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs/efendic_2022_affect.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs/ieee_access_2.err +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs/ieee_access_2.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs/ip_feldman_2025_pspb.err +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs/ip_feldman_2025_pspb.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs/korbmacher_2022_kruger.err +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs/korbmacher_2022_kruger.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs/nat_comms_1.err +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs/nat_comms_1.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs/ziano_2021_joep.err +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs/ziano_2021_joep.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs-new/am_sociol_rev_3.err +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs-new/am_sociol_rev_3.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs-new/amc_1.err +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs-new/amc_1.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs-new/amj_1.err +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs-new/amj_1.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs-new/amle_1.err +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs-new/amle_1.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs-new/ar_apa_j_jesp_2009_12_010.err +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs-new/ar_apa_j_jesp_2009_12_010.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs-new/ar_royal_society_rsos_140066.err +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs-new/ar_royal_society_rsos_140066.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs-new/ar_royal_society_rsos_140072.err +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs-new/ar_royal_society_rsos_140072.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs-new/bjps_1.err +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs-new/bjps_1.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs-new/chan_feldman_2025_cogemo.err +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs-new/chan_feldman_2025_cogemo.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs-new/chen_2021_jesp.err +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs-new/chen_2021_jesp.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs-new/demography_1.err +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs-new/demography_1.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs-new/ieee_access_3.err +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs-new/ieee_access_3.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs-new/ieee_access_4.err +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs-new/ieee_access_4.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs-new/jama_open_1.err +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs-new/jama_open_1.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs-new/jama_open_2.err +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs-new/jama_open_2.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs-new/jmf_1.err +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs-new/jmf_1.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs-new/nat_comms_2.err +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs-new/nat_comms_2.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs-new/sci_rep_1.err +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs-new/sci_rep_1.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs-new/social_forces_1.err +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/outputs-new/social_forces_1.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/papers.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/report.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/splice_spike.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/splice-spike/test_splice_spike.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/specs/2026-04-27-request-09-reference-normalization-design.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/specs/2026-05-06-section-identification-design.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/specs/2026-05-06-table-extraction-design.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/specs/2026-05-08-unified-extraction-design.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/scripts/verify_corpus.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/scripts/verify_corpus_full.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/__init__.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/conftest.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/fixtures/__init__.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/fixtures/sections/__init__.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/fixtures/sections/builders.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/fixtures/structured/.gitkeep +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/fixtures/structured/MANIFEST.json +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/fixtures/structured/README.md +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/golden/sections/apa_multi_study_pdf.json +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/golden/sections/apa_single_study_pdf.json +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/golden/sections/html_real_headings.json +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/snapshots/amj_lattice.txt +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/snapshots/apa_chan_feldman_lineless.txt +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/snapshots/apa_chen_jesp_lineless.txt +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/snapshots/apa_efendic_affect.txt +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/snapshots/apa_ip_feldman_pspb.txt +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/snapshots/bmc_lattice.txt +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/snapshots/ieee_figure_heavy.txt +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/snapshots/ieee_lattice.txt +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/snapshots/jama_lattice.txt +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/snapshots/nat_comms_figure_only.txt +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/snapshots/nature_minimal_rule.txt +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/snapshots/scirep_minimal_rule.txt +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_bbox_utils.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_benchmark_docx_html.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_caption_regex.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_cli_sections.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_cli_structured.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_confidence.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_corpus_smoke.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_d5_normalization_audit.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_edge_cases.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_extract_docx.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_extract_filter_sugar.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_extract_html.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_extract_layout.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_extract_pdf_structured.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_extraction.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_f0_table_region_aware.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_fixtures_manifest.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_lattice_cluster.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_metaesci_followups.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_normalization.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_normalize_f0_footnote_strip.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_normalize_layout_param.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_normalize_report_layout_fields.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_normalize_v18_strips.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_quality.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_render.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_render_html.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_request_09_reference_normalization.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_sections_boundaries.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_sections_boundary_truncation.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_sections_core_partition.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_sections_docx_annotator.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_sections_extract_text.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_sections_footnote_section.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_sections_golden.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_sections_html_annotator.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_sections_pdf_annotator.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_sections_public_api.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_sections_real_corpus.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_sections_taxonomy.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_sections_text_annotator.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_sections_types.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_sections_unit_corpus.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_sections_v161_coalesce.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_sections_v161_subheadings.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_sections_v161_taxonomy.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_sections_v161_text_annotator.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_sections_version.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_smoke_fixtures.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_structured_result_type.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_structured_types.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_structured_version.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_table_detect.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_tables_cell_cleaning.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_text_mode.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_v23_1_fixes.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_v23_bug_fixes.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_v23_post_corpus.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_v23_post_corpus_v2.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_v2_backwards_compat.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_v2_top_level_exports.py +0 -0
- {docpluck-2.4.3 → docpluck-2.4.4}/tests/test_whitespace_cluster.py +0 -0
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [2.4.4] — 2026-05-13
|
|
4
|
+
|
|
5
|
+
Bug fix on v2.4.3's caption-trim feature + extension to a second chart-data signature.
|
|
6
|
+
|
|
7
|
+
### Bug fix
|
|
8
|
+
|
|
9
|
+
1. **`docpluck/extract_structured.py::_extract_caption_text`** — v2.4.3's `_trim_caption_at_chart_data` was added to `docpluck/figures/detect.py::_full_caption_text`, but the live render pipeline never calls that function — figure captions are built in `extract_structured.py::_extract_caption_text` (which `_figure_from_caption` calls). v2.4.3's caption-trim was therefore a no-op on real renders despite its tests passing in isolation. v2.4.4 applies the trim to `_extract_caption_text` for `kind == "figure"` captions, so the trim actually fires during `render_pdf_to_markdown(pdf_bytes)`. Verified by manual render of `jama_open_6` (caption 400 chars → 47 chars) and `jama_open_3` (405 → 208 chars).
|
|
10
|
+
|
|
11
|
+
### Enhancement
|
|
12
|
+
|
|
13
|
+
2. **`docpluck/extract_structured.py::_trim_caption_at_chart_data`** — extended with a second chart-data signature: a run of 5+ short (1–4 digit) numeric tokens separated only by whitespace. Catches axis-tick label sequences (``0 5 10 15 20``) and stacked column values (``340 321 280 5 270``) that the 6-digit-run rule didn't see on charts with small-magnitude data. The two signatures are evaluated jointly; the earlier match in the caption wins so the caption is trimmed at the start of the chart data, not partway through it. Same conservative gates as before (caption ≥ 150 chars, surviving text ≥ 40 chars). Affects most JAMA Network Open Kaplan-Meier and Sci Rep / BMC clinical-trial papers — caption length drops from 400-char hard cap to ~150 chars of real prose.
|
|
14
|
+
|
|
15
|
+
### Bumps
|
|
16
|
+
|
|
17
|
+
- `__version__`: `2.4.3` → `2.4.4`. Patch — figure-caption truncation is now real and broader.
|
|
18
|
+
|
|
19
|
+
### Tests
|
|
20
|
+
|
|
21
|
+
3 new tests in `tests/test_figure_detect.py` (tick-run truncation, prose-with-inline-numbers no-op, earlier-of-two-signatures priority).
|
|
22
|
+
|
|
3
23
|
## [2.4.3] — 2026-05-13
|
|
4
24
|
|
|
5
25
|
Same-day follow-up. Two preventative improvements aimed at quality issues that didn't trip the verifier tags but were visible in rendered output:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: docpluck
|
|
3
|
-
Version: 2.4.
|
|
3
|
+
Version: 2.4.4
|
|
4
4
|
Summary: PDF, DOCX, and HTML text extraction and normalization for academic papers
|
|
5
5
|
Project-URL: Homepage, https://github.com/giladfeldman/docpluck
|
|
6
6
|
Project-URL: Documentation, https://github.com/giladfeldman/docpluck/tree/main/docs
|
|
@@ -71,7 +71,7 @@ from .figures import Figure
|
|
|
71
71
|
from .extract_structured import TABLE_EXTRACTION_VERSION, StructuredResult, extract_pdf_structured
|
|
72
72
|
from .render import render_pdf_to_markdown
|
|
73
73
|
|
|
74
|
-
__version__ = "2.4.
|
|
74
|
+
__version__ = "2.4.4"
|
|
75
75
|
__author__ = "Gilad Feldman"
|
|
76
76
|
__license__ = "MIT"
|
|
77
77
|
|
|
@@ -332,11 +332,57 @@ def _extract_caption_text(
|
|
|
332
332
|
# Re-prefix the label if stripping ate it.
|
|
333
333
|
if cap.label and not snippet.startswith(cap.label):
|
|
334
334
|
snippet = f"{cap.label}. {snippet}".strip()
|
|
335
|
+
# v2.4.4: trim chart-data appendage from figure captions (axis-tick
|
|
336
|
+
# sequences, raw bar-chart values pdftotext joined inline into the
|
|
337
|
+
# caption paragraph). For tables the appendage is usually the next-
|
|
338
|
+
# row continuation so skip — the caption hard-cap at 400 below
|
|
339
|
+
# bounds it.
|
|
340
|
+
if cap.kind == "figure":
|
|
341
|
+
snippet = _trim_caption_at_chart_data(snippet)
|
|
335
342
|
if len(snippet) > 400:
|
|
336
343
|
snippet = snippet[:400].rsplit(" ", 1)[0] + "…"
|
|
337
344
|
return snippet
|
|
338
345
|
|
|
339
346
|
|
|
347
|
+
# v2.4.4: shared chart-data trim, duplicated logic from
|
|
348
|
+
# ``docpluck.figures.detect._trim_caption_at_chart_data`` so this module
|
|
349
|
+
# doesn't import from ``figures.detect`` (which has its own layout-channel
|
|
350
|
+
# dependencies). Two signatures of pdftotext-joined chart data:
|
|
351
|
+
# 1. Run of 6+ consecutive digits — flowchart counts, row IDs.
|
|
352
|
+
# 2. Run of 5+ short (1–4 digit) numeric tokens separated only by
|
|
353
|
+
# whitespace — axis-tick label sequences.
|
|
354
|
+
_CHART_DATA_DIGIT_RUN_RE_STRUCT = re.compile(r"\b\d{6,}\b")
|
|
355
|
+
_CHART_DATA_TICK_RUN_RE_STRUCT = re.compile(r"(?:\b\d{1,4}\b[ \t]+){5,}")
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
def _trim_caption_at_chart_data(caption: str) -> str:
|
|
359
|
+
"""Truncate a caption when it transitions from prose to chart-data.
|
|
360
|
+
|
|
361
|
+
Conservative: only fires when caption ≥ 150 chars AND the surviving
|
|
362
|
+
trimmed text is ≥ 40 chars. The two regex signatures catch
|
|
363
|
+
complementary chart-data patterns (large counts and small axis-tick
|
|
364
|
+
sequences); the earlier match wins.
|
|
365
|
+
"""
|
|
366
|
+
if not caption or len(caption) < 150:
|
|
367
|
+
return caption
|
|
368
|
+
candidates: list[int] = []
|
|
369
|
+
m1 = _CHART_DATA_DIGIT_RUN_RE_STRUCT.search(caption)
|
|
370
|
+
if m1 is not None:
|
|
371
|
+
candidates.append(m1.start())
|
|
372
|
+
m2 = _CHART_DATA_TICK_RUN_RE_STRUCT.search(caption)
|
|
373
|
+
if m2 is not None:
|
|
374
|
+
candidates.append(m2.start())
|
|
375
|
+
if not candidates:
|
|
376
|
+
return caption
|
|
377
|
+
cut = min(candidates)
|
|
378
|
+
while cut > 0 and not caption[cut - 1].isspace():
|
|
379
|
+
cut -= 1
|
|
380
|
+
trimmed = caption[:cut].rstrip(" ,;:")
|
|
381
|
+
if len(trimmed) < 40:
|
|
382
|
+
return caption
|
|
383
|
+
return trimmed
|
|
384
|
+
|
|
385
|
+
|
|
340
386
|
def _isolated_table_from_caption(
|
|
341
387
|
cap: CaptionMatch,
|
|
342
388
|
raw_text: str,
|
|
@@ -146,6 +146,14 @@ def _full_caption_text(raw_text: str, cap: CaptionMatch) -> str:
|
|
|
146
146
|
# that pdftotext joined chart data (raw bar-chart values, participant counts,
|
|
147
147
|
# row IDs) into the caption.
|
|
148
148
|
_CHART_DATA_DIGIT_RUN_RE = re.compile(r"\b\d{6,}\b")
|
|
149
|
+
# A run of 5+ short numeric tokens (1–4 digits each) separated only by
|
|
150
|
+
# whitespace is a v2.4.4 signal — captures axis-tick label sequences
|
|
151
|
+
# (``0 5 10 15 20``) and stacked column values (``340 321 280 5 270``)
|
|
152
|
+
# that the 6-digit rule misses on charts with small-magnitude data.
|
|
153
|
+
# Real captions reference numbers via prose ("with n = 1234 participants",
|
|
154
|
+
# "p < .001"), so digit tokens are interleaved with words rather than
|
|
155
|
+
# stacked five-in-a-row.
|
|
156
|
+
_CHART_DATA_TICK_RUN_RE = re.compile(r"(?:\b\d{1,4}\b[ \t]+){5,}")
|
|
149
157
|
|
|
150
158
|
|
|
151
159
|
def _trim_caption_at_chart_data(caption: str) -> str:
|
|
@@ -161,21 +169,27 @@ def _trim_caption_at_chart_data(caption: str) -> str:
|
|
|
161
169
|
where the real caption is "Flowchart of Study Sample Selection" and the
|
|
162
170
|
rest is chart data values.
|
|
163
171
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
the word boundary so we don't end mid-word.
|
|
172
|
+
v2.4.4: two complementary signatures are scanned (see module-level
|
|
173
|
+
constants); the *earlier* match in the caption wins so the caption is
|
|
174
|
+
trimmed at the start of the chart data, not partway through it.
|
|
168
175
|
|
|
169
176
|
Conservative: only fires when the caption is ≥ 150 chars (real short
|
|
170
|
-
captions almost never have chart-data appendage), and only when the
|
|
171
|
-
surviving trimmed caption is ≥ 40 chars
|
|
177
|
+
captions almost never have a chart-data appendage), and only when the
|
|
178
|
+
surviving trimmed caption is ≥ 40 chars (sanity check protects against
|
|
179
|
+
edge cases where the digit run lands near the label).
|
|
172
180
|
"""
|
|
173
181
|
if not caption or len(caption) < 150:
|
|
174
182
|
return caption
|
|
175
|
-
|
|
176
|
-
|
|
183
|
+
candidates: list[int] = []
|
|
184
|
+
m1 = _CHART_DATA_DIGIT_RUN_RE.search(caption)
|
|
185
|
+
if m1 is not None:
|
|
186
|
+
candidates.append(m1.start())
|
|
187
|
+
m2 = _CHART_DATA_TICK_RUN_RE.search(caption)
|
|
188
|
+
if m2 is not None:
|
|
189
|
+
candidates.append(m2.start())
|
|
190
|
+
if not candidates:
|
|
177
191
|
return caption
|
|
178
|
-
cut =
|
|
192
|
+
cut = min(candidates)
|
|
179
193
|
# Walk back to the previous word boundary.
|
|
180
194
|
while cut > 0 and not caption[cut - 1].isspace():
|
|
181
195
|
cut -= 1
|
|
@@ -159,3 +159,62 @@ def test_trim_caption_keeps_minimum_post_label_content():
|
|
|
159
159
|
out = _trim_caption_at_chart_data(short_pre_label)
|
|
160
160
|
# Sanity check fires; return original.
|
|
161
161
|
assert out == short_pre_label
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
# v2.4.4: caption truncation extended to short-token tick runs (5+ short
|
|
165
|
+
# numeric tokens in a row — axis-tick label sequences from charts).
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def test_trim_caption_at_tick_run_truncates_axis_labels():
|
|
169
|
+
"""v2.4.4: detect chart axis-tick sequences (5+ short numeric tokens
|
|
170
|
+
separated only by whitespace) — jama_open_3-style Kaplan-Meier
|
|
171
|
+
captions absorb gridline values like ``0 0 5 10 15`` that the 6-digit
|
|
172
|
+
rule didn't catch."""
|
|
173
|
+
from docpluck.figures.detect import _trim_caption_at_chart_data
|
|
174
|
+
cap = (
|
|
175
|
+
"Figure 1. Unadjusted Kaplan-Meier Curves Across Groups With "
|
|
176
|
+
"Different Objective Sleep Duration for All-Cause Mortality 100 "
|
|
177
|
+
"90 Survival probability, % 80 70 Sleep duration 60 seven hours "
|
|
178
|
+
"6 to 7 hours 50 5 to 6 hours less than 5 hours 0 0 5 10 15 "
|
|
179
|
+
"Follow-up time y No at risk Sleep duration seven hours 340 321 "
|
|
180
|
+
"280 5 Sleep duration"
|
|
181
|
+
)
|
|
182
|
+
out = _trim_caption_at_chart_data(cap)
|
|
183
|
+
assert "0 0 5 10 15" not in out
|
|
184
|
+
# Trim should preserve the prose lead-in.
|
|
185
|
+
assert out.startswith("Figure 1. Unadjusted Kaplan-Meier Curves")
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def test_trim_caption_preserves_legitimate_prose_with_inline_numbers():
|
|
189
|
+
"""Real caption prose references numbers in stats ('n = 1234', 'p < .001'),
|
|
190
|
+
but each number is followed by a word — not 5+ stacked numerics in a row."""
|
|
191
|
+
from docpluck.figures.detect import _trim_caption_at_chart_data
|
|
192
|
+
cap = (
|
|
193
|
+
"Figure 2. Mean reaction times across the four experimental "
|
|
194
|
+
"conditions, with n = 1234 participants total (95% CI [120.5, "
|
|
195
|
+
"180.3] ms for condition A; 95% CI [110.2, 175.4] for condition "
|
|
196
|
+
"B). Significant differences observed at p < .001 between paired "
|
|
197
|
+
"conditions in all 4 contrasts of interest, as predicted."
|
|
198
|
+
)
|
|
199
|
+
out = _trim_caption_at_chart_data(cap)
|
|
200
|
+
assert out == cap
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
def test_trim_caption_picks_earliest_match_across_both_rules():
|
|
204
|
+
"""When both the 6-digit-run and the 5-token-tick rules match,
|
|
205
|
+
truncate at the earlier offset so we don't keep chart data past the
|
|
206
|
+
first signal."""
|
|
207
|
+
from docpluck.figures.detect import _trim_caption_at_chart_data
|
|
208
|
+
# Tick run appears first; 6-digit run appears later.
|
|
209
|
+
cap = (
|
|
210
|
+
"Figure 3. Bar plot of conditions A through F across the years "
|
|
211
|
+
"of interest 2020 2021 2022 2023 2024 2025 with later analytic "
|
|
212
|
+
"subsample participant total 4876956 in the secondary cohort "
|
|
213
|
+
"described in the methods section above and detailed in the "
|
|
214
|
+
"supplementary materials accompanying this paper."
|
|
215
|
+
)
|
|
216
|
+
out = _trim_caption_at_chart_data(cap)
|
|
217
|
+
# The tick run "2020 2021 2022 2023 2024 2025" appears earlier; trim
|
|
218
|
+
# there.
|
|
219
|
+
assert "2020 2021" not in out
|
|
220
|
+
assert "4876956" not in out
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{docpluck-2.4.3 → docpluck-2.4.4}/.claude/skills/docpluck-qa/references/check-11-hard-rules.md
RENAMED
|
File without changes
|
|
File without changes
|
{docpluck-2.4.3 → docpluck-2.4.4}/.claude/skills/docpluck-qa/references/check-5-escicheck-library.md
RENAMED
|
File without changes
|
|
File without changes
|
{docpluck-2.4.3 → docpluck-2.4.4}/.claude/skills/docpluck-qa/references/check-7-batch-smoke.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{docpluck-2.4.3 → docpluck-2.4.4}/docs/HANDOFF_2026-05-12_remaining_ui_and_chrome_verification.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/2026-05-06-section-identification.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{docpluck-2.4.3 → docpluck-2.4.4}/docs/superpowers/plans/spot-checks/2026-05-07_spot-01_apa.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|