Register Guidelines E-Books Today's Posts Search

Go Back   MobileRead Forums > E-Book Formats > ePub

Notices

Reply
 
Thread Tools Search this Thread
Old 08-23-2026, 04:09 PM   #241
KevinH
Sigil Developer
KevinH ought to be getting tired of karma fortunes by now.KevinH ought to be getting tired of karma fortunes by now.KevinH ought to be getting tired of karma fortunes by now.KevinH ought to be getting tired of karma fortunes by now.KevinH ought to be getting tired of karma fortunes by now.KevinH ought to be getting tired of karma fortunes by now.KevinH ought to be getting tired of karma fortunes by now.KevinH ought to be getting tired of karma fortunes by now.KevinH ought to be getting tired of karma fortunes by now.KevinH ought to be getting tired of karma fortunes by now.KevinH ought to be getting tired of karma fortunes by now.
 
Posts: 9,961
Karma: 7518950
Join Date: Nov 2009
Device: many
You misunderstand. dc:language is for the book. xml:lang is for the contents of the opf (metadata, etc).
KevinH is offline   Reply With Quote
Old 08-23-2026, 04:12 PM   #242
JSWolf
Resident Curmudgeon
JSWolf ought to be getting tired of karma fortunes by now.JSWolf ought to be getting tired of karma fortunes by now.JSWolf ought to be getting tired of karma fortunes by now.JSWolf ought to be getting tired of karma fortunes by now.JSWolf ought to be getting tired of karma fortunes by now.JSWolf ought to be getting tired of karma fortunes by now.JSWolf ought to be getting tired of karma fortunes by now.JSWolf ought to be getting tired of karma fortunes by now.JSWolf ought to be getting tired of karma fortunes by now.JSWolf ought to be getting tired of karma fortunes by now.JSWolf ought to be getting tired of karma fortunes by now.
 
JSWolf's Avatar
 
Posts: 84,627
Karma: 153744815
Join Date: Nov 2006
Location: Roslindale, Massachusetts
Device: Kobo Libra 2, Kobo Aura H2O, PRS-650, PRS-T1, nook STR, PW3
Quote:
Originally Posted by KevinH View Post
You misunderstand. dc:language is for the book. xml:lang is for the contents of the opf (metadata, etc).
Thanks for the clarification.
JSWolf is offline   Reply With Quote
Old 08-23-2026, 04:44 PM   #243
Kayadelenium
Connoisseur
Kayadelenium rocks like Gibraltar!Kayadelenium rocks like Gibraltar!Kayadelenium rocks like Gibraltar!Kayadelenium rocks like Gibraltar!Kayadelenium rocks like Gibraltar!Kayadelenium rocks like Gibraltar!Kayadelenium rocks like Gibraltar!Kayadelenium rocks like Gibraltar!Kayadelenium rocks like Gibraltar!Kayadelenium rocks like Gibraltar!Kayadelenium rocks like Gibraltar!
 
Kayadelenium's Avatar
 
Posts: 90
Karma: 100000
Join Date: Jul 2026
Location: Planet Earth
Device: Kobo Forma
Thank you all — four reports since 0.11.0, four issues, and all four are things we miss rather than things we wrongly report, which is the direction I much prefer them to arrive in.

Doitsu, enc:EncryptedData with no enc:CipherData — #88 (https://github.com/veripublica/epubveri/issues/88). Our encryption.xml check validates the root element's children and never looks inside them. Worth flagging what I found while writing it up: the requirement inverts between versions. EPUB 3 requires CipherData and makes EncryptionMethod optional; OPF 2.0.1's schema does exactly the opposite. So this needs a version check rather than one rule, or it becomes a false positive on EPUB 2.

JSWolf, empty <tours> — #87 (https://github.com/veripublica/epubveri/issues/87). The grammar knows the element exists and never got its content model. <guide> sits three lines above it in the same file with the right shape already, so the fix is small.

JSWolf, RSC-004 on the encrypted font — #89 (https://github.com/veripublica/epubveri/issues/89). You are right: epubcheck names the font, we name the file that mentions it. The finding is a fact about the font, so epubcheck's location is the correct one. Location only — the message, severity and everything machine-readable stay as they are.

