开源阅读 Legado 安利帖 | 一片痴心俱成灰

开源阅读 Legado 安利帖

2024-12-24 Views 砺石录3083字15 min read

2024 我终于开始用我们匿版坠流行的阅读 app 开源阅读(注:仅支持安卓平台)了。深度体验三个月,写一下使用感想,可当作安利帖观看。

首先区别一下它和其他浏览本地文件的阅读app,在我看来开源阅读不适合纯下载党。

  1. 不支持doc文档(只支持docx)
  2. 没有pdf重排版功能
  3. 自动拆分长章节,打开本地文件每次手动取消非常不爽……

主要阅读pdf本地文档的话更适合用魔改版多看阅读或者静读天下。txt文包下载党则更适合Kindle。

此前也写过,前几年主要在Kindle上读同人,靠同人大大提升了Kindle使用时长。

相关链接:同人女与 Kindle

我现在仍然是以上观点,Kindle非常适合下了文包,用邮箱一口气发送过去。多了个云端储存,大部分格式也都没问题(pdf除外,别为难它)

不过没有现成文包,需要从AO3/支部/lofter自己爬取文档时,再导入Kindle这样实际操作起来也着实不够方便。(尤其是lofter)

这种使用场景,开源阅读就更合适一些。

本质上开源阅读和漫画类阅读器Tachiyomi一样,自身并不提供内容,通过导入各种书源,使用在线网站接口,并且重新排版,适配手机界面阅读。有点类似RSS聚合阅读器。

相关链接:漫画站也能像 RSS 一样整合到一起吗?Tachiyomi 说看看我呢

这里的重排版指的是,包括但不仅限于,

  • 过滤网页内的评论区、本章说、广告等区域
  • 多种关键词格式正则匹配,自动生成目录层级
  • 全文替换,还原和谐屏蔽词
  • 调整分页

也就是说,只要挂载编写好的书源,就可以在开源阅读内实现一站式搜索/浏览榜单/加入书架/阅读/导出备份。无需在多个网页之间反复横跳,也不必下载繁重的各方app,仅通过阅读内置浏览器登陆对应网站,即可实现多站聚合。

人家导入的书源一览

注:在这个页面长按书源登陆对应网站。

例:
在预先导入AO3+lofter+支部等书源的条件下,搜索同一标题,可同时在搜索结果页得到这几个网站内所有符合条件的结果。根据书源编写规则,有的则支持搜索作者名、合集名。

同时,它的离线缓存批量导出功能也非常适合备份同人。在这2024年……(喃喃)

当然不便之处还是有的,比如阅读里无法直接点心/收藏/评论,不过可以在订阅源里实现。

书源替换规则字典等都有大量现成的资源,这里不再赘述。正由于以上功能都完全可由自己编写代码,自由度比较高,愿意折腾你甚至可以给自cp论坛也做一份书源,优化阅读体验,用更舒服的界面显示来浏览帖子。

书源不难找,大站点基本都有人写了,此处分享一下我在原作者基础上修改过的部分。

晋江

channel=noyq

{
  "User-Agent": "Mozilla/5.0 (Linux; Android 11; Pixel 5 Build/RQ3A.210805.001) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.5993.90 Mobile Safari/537.36"
}

AO3

  • 原tag没有显示是否完结、分级。在搜索标签页下的分类规则

直接匹配正则好像会让搜索有点问题懒得想了就用gay域名写了一部分功能,如此一来可保留org域名原有功能,然后把这两个放一个分组,用的时候就能一起搜了。
嗯挺好我就那个表情,嘴吹水壶,壶嘴喷射.jpg
我不需要看文档也可以让代码跑起来.jpg

全局搜索这种共通的就不讲了,讲下我修改过的部分。新增了添加到书柜的两种方式。

书源可固定标签
订阅源用于浏览网页、点心、评论,以及添加到书柜

在这个页面长按订阅源登陆对应网站。

