# novel **Repository Path**: xjq11029/novel ## Basic Information - **Project Name**: novel - **Description**: 在 VS Code 里导入书源直接搜书、读书。自带一个用 TypeScript 重写的 Legado 规则引擎:CSS / XPath / JSONPath / 正则 / @js: 五类规则全支持,多源并发检索、书架与阅读进度记忆、目录筛选、四套阅读主题。摸鱼快乐 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-10-14 - **Last Updated**: 2026-10-14 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 小说阅读器 · Legado 书源(VS Code 扩展) 在 VS Code 里读网络小说——数据用你熟悉的「阅读 / Legado」书源。 写这个插件最麻烦的部分不是界面,是规则引擎。Legado 书源里的 `.bookname a@href`、`//h3/a/text()`、`$.info.Datas`、`##:author"[^"]*"([^"]*)##$1###`、`...` 是一套自成一体的 DSL,而社区里唯一像样的 TypeScript 实现和别的运行时强耦合,没法直接搬。所以这里按官方规则文档重写了一个,并用真实书源里的写法逐条做回归测试。 **和手机端的不同点**:它只做「能安静读完一本书」这条路径——搜索、目录、正文、记住你读到第几段。登录、离线下载、漫画、听书不在目标里。 ## 快速开始 1. 打开左侧活动栏的 **小说阅读器** 图标。 2. 「书源」面板点 `+` 导入书源 JSON(支持数组、`{"data":[...]}`、`{"bookSourceItems":[...]}` 三种导出格式,可多选文件合并导入)。 3. 「书架」面板点 🔍 搜索关键字 → 选择检索范围 → 结果出现在「搜索结果」里。 4. 单击结果即打开阅读界面,并自动加入书架;进度与滚动位置会被记住。 书源属于个人数据,本仓库不附带,请自行从「阅读」App 导出或使用自己的来源。 ## 特性 **规则引擎** - Default jsoup 语法:`class.x.0@tag.a@text`、`textNodes` / `ownText` / `html` / `all` / 任意属性名、`[-1:0]` 索引与区间、`!` 排除、前导 `-` 列表反序 - `@css:` 含 Legado 扩展伪类 `:eq()` `:index()` `:first` `:last` `:even` `:odd` `:gt()` `:lt()` `:contains()` `:matches()` - `@XPath:` / `//`,子规则以当前节点为根(与 JsoupXpath 行为一致) - `@json:` / `$.`,支持 `$..books[*]`、`chapters.[*]` 这类 Jayway 写法 - 组合符 `&&`(合并)、`||`(回退)、`%%`(交叉取数),均为括号 / 引号感知的顶层切分 - 正则三形态:AllInOne(`:` 前缀 + `$1`/`$2` 分组引用)、OnlyOne(`##re##repl###`,对首个匹配做替换并返回该匹配)、净化(`##re##repl` 全局替换);Java 的 `$0` 自动映射为 JS 的 `$&` - URL:`{{key}}` `{{page}}`、`{"charset":"gbk","method":"POST","body":...,"headers":...,"retry":n}` 请求选项、相对地址拼接、`<第一页,其他页>` 条件页、`{$.path}` 单花括号 JSONPath - `@put:{k:rule}` / `@get:{k}` 变量在「搜索 → 详情 → 目录 → 正文」之间传递 - `ruleBookInfo.init` 预处理、`nextTocUrl` 分页目录、`nextContentUrl` 分页正文、`replaceRegex` 净化 **JS 规则沙箱** `node:vm` 里重建常用 `java.*`:`ajax` / `get` / `post` / `getCookie` / `base64*` / `md5Encode(16)` / `sha1` / `sha256` / `aes*` / `utf8ToGbk` / `encodeURI` / `timeFormat` / `htmlFormat` / `log` / `put` / `get` / `getString` / `getStringList` / `getElements` / `setContent`,外加 `source.getKey()`、`book.*`、`chapter.*`、`cache`。 **中文站适配** GBK / GB18030 / Big5 编码自动识别,中文关键字按站点字符集百分号编码,按书源域名隔离的 Cookie 罐,并发数与超时可调。 **阅读体验** 四套主题(跟随 VS Code / 宣纸 / 豆绿 / 夜间)、字号行高行宽可调、可按章节名筛选的目录抽屉、滚动位置自动保存。正文一律以文本节点插入并配 CSP,远端内容不会作为脚本执行。 **测试** 50 项自动化测试:引擎用例全部取自真实书源写法;Webview 逻辑用 jsdom 真实执行脚本,含 XSS 用例;另有加载打包产物的激活冒烟测试。 ## 实测数据 抽样 150 个书源跑完整链路(`npm run probe`): ``` 94 个可访问 → 34 个返回搜索结果 → 15 个解析出目录 → 14 个完整读到正文 ``` 其中不乏 2500+ 章的长篇。失败主要来自站点本身已失效(404 / 403 / 连接重置 / 超时),而不是解析不出来。探针脚本随仓库提供,欢迎对你自己的书源跑一遍。 ## 命令 | 命令 | 说明 | | --- | --- | | 小说阅读器: 导入书源 | 从文件或剪贴板导入,也可清空 | | 小说阅读器: 搜索小说 | 多源并发检索 | | 小说阅读器: 发现(浏览分类) | 使用书源的 `exploreUrl` 栏目 | | 小说阅读器: 从书源网址打开书籍 | 粘贴详情页 / 目录页 URL 自动匹配书源 | | 小说阅读器: 上一章 / 下一章 | `Alt+←` / `Alt+→`(阅读界面聚焦时) | | 小说阅读器: 测试书源可用性 | 跑一遍搜索 → 目录 → 正文,报告失败原因 | | 小说阅读器: 清除章节缓存 | 站点改版后重建缓存 | 阅读界面内快捷键:`←` / `→` 翻章,`T` 开合目录,`+` / `−` 调字号,`Esc` 关目录。 ## 安装 ```bash npm install npm run test # 类型检查 + 构建 + 50 项测试 npm run package # 生成 novel-reader-<版本>.vsix code --install-extension legado-novel-reader-0.1.0.vsix ``` 也可以直接按 F5「运行扩展」,在调试宿主里跑未发布的版本。 ## 已知限制 - **`webView: true` 不支持**:需要真实浏览器渲染的站点(JS 动态目录 / 正文)抓不到内容,会退化成普通请求重试。 - **依赖 Rhino + jsoup 对象模型的 JS 规则不支持**:例如 `org.jsoup.Jsoup.parse(...)`、`r.select(...).size()`、`:matchesOwn()`、`book.putVariable(...)`。这类写法约占书源的 1–2%。 - 只取正文文字;漫画(`bookSourceType` 非 0)与听书类默认排除,可在设置里放开。 - 规则解析运行在扩展宿主进程,超大页面首次解析有数百毫秒占用;`java.ajax` 这类同步网络调用会短暂阻塞该线程。 ## 开发 ```bash npm run build # esbuild 打包到 dist/extension.js npm run test # 引擎离线测试 + Webview 界面测试 + 激活冒烟测试 npm run test:engine # 只跑规则引擎用例 npm run typecheck SOURCE_FILE=./我的书源.json npm run probe -- 凡人修仙传 150 # 线上探针,会真实联网 ``` ``` src/legado/ split.ts 括号/引号感知的规则切分 selectors.ts Default / CSS / XPath / JSONPath / 正则 AllInOne engine.ts AnalyzeRule 等价实现(规则求值编排) jsapi.ts @js 沙箱与 java.* API http.ts 编码识别 / Cookie / 重定向 service.ts 搜索 → 详情 → 目录 → 正文流程 src/ui/ 侧边栏视图与阅读 Webview src/test/ 离线用例、Webview 测试、激活冒烟、线上探针 ``` ## 数据位置 扩展全局目录(`globalStorage`)下:`sources.json` 书源库、`shelf.json` 书架、`progress.json` 阅读进度、`books/` 目录缓存、`cache/` 页面缓存、`cookies.json` 登录态。卸载扩展即全部清除,不写系统其它位置。 ## 免责声明 本项目仅作为书源规则解析与编辑器内阅读体验的技术实现示例,供个人学习与研究使用。仓库不提供、不包含任何书源,也不存储任何站点内容;抓取行为请遵守目标网站的访问规则与当地法律法规,勿用于分发、转载或商业用途。 ## 作者 xjq11029 · [Gitee](https://gitee.com/xjq11029/novel) ## License MIT