JSWolf, xml:lang on an EPUB 2 <package> — #90 (https://github.com/veripublica/epubveri/issues/90). Wider than the one attribute: epubcheck's EPUB 2 <package> takes only version, unique-identifier and id, and ours takes anything at all. I checked all 312 EPUB 2 books on my test shelf — 310 carry nothing extra, two carry prefix (an EPUB 3 attribute in a 2.0 package, which epubcheck also rejects). So closing this costs nothing and gains two correct findings. Not one book of the 312 has xml:lang on <package>, which is a useful reminder that my shelf can only tell me about constructs it has actually seen.

KevinH — your reading is right, and your last post puts the part that matters better than I would have: dc:language is about the book, xml:lang is about the OPF's own contents, and they are not the same fact. That is exactly why an OPF-specific schema should not have overridden something XML makes available on every element.

It does not change what I will do, though. epubcheck owns the verdict here. A book that fails epubcheck has to fail epubveri too — otherwise someone whose retailer gates on epubcheck has no way to tell my judgement from my bug, and that is the one thing I cannot afford to be ambiguous about. Disagreeing with a rule is a reason to take it upstream, not a reason to stay quiet about it. So I will implement it, and if that argument does go to w3c/epubcheck it should go as yours rather than second-hand from me.

JSWolf — "changing an ePub3 to ePub2 without changing the rest of the code is actually pretty good at finding errors in epubveri" is a fair description of where my weakest surface is, and I am going to steal it. Doing that deliberately across my shelf is a great deal cheaper than waiting for the next one to surface.

All four are queued for the next release.
Kayadelenium is online now   Reply With Quote
Old 08-23-2026, 07:18 PM   #244
JSWolf
Resident Curmudgeon
JSWolf ought to be getting tired of karma fortunes by now.JSWolf ought to be getting tired of karma fortunes by now.JSWolf ought to be getting tired of karma fortunes by now.JSWolf ought to be getting tired of karma fortunes by now.JSWolf ought to be getting tired of karma fortunes by now.JSWolf ought to be getting tired of karma fortunes by now.JSWolf ought to be getting tired of karma fortunes by now.JSWolf ought to be getting tired of karma fortunes by now.JSWolf ought to be getting tired of karma fortunes by now.JSWolf ought to be getting tired of karma fortunes by now.JSWolf ought to be getting tired of karma fortunes by now.
 
JSWolf's Avatar
 
Posts: 84,627
Karma: 153744815
Join Date: Nov 2006
Location: Roslindale, Massachusetts
Device: Kobo Libra 2, Kobo Aura H2O, PRS-650, PRS-T1, nook STR, PW3
I really appreciate your quick responses and new versions with the fixes. You are doing very well. Thank you.
JSWolf is offline   Reply With Quote
Old Yesterday, 05:17 AM   #245
Kayadelenium
Connoisseur
Kayadelenium rocks like Gibraltar!Kayadelenium rocks like Gibraltar!Kayadelenium rocks like Gibraltar!Kayadelenium rocks like Gibraltar!Kayadelenium rocks like Gibraltar!Kayadelenium rocks like Gibraltar!Kayadelenium rocks like Gibraltar!Kayadelenium rocks like Gibraltar!Kayadelenium rocks like Gibraltar!Kayadelenium rocks like Gibraltar!Kayadelenium rocks like Gibraltar!
 
Kayadelenium's Avatar
 
