Skip to content

v0.14.0

Choose a tag to compare

@github-actions github-actions released this 09 Sep 17:01
· 10 commits to main since this release

Minor rather than patch, and the reason is the dependency again. epubveri
types are in this crate's public API — ChangeReport::before is an
epubveri::report::Report and fixers::plan takes one — so moving the floor
from ^0.13.2 to ^0.13.7 breaks a library consumer even though the CLI looks
unchanged. Same reasoning as 0.10.0, 0.12.0 and 0.13.0, each of which carried a
detector floor. This one goes further than tracking: it consumes
epubveri::xmlext::is_xml_blank, so the floor is load-bearing at compile time.

Two bad repairs that shipped in 0.13.0 are fixed here, both found by
whole-shelf audit rather than by any test, and both in fixers that looked
finished.

Added

  • fix.navdoc_empty_nav — an optional <nav> in the navigation document
    whose <ol> holds no <li>
    (RSC-005 / navdoc.ol.empty, error). The
    whole <nav> is deleted, not just the list: leaving the <nav> behind
    produces navdoc.nav.missing_ol and navdoc.nav.not_flat in its place. A
    landmarks or page-list nav is optional, and one whose list is empty states
    nothing.

    The finding cannot say which <ol> it meansparams is empty, and
    epubsana never reads a finding's position — so the fixer re-derives the target
    from the document. Four shapes emit the identical message and only one is
    repairable, so it declines the toc nav (deleting it would author
    navdoc.document.missing_toc), a list nested inside an <li>, a nav carrying
    a heading, and any subtree holding an id that a fragment link could name. A
    <nav> with no epub:type is never touched at all: its content model is
    unrestricted, so the detector reports nothing about it. Each decline is an
    answer the detector gave to a fixture, and each is pinned by a
    mutation-checked test.

    Measured on 474 books: 3 proposals on 3 books, exactly the finding count,
    three errors cleared, nothing authored at any severity, and one book becomes
    fully valid
    (72 → 73). All three books are one producer's output, so the
    shape is not known to generalise.

Fixed

  • fix.manifest_dangling_item no longer deletes the wrong item when two share
    an id.
    One book on the 474-book shelf declares two <item id="added2">
    one naming the missing font the finding is about, one naming a font the
    container really holds. The lookup took the first match and deleted the
    present one: the reported RSC-001 never moved, an OPF-003 was authored,
    and a real resource lost its only manifest declaration. The fixer now declines
    when the id is not unique, because <itemref idref> and
    <meta name="cover" content> are ambiguous on exactly the same book.

    The error count went down while the book got worse — deleting one of the
    two items cleared both duplicate id "added2" errors as a side effect — which
    is why only regression_audit, which watches for findings that did not exist
    before, could see it.

  • fix.manifest_dangling_item no longer drops an item named by a <spine>
    attribute.
    toc (the NCX) and page-map (Adobe's extension) both hold a
    manifest id and neither is an <itemref>, so the spine walk the fixer's other
    checks use cannot see them. Dropping the item named by
    <spine page-map="_page_map_"> cleared RSC-001 and authored OPF-063 in its
    place — the same trade the navigation-document guard already refuses. toc is
    guarded on the argument that it is the same shape; no shelf book has a dangling
    NCX item.

    Both defects are live in 0.13.0 on crates.io. Together the guards cost exactly
    two of the fixer's eight whole-shelf proposals — the plan digest over 474
    books loses those two lines and nothing else — and take regression_audit back
    to introducing nothing at any severity.

  • Four sites no longer treat a NO-BREAK SPACE as emptiness. str::trim
    strips Unicode whitespace, so an element whose entire content is &#160;
    looked empty. epubcheck 5.3.0 does not agree, and epubveri stopped agreeing at
    0.13.7. Two of the four sites delete on that judgement
    (fix.empty_metadata_element, fix.empty_dc_date), one decides whether to
    overwrite a <title> (fix.empty_title), and one decides whether to
    unwrap a nested anchor — where the argument is not epubcheck parity but simply
    that an NBSP is a space a reader can see.

    The upstream fix does not cover this, which is the part worth knowing.
    fix.empty_metadata_element dispatches per file and then re-derives every
    droppable element itself, so a finding disappearing upstream does not stop the
    deletion: with an NBSP-only <dc:description> beside a genuinely empty
    <dc:source>, epubveri reports only the second and epubsana dropped both.

    All four now read epubveri::xmlext::is_xml_blank, rather than a local copy,
    so the family has one spelling for "is this element empty". Verified by
    fixture, because no book on the 474-book shelf holds the shape — the
    whole-shelf plan digest is byte-identical across the change.

Changed

  • The epubveri floor is 0.13.7 (from 0.13.2, five upstream releases).
    Through 0.13.6 this was tracking only: no source change was needed, and both
    the whole-shelf plan digest and the whole rule_census are byte-identical
    across that boundary — none of the eleven false positives 0.13.3 closed had a
    population on this shelf. 0.13.7 is a correctness floor, and the first that
    is also an API floor: the NBSP predicate above is consumed from it.

Full notes: CHANGELOG.md. Also on crates.io.