v0.7.0
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_bodynow 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 aselement "a" is not allowed here; expected one of … "div" …. The detector's ownparamsnamedivat 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),centerand a strayliarrive 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_idis unchanged even though the name is now narrower than the
behaviour: it is a published identifierepubliftreads 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: aproperties="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
propertiestoken (nav,mathml, …) declines — EPUB 2 has no
equivalent declaration, so dropping one would discard a real claim rather than
a repeat. So does acover-imagewith no matching or a mismatched
<meta name="cover">, where the attribute is the only cover declaration, and
so doespage-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
idthat 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
#valuein 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
epublifthanded over (#5).
An element with no content states no date, anddc:dateis 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 cover2022-09-08)andMarch 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 whoseida<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 "repairsOPF-054".Worth recording for anyone reading the id:
OPF-054is EPUB 2 only. On
EPUB 3 the identical condition isOPF-053at 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 anOPF-053reading2022-09-08)— the
declining case, on the id this fixer does not act on.
Full notes: CHANGELOG.md. Also on crates.io.