Posts: 90
Karma: 100000
Join Date: Jul 2026
Location: Planet Earth
Device: Kobo Forma
epubveri 0.12.0 is out — crates.io, npm and the eight pre-built binaries. This is the release I said the four reports were queued for, so all of them are in it: release notes (https://github.com/veripublica/epubv...es/tag/v0.12.0).

Why 0.12.0 and not 0.11.1, since a third minor bump in three days invites the wrong conclusion. One public Rust function changed shape, which for a pre-1.0 crate forces a minor bump — that is the whole reason. Nothing moves for the CLI, the JSON output or the browser build, with one deliberate exception noted below. And unlike 0.10.0 and 0.11.0, this one is actually about the validator: four real gaps close.

Empty <tours> is now an error (JSWolf, #234). OPF 2.0.1 makes the <tour> child mandatory. I had added <tours> to my grammar in July for the opposite reason — I was wrongly rejecting a legacy book that used it — and what I added was the element's existence, with a permissive placeholder standing in for its content model. Its <guide> neighbour, three lines above in the same file, had required a child all along.

RSC-004 now names the encrypted font, not META-INF/encryption.xml (JSWolf, #235). You were right: the finding is a fact about the font, and epubcheck locates it that way. It carries no position now either, for the same reason epubcheck prints -1,-1 — there is nothing inside a binary to point at. Doitsu, this one is visible in the JSON: the location value changes; code, severity, rule and params do not.

encryption.xml's encrypted items are checked now (Doitsu, #233) — and the part I did not expect is that the requirement inverts between the two versions:

inside <enc:EncryptedData> EPUB 2 EPUB 3
nothing missing EncryptionMethod missing CipherData
EncryptionMethod only accepted missing CipherData
CipherData only method must come first accepted
empty CipherData needs Reference/Value same

Every cell was measured against epubcheck 5.3.0 with one book per shape rather than read off the two schemas, and all eight now agree. That was worth the trouble: my first attempt filed the ordering rule as EPUB 2-only, on the reasonable-sounding grounds that only OPF 2.0.1's grammar is a sequence. Both are — so EPUB 3 was left silent on a file epubcheck reports. Building each shape and asking is what caught it; re-reading my own code would not have.

An EPUB 2 <package> no longer accepts any attribute (JSWolf, #236). epubcheck's list is exactly three — version, unique-identifier, optional id — and mine was a wildcard, so xml:lang and every EPUB 3 attribute passed silently. Across the 312 EPUB 2 books on my shelf this produced two new findings, both prefix="calibre: …" on a 2.0 package, both matching epubcheck exactly, and no false positives. The EPUB 3 grammar is untouched, with a test that says so in both directions: prefix and xml:lang are perfectly valid on a 3.0 package, and closing both lists would have traded a legacy gap for a false positive on most modern books.

KevinH — my view has not changed, only what I ship. Your objection is now written into the source beside the rule, so whoever reads that code next meets the argument and not just the constraint.

Two things I have not done, so they do not sit here looking finished. JSWolf's "changing an ePub3 to ePub2 without changing the rest of the code is actually pretty good at finding errors in epubveri" — I said I would steal that as a test, and I have not started; doing it properly means running it across the whole shelf, not on one book. And the EPUB 2 unused-resources check from earlier in the thread is still where I left it: measured, not promised.

As always — if anything here reports a problem on a book that is actually fine, that is the report I want most, and it jumps the queue ahead of everything else.
Kayadelenium is online now   Reply With Quote
Old Today, 06:19 AM   #246
Kayadelenium
Connoisseur
Kayadelenium rocks like Gibraltar!Kayadelenium rocks like Gibraltar!Kayadelenium rocks like Gibraltar!Kayadelenium rocks like Gibraltar!Kayadelenium rocks like Gibraltar!Kayadelenium rocks like Gibraltar!Kayadelenium rocks like Gibraltar!Kayadelenium rocks like Gibraltar!Kayadelenium rocks like Gibraltar!Kayadelenium rocks like Gibraltar!Kayadelenium rocks like Gibraltar!
 
Kayadelenium's Avatar
 
Posts: 90
Karma: 100000
Join Date: Jul 2026
Location: Planet Earth
Device: Kobo Forma
I have published a performance measurement of epubveri against epubcheck:

docs/BENCHMARK.md

First, the part that matters more than the speed. A tool that validates less is not faster, so the document opens with the evidence that both tools did the same work. On the same 385 real books the two agree on the verdict for 384, and a finding-by-finding run found identical message-ID sets on 383 of 385, with no message ID reported by epubveri alone. This is a performance document, not a correctness claim -- for what the two tools actually find, the coverage matrix is the honest place to look.

The setup. epubveri 0.12.0 against epubcheck 5.3.0 on OpenJDK 26, one machine (Apple M2 Pro, 10 cores, 32 GiB), 385 real EPUBs totalling 611 MiB, each tool run alone, both given -u.

Code:
  SUMMARY                     epubveri    epubcheck    ratio
  Wall-clock time                 69 s        758 s      11x
  CPU time                        68 s      2 875 s      42x
  Memory, typical book         7.4 MiB      415 MiB      56x
  Install footprint             2.8 MB       434 MB     156x
Time. The same three situations for both tools:

Code:
  TIME                        epubveri    epubcheck
  One small book (78 KB)          9 ms       1.76 s
  A typical book (median)       0.08 s       1.89 s
  The whole 385-book library      69 s        758 s
Worth knowing before you quote any ratio: epubcheck's time barely depends on the book. Its median is 1.77 s under 100 KB and 2.00 s at 2-10 MB -- 13% over a hundredfold range of content.

CPU.

Code:
  CPU                         epubveri    epubcheck
  Whole library                   68 s      2 875 s
  A typical book (median)       0.07 s       7.02 s
  Cores busy while running        0.99         3.79
The CPU gap is four times the clock gap, and that last row is why: epubcheck keeps about 3.79 cores busy -- JIT compiler and garbage collector threads alongside the work -- while epubveri is single-threaded. So epubcheck wins part of the wall-clock difference back through parallelism, but it takes that from the rest of the machine. If you are running a pipeline where you want those cores for your own concurrency, or you are on battery, the CPU column is the one that applies to you rather than the clock.

Memory.

Code:
  MEMORY (peak RSS)           epubveri    epubcheck
  A typical book (median)      7.4 MiB      415 MiB
  Worst book on the shelf       90 MiB    1 687 MiB
  Books needing over 512 MiB         0           94
  Books needing over 1 GiB           0            6
The tail says more than the average here. A quarter of my shelf pushes epubcheck past 512 MiB. In a memory-capped container, or inside an application, that is the number that decides whether the tool fits at all.

Disk.

Code:
  DISK                        epubveri    epubcheck
  Application / libraries       2.8 MB      36.4 MB
  Runtime required                none       398 MB
  Total to install              2.8 MB       434 MB

  Release archive, per OS   1.0-1.3 MB
  Browser build, over wire      477 KB
epubveri is one file with no runtime; epubcheck is 40 jars plus the JVM they need. Disk traffic during validation was not a differentiator -- with a warm cache neither tool reached the disk, and on a cold one both must read the same book.

Where the difference comes from, stated fairly to epubcheck. The usual explanation is JVM startup. I measured it, and it is not: a bare JVM starts in 22 ms and loading epubcheck's classes takes 65 ms, against 1758 ms to validate the smallest book on my shelf. Nor is it work proportional to the book, as the flat line above shows. About 1.7 seconds is fixed setup performed inside the validation path, most likely compiling the RELAX NG and Schematron schemas, so roughly 90% of a typical epubcheck run is book-independent. epubveri has no equivalent only because its schemas are compiled into the binary.

That also states epubcheck's best case: subtract each tool's floor and the remaining per-book work is about 0.13 s against 0.07 s -- much closer. epubcheck simply cannot reach it from the command line, which takes one file per invocation, so it pays the 1.7 s again for every book.

Limits, plainly. One machine, one library, one day. My shelf is mostly Turkish trade titles, Calibre output and Project Gutenberg. epubcheck ran with default JVM settings. Nothing was measured under parallelism. Any number above is an observation, not a property of either tool.

Which brings me to a request. I would rather you checked this than believed it.
  • Run epubveri over your own books. Your libraries are nothing like mine. Several of the wrong errors I have fixed since 0.9.x were found by people in this thread rather than by my own test corpus, and the ones that reached a user all arrived that way. A false positive -- an error on a book you know is fine -- is the report I most want. A missing error is worth reporting too, just less urgent.
  • If you have Java installed, run the comparison yourself. The recipe is in the document. The one thing that makes it unfair if you skip it is the -u flag: epubcheck hides usage findings by default and much of epubveri's output is usage, so pass it to both.

Code:
epubveri -u -i book.epub
java -jar epubcheck.jar -u book.epub
If your numbers come out different from mine, that is useful and I would like to see them -- a slower machine, a bigger book, a producer I have never seen. And if the two tools disagree about a book, that is more useful still. Downloads for eight platforms and a step-by-step guide are here if you have not tried it before: docs/USAGE.md.
Kayadelenium is online now   Reply With Quote
Reply


Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
EPUBCheck v4.2.6 jhowell ePub 0 06-30-2021 03:49 PM
EPUBCheck v4.2.5 jhowell ePub 0 03-23-2021 09:45 AM
EPUBCheck v4.2.4 jhowell ePub 3 06-24-2020 09:51 AM
EPUBCheck v4.1.1 Doitsu ePub 2 03-18-2019 10:39 AM
Web-based epubcheck upgraded to epubcheck 1.0.5 kjk ePub 4 02-09-2010 09:53 PM


All times are GMT -4. The time now is 04:15 PM.


MobileRead.com is a privately owned, operated and funded community.