feat(reader): stop detecting 卷 in txt splitting (volume lines stay body text, volume-only books fall back to pseudo-sections); replace chapter dropdown with a 目录 sidebar overlay (active row highlighted + centered, click-away/pick to close)
This commit is contained in:
@@ -39,20 +39,19 @@ it("短文无标记 → 单节,chapterText 即全文", () => {
|
||||
expect(chapterText(t, chs, 0)).toBe(t);
|
||||
});
|
||||
|
||||
it("卷不是章节边界:只按章切,卷题作分组标签并并入所属章开头", () => {
|
||||
it("卷不感知:只按章切,卷题行留在正文里", () => {
|
||||
const t =
|
||||
"第一卷 天云世界\n第一章 铜镜\n" + pad(500) + "\n第二章 修炼\n" + pad(500) +
|
||||
"\n\n\n第二卷 仙界\n第三章 飞升\n" + pad(300);
|
||||
const chs = splitChapters(t);
|
||||
expect(chs.map((c) => c.title)).toEqual(["第一章 铜镜", "第二章 修炼", "第三章 飞升"]);
|
||||
expect(chs.map((c) => c.vol)).toEqual(["第一卷 天云世界", "第一卷 天云世界", "第二卷 仙界"]);
|
||||
expect(chs[2].start).toBe(t.indexOf("第二卷 仙界")); // 卷题行从本章开头渲染,而非上一章结尾
|
||||
expect(chapterText(t, chs, 2)).toMatch(/^第二卷 仙界/);
|
||||
expect(chs[0].start).toBe(t.indexOf("第一章"));
|
||||
expect(chs[2].start).toBe(t.indexOf("第三章"));
|
||||
expect(chapterText(t, chs, 1)).toContain("第二卷 仙界"); // 卷题在第二章结尾,不进第三章开头
|
||||
});
|
||||
|
||||
it("只有卷没有章的书:卷即章节", () => {
|
||||
it("只有卷没有章的书:按伪章节切", () => {
|
||||
const t = "第一卷 起\n" + pad(600) + "\n第二卷 承\n" + pad(600) + "\n第三卷 转\n" + pad(600);
|
||||
const chs = splitChapters(t);
|
||||
expect(chs.map((c) => c.title)).toEqual(["第一卷 起", "第二卷 承", "第三卷 转"]);
|
||||
expect(chs.every((c) => c.vol === undefined)).toBe(true);
|
||||
expect(chs).toEqual([{ title: "第 1 节", start: 0 }]);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user