订阅源浏览效果

此处使用了潮汐:一個平滑乾淨的Ao3版型主题设置。

从订阅源进入文章详情页,点击右下角按钮,添加到书柜
使用添加网址功能添加到书柜
添加ao3文章地址,数字我打码了
添加到书柜之后的书籍详情页,此处手动更换了封面

另外在详情页点击作者名,可搜索同作者的作品。

书源部分
[
  {
    "bookSourceGroup": "AO3",
    "bookSourceName": "ao3",
    "bookSourceType": 0,
    "bookSourceUrl": "https://archiveofourown.gay/",
    "bookUrlPattern": "",
    "customOrder": 0,
    "enabled": true,
    "enabledCookieJar": true,
    "enabledExplore": true,
    "exploreUrl": "你cp tag最新::tags/【这个地方去地址栏复制你cp的名字】/works?page={{page}}&view_adult=true&work_search%5Bcomplete%5D=&work_search%5Bcrossover%5D=&work_search%5Bdate_from%5D=&work_search%5Bdate_to%5D=&work_search%5Bexcluded_tag_names%5D=&work_search%5Blanguage_id%5D=&work_search%5Bother_tag_names%5D=&work_search%5Bquery%5D=&work_search%5Bsort_column%5D=revised_at&work_search%5Bwords_from%5D=&work_search%5Bwords_to%5D=\n\n你cp tag 按kudos::tags/【这个地方去地址栏复制你cp的名字】/works?page={{page}}&work_search%5Bcomplete%5D=&work_search%5Bcrossover%5D=&work_search%5Bdate_from%5D=&work_search%5Bdate_to%5D=&work_search%5Bexcluded_tag_names%5D=&work_search%5Blanguage_id%5D=&work_search%5Bother_tag_names%5D=&work_search%5Bquery%5D=&work_search%5Bsort_column%5D=kudos_count&work_search%5Bwords_from%5D=&work_search%5Bwords_to%5D=",
    "lastUpdateTime": 1735397918695,
    "loginUrl": "https://archiveofourown.gay/",
    "respondTime": 180000,
    "ruleBookInfo": {
      "author": "class.byline heading@text",
      "intro": "class.summary module@html&&class.notes module@html&&id.work_endnotes@html",
      "kind": "class.tag.a.0@text&&class.chapters@text&&class.language@text##Language:|Chapters:",
      "lastChapter": "class.chapters@text##\\s*",
      "name": "class.title heading@text",
      "tocUrl": "@js:if(result.match(/This work could have adult content/)){result=baseUrl+\"?view_adult=true\"}else{result=baseUrl}\nresult+\",{\\\"webView\\\":true}\"",
      "wordCount": "class.words@text##Words:\\s*|,"
    },
    "ruleContent": {
      "content": "class.ql-author-18308191 ql-size-12@text||class.userstuff@tag.p@textNodes",
      "imageStyle": "0",
      "nextContentUrl": "",
      "replaceRegex": "##<!-- end cache -->"
    },
    "ruleExplore": {},
    "ruleSearch": {
      "author": "h4@tag.a.1@text",
      "bookList": "class.work index group@li",
      "bookUrl": "h4@tag.a.0@href",
      "intro": "class.tags commas@text&&class.summary@text",
      "kind": "class.help symbol question modal.a.0@text&&class.chapters@text&&class.language@text##Language:|Chapters:",
      "lastChapter": "class.chapters@text##\\s*",
      "name": "h4@tag.a.0@text",
      "wordCount": "class.words@text##Words:\\s*|,"
    },
    "ruleToc": {
      "chapterList": "tag.select@option||tag.html",
      "chapterName": "class.title heading@text||text",
      "chapterUrl": "value@js:if(baseUrl.match(/\\d+/)){\nUrl=baseUrl.match(/(.*?\\d+)/)[1];\nresult=Url+\"/chapters/\"+result}else{result=baseUrl};"
    },
    "searchUrl": "/works/search?page={{page}}&utf8=%E2%9C%93&work_search%5Bquery%5D={{key}}",
    "weight": 0
  },
  {
    "bookSourceComment": "官方地址(🛫)\nhttps://archiveofourown.org/",
    "bookSourceGroup": "AO3",
    "bookSourceName": "ao3",
    "bookSourceType": 0,
    "bookSourceUrl": "https://archiveofourown.org/",
    "bookUrlPattern": "(https?://)?(www.)?archiveofourown.org/works/.*",
    "customOrder": 0,
    "enabled": true,
    "enabledCookieJar": false,
    "enabledExplore": true,
    "exploreUrl": "",
    "lastUpdateTime": 1735398104165,
    "loginUrl": "https://archiveofourown.org/",
    "respondTime": 180000,
    "ruleBookInfo": {
      "author": "class.byline heading@text",
      "coverUrl": "",
      "init": "",
      "intro": "class.summary module@html&&class.notes module@html&&id.work_endnotes@html",
      "kind": "class.tag.a.0@text&&class.chapters@text&&class.language@text##Language:|Chapters:",
      "lastChapter": "class.chapters@text##\\s*",
      "name": "class.title heading@text",
      "tocUrl": "@js:if(result.match(/This work could have adult content/)){result=baseUrl+\"?view_adult=true\"}else{result=baseUrl}\nresult+\",{\\\"webView\\\":true}\"",
      "wordCount": "class.words@text##Words:\\s*|,"
    },
    "ruleContent": {
      "content": "class.ql-author-18308191 ql-size-12@text||class.userstuff@tag.p@textNodes",
      "imageStyle": "0",
      "nextContentUrl": "",
      "replaceRegex": "##<!-- end cache -->",
      "sourceRegex": "",
      "webJs": ""
    },
    "ruleExplore": {
      "author": "",
      "bookList": "",
      "bookUrl": "",
      "coverUrl": "",
      "intro": "",
      "kind": "",
      "lastChapter": "",
      "name": "",
      "wordCount": ""
    },
    "ruleSearch": {
      "author": "h4@tag.a.1@text",
      "bookList": "class.work index group@li",
      "bookUrl": "h4@tag.a.0@href",
      "coverUrl": "",
      "intro": "class.tags commas@text&&class.summary@text",
      "kind": "class.help symbol question modal.a.0@text&&class.chapters@text&&class.language@text##Language:|Chapters:",
      "lastChapter": "class.chapters@text##\\s*",
      "name": "h4@tag.a.0@text",
      "wordCount": "class.words@text##Words:\\s*|,"
    },
    "ruleToc": {
      "chapterList": "tag.select@option||tag.html",
      "chapterName": "class.title heading@text||text",
      "chapterUrl": "value@js:if(baseUrl.match(/\\d+/)){\nUrl=baseUrl.match(/(.*?\\d+)/)[1];\nresult=Url+\"/chapters/\"+result}else{result=baseUrl};",
      "isVip": "",
      "nextTocUrl": "",
      "updateTime": ""
    },
    "searchUrl": "/works/search?page={{page}}&utf8=%E2%9C%93&work_search%5Bquery%5D={{key}}",
    "weight": 0
  }
]
订阅源部分
[
  {
    "articleStyle": 0,
    "customOrder": 0,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "header": "{\"User-Agent\"=\"Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Mobile Safari/537.36\"}",
    "injectJs": "if (!/^https:\\/\\/(so\\.toutiao\\.com\\/search\\/?|quark\\.sm\\.cn\\/s|wap\\.sogou\\.com\\/web\\/searchList\\.jsp|m\\.so\\.com\\/s|cn\\.bing\\.com\\/search|www\\.baidu\\.com\\/s)\\?/.test(window.location.href) && !document.getElementById('open-yuedu-bookshelf')) {\n    const btn = document.createElement('div');\n    btn.innerHTML = `<button type=\"button\" id='open-yuedu-bookshelf' style=\"z-index: 9999999999;\n    position: fixed;bottom: 7%;right: 7%;background-color: rgb(255, 153, 0);border-radius: 2px;border: 1px solid rgb(255, 153, 0);color: #fff;\n    font-size:${window.innerWidth/80}vw;font-weight: 400;padding: ${window.innerWidth/400}vw ${window.innerWidth/150}vw;\n    \"onclick=\"window.open('legado://import/addToBookshelf?src=${encodeURIComponent(window.location.href)}','_blank');location.reload();\">加入书架</button>`;\n    document.body.appendChild(btn);\n    }\n    \n    let time,num=0;\n    const herfs = new Map();\n    function onTouchStart(evt) {\n      for (const el of evt.path) {\n        if (el.tagName === \"A\") {\n          if (el.href !== 'javascript:void(0)') {\n            const inner = el.href;\n            herfs.set(el, inner);\n            el.setAttribute('href', 'javascript:void(0)');\n            time = setTimeout(() => {\twindow.open(`legado://import/addToBookshelf?src=${encodeURIComponent(inner)}`, '_blank')\n            }, 600);\n          }\n          break;\n        }\n      }\n    };\nfunction onTouchEnd(evt) {\n      if (time) {\n        clearTimeout(time);\n        time = undefined;\n      }\n\tfor (const el of evt.path) {\n        if (el.tagName === \"A\") {\n          if (el.href === 'javascript:void(0)') {\n            const herf = herfs.get(el);\n            if (herf) {\n              el.setAttribute('href', herf)\n            }\n          }\n          break;\n        }\n    }\n}\n\nfunction addListener(els){\nArray.from(els, (item) => {\n      if (item.getAttribute('add-yuedu-bookshelf') !== 'add-yuedu-bookshelf' && item.innerText && item.href && !/^#|^javascript:/.test(item.href)) {\n        item.setAttribute('add-yuedu-bookshelf', 'add-yuedu-bookshelf');\n        item.addEventListener('touchstart', onTouchStart);\n        item.addEventListener('touchend', onTouchEnd);\n        item.addEventListener('touchcancel', onTouchEnd);\n        item.addEventListener('mousedown', onTouchStart);\n        item.addEventListener('mouseup', onTouchEnd);\n      }\n    });\nnum= els.length;\n}\n\nfunction reAdd(){\n\t\tconst els = document.getElementsByTagName('a');\n\tif(els.length>num)addListener(els);\n}\n\nreAdd();\n\nconst observer = new ResizeObserver(reAdd);\nobserver.observe(document.body);",
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "loginUrl": "https://archiveofourown.org/",
    "singleUrl": true,
    "sourceGroup": "AO3",
    "sourceIcon": "https://archiveofourown.org/images/ao3_logos/logo_42.png",
    "sourceName": "AO3",
    "sourceUrl": "https://archiveofourown.org/",
    "style": ""
  }
]

支部

(\[newpage\])|(?<=[\s ]{0,4})\[chapter:.{1,30}\][  ]{0,4}$

然后记一下比较方便的功能。

订阅源的规则订阅

在这个订阅源的规则订阅录入固定链接,之后即可点击更新书源以及订阅源版本。

记得分类选择书源 https://raw.githubusercontent.com/windyhusky/PixivSource/main/pixiv.json
记得分类选择订阅源 https://raw.githubusercontent.com/windyhusky/PixivSource/main/btsrk.json

另外添加了比较常见的日语词典。

字典

weblio中日/日中

url规则https://cjjc.weblio.jp/content/{{key}}
显示规则
id.main@html

kotobank

url规则
https://kotobank.jp/word/{{key}}
显示规则
id.mainArea@html

此举可以完美绕过kotobank“您屏蔽了本站广告”的干扰提示
EOF