Repository navigation
Conversation
Clippy 0.1.98 flags two new lints that break the CI step
`cargo clippy --all-targets -- -D warnings` on stable:
- chunks_exact_to_as_chunks (attachments.rs): iterate the
/Names leaf with `as_chunks::<2>()`. The trailing odd element
is still skipped, as with `chunks_exact(2)`.
- collapsible_match (layout.rs): move the "no trailing space"
check into the TJ match guards. A failing guard falls through
to `_ => {}`, which is what the inner `if` did.
No behaviour change. `as_chunks` needs Rust 1.88 or newer.
docugraph ships a binary, so the lockfile belongs in the repo. Without it every build resolves dependencies again and a fixed commit does not pin rmcp, lopdf, tokio and the rest. The lock is the one resolved for 2832efa (182 packages, rmcp 3.3.0, lopdf 0.45.0, tokio 1.53.1) and matches Cargo.toml under `--locked`.
test_real_pdf_loading_and_extraction read a hardcoded Windows path and returned early when it was missing, so it reported "ok" without testing anything on every machine but one. Read the path from DOCUGRAPH_TEST_PDF instead and mark the test #[ignore] with a reason, so it shows up as ignored by default. Run it with `DOCUGRAPH_TEST_PDF=... cargo test -- --ignored`; a missing variable or file now fails loudly.
Now that Cargo.lock is tracked, fail CI when it is out of date with Cargo.toml instead of silently rewriting it. There is no separate build step: clippy is the first step that resolves dependencies and `cargo test` builds the crate, so both get --locked. Without it on clippy the lock would be rewritten before the test step runs.
Named destinations were only looked up in the root /Names array of the /Dests name tree, so trees split into /Kids (as LaTeX/hyperref writes them) never matched. The fallback then read a numeric name "N" as page N+1, which put 61 of 96 bookmarks of a real hyperref book on the wrong page. Walk /Kids using /Limits to prune (with a full scan if that misses), accept destination dictionaries (<< /D [...] >>) and drop the numeric guess: an unknown name now resolves to None. Recursion through references, names and tree nodes is depth-limited.
traverse_outline_items passed the parent id only to the first child (/First) and recursed into /Next with None, so every later sibling lost its parent: in a real book only 14 of 81 subsections had a parent_id. Walk the /Next chain in a loop that gives every sibling the same parent, skipping items already visited so a malformed cycle cannot loop forever.
When a search hit was a section, get_evidence cited the section's first page even if the snippet came from a later page of that section. Search units now record the offset where each page's text starts, so a hit can report snippet_page: the page holding the matched term. Search results expose it, and get_evidence and the page snippets of get_context cite it instead of page_start.
PDF page numbers are physical positions, while books print their own numbering (roman front matter, arabic pages restarting at 1). When the catalog has /PageLabels, compute each page's label from the number tree (/Nums and /Kids; styles D, R, r, A, a; /P prefix; /St start) and store it on the page. The label is shown next to the PDF page: page_label_start/end in document_outline, has_page_labels and "impresas" ranges in document_info, "(impresa N)" in document_read_pages headers and in get_evidence/get_context citations, and snippet_page_label in search hits. PDFs without /PageLabels get no labels: no offset is guessed.
Owner
Author
|
Se descarta: los arreglos de docugraph los está haciendo el autor en su copia local y estos cambios chocarían con ellos. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problema
Con los dos libros reales (Aprendiendo Git y Sumérgete en los patrones de diseño), las citas no eran fiables:
/A << /S /GoTo /D (0) >>), y esos nombres están en un árbol/Names /Destsrepartido en/Kidscon/Limits.resolve_named_destinationsolo miraba el array/Namesde la raíz, así que nunca encontraba nada. Después, la reserva deresolve_destleía el nombre «N» como la página N+1.parent_iddel outline nativo.traverse_outline_itemspasaba el padre solo al primer hijo (/First) y recorría/NextconNone. En cada capítulo, solo la primera subsección conocía a su padre.get_evidencecitabapage_start(la primera página de la sección) aunque el fragmento viniera de otra página.Cambios (un commit por problema)
fix(links): resolve nested named destinations/Kids, podando con/Limits. Si esa búsqueda falla, repite el recorrido completo sin poda.<< /D [...] >>), tanto en/Namescomo en el/Destsde PDF 1.1.None, y el enlace queda comonameden vez de apuntar a una página falsa.fix(outline): keep parent_id on sibling sections/Nextse recorre en un bucle que da el mismo padre a todos los hermanos./Nexto/Firstmal formado ya no provoca un bucle infinito.fix(evidence): cite the page of each snippetdocument_searchydocument_search_hybridexponensnippet_page: la página donde está el término encontrado.get_evidencey los fragmentos de página deget_contextcitan esa página.feat(pages): expose printed page labels/PageLabels, se calcula la etiqueta de cada página a partir del árbol de números:/Numsy/Kids; estilos D, R, r, A y a; prefijo/P; inicio/St.document_info:has_page_labelsy rangos «pp. 96-101, impresas 89-94».document_outline:page_label_startypage_label_end.document_read_pages: «--- Página 190 (impresa 183) ---».get_evidenceyget_context: «p. 190 (impresa 183)».snippet_page_label./PageLabels: no se inventan desfases./PageLabels(/Nums [0 <</S/r>> 3 <</P()>> 7 <</S/D>>]) y el resultado coincide con el desfase medido (−7)./PageLabels(su catálogo solo tiene/Lang,/Outlinesy/Pages), así que no sale etiqueta. El desfase de −1 que se midió a mano no se aplica.Los tests nuevos generan sus propios PDFs sintéticos con lopdf; no hay nada de los libros en el repo.
tests/outline_pages_test.rs: árbol de nombres de tres niveles con claves «0», «1a», «2c»…;/Destsde PDF 1.1; nombre inexistente;parent_iden tres niveles;/PageLabelscon/Kids, prefijo vacío,/Sty referencias, comprobado de punta a punta con info, outline, read_pages y evidence.tests/page_citations_test.rs:snippet_pageen search; cita de sección con la página del fragmento; formatos romano y alfabético; documento sin etiquetas.Cómo se verificó
En local, en
c1795c3, connice -n 19 ionice -c3y-j 2:cargo testse lanzó objetivo a objetivo, borrando cada binario de test al terminar, porque el/tmpcompartido (tmpfs) estaba al 98-100 %. Son los mismos objetivos que ejecutacargo testde una vez, y la CI lo corre completo.CARGO_PROFILE_DEV_DEBUG=0ySTRIP=symbolspor la misma razón.fmt --check,clippy --all-targets -D warningsy sus tests nuevos:37cf666: 2 passed81bdc57: 3 passeda6b648c: 3 + 2 passedMedición con los libros reales:
d2d6941) y con el de esta rama, cada uno en su caché dentro del sandbox. Las cachés no salen de ahí ni se suben.pdftohtml -xml) por orden, título, nivel y página.document_search_hybrid(limit 5, condocument_id) ydocument_get_evidence(por defecto).pdftotextpara saber en qué página está de verdad./PageLabels: se descomprimieron los flujos de objetos de cada PDF y se buscó la clave.Cifras antes y después (libros reales)
d2d6941)c1795c3)parent_idparent_idget_evidence: citas con la página real del fragmento (48 citas, 47 localizables en pdftotext)search_hybridcon rótulo o página falsos/PageLabels)Top-1 de
search_hybrid: cambia en 4 de las 12 consultas; las otras 8 (P1-P6, G2, G6) quedan igual.Con el mismo criterio manual del informe previo, las 12 respuestas pasan de 6 correctas, 2 parciales y 4 incorrectas a 7, 2 y 3.
Detalle de las citas de
get_evidence:page_start. Estaban en P1 (dos), P3, P6, G1, G4 y G6.Tiempos, con binario de depuración y solo como orientación:
search_hybriden Git: pasa de 5,3-5,5 s a 3,0-3,5 s, porque las secciones ya no abarcan rangos enormes de páginas equivocadas. En Patrones sigue en 7,1-7,9 s.Notas
docugraph index).snippet_page,snippet_page_label,page_label_start/end,has_page_labels,page_labelenEvidenceItem). El texto de las citas añade «(impresa N)» solo cuando la etiqueta existe y es distinta del número de página del PDF.