Skip to content

v0.7.0

Choose a tag to compare

@github-actions github-actions released this 06 Aug 06:20
· 17 commits to main since this release

Four fixers' worth of new repair — three added and one widened, twenty-one to
twenty-four — chosen by measuring the shelf rather than by working down a
list. On the 94 shared books, error-severity findings fall 4677 → 3366, one
more book reaches fully valid, and both whole-shelf instruments (regression_audit
and the round-trip check, which compares ID sets as well as counts) report
nothing introduced anywhere.

Two of them are the first of their kind here: one edits more than a single file,
and one deletes on an AutoSafe tier because it verifies the redundancy first.
As much of the work went into what these decline — a malformed date, an
identically-named id in another document, an element XHTML 1.1 does not have —
and each entry below says so, because that is the part a repairer is judged on.

This is also the first release the tag-triggered automation publishes end to end,
and it carries the LICENSE-COMMERCIAL.md packaging fix that npm 0.6.0 shipped
without.

Changed

  • fix.bare_text_in_body now owns all non-block content in <body>, not just
    text.
    XHTML 1.1 wants block-level content there, and a converter leaves inline
    elements behind as readily as text: the 94-book shelf holds 281 stray <a>,
    92 <br>, and a handful of <img>/<span>/<sup>/<sub> sitting directly in
    <body>, reported as element "a" is not allowed here; expected one of … "div" …. The detector's own params name div at that position, so the
    wrapper this fixer already used is the one the grammar asks for.

    It wraps each maximal run — text and inline elements together, in document
    order — in a single <div>. That grouping is the point rather than a detail:
    of 244 runs on the shelf, 116 mix text and elements, so wrapping text alone
    would have split one rendered line into two blocks, and two fixers each owning
    half a run would have collided, the second silently finding nothing to do while
    the report claimed it applied.

    What it refuses is the larger half. figure (151 findings), section
    (92), figcaption (90), center and a stray li arrive through the same
    message at the same position, and a <div> around one would not clear it —
    XHTML 1.1 does not have the element at all, so the violation would move rather
    than go away. Repairing those means renaming them, which is a different
    operation and a different argument. They end the run and are left alone.

    The fix_id is unchanged even though the name is now narrower than the
    behaviour: it is a published identifier epublift reads out of our JSON.

    Measured: findings cleared on the shelf rise by 380, books receiving at
    least one proposal go 15 → 18, and both whole-shelf instruments still report
    nothing introduced anywhere.

Added

  • A fixer for an EPUB 3 attribute on an EPUB 2 package document
    (opf.package.schema_violation) — the third of the family, and the one whose
    value is in what it refuses to do. All four findings on the shelf turn out to
    assert nothing the book does not already say, so each is deleted only after
    that redundancy is verified in that book
    : a properties="cover-image" whose
    cover is also declared by <meta name="cover"> on the same item, and a
    page-progression-direction="ltr", which is the default everywhere.

    Any other properties token (nav, mathml, …) declines — EPUB 2 has no
    equivalent declaration, so dropping one would discard a real claim rather than
    a repeat. So does a cover-image with no matching or a mismatched
    <meta name="cover">, where the attribute is the only cover declaration, and
    so does page-progression-direction="rtl": a right-to-left reading order is
    authored information EPUB 2 has nowhere to put, which is a reason to leave the
    book alone rather than erase it.

    AutoSafe, unusually for a deletion, because the redundancy is checked before
    the fix is proposed rather than assumed from the shape.

    Measured: 4 findings across 4 books, all cleared — the rule goes to zero on
    the shelf, with nothing introduced. The declines cost nothing here because no
    shelf book carries the shapes they guard against; they are written from the
    specification, not from the corpus.

  • A fixer for an id that is not a valid XML NCName — and the first one that
    edits more than one file at a time. All 312 findings on the 94-book shelf are
    one defect: an id that starts with a digit. Each is sanitized to the nearest
    valid, unique name, exactly as the NCX fixer does.

    The reason it took a cross-file design is that unlike NCX ids, these are
    reference targets: 191 of the 312 are pointed at, 181 times from the NCX, 150
    from other content documents. So every reference moves with the id it names —
    fragments inside the document, links from other documents, the NCX's
    <content src="…#…"/> — in the same edit you approve once. A rename that left
    a reference behind would trade this finding for a dangling fragment.

    References are resolved, never globally replaced: the path part of the
    attribute value is resolved against the referring file's own directory, and
    rewritten only when it lands on this document. That is not caution for its own
    sake — six values on the shelf are carried by 6–12 different documents of the
    same book
    , so a global rewrite would move links meaning another document's
    identically-named id.

    Anything that cannot be classified — a #value in a stylesheet selector, in
    script, or in prose — makes the fixer decline that id rather than guess.

    Measured: 312 findings across 5 books, and after the repair all five hold
    zero invalid ids. One more book reaches fully valid, and both whole-shelf
    instruments (regression_audit, and the round-trip check at the ID-set level)
    report nothing introduced anywhere.

  • A fixer for an empty <dc:date> (OPF-054), the last of the four defects
    epublift handed over (#5).
    An element with no content states no date, and dc:date is optional, so it is
    dropped.

    What it does not do is the point of it. epubveri's check is not "is the
    date empty" but "is it a valid W3C-DTF date", so the same id and the same
    message also cover 2022-09-08) and March 2019 — malformed values that still
    carry a date the author wrote. Those are declined: dropping one would
    destroy information the book has, and repairing one means guessing which
    characters are stray. The finding survives the repair, which is the honest
    outcome. An empty element whose id a <meta refines> targets is declined too.

    The claim to make for this fixer is therefore "removes an empty dc:date,
    leaves a malformed one alone"
    — not "repairs OPF-054".

    Worth recording for anyone reading the id: OPF-054 is EPUB 2 only. On
    EPUB 3 the identical condition is OPF-053 at Warning, which never moves the
    validity line — the same version-scoped id split as the duplicate spine
    itemref, cutting the other way.

    Zero occurrences on the 94-book shelf, and zero on the earlier 171-book
    corpus: verified by injection end to end (an empty date takes a book from 1
    error to fully valid; a malformed one is left untouched with its finding
    intact), and its guards are covered by unit tests rather than by real books.
    The shelf's one nearby specimen is an OPF-053 reading 2022-09-08) — the
    declining case, on the id this fixer does not act on.

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