diff options
| author | Simen A. W. Olsen <hello@simenandre.no> | 2026-05-29 00:06:48 +0200 |
|---|---|---|
| committer | Simen A. W. Olsen <hello@simenandre.no> | 2026-05-29 00:06:48 +0200 |
| commit | 0806fecb47f5a2a26e73ca8b6e28c08f9945ef75 (patch) | |
| tree | 824a12cbcba1b0c2ad704e7bd64e25fa2389f34b | |
| parent | 330a0c896970d99320529a47f186c831a6ecc4a0 (diff) | |
| download | ziglang-docs-epub-0806fecb47f5a2a26e73ca8b6e28c08f9945ef75.tar.gz ziglang-docs-epub-0806fecb47f5a2a26e73ca8b6e28c08f9945ef75.zip | |
fix problems after testing with epubcheck
| -rw-r--r-- | epubs/zig-0.11.0.epub | bin | 1083315 -> 1086285 bytes | |||
| -rw-r--r-- | epubs/zig-0.12.0.epub | bin | 925023 -> 928020 bytes | |||
| -rw-r--r-- | epubs/zig-0.12.1.epub | bin | 935649 -> 938646 bytes | |||
| -rw-r--r-- | epubs/zig-0.13.0.epub | bin | 935698 -> 938695 bytes | |||
| -rw-r--r-- | epubs/zig-0.14.0.epub | bin | 966701 -> 969788 bytes | |||
| -rw-r--r-- | epubs/zig-0.14.1.epub | bin | 970004 -> 973091 bytes | |||
| -rw-r--r-- | epubs/zig-0.15.1.epub | bin | 973287 -> 976374 bytes | |||
| -rw-r--r-- | epubs/zig-0.15.2.epub | bin | 972519 -> 975597 bytes | |||
| -rw-r--r-- | epubs/zig-0.16.0.epub | bin | 986269 -> 989455 bytes | |||
| -rw-r--r-- | epubs/zig-0.9.0.epub | bin | 1115228 -> 1118090 bytes | |||
| -rw-r--r-- | epubs/zig-0.9.1.epub | bin | 1115381 -> 1118252 bytes | |||
| -rw-r--r-- | epubs/zig-master.epub | bin | 969372 -> 972486 bytes | |||
| -rw-r--r-- | src/html.zig | 13 | ||||
| -rwxr-xr-x | validate.sh | 32 |
14 files changed, 43 insertions, 2 deletions
diff --git a/epubs/zig-0.11.0.epub b/epubs/zig-0.11.0.epub Binary files differindex 1dfc0f0..8751a77 100644 --- a/epubs/zig-0.11.0.epub +++ b/epubs/zig-0.11.0.epub diff --git a/epubs/zig-0.12.0.epub b/epubs/zig-0.12.0.epub Binary files differindex 05bb36e..9dca6f3 100644 --- a/epubs/zig-0.12.0.epub +++ b/epubs/zig-0.12.0.epub diff --git a/epubs/zig-0.12.1.epub b/epubs/zig-0.12.1.epub Binary files differindex 1907d2f..64b2179 100644 --- a/epubs/zig-0.12.1.epub +++ b/epubs/zig-0.12.1.epub diff --git a/epubs/zig-0.13.0.epub b/epubs/zig-0.13.0.epub Binary files differindex 98cce35..f242a27 100644 --- a/epubs/zig-0.13.0.epub +++ b/epubs/zig-0.13.0.epub diff --git a/epubs/zig-0.14.0.epub b/epubs/zig-0.14.0.epub Binary files differindex 39d7ea3..1af8ecd 100644 --- a/epubs/zig-0.14.0.epub +++ b/epubs/zig-0.14.0.epub diff --git a/epubs/zig-0.14.1.epub b/epubs/zig-0.14.1.epub Binary files differindex 1f14838..378dbb1 100644 --- a/epubs/zig-0.14.1.epub +++ b/epubs/zig-0.14.1.epub diff --git a/epubs/zig-0.15.1.epub b/epubs/zig-0.15.1.epub Binary files differindex be73887..564ab1e 100644 --- a/epubs/zig-0.15.1.epub +++ b/epubs/zig-0.15.1.epub diff --git a/epubs/zig-0.15.2.epub b/epubs/zig-0.15.2.epub Binary files differindex f4845af..152f4e4 100644 --- a/epubs/zig-0.15.2.epub +++ b/epubs/zig-0.15.2.epub diff --git a/epubs/zig-0.16.0.epub b/epubs/zig-0.16.0.epub Binary files differindex 6490d41..114bee7 100644 --- a/epubs/zig-0.16.0.epub +++ b/epubs/zig-0.16.0.epub diff --git a/epubs/zig-0.9.0.epub b/epubs/zig-0.9.0.epub Binary files differindex 514d283..b6f6dd4 100644 --- a/epubs/zig-0.9.0.epub +++ b/epubs/zig-0.9.0.epub diff --git a/epubs/zig-0.9.1.epub b/epubs/zig-0.9.1.epub Binary files differindex 9914fdd..fbc087d 100644 --- a/epubs/zig-0.9.1.epub +++ b/epubs/zig-0.9.1.epub diff --git a/epubs/zig-master.epub b/epubs/zig-master.epub Binary files differindex 139d828..2dd2111 100644 --- a/epubs/zig-master.epub +++ b/epubs/zig-master.epub diff --git a/src/html.zig b/src/html.zig index ec9ecfd..fe7f287 100644 --- a/src/html.zig +++ b/src/html.zig @@ -63,10 +63,16 @@ pub fn transform(allocator: std.mem.Allocator, page: []const u8) !Document { const no_sidebar = try removeNavigation(allocator, escaped); defer allocator.free(no_sidebar); + // Section headings link back to their entry in the removed sidebar + // (`href="#toc-X"`); redirect those to the matching anchors now in nav.xhtml, + // otherwise they are dangling fragments (epubcheck RSC-012, breaks Kindle). + const relinked = try std.mem.replaceOwned(u8, allocator, no_sidebar, "href=\"#toc-", "href=\"nav.xhtml#toc-"); + defer allocator.free(relinked); + var out: std.Io.Writer.Allocating = .init(allocator); defer out.deinit(); try out.writer.writeAll(xml_decl); - try writeWithFixups(&out.writer, no_sidebar); + try writeWithFixups(&out.writer, relinked); const content = try out.toOwnedSlice(); assert(std.mem.startsWith(u8, content, "<?xml")); @@ -536,7 +542,7 @@ test "transform extracts TOC and removes the navigation sidebar" { "<ul><li><a id=\"toc-Intro\" href=\"#Intro\">Intro</a>" ++ "<ul><li><a href=\"#Sub\">Sub</a></li></ul></li></ul>" ++ "</nav></div>" ++ - "<main id=\"contents\"><h2 id=\"Intro\">Intro</h2><p>body</p></main>" ++ + "<main id=\"contents\"><h2 id=\"Intro\"><a href=\"#toc-Intro\">Intro</a></h2><p>body</p></main>" ++ "</div></body></html>"; var doc = try transform(gpa, page); @@ -549,6 +555,9 @@ test "transform extracts TOC and removes the navigation sidebar" { try std.testing.expect(std.mem.indexOf(u8, doc.content, "<main id=\"contents\">") != null); try std.testing.expect(std.mem.indexOf(u8, doc.content, "<h2 id=\"Intro\">") != null); try std.testing.expect(isWellFormed(doc.content)); + // Back-to-contents link is redirected to the nav document (no dangling fragment). + try std.testing.expect(std.mem.indexOf(u8, doc.content, "href=\"nav.xhtml#toc-Intro\"") != null); + try std.testing.expect(std.mem.indexOf(u8, doc.content, "href=\"#toc-Intro\"") == null); // TOC extracted, ul->ol, links rewritten into the content document. try std.testing.expect(doc.toc != null); diff --git a/validate.sh b/validate.sh new file mode 100755 index 0000000..f932f11 --- /dev/null +++ b/validate.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash +# Validate every generated EPUB with epubcheck (the official EPUB validator). +# Exits non-zero if any EPUB has errors, so it can gate CI. +# +# Requires epubcheck on PATH (e.g. `brew install epubcheck`). + +set -uo pipefail + +if ! command -v epubcheck >/dev/null 2>&1; then + echo "error: epubcheck not found. Install it (e.g. 'brew install epubcheck')." >&2 + exit 127 +fi + +shopt -s nullglob +epubs=(epubs/*.epub) +if [ ${#epubs[@]} -eq 0 ]; then + echo "error: no EPUBs in epubs/. Run 'zig build run' first." >&2 + exit 1 +fi + +fail=0 +for f in "${epubs[@]}"; do + if epubcheck "$f" >/dev/null 2>&1; then + echo "PASS $f" + else + echo "FAIL $f" + epubcheck "$f" 2>&1 | grep -E '^(ERROR|FATAL|WARNING)' | sed 's/^/ /' + fail=1 + fi +done + +exit $fail |
