chore: checkpoint current milestone work
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
---
|
||||
phase: 03-page-metadata-pagination
|
||||
plan: 01
|
||||
type: execute
|
||||
wave: 1
|
||||
depends_on: []
|
||||
files_modified:
|
||||
- Sources/RDReaderView/EPUBCore/RDEPUBReadingModels.swift
|
||||
- Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRenderer.swift
|
||||
- Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift
|
||||
- Sources/RDReaderView/EPUBTextRendering/RDEPUBTextPaginationSupport.swift
|
||||
autonomous: true
|
||||
requirements:
|
||||
- REND-03
|
||||
user_setup: []
|
||||
must_haves:
|
||||
truths:
|
||||
- `RDEPUBTextPage` / `RDEPUBTextChapter` gain explicit page metadata hooks for blocks, attachments, and page-edge reasoning.
|
||||
- `pageStartOffset`, `pageEndOffset`, chapter text continuity, and fragment offsets remain first-class compatibility fields.
|
||||
- new metadata is serializable or structurally accessible from current native rendering models rather than hidden inside temporary layout locals.
|
||||
artifacts:
|
||||
- .planning/phases/03-page-metadata-pagination/03-01-SUMMARY.md
|
||||
key_links:
|
||||
- `RDEPUBTextOffsetRangeInfo` remains compatible with absolute chapter offsets.
|
||||
- `RDEPUBTextBookBuilder` stays the owner of chapter/page assembly.
|
||||
---
|
||||
|
||||
<objective>
|
||||
定义页面级 attributed string 元数据与自定义属性键,为 Phase 3 的复杂分页器建立稳定数据契约。
|
||||
|
||||
Purpose: 先把“页面语义到底长什么样”固定下来,再让 paginator 和验证围绕这套契约扩展,而不是在分页逻辑里临时发明结构。
|
||||
Output: richer page/chapter metadata models、attribute key definitions,以及保持 offset continuity 的序列化/传递路径。
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
@$HOME/.codex/get-shit-done/workflows/execute-plan.md
|
||||
@$HOME/.codex/get-shit-done/templates/summary.md
|
||||
</execution_context>
|
||||
|
||||
<context>
|
||||
@.planning/ROADMAP.md
|
||||
@.planning/STATE.md
|
||||
@.planning/REQUIREMENTS.md
|
||||
@.planning/phases/01-current-engine-boundaries/01-refactor-entry-strategy.md
|
||||
@.planning/phases/02-typesetter-css/02-RESEARCH.md
|
||||
@.planning/phases/03-page-metadata-pagination/03-RESEARCH.md
|
||||
@.planning/phases/03-page-metadata-pagination/03-PATTERNS.md
|
||||
@Sources/RDReaderView/EPUBCore/RDEPUBReadingModels.swift
|
||||
@Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRenderer.swift
|
||||
@Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift
|
||||
@Sources/RDReaderView/EPUBTextRendering/RDEPUBTextPaginationSupport.swift
|
||||
@Sources/RDReaderView/EPUBUI/RDEPUBTextContentView.swift
|
||||
</context>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1: 定义页面元数据与 attributed string 属性键</name>
|
||||
<files>Sources/RDReaderView/EPUBCore/RDEPUBReadingModels.swift, Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRenderer.swift</files>
|
||||
<read_first>Sources/RDReaderView/EPUBCore/RDEPUBReadingModels.swift, Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRenderer.swift, Sources/RDReaderView/EPUBUI/RDEPUBTextContentView.swift</read_first>
|
||||
<action>在现有 native text 模型旁定义 page metadata 契约和 attributed string 语义键,至少覆盖 block boundary、attachment/image semantic、page break reason、future page style hook 这几类能力;把它们放在 `RDEPUBReadingModels.swift` 或与之紧邻的 native rendering 模型里,并保持 `RDEPUBTextOffsetRangeInfo` 继续基于绝对 chapter offsets 工作。不要删除或弱化 `pageStartOffset`、`pageEndOffset`、`fragmentOffsets`、`href` 等现有兼容字段。</action>
|
||||
<acceptance_criteria>
|
||||
- `Sources/RDReaderView/EPUBCore/RDEPUBReadingModels.swift` contains new page metadata types or fields for block / attachment / page break semantics
|
||||
- `Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRenderer.swift` or adjacent rendering models contain explicit native metadata/attribute-key definitions
|
||||
- `RDEPUBTextOffsetRangeInfo` remains present and still serializes absolute offset ranges
|
||||
</acceptance_criteria>
|
||||
<verify>rg -n "metadata|attachment|block|pageBreak|pageStartOffset|pageEndOffset|fragmentOffsets" Sources/RDReaderView/EPUBCore/RDEPUBReadingModels.swift Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRenderer.swift</verify>
|
||||
<done>native text pipeline now has an explicit metadata vocabulary that later pagination and validation steps can consume.</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 2: 扩展 chapter/page model 以承接新语义但保留 offset continuity</name>
|
||||
<files>Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift, Sources/RDReaderView/EPUBTextRendering/RDEPUBTextPaginationSupport.swift</files>
|
||||
<read_first>Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift, Sources/RDReaderView/EPUBTextRendering/RDEPUBTextPaginationSupport.swift, Sources/RDReaderView/EPUBCore/RDEPUBReadingSession.swift, Sources/RDReaderView/EPUBTextRendering/RDEPUBTextSearchEngine.swift</read_first>
|
||||
<action>把 `RDEPUBTextChapter` 和 `RDEPUBTextPage` 扩展成可承接新 metadata 的模型,同时保留 `RDEPUBTextBook.pageNumber(for:)`、`location(forPageNumber:)`、search/highlight 所依赖的 offset continuity。若需要新增 page-slice carrier(例如 layout snapshot 或 page metadata payload),它必须最终落回 `RDEPUBTextPage`,不能绕开现有 `RDEPUBTextBook` 契约。</action>
|
||||
<acceptance_criteria>
|
||||
- `RDEPUBTextPage` includes explicit metadata payloads or fields beyond bare range/offsets
|
||||
- `RDEPUBTextBook.pageNumber(for:)` and `location(forPageNumber:)` still use offset-compatible fields
|
||||
- source code still contains `pageStartOffset`, `pageEndOffset`, and `fragmentOffsets` after the refactor
|
||||
</acceptance_criteria>
|
||||
<verify>rg -n "struct RDEPUBTextPage|struct RDEPUBTextChapter|pageStartOffset|pageEndOffset|fragmentOffsets|metadata" Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift</verify>
|
||||
<done>the page model is richer, but all current consumers still have a stable offset-based contract to target.</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<verification>
|
||||
Before declaring plan complete:
|
||||
- [ ] `rg -n "metadata|attachment|block|pageBreak" Sources/RDReaderView/EPUBCore/RDEPUBReadingModels.swift Sources/RDReaderView/EPUBTextRendering`
|
||||
- [ ] `rg -n "pageStartOffset|pageEndOffset|fragmentOffsets" Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift Sources/RDReaderView/EPUBCore/RDEPUBReadingModels.swift`
|
||||
- [ ] no changes route page presentation around `RDEPUBTextBook`
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
|
||||
- All tasks completed
|
||||
- All verification checks pass
|
||||
- No compatibility field needed by highlight/search/navigation is removed
|
||||
- Phase 3.2 can consume the metadata contract without redefining the page model again
|
||||
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
After completion, create `.planning/phases/03-page-metadata-pagination/03-01-SUMMARY.md`
|
||||
</output>
|
||||
@@ -0,0 +1,20 @@
|
||||
# 03-01 Summary
|
||||
|
||||
## Outcome
|
||||
|
||||
Wave 1 landed the page metadata contract without breaking the existing offset-based book model.
|
||||
|
||||
- Added `RDEPUBTextPageBreakReason`, `RDEPUBTextAttachmentKind`, and `RDEPUBTextPageMetadata` in `RDEPUBReadingModels.swift`
|
||||
- Added attributed-string keys in `RDEPUBTextRenderer.swift` for block range/index, fragment id, and attachment kind
|
||||
- Extended `RDEPUBTextPage` with `metadata`
|
||||
- Extended `RDEPUBTextChapter` with `pageBreakReasons`
|
||||
- Tagged normalized attributed content in `RDEPUBTextRendererSupport.normalizeReadingAttributes` so later pagination can inspect block and attachment semantics
|
||||
|
||||
## Compatibility
|
||||
|
||||
- `pageStartOffset`, `pageEndOffset`, `contentRange`, `fragmentOffsets`, and chapter text continuity remain intact
|
||||
- Existing `RDEPUBTextBook` page lookup and location mapping continue to operate on absolute chapter offsets
|
||||
|
||||
## Notes
|
||||
|
||||
This wave deliberately extended the current book contract instead of replacing it. That kept highlight/search/navigation consumers stable while creating a place to land richer pagination semantics in Wave 2.
|
||||
@@ -0,0 +1,106 @@
|
||||
---
|
||||
phase: 03-page-metadata-pagination
|
||||
plan: 02
|
||||
type: execute
|
||||
wave: 2
|
||||
depends_on:
|
||||
- "03-01"
|
||||
files_modified:
|
||||
- Sources/RDReaderView/EPUBTextRendering/RDEPUBTextPaginationSupport.swift
|
||||
- Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift
|
||||
- Sources/RDReaderView/EPUBTextRendering/RDEPUBTextLayouter.swift
|
||||
- Sources/RDReaderView/EPUBTextRendering/RDEPUBTextLayoutFrame.swift
|
||||
autonomous: true
|
||||
requirements:
|
||||
- REND-03
|
||||
- REND-04
|
||||
user_setup: []
|
||||
must_haves:
|
||||
truths:
|
||||
- pagination is no longer implemented as only `CTFrameGetVisibleStringRange` range slicing.
|
||||
- layouter/layout-frame responsibilities live inside `EPUBTextRendering`, not in reader UI classes.
|
||||
- stronger page edges still resolve to stable `RDEPUBTextPage` offsets and chapter continuity.
|
||||
artifacts:
|
||||
- .planning/phases/03-page-metadata-pagination/03-02-SUMMARY.md
|
||||
key_links:
|
||||
- `RDEPUBTextPaginationSupport` remains the entry point for native pagination work.
|
||||
- `RDEPUBTextBookBuilder` still assembles final pages and chapters.
|
||||
---
|
||||
|
||||
<objective>
|
||||
在旧引擎基础上重构分页器,引入内部 layouter / layout-frame 语义,并把纯 visible-range slicing 升级为更强的页面边界控制。
|
||||
|
||||
Purpose: 让 native paginator 能表达 block / image / attachment 的页面边界语义,同时不破坏现有 page model 与 chapter offset continuity。
|
||||
Output: stronger paginator implementation, internal layouter/frame types, and book-builder wiring onto the new pagination path.
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
@$HOME/.codex/get-shit-done/workflows/execute-plan.md
|
||||
@$HOME/.codex/get-shit-done/templates/summary.md
|
||||
</execution_context>
|
||||
|
||||
<context>
|
||||
@.planning/ROADMAP.md
|
||||
@.planning/STATE.md
|
||||
@.planning/REQUIREMENTS.md
|
||||
@.planning/phases/01-current-engine-boundaries/01-refactor-entry-strategy.md
|
||||
@.planning/phases/03-page-metadata-pagination/03-RESEARCH.md
|
||||
@.planning/phases/03-page-metadata-pagination/03-PATTERNS.md
|
||||
@.planning/phases/03-page-metadata-pagination/03-01-PLAN.md
|
||||
@Sources/RDReaderView/EPUBTextRendering/RDEPUBTextPaginationSupport.swift
|
||||
@Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift
|
||||
@Sources/RDReaderView/EPUBCore/RDEPUBReadingSession.swift
|
||||
@Sources/RDReaderView/EPUBUI/RDEPUBTextContentView.swift
|
||||
</context>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1: 引入 layouter / layout-frame 语义并升级分页入口</name>
|
||||
<files>Sources/RDReaderView/EPUBTextRendering/RDEPUBTextPaginationSupport.swift, Sources/RDReaderView/EPUBTextRendering/RDEPUBTextLayouter.swift, Sources/RDReaderView/EPUBTextRendering/RDEPUBTextLayoutFrame.swift</files>
|
||||
<read_first>Sources/RDReaderView/EPUBTextRendering/RDEPUBTextPaginationSupport.swift, Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift, .planning/phases/01-current-engine-boundaries/01-refactor-entry-strategy.md</read_first>
|
||||
<action>把当前 `ss_pageRanges(size:)` 的纯 range slicing 入口升级成内部 layouter / layout-frame 驱动的分页路径;新路径至少要能表达 page break reason、block boundary avoidance、image/attachment boundary handling 这三类语义。新增类型应放在 `EPUBTextRendering` 内部,例如 `RDEPUBTextLayouter` / `RDEPUBTextLayoutFrame`,并由 `RDEPUBTextPaginationSupport` 调用,而不是把复杂分页逻辑堆到 UI controller 里。</action>
|
||||
<acceptance_criteria>
|
||||
- `Sources/RDReaderView/EPUBTextRendering` contains layouter/frame types or equivalent internal pagination structures
|
||||
- paginator code contains semantics beyond plain `CTFrameGetVisibleStringRange` slicing
|
||||
- source tree does not move pagination logic into `RDEPUBReaderController` or `RDEPUBTextContentView`
|
||||
</acceptance_criteria>
|
||||
<verify>rg -n "Layouter|LayoutFrame|pageBreak|attachment|avoid|CTFrameGetVisibleStringRange|CTTypesetter" Sources/RDReaderView/EPUBTextRendering</verify>
|
||||
<done>native pagination now has a real internal layout vocabulary rather than one visible-range helper.</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 2: 把更强分页结果接回 `RDEPUBTextBookBuilder` 与现有页模型</name>
|
||||
<files>Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift</files>
|
||||
<read_first>Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift, Sources/RDReaderView/EPUBCore/RDEPUBReadingSession.swift, Sources/RDReaderView/EPUBTextRendering/RDEPUBTextSearchEngine.swift, Sources/RDReaderView/EPUBUI/RDEPUBTextContentView.swift</read_first>
|
||||
<action>让 `RDEPUBTextBookBuilder` 消费新分页结果并把 page-level metadata 落到 `RDEPUBTextPage` / `RDEPUBTextChapter` 上,同时保持 `pageStartOffset` / `pageEndOffset`、chapter order、fragmentOffsets 和 search/highlight overlap 逻辑不变。需要时可以在 builder 内转换 layouter output,但最终输出仍必须是当前 `RDEPUBTextBook` 契约,而不是新的 UI-only page list。</action>
|
||||
<acceptance_criteria>
|
||||
- `RDEPUBTextBookBuilder` constructs pages from the upgraded pagination output rather than raw `ss_pageRanges(size:)` only
|
||||
- page model assembly still emits `RDEPUBTextBook(chapters:pages:)`
|
||||
- search/highlight/navigation dependent fields remain present in the built pages
|
||||
</acceptance_criteria>
|
||||
<verify>rg -n "RDEPUBTextBook\\(|pageStartOffset|pageEndOffset|fragmentOffsets|metadata|layout" Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift</verify>
|
||||
<done>the richer paginator is wired back into the existing native book contract and remains consumable by later reader phases.</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<verification>
|
||||
Before declaring plan complete:
|
||||
- [ ] `test -f Sources/RDReaderView/EPUBTextRendering/RDEPUBTextPaginationSupport.swift`
|
||||
- [ ] `rg -n "Layouter|LayoutFrame|pageBreak|attachment|avoid" Sources/RDReaderView/EPUBTextRendering`
|
||||
- [ ] `rg -n "RDEPUBTextBook\\(|pageStartOffset|pageEndOffset|fragmentOffsets" Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift`
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
|
||||
- All tasks completed
|
||||
- All verification checks pass
|
||||
- paginator semantics are meaningfully stronger than pure visible-range slicing
|
||||
- output still flows through the existing native text book/page model
|
||||
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
After completion, create `.planning/phases/03-page-metadata-pagination/03-02-SUMMARY.md`
|
||||
</output>
|
||||
@@ -0,0 +1,21 @@
|
||||
# 03-02 Summary
|
||||
|
||||
## Outcome
|
||||
|
||||
Wave 2 replaced the range-only pagination path with an internal layouter/frame vocabulary inside `EPUBTextRendering`.
|
||||
|
||||
- Added `RDEPUBTextLayouter.swift`
|
||||
- Added `RDEPUBTextLayoutFrame.swift`
|
||||
- Updated `RDEPUBTextPaginationSupport.swift` so `ss_pageRanges(size:)` now delegates to `rd_paginatedFrames(size:fragmentOffsets:)`
|
||||
- Updated `RDEPUBTextBookBuilder` and `RDPlainTextBookBuilder` to build pages from layout frames instead of bare `NSRange` slices
|
||||
|
||||
## New Semantics
|
||||
|
||||
- Page breaks now carry one of `chapterEnd`, `frameLimit`, `blockBoundary`, or `attachmentBoundary`
|
||||
- Layout frames capture block-range context, attachment ranges/kinds, trailing fragment id, and page-edge diagnostics
|
||||
- The layouter still uses CoreText measurement, but page boundaries are adjusted with block/attachment-aware rules before serialization back into `RDEPUBTextPage`
|
||||
|
||||
## Compatibility
|
||||
|
||||
- Final output is still `RDEPUBTextBook(chapters: pages:)`
|
||||
- `pageStartOffset` / `pageEndOffset` remain the compatibility key for search, highlights, and later reader reintegration
|
||||
@@ -0,0 +1,106 @@
|
||||
---
|
||||
phase: 03-page-metadata-pagination
|
||||
plan: 03
|
||||
type: execute
|
||||
wave: 3
|
||||
depends_on:
|
||||
- "03-02"
|
||||
files_modified:
|
||||
- Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift
|
||||
- Sources/RDReaderView/EPUBTextRendering/RDEPUBTextPaginationSupport.swift
|
||||
- Sources/RDReaderView/EPUBUI/RDEPUBTextContentView.swift
|
||||
- ReadViewDemo/ReadViewDemo/ViewController.swift
|
||||
autonomous: true
|
||||
requirements:
|
||||
- REND-03
|
||||
- REND-04
|
||||
user_setup: []
|
||||
must_haves:
|
||||
truths:
|
||||
- sample EPUBs with images or large blocks can prove stronger page-edge semantics through real diagnostics, not only visual inspection.
|
||||
- offset-based highlight/search compatibility survives the stronger paginator.
|
||||
- the current demo app remains the validation entry point.
|
||||
artifacts:
|
||||
- .planning/phases/03-page-metadata-pagination/03-03-SUMMARY.md
|
||||
key_links:
|
||||
- `ReadViewDemo/ReadViewDemo/book/` remains the regression corpus.
|
||||
- `RDEPUBTextContentView` still derives overlaps from `pageStartOffset` / `pageEndOffset`.
|
||||
---
|
||||
|
||||
<objective>
|
||||
用真实样本验证复杂块元素、图片与分页边界控制在新分页器下可工作,并确认 offset-compatible highlight/search 行为没有被破坏。
|
||||
|
||||
Purpose: 证明 Phase 3 的 richer metadata 和 stronger paginator 不只是结构升级,而是能在真实 EPUB 上给出可解释、可回归的分页结果。
|
||||
Output: demo-visible diagnostics, sample-book spot-check path, and source assertions around metadata + offset compatibility.
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
@$HOME/.codex/get-shit-done/workflows/execute-plan.md
|
||||
@$HOME/.codex/get-shit-done/templates/summary.md
|
||||
</execution_context>
|
||||
|
||||
<context>
|
||||
@.planning/ROADMAP.md
|
||||
@.planning/STATE.md
|
||||
@.planning/phases/03-page-metadata-pagination/03-RESEARCH.md
|
||||
@.planning/phases/03-page-metadata-pagination/03-PATTERNS.md
|
||||
@.planning/phases/03-page-metadata-pagination/03-01-PLAN.md
|
||||
@.planning/phases/03-page-metadata-pagination/03-02-PLAN.md
|
||||
@Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift
|
||||
@Sources/RDReaderView/EPUBTextRendering/RDEPUBTextPaginationSupport.swift
|
||||
@Sources/RDReaderView/EPUBUI/RDEPUBTextContentView.swift
|
||||
@ReadViewDemo/ReadViewDemo/ViewController.swift
|
||||
@ReadViewDemo/ReadViewDemo/book/
|
||||
</context>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1: 对真实 EPUB 暴露分页诊断并验证图片/块元素边界</name>
|
||||
<files>Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift, Sources/RDReaderView/EPUBTextRendering/RDEPUBTextPaginationSupport.swift, ReadViewDemo/ReadViewDemo/ViewController.swift</files>
|
||||
<read_first>Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift, Sources/RDReaderView/EPUBTextRendering/RDEPUBTextPaginationSupport.swift, ReadViewDemo/ReadViewDemo/ViewController.swift, ReadViewDemo/ReadViewDemo/book/</read_first>
|
||||
<action>基于现有 demo 样本书,为 stronger paginator 增加最小但可观察的分页诊断输出,至少能报告 page metadata / page break reason / image-or-block boundary evidence 中的一部分,并用 `ReadViewDemo/ReadViewDemo/book/` 的 reflowable EPUB 验证复杂块元素和图片没有回退到不可解释的纯 slicing 行为。不要新增并行 reader shell。</action>
|
||||
<acceptance_criteria>
|
||||
- demo or runtime logs expose pagination diagnostics tied to the new metadata or page-break semantics
|
||||
- source tree still uses `ReadViewDemo/ReadViewDemo/ViewController.swift` as the validation entry point
|
||||
- `ReadViewDemo/ReadViewDemo/book` remains the sample corpus referenced by the validation path
|
||||
</acceptance_criteria>
|
||||
<verify>rg -n "diagnostic|metadata|page break|attachment|image|block" Sources/RDReaderView/EPUBTextRendering ReadViewDemo/ReadViewDemo</verify>
|
||||
<done>sample books can demonstrate that new pagination semantics are active and inspectable.</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 2: 验证 offset-compatible 高亮/搜索页内映射没有退化</name>
|
||||
<files>Sources/RDReaderView/EPUBUI/RDEPUBTextContentView.swift, Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift</files>
|
||||
<read_first>Sources/RDReaderView/EPUBUI/RDEPUBTextContentView.swift, Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift, Sources/RDReaderView/EPUBTextRendering/RDEPUBTextSearchEngine.swift, Sources/RDReaderView/EPUBCore/RDEPUBReadingModels.swift</read_first>
|
||||
<action>确认 stronger paginator 产出的 page metadata 仍能支持 `RDEPUBTextContentView` 的 highlight/search overlap 计算和 `RDEPUBTextOffsetRangeInfo` 的绝对 offset 语义;如果需要,可补充最小的 source-level guard 或 diagnostics,但不要把兼容修复扩展成 Phase 4 的 reader reintegration。重点是验证 page-local presentation 依然能从 absolute chapter offsets 正确切出相对范围。</action>
|
||||
<acceptance_criteria>
|
||||
- `RDEPUBTextContentView` still computes overlaps from `pageStartOffset` / `pageEndOffset`
|
||||
- `RDEPUBTextOffsetRangeInfo` remains decodable and tied to absolute chapter offsets
|
||||
- no code path replaces highlight/search overlap logic with page-local-only identifiers
|
||||
</acceptance_criteria>
|
||||
<verify>rg -n "pageStartOffset|pageEndOffset|RDEPUBTextOffsetRangeInfo|rangeInfo|searchState" Sources/RDReaderView/EPUBUI/RDEPUBTextContentView.swift Sources/RDReaderView/EPUBTextRendering Sources/RDReaderView/EPUBCore</verify>
|
||||
<done>Phase 3 finishes with stronger pagination semantics and intact offset-based presentation compatibility.</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<verification>
|
||||
Before declaring plan complete:
|
||||
- [ ] `test -d ReadViewDemo/ReadViewDemo/book`
|
||||
- [ ] `rg -n "diagnostic|metadata|page break|attachment|image|block" Sources/RDReaderView ReadViewDemo/ReadViewDemo`
|
||||
- [ ] `rg -n "pageStartOffset|pageEndOffset|RDEPUBTextOffsetRangeInfo|rangeInfo" Sources/RDReaderView/EPUBUI/RDEPUBTextContentView.swift Sources/RDReaderView/EPUBTextRendering Sources/RDReaderView/EPUBCore`
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
|
||||
- All tasks completed
|
||||
- All verification checks pass
|
||||
- sample books prove stronger paginator behavior is both active and inspectable
|
||||
- offset-based highlight/search presentation compatibility remains intact for Phase 4 handoff
|
||||
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
After completion, create `.planning/phases/03-page-metadata-pagination/03-03-SUMMARY.md`
|
||||
</output>
|
||||
@@ -0,0 +1,19 @@
|
||||
# 03-03 Summary
|
||||
|
||||
## Outcome
|
||||
|
||||
Wave 3 exposed real-book pagination diagnostics and confirmed that offset-compatible highlight/search presentation stayed intact.
|
||||
|
||||
- Added builder-level `RDEPUBTextChapterPaginationDiagnostic`
|
||||
- `RDEPUBTextBookBuilder` now records `lastBuildPaginationDiagnostics`
|
||||
- `ReadViewDemo/ViewController.swift` reports pagination evidence from sample EPUBs in UI/runtime logs
|
||||
- `RDEPUBTextContentView.swift` still computes highlight/search overlap from absolute `pageStartOffset` / `pageEndOffset`, now via an explicit helper
|
||||
|
||||
## Demo Evidence
|
||||
|
||||
Runtime log from the simulator:
|
||||
|
||||
- `EPUB 资源验证:2/2 通过`
|
||||
- `分页诊断:宝山辽墓材料与释读 · 章节 10 · attachment 页 54 · semantic break 页 57 · reasons [attachmentBoundary:31, blockBoundary:26, frameLimit:17, chapterEnd:4] · page break: blockBoundary`
|
||||
|
||||
This confirms the stronger paginator is active on real EPUB content and not silently falling back to pure visible-range slicing.
|
||||
@@ -0,0 +1,31 @@
|
||||
# Phase 3: 重构属性体系与复杂分页器 - Pattern Map
|
||||
|
||||
## Goal
|
||||
|
||||
为 Phase 3 执行提供“先看哪里、怎么保持兼容”的最短路径。这个阶段的关键不是改 reader UI,而是扩展 page metadata 并把 paginator 从纯 range slicing 升级为可表达页面语义的内部 layouter。
|
||||
|
||||
## Planned Outputs
|
||||
|
||||
| Planned file | Role | Primary evidence | Why this is the right analog |
|
||||
|--------------|------|------------------|------------------------------|
|
||||
| `.planning/phases/03-page-metadata-pagination/03-01-PLAN.md` | 页面级 attributed string 元数据与属性键实现计划 | `Sources/RDReaderView/EPUBCore/RDEPUBReadingModels.swift`, `Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift`, `Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRenderer.swift` | 这些文件共同定义 page/chapter contract、range info、fragment offsets 与 renderer output。 |
|
||||
| `.planning/phases/03-page-metadata-pagination/03-02-PLAN.md` | 复杂分页器与 layouter/frame 重构计划 | `Sources/RDReaderView/EPUBTextRendering/RDEPUBTextPaginationSupport.swift`, `RDEPUBTextBookBuilder.swift` | 当前所有分页都在这里;Phase 3 必须从这条路径升级,而不是另起 reader shell。 |
|
||||
| `.planning/phases/03-page-metadata-pagination/03-03-PLAN.md` | 复杂块元素/图片分页验证计划 | `ReadViewDemo/ReadViewDemo/book/*.epub`, `ReadViewDemo/ReadViewDemo/ViewController.swift`, `RDEPUBTextContentView.swift` | 需要真实样本和现有 demo 入口来证明分页语义变强但 offset compatibility 没坏。 |
|
||||
|
||||
## Code Evidence Map
|
||||
|
||||
| Concern | Closest source of truth | Evidence to extract |
|
||||
|---------|-------------------------|---------------------|
|
||||
| 当前 page model 的边界 | `Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift` | `RDEPUBTextPage` / `RDEPUBTextChapter` 当前只有 offsets、ranges、fragmentOffsets。 |
|
||||
| 当前 paginator 的真实实现 | `Sources/RDReaderView/EPUBTextRendering/RDEPUBTextPaginationSupport.swift` | `CTFramesetterCreateFrame` + `CTFrameGetVisibleStringRange` 的纯 slicing 逻辑。 |
|
||||
| 位置/导航如何依赖 offsets | `Sources/RDReaderView/EPUBCore/RDEPUBReadingSession.swift` | `pageIndex(for:)`、pending navigation、href/progression 到 page 的映射。 |
|
||||
| 高亮/选区如何依赖 offsets | `Sources/RDReaderView/EPUBUI/RDEPUBTextContentView.swift`, `Sources/RDReaderView/EPUBCore/RDEPUBReadingModels.swift` | `RDEPUBTextOffsetRangeInfo` 与 `pageStartOffset/pageEndOffset` 的 overlap 计算。 |
|
||||
| 搜索如何依赖 chapter text continuity | `Sources/RDReaderView/EPUBTextRendering/RDEPUBTextSearchEngine.swift` | chapter-level attributed string 搜索 + rangeLocation/rangeLength。 |
|
||||
| 复杂块元素/图片验证入口 | `ReadViewDemo/ReadViewDemo/book/`, `ReadViewDemo/ReadViewDemo/ViewController.swift` | 现有 demo 与样本 corpus 已经是可运行回归入口。 |
|
||||
|
||||
## Writing Guidance
|
||||
|
||||
- 计划必须把 “metadata first, paginator second, validation third” 的顺序写清楚,避免把所有变更压进一个 plan。
|
||||
- 任何新分页语义都要同时写出 “增强点” 和 “必须保留的 offset invariant”。
|
||||
- 如果引入内部 layouter / layout-frame 类型,职责要落在 `EPUBTextRendering` 内部,不要扩散到 `RDEPUBReaderController`。
|
||||
- 验证计划除了 demo/run,还要有源代码断言,确保 metadata 与 page-edge reason 真正落盘到模型里。
|
||||
@@ -0,0 +1,144 @@
|
||||
# Phase 3: 重构属性体系与复杂分页器 - Research
|
||||
|
||||
**Researched:** 2026-05-22
|
||||
**Domain:** iOS EPUB native pagination / page metadata / CoreText layout semantics
|
||||
**Confidence:** HIGH
|
||||
|
||||
<user_constraints>
|
||||
## User Constraints
|
||||
|
||||
No `CONTEXT.md` exists for this phase. Planning is based on ROADMAP requirements, current code, Phase 1 strategy, and Phase 2 implementation artifacts only.
|
||||
</user_constraints>
|
||||
|
||||
<architectural_responsibility_map>
|
||||
## Architectural Responsibility Map
|
||||
|
||||
| Capability | Primary Tier | Secondary Tier | Rationale |
|
||||
|------------|-------------|----------------|-----------|
|
||||
| Page-level attributed string metadata | EPUBTextRendering | EPUBCore | Metadata must stay adjacent to chapter/page models so offsets, fragments, and attachments remain queryable. |
|
||||
| Stronger pagination semantics | EPUBTextRendering | CoreText | `ss_pageRanges(size:)` is the only current paginator; Phase 3 must replace or wrap it with richer layout decisions. |
|
||||
| Offset continuity for location/highlight/search | EPUBTextRendering | EPUBUI | `RDEPUBTextBook`, `RDEPUBTextContentView`, and `RDEPUBReadingSession` all assume stable chapter offsets. |
|
||||
| Reader state + navigation orchestration | EPUBCore | EPUBUI | `RDEPUBReadingSession` should keep owning navigation/page lookup; it should consume richer page metadata rather than invent a new UI model. |
|
||||
| Fixed / interactive EPUB rendering | EPUBCore | WebKit | Still out of scope; WebView paths remain unchanged. |
|
||||
|
||||
</architectural_responsibility_map>
|
||||
|
||||
<research_summary>
|
||||
## Summary
|
||||
|
||||
Phase 2 solved the renderer input problem. The native reflowable path now has chapter-scoped preprocessing, explicit CSS precedence, and resolver-backed resource diagnostics. What remains weak is the page model and paginator. `RDEPUBTextPaginationSupport.ss_pageRanges(size:)` still slices the chapter with `CTFrameGetVisibleStringRange` and returns only bare `NSRange` values. `RDEPUBTextPage` then stores those ranges plus `pageStartOffset` / `pageEndOffset`, but no block metadata, no attachment semantics, no page-edge reasons, and no way to explain why a page boundary landed where it did.
|
||||
|
||||
That limitation is now the main blocker for `REND-03` and `REND-04`. Search, selection, highlights, `RDEPUBReadingSession.pageIndex(for:)`, and `RDEPUBTextContentView` all depend on stable offsets. Phase 3 therefore cannot replace `RDEPUBTextBook` with a new UI-only model. It has to extend the existing `RDEPUBTextChapter` / `RDEPUBTextPage` contract with richer metadata while preserving chapter text continuity and global offsets.
|
||||
|
||||
The safest implementation path is incremental:
|
||||
|
||||
1. Define page metadata and attribute keys first.
|
||||
2. Introduce an internal layouter / layout-frame abstraction that can reason about blocks, attachments, and page edges while still returning offset-stable page slices.
|
||||
3. Validate the new paginator on real EPUBs with large blocks and images before touching Phase 4 reader reintegration.
|
||||
|
||||
The repo already exposes the exact compatibility surface we need to preserve:
|
||||
|
||||
- `RDEPUBTextContentView` derives relative highlight/search ranges from `pageStartOffset` and `pageEndOffset`.
|
||||
- `RDEPUBTextOffsetRangeInfo` serializes highlight ranges as absolute chapter offsets.
|
||||
- `RDEPUBTextSearchEngine` indexes chapter-level attributed strings and stores match ranges by chapter offset.
|
||||
- `RDEPUBReadingSession` still resolves navigation by href + progression and maps that back onto active pages.
|
||||
|
||||
**Primary recommendation:** Build a richer internal pagination layer under `EPUBTextRendering` that emits extended `RDEPUBTextPage` metadata while keeping `pageStartOffset`, `pageEndOffset`, `fragmentOffsets`, and chapter text continuity intact. Do not move layout logic into `RDEPUBReaderController` or `RDEPUBTextContentView`.
|
||||
</research_summary>
|
||||
|
||||
<standard_stack>
|
||||
## Standard Stack
|
||||
|
||||
### Core
|
||||
| Library | Version | Purpose | Why Standard |
|
||||
|---------|---------|---------|--------------|
|
||||
| Foundation | System | Metadata models, ranges, serialization, diagnostics | Existing page/highlight/search models are already Foundation-driven. |
|
||||
| CoreText | System | Low-level line/frame measurement | Needed to upgrade beyond pure visible-range slicing. |
|
||||
| UIKit | iOS 15+ SDK | Text page presentation and selection mapping | `RDEPUBTextContentView` still presents `NSAttributedString` pages and maps ranges back to offsets. |
|
||||
| DTCoreText | 1.6.28 | HTML-to-attributed-string import | Phase 3 builds on imported attributed content rather than replacing the typesetter. |
|
||||
|
||||
### Supporting
|
||||
| Library | Version | Purpose | When to Use |
|
||||
|---------|---------|---------|-------------|
|
||||
| ZIPFoundation | 0.9.20 | EPUB archive access | Real-book validation still depends on sample EPUB extraction. |
|
||||
| DTFoundation | 1.7.19 | DTCoreText support | Attachment and HTML import remain rooted here. |
|
||||
|
||||
### Alternatives Considered
|
||||
| Instead of | Could Use | Tradeoff |
|
||||
|------------|-----------|----------|
|
||||
| Extend `RDEPUBTextPage` / `RDEPUBTextChapter` | Create a brand-new page tree model | Would break current reader/highlight/search callers too early and enlarge Phase 4 scope. |
|
||||
| Introduce layouter/frame types under `EPUBTextRendering` | Keep growing `ss_pageRanges(size:)` as a single function | Hard to express page-edge reasons, block avoidance rules, and attachment metadata in one range-only helper. |
|
||||
| Preserve chapter offsets as the compatibility key | Shift to page-local only locations | Would break selection/highlight persistence and make Phase 4 much harder. |
|
||||
|
||||
</standard_stack>
|
||||
|
||||
<architecture_patterns>
|
||||
## Architecture Patterns
|
||||
|
||||
### Pattern 1: Extend, don't replace, the book contract
|
||||
**What:** Add metadata to `RDEPUBTextPage` / `RDEPUBTextChapter` while preserving existing offset fields.
|
||||
**When to use:** When downstream readers already depend on `href + offsets + pages`.
|
||||
**Why:** Highlights, search matches, and navigation already serialize offsets and chapter hrefs.
|
||||
|
||||
### Pattern 2: Separate layouter from page serialization
|
||||
**What:** Use internal layouter/layout-frame types to compute page boundaries, then convert those results into `RDEPUBTextPage`.
|
||||
**When to use:** When pagination logic is becoming more complex than plain visible-range slicing.
|
||||
**Why:** Keeps `RDEPUBTextBookBuilder` as the chapter/page assembly boundary without forcing it to own all layout heuristics inline.
|
||||
|
||||
### Pattern 3: Preserve chapter-level continuity as the invariant
|
||||
**What:** Every new metadata structure should be traceable back to absolute chapter offsets.
|
||||
**When to use:** For block edges, attachments, fragment anchors, and page break reasons.
|
||||
**Why:** Current location/highlight/search behavior uses absolute chapter ranges; Phase 3 should enrich that graph, not replace it.
|
||||
|
||||
### Anti-Patterns to Avoid
|
||||
- Rewriting `RDReaderView` or page presentation controls in the name of pagination.
|
||||
- Introducing metadata that cannot be mapped back to `pageStartOffset` / `pageEndOffset`.
|
||||
- Letting validation rely only on “looks okay” manual checks without capturing page-edge or attachment evidence.
|
||||
|
||||
</architecture_patterns>
|
||||
|
||||
<dont_hand_roll>
|
||||
## Don't Hand-Roll
|
||||
|
||||
| Problem | Don't Build | Use Instead | Why |
|
||||
|---------|-------------|-------------|-----|
|
||||
| Reader reintegration | A new reader shell | Existing `RDEPUBTextBook` / `RDEPUBReadingSession` contract | Phase 4 needs continuity, not a second UI model. |
|
||||
| Location persistence | Page-local ephemeral IDs only | Absolute chapter offsets + fragment compatibility | Current highlights and search results already use offset-based range info. |
|
||||
| Validation | Purely visual checks with no metadata evidence | Source assertions plus sample EPUB diagnostics | Complex pagination bugs need explainable metadata, not only screenshots. |
|
||||
|
||||
</dont_hand_roll>
|
||||
|
||||
<common_pitfalls>
|
||||
## Common Pitfalls
|
||||
|
||||
### Pitfall 1: Richer metadata that doesn't survive page serialization
|
||||
If metadata lives only in temporary layout structures and never lands on `RDEPUBTextPage`, Phase 4 cannot consume it.
|
||||
|
||||
### Pitfall 2: Better page edges but broken offset continuity
|
||||
If page boundaries improve but `pageStartOffset` / `pageEndOffset` drift from chapter content, highlights and search navigation regress immediately.
|
||||
|
||||
### Pitfall 3: Attachment-aware pagination without validation hooks
|
||||
Image/attachment rules are hard to trust unless the phase leaves behind enough metadata or demo diagnostics to confirm what happened on a given page boundary.
|
||||
|
||||
</common_pitfalls>
|
||||
|
||||
<sota_updates>
|
||||
## State of the Art (2024-2025)
|
||||
|
||||
| Old Approach | Current Approach | Impact |
|
||||
|--------------|------------------|--------|
|
||||
| `CTFrameGetVisibleStringRange` only | Layout pipeline with page-edge semantics and attachment-aware metadata | Needed to express avoid-break rules and richer page reasoning. |
|
||||
| Range-only page model | Page model with semantic metadata and diagnostics | Needed for later reader reintegration and regression debugging. |
|
||||
| Paginator hidden inside a helper | Layouter/frame responsibilities separated from book assembly | Improves testability and makes pagination regressions explainable. |
|
||||
|
||||
</sota_updates>
|
||||
|
||||
<open_questions>
|
||||
## Open Questions
|
||||
|
||||
- Which page metadata belongs directly on `RDEPUBTextPage` versus a nested layout-metadata payload?
|
||||
- Should attachment/block metadata be encoded as custom `NSAttributedString.Key` values, separate page structs, or both?
|
||||
- How much of the new layouter/frame API should remain internal to `EPUBTextRendering` versus surfaced through `RDEPUBTextBookBuilder`?
|
||||
- Which sample EPUBs in `ReadViewDemo/ReadViewDemo/book/` best expose large-block and image boundary cases for repeatable validation?
|
||||
|
||||
</open_questions>
|
||||
@@ -0,0 +1,63 @@
|
||||
---
|
||||
phase: 3
|
||||
slug: page-metadata-pagination
|
||||
status: draft
|
||||
nyquist_compliant: true
|
||||
wave_0_complete: false
|
||||
created: 2026-05-22
|
||||
---
|
||||
|
||||
# Phase 3 — Validation Strategy
|
||||
|
||||
> Per-phase validation contract for page metadata and paginator-semantic work.
|
||||
|
||||
---
|
||||
|
||||
## Test Infrastructure
|
||||
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| **Framework** | shell assertions + Xcode build smoke + demo EPUB diagnostics |
|
||||
| **Config file** | none — repo still has no dedicated XCTest target for this phase |
|
||||
| **Quick run command** | `test -f .planning/phases/03-page-metadata-pagination/03-RESEARCH.md && test -f .planning/phases/03-page-metadata-pagination/03-PATTERNS.md` |
|
||||
| **Full suite command** | `xcodebuild -workspace ReadViewDemo/ReadViewDemo.xcworkspace -scheme ReadViewDemo -destination 'platform=iOS Simulator,name=iPhone 17' build` |
|
||||
| **Estimated runtime** | ~60-90 seconds |
|
||||
|
||||
## Sampling Rate
|
||||
|
||||
- **After every task commit:** Run the task’s `rg` assertions against touched rendering/pagination files.
|
||||
- **After every wave:** Run the `ReadViewDemo` simulator build smoke.
|
||||
- **Before `$gsd-verify-work`:** Demo sample EPUB diagnostics must still pass, and Phase 3 plans/summaries must exist.
|
||||
- **Max feedback latency:** 90 seconds
|
||||
|
||||
## Per-Task Verification Map
|
||||
|
||||
| Task ID | Plan | Wave | Requirement | Secure Behavior | Test Type | Automated Command | Status |
|
||||
|---------|------|------|-------------|-----------------|-----------|-------------------|--------|
|
||||
| 03-01-01 | 01 | 1 | REND-03 | Page/chapter models expose richer metadata without dropping offset continuity | source | `rg -n "metadata|attachment|block|pageStartOffset|pageEndOffset|fragmentOffsets" Sources/RDReaderView/EPUBTextRendering Sources/RDReaderView/EPUBCore` | ⬜ pending |
|
||||
| 03-02-01 | 02 | 2 | REND-04 | Paginator no longer relies on pure visible-range slicing and introduces layouter/frame semantics | source | `rg -n "Layouter|LayoutFrame|pageBreak|avoid|attachment|CTTypesetter|CTFramesetter" Sources/RDReaderView/EPUBTextRendering` | ⬜ pending |
|
||||
| 03-03-01 | 03 | 3 | REND-03, REND-04 | Sample EPUBs and page diagnostics prove large blocks/images keep offset-compatible pagination | smoke/source | `rg -n "diagnostic|metadata|page break|attachment|image|block" Sources/RDReaderView ReadViewDemo/ReadViewDemo` | ⬜ pending |
|
||||
|
||||
## Wave 0 Requirements
|
||||
|
||||
- [ ] `ReadViewDemo/ReadViewDemo.xcworkspace` and `ReadViewDemo` scheme still build before close-out.
|
||||
- [ ] Validation continues to use `ReadViewDemo/ReadViewDemo/book/` as the regression corpus.
|
||||
- [ ] No plan may remove `pageStartOffset`, `pageEndOffset`, or fragment offset compatibility.
|
||||
|
||||
## Manual-Only Verifications
|
||||
|
||||
| Behavior | Requirement | Why Manual | Test Instructions |
|
||||
|----------|-------------|------------|-------------------|
|
||||
| Large blocks and images break at better boundaries | REND-04 | Visual edge quality still needs a human read-through | Open a sample EPUB with images and long paragraphs; confirm boundaries are improved versus old slicing. |
|
||||
| Highlight/search navigation still lands on the correct page after repagination | REND-03, REND-04 | Requires end-to-end interaction with existing reader flow | Use the demo reader to navigate to saved ranges or search matches after pagination changes. |
|
||||
|
||||
## Validation Sign-Off
|
||||
|
||||
- [ ] All tasks have automated verification commands
|
||||
- [ ] Sampling continuity: no 3 consecutive tasks without automated verify
|
||||
- [ ] Wave 0 covers offset-compatibility invariants
|
||||
- [ ] No watch-mode flags
|
||||
- [ ] Feedback latency < 90s
|
||||
- [ ] `nyquist_compliant: true` set in frontmatter
|
||||
|
||||
**Approval:** pending
|
||||
@@ -0,0 +1,31 @@
|
||||
# Phase 3 Verification
|
||||
|
||||
## Commands
|
||||
|
||||
- `pod install` in `ReadViewDemo/`
|
||||
- `build_sim` for scheme `ReadViewDemo`
|
||||
- `build_run_sim` for scheme `ReadViewDemo`
|
||||
- `rg -n "diagnostic|metadata|page break|attachment|image|block|pageStartOffset|pageEndOffset|RDEPUBTextOffsetRangeInfo|rangeInfo" Sources/RDReaderView ReadViewDemo/ReadViewDemo -S`
|
||||
- `test -d ReadViewDemo/ReadViewDemo/book`
|
||||
|
||||
## Results
|
||||
|
||||
- Build succeeded on iOS Simulator
|
||||
- App launch succeeded on simulator `iPhone 17`
|
||||
- Sample corpus directory exists: `ReadViewDemo/ReadViewDemo/book`
|
||||
- Source verification confirms:
|
||||
- internal layouter/layout-frame types exist under `EPUBTextRendering`
|
||||
- paginator now emits page-break semantics and attachment/block diagnostics
|
||||
- `RDEPUBTextContentView` still uses `pageStartOffset` / `pageEndOffset`
|
||||
- `RDEPUBTextOffsetRangeInfo` remains the absolute-offset persistence format
|
||||
|
||||
## Runtime Evidence
|
||||
|
||||
From the app runtime log:
|
||||
|
||||
- `EPUB 资源验证:2/2 通过`
|
||||
- `分页诊断:宝山辽墓材料与释读 · 章节 10 · attachment 页 54 · semantic break 页 57 · reasons [attachmentBoundary:31, blockBoundary:26, frameLimit:17, chapterEnd:4] · page break: blockBoundary`
|
||||
|
||||
## Residual Risk
|
||||
|
||||
- The layouter heuristics are intentionally incremental, not a full WXRead-equivalent paginator. Phase 4 should validate the stronger page model against live reader navigation/highlight/search flows, and Phase 5 should broaden corpus coverage.
|
||||
Reference in New Issue
Block a user