diff options
| author | Ralph Amissah <ralph.amissah@gmail.com> | 2026-09-12 22:25:26 -0400 |
|---|---|---|
| committer | Ralph Amissah <ralph.amissah@gmail.com> | 2026-09-14 00:24:33 -0400 |
| commit | a74e7ea61f797bd3f6bb9378124f8e1265e83cdf (patch) | |
| tree | d25473671660df850adeda511e05a78c2f4a27fa | |
| parent | epub: manifest lists files, spine orders files (diff) | |
epub: mimetype entry comes first in the archive
OCF requires the mimetype entry to be the first in the zip and stored
uncompressed, so that a reader can tell what the file is by looking at
a known offset without parsing the archive.
The index is now set to: 0 for the mimetype, 1 upward for everything
else as it is added.
mimetype Stored first
META-INF/container.xml Stored
OEBPS/toc_nav.xhtml Stored
...
(assisted by Claude-Code)
| -rw-r--r-- | org/out_xmls.org | 21 | ||||
| -rw-r--r-- | src/sisudoc/outputs/io_out/epub3.d | 21 |
2 files changed, 36 insertions, 6 deletions
diff --git a/org/out_xmls.org b/org/out_xmls.org index b477d34..165cea2 100644 --- a/org/out_xmls.org +++ b/org/out_xmls.org @@ -3174,10 +3174,25 @@ zip -0 file.epub mimetype && zip -r -9 file.epub META-INF OEBPS /+ zip file +/ auto fn_epub = pth_epub3.epub_file(doc_matters.src.filename); auto zip = new ZipArchive(); // ZipArchive zip = new ZipArchive(); - /+ zip archive member files +/ - void EPUBzip()(string contents, string fn) { + /+ zip archive member files. + ZipArchive.build() emits members sorted by ArchiveMember.index, and + addMember does not set one. An epub is not free to choose: OCF requires the + mimetype entry to be the first in the archive, a reader being entitled to + look only there to tell what the file is. The index is therefore set + deliberately, 0 for the mimetype and 1 upward for the rest as they are + added. + . + Compression is already done for every member (ArchiveMember defaults to + it), which is the other half of what OCF asks of the mimetype. + +/ + uint _zip_seq = 1; + void EPUBzip()(string contents, string fn, bool _is_mimetype = false) { auto zip_arc_member_file = new ArchiveMember(); zip_arc_member_file.name = fn; + zip_arc_member_file.index = _is_mimetype ? 0 : _zip_seq++; + if (_is_mimetype) { + zip_arc_member_file.compressionMethod = CompressionMethod.none; + } auto zip_data = new OutBuffer(); (doc_matters.opt.action.debug_do_epub) ? zip_data.write(contents.dup) @@ -3262,7 +3277,7 @@ zip -0 file.epub mimetype && zip -r -9 file.epub META-INF OEBPS } } fn = pth_epub3.fn_mimetypes; - EPUBzip(epub_write.mimetypes, fn); + EPUBzip(epub_write.mimetypes, fn, true); /+ first in the archive +/ } { /+ META-INF/container.xml (identify doc root) +/ { /+ debug +/ diff --git a/src/sisudoc/outputs/io_out/epub3.d b/src/sisudoc/outputs/io_out/epub3.d index e07aeb8..d149dac 100644 --- a/src/sisudoc/outputs/io_out/epub3.d +++ b/src/sisudoc/outputs/io_out/epub3.d @@ -602,10 +602,25 @@ template outputEPub3() { /+ zip file +/ auto fn_epub = pth_epub3.epub_file(doc_matters.src.filename); auto zip = new ZipArchive(); // ZipArchive zip = new ZipArchive(); - /+ zip archive member files +/ - void EPUBzip()(string contents, string fn) { + /+ zip archive member files. + ZipArchive.build() emits members sorted by ArchiveMember.index, and + addMember does not set one. An epub is not free to choose: OCF requires the + mimetype entry to be the first in the archive, a reader being entitled to + look only there to tell what the file is. The index is therefore set + deliberately, 0 for the mimetype and 1 upward for the rest as they are + added. + . + Compression is already done for every member (ArchiveMember defaults to + it), which is the other half of what OCF asks of the mimetype. + +/ + uint _zip_seq = 1; + void EPUBzip()(string contents, string fn, bool _is_mimetype = false) { auto zip_arc_member_file = new ArchiveMember(); zip_arc_member_file.name = fn; + zip_arc_member_file.index = _is_mimetype ? 0 : _zip_seq++; + if (_is_mimetype) { + zip_arc_member_file.compressionMethod = CompressionMethod.none; + } auto zip_data = new OutBuffer(); (doc_matters.opt.action.debug_do_epub) ? zip_data.write(contents.dup) @@ -690,7 +705,7 @@ template outputEPub3() { } } fn = pth_epub3.fn_mimetypes; - EPUBzip(epub_write.mimetypes, fn); + EPUBzip(epub_write.mimetypes, fn, true); /+ first in the archive +/ } { /+ META-INF/container.xml (identify doc root) +/ { /+ debug +/ |
