8 层功力的 remnote 制卡 并多多一键制卡更新,支持列表项制卡,增加一键移除

本贴最后更新于 870 天前,其中的信息可能已经事过境迁

需要了解是什么参见并夕夕版 文档树制卡 v0.5 支持直接获取路径和分屏,演示见下:

一键添加和移除.gif

列表项制卡的符号参考了 remnote,也就是》》和 >>。要是有什么容易打出来也不大可能有其他用途、而且好看的符号也可以提,当然更欢迎自行添加。

另外,由于接口的限制,暂时没办法移除使用快捷键添加的卡片——因为获取不到 ALL 卡包。

喜欢的话留个言,也让我知道除我以外还有人用。

// 一键移除卡片 v0.1 // 请求函数 // 使用匿名函数,防止污染空间 (() => { function request(url, data = null, method = "POST") { return new Promise((resolve, reject) => { if (method.toUpperCase() == "POST") { fetch(url, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(data), }) .then( (data) => resolve(data.json()), (error) => { reject(error); } ) .catch((err) => { console.error("请求失败:", err); }); } }); } // 弹出提示信息 async function showMessage(msg) { await request("/api/notification/pushMsg", { msg, timeout: 3000 }); } function getCurrentPage() { //获取当前屏幕 const currentScreen = document.querySelector(".layout__wnd--active"); //获取当前页面 const currentPage = currentScreen.querySelector( ".fn__flex-1.protyle:not(.fn__none)" ); return currentPage; } //传入 node节点列表 arr和数据抽取函数 fliter。 // fliter 传入一个节点,返回一个字典 // 字典格式: // {status,data} // status 为 ok,则代表为抽取成功,将data压入返回列表anwer,并最后返回。 function iterArr(arr, fliter) { if (!arr && arr.length <= 0) { return []; } length = arr.length; anwer = []; for (let node of arr) { data = fliter(node); if (data["status"] === "ok" && data["data"]) { anwer.push(data["data"]); } } return anwer; } function fliterBlockCard(node) { return { status: "ok", data: node.getAttribute("data-node-id") } } async function removeCards() { //获取全部deck let res = await request("/api/riff/getRiffDecks", {}); //获取deck.id let customDeckIdArr = []; Array.from(res.data).forEach((item) => { customDeckIdArr.push(item.id); }) if (customDeckIdArr.length === 0) { showMessage(`未能获取到卡包`); return; } // 获取需要被制成卡片的块的ID const currentPage = getCurrentPage() //已制卡块 const cardedBlockList = currentPage.querySelectorAll(".protyle-wysiwyg [data-node-id][custom-riff-decks]") let arr = []; var cardedBlockIdList = iterArr(cardedBlockList, fliterBlockCard) arr = arr.concat(cardedBlockIdList) if (arr.length === 0) { showMessage(`未能获取到页面的卡片`); return; } // 去重 arr = [... new Set(arr)]; for (deckIndex in customDeckIdArr) { // 把标记所在块全部制成卡片 let body = { deckID: customDeckIdArr[deckIndex], blockIDs: arr, }; let res = await request("/api/riff/removeRiffCards", body); if (res.code === 0) { showMessage(`${res.data.name}卡包的总卡片数:${res.data.size}`); } } } const barMode = document.getElementById("barMode"); barMode.insertAdjacentHTML( "beforebegin", '<div id="removeCards" class="toolbar__item b3-tooltips b3-tooltips__se" aria-label="移除卡片" ></div>' ); const removeCardsBtn = document.getElementById("removeCards"); removeCardsBtn.style.width = "auto"; const removeCardsBtnIcon = `<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 96 960 960" width="48"><path d="M600 826v-60h145v60H600Zm0-368v-60h280v60H600Zm0 184v-60h235v60H600ZM125 381H80v-60h170v-45h135v45h170v60h-45v415q0 24-18 42t-42 18H185q-24 0-42-18t-18-42V381Zm60 0v415h265V381H185Zm0 0v415-415Z"/></svg>`; removeCardsBtn.innerHTML = removeCardsBtnIcon; removeCardsBtn.addEventListener( "click", (e) => { removeCards(); e.stopPropagation(); e.preventDefault(); }, true ); })();
// 一键制卡 v0.6 // 请求函数 // 使用匿名函数,防止污染空间 (() => { function request(url, data = null, method = "POST") { return new Promise((resolve, reject) => { if (method.toUpperCase() == "POST") { fetch(url, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(data), }) .then( (data) => resolve(data.json()), (error) => { reject(error); } ) .catch((err) => { console.error("请求失败:", err); }); } }); } // 弹出提示信息 async function showMessage(msg) { await request("/api/notification/pushMsg", { msg, timeout: 3000 }); } // 获取当前文档id function getFileID() { //获取当前页面 const currentPage = getCurrentPage(); //获取当前页面id const currentPageID = currentPage.querySelector( "span.protyle-breadcrumb__item--active" ).getAttribute("data-node-id"); return currentPageID; } function getCurrentPage() { //获取当前屏幕 const currentScreen = document.querySelector(".layout__wnd--active"); //获取当前页面 const currentPage = currentScreen.querySelector( ".fn__flex-1.protyle:not(.fn__none)" ); return currentPage; } //传入 node节点列表 arr和数据抽取函数 fliter。 // fliter 传入一个节点,返回一个字典 // 字典格式: // {status,data} // status 为 ok,则代表为抽取成功,将data压入返回列表anwer,并最后返回。 function iterArr(arr, fliter) { if (!arr && arr.length <= 0) { return []; } length = arr.length; anwer = []; for (let node of arr) { data = fliter(node); if (data["status"] === "ok" && data["data"]) { anwer.push(data["data"]); } } return anwer; } // 传入列表下的段落,返回被标记段落的父节点:列表项的id function fliterListCard(node) { var re = /(>>|(》》))\s?\u200b?$/; if (re.test(node.innerText)) { return { status: "ok", data: node.parentElement.getAttribute("data-node-id") } } return { status: "no", data: null }; } function fliterMarkCard(node) { return { status: "ok", data: node.parentElement.parentElement.getAttribute("data-node-id") } } function fliterSuperBlockCard(node) { return { status: "ok", data: node.getAttribute("data-node-id") } } // 获取当前文档路径 async function getHpath() { currentPageID = getFileID() body = { "id": currentPageID } let res = await request("/api/filetree/getHPathByID", body); //检测返回值 if (res.code === 0) { let currentPagePath = res.data; return currentPagePath; } return null; } // 添加多个卡片 async function addCards() { //获取全部deck let res = await request("/api/riff/getRiffDecks", {}); //获取当前打开文档的路径 focusItemPath = await getHpath() if (focusItemPath === null) { showMessage(`未能当前文档读取路径`); return; } //获取deck.id, 其deck.name 包含在 focusItemPath 中 let customDeckIdArr = []; Array.from(res.data).forEach((item) => { let name = item.name; if (focusItemPath.search(name) != -1) { customDeckIdArr.push(item.id); } }) if (customDeckIdArr.length === 0) { showMessage(`未能获取到:${focusItemPath} 的卡包`); return; } // 获取需要被制成卡片的块的ID const currentPage = getCurrentPage() //标记块 const markList = currentPage.querySelectorAll("span[data-type='mark']") //超级块 const superBlockList = currentPage.querySelectorAll("div[class='sb']") //列表块 const listList = currentPage.querySelectorAll("div[class='li']:has(div[class='li']) > div[class = 'p']") let arr = []; var markCardList = iterArr(markList, fliterMarkCard) var superBlockCardList = iterArr(superBlockList, fliterSuperBlockCard) var listCardList = iterArr(listList, fliterListCard) arr = arr.concat(markCardList, superBlockCardList, listCardList) if (arr.length === 0) { showMessage(`未能获取到:${focusItemPath} 页面的卡片`); return; } // 去重 arr = [... new Set(arr)]; for (deckIndex in customDeckIdArr) { // 把标记所在块全部制成卡片 let body = { deckID: customDeckIdArr[deckIndex], blockIDs: arr, }; let res = await request("/api/riff/addRiffCards", body); if (res.code === 0) { showMessage(`${res.data.name}卡包的总卡片数:${res.data.size}`); } } } // 添加一个按钮 const barMode = document.getElementById("barMode"); barMode.insertAdjacentHTML( "beforebegin", '<div id="addCards" class="toolbar__item b3-tooltips b3-tooltips__se" aria-label="制作卡片" ></div>' ); const addCardsBtn = document.getElementById("addCards"); addCardsBtn.style.width = "auto"; const addCardsBtnIcon = `<svg t="1674130669751" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4526" width="200" height="200"><path d="M928 160H96a32 32 0 0 0-32 32v672a32 32 0 0 0 32 32h832a32 32 0 0 0 32-32V192a32 32 0 0 0-32-32z m-32 672H128V224h768v608z" p-id="4527" fill="#9aa0a6"></path><path d="M230.592 448.096H544a32 32 0 1 0 0-64H230.592a32 32 0 0 0 0 64zM230.592 640.096H544a32 32 0 1 0 0-64H230.592a32 32 0 1 0 0 64zM768 704a32 32 0 0 0 32-32V350.016a32 32 0 1 0-64 0V672a32 32 0 0 0 32 32z" p-id="4528" fill="#9aa0a6"></path></svg>`; addCardsBtn.innerHTML = addCardsBtnIcon; addCardsBtn.addEventListener( "click", (e) => { addCards(); e.stopPropagation(); e.preventDefault(); }, true ); })();
  • 思源笔记

    思源笔记是一款隐私优先的个人知识管理系统,支持完全离线使用,同时也支持端到端加密同步。

    融合块、大纲和双向链接,重构你的思维。

    26399 引用 • 109779 回帖 • 2 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • Hibernate

    Hibernate 是一个开放源代码的对象关系映射框架,它对 JDBC 进行了非常轻量级的对象封装,使得 Java 程序员可以随心所欲的使用对象编程思维来操纵数据库。

    39 引用 • 103 回帖 • 726 关注
  • 旅游

    希望你我能在旅途中找到人生的下一站。

    100 引用 • 905 回帖
  • 服务器

    服务器,也称伺服器,是提供计算服务的设备。由于服务器需要响应服务请求,并进行处理,因此一般来说服务器应具备承担服务并且保障服务的能力。

    125 引用 • 585 回帖 • 1 关注
  • Elasticsearch

    Elasticsearch 是一个基于 Lucene 的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于 RESTful 接口。Elasticsearch 是用 Java 开发的,并作为 Apache 许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。

    117 引用 • 99 回帖 • 199 关注
  • Oracle

    Oracle(甲骨文)公司,全称甲骨文股份有限公司(甲骨文软件系统有限公司),是全球最大的企业级软件公司,总部位于美国加利福尼亚州的红木滩。1989 年正式进入中国市场。2013 年,甲骨文已超越 IBM,成为继 Microsoft 后全球第二大软件公司。

    107 引用 • 127 回帖 • 344 关注
  • 脑图

    脑图又叫思维导图,是表达发散性思维的有效图形思维工具 ,它简单却又很有效,是一种实用性的思维工具。

    32 引用 • 99 回帖
  • 新人

    让我们欢迎这对新人。哦,不好意思说错了,让我们欢迎这位新人!
    新手上路,请谨慎驾驶!

    52 引用 • 228 回帖
  • Vue.js

    Vue.js(读音 /vju ː/,类似于 view)是一个构建数据驱动的 Web 界面库。Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。

    268 引用 • 666 回帖 • 1 关注
  • SVN

    SVN 是 Subversion 的简称,是一个开放源代码的版本控制系统,相较于 RCS、CVS,它采用了分支管理系统,它的设计目标就是取代 CVS。

    29 引用 • 98 回帖 • 697 关注
  • Google

    Google(Google Inc.,NASDAQ:GOOG)是一家美国上市公司(公有股份公司),于 1998 年 9 月 7 日以私有股份公司的形式创立,设计并管理一个互联网搜索引擎。Google 公司的总部称作“Googleplex”,它位于加利福尼亚山景城。Google 目前被公认为是全球规模最大的搜索引擎,它提供了简单易用的免费服务。不作恶(Don't be evil)是谷歌公司的一项非正式的公司口号。

    49 引用 • 192 回帖
  • 安装

    你若安好,便是晴天。

    132 引用 • 1184 回帖 • 1 关注
  • 笔记

    好记性不如烂笔头。

    311 引用 • 794 回帖
  • Scala

    Scala 是一门多范式的编程语言,集成面向对象编程和函数式编程的各种特性。

    13 引用 • 11 回帖 • 155 关注
  • 生活

    生活是指人类生存过程中的各项活动的总和,范畴较广,一般指为幸福的意义而存在。生活实际上是对人生的一种诠释。生活包括人类在社会中与自己息息相关的日常活动和心理影射。

    230 引用 • 1432 回帖
  • jsDelivr

    jsDelivr 是一个开源的 CDN 服务,可为 npm 包、GitHub 仓库提供免费、快速并且可靠的全球 CDN 加速服务。

    5 引用 • 31 回帖 • 108 关注
  • Sillot

    Insights(注意当前设置 master 为默认分支)

    汐洛彖夲肜矩阵(Sillot T☳Converbenk Matrix),致力于服务智慧新彖乄,具有彖乄驱动、极致优雅、开发者友好的特点。其中汐洛绞架(Sillot-Gibbet)基于自思源笔记(siyuan-note),前身是思源笔记汐洛版(更早是思源笔记汐洛分支),是智慧新录乄终端(多端融合,移动端优先)。

    主仓库地址:Hi-Windom/Sillot

    文档地址:sillot.db.sc.cn

    注意事项:

    1. ⚠️ 汐洛仍在早期开发阶段,尚不稳定
    2. ⚠️ 汐洛并非面向普通用户设计,使用前请了解风险
    3. ⚠️ 汐洛绞架基于思源笔记,开发者尽最大努力与思源笔记保持兼容,但无法实现 100% 兼容
    29 引用 • 25 回帖 • 134 关注
  • SQLServer

    SQL Server 是由 [微软] 开发和推广的关系数据库管理系统(DBMS),它最初是由 微软、Sybase 和 Ashton-Tate 三家公司共同开发的,并于 1988 年推出了第一个 OS/2 版本。

    21 引用 • 31 回帖 • 2 关注
  • QQ

    1999 年 2 月腾讯正式推出“腾讯 QQ”,在线用户由 1999 年的 2 人(马化腾和张志东)到现在已经发展到上亿用户了,在线人数超过一亿,是目前使用最广泛的聊天软件之一。

    45 引用 • 557 回帖
  • 域名

    域名(Domain Name),简称域名、网域,是由一串用点分隔的名字组成的 Internet 上某一台计算机或计算机组的名称,用于在数据传输时标识计算机的电子方位(有时也指地理位置)。

    43 引用 • 208 回帖
  • Ngui

    Ngui 是一个 GUI 的排版显示引擎和跨平台的 GUI 应用程序开发框架,基于
    Node.js / OpenGL。目标是在此基础上开发 GUI 应用程序可拥有开发 WEB 应用般简单与速度同时兼顾 Native 应用程序的性能与体验。

    7 引用 • 9 回帖 • 409 关注
  • 大疆创新

    深圳市大疆创新科技有限公司(DJI-Innovations,简称 DJI),成立于 2006 年,是全球领先的无人飞行器控制系统及无人机解决方案的研发和生产商,客户遍布全球 100 多个国家。通过持续的创新,大疆致力于为无人机工业、行业用户以及专业航拍应用提供性能最强、体验最佳的革命性智能飞控产品和解决方案。

    2 引用 • 14 回帖 • 1 关注
  • V2Ray
    1 引用 • 15 回帖 • 3 关注
  • Access
    1 引用 • 3 回帖
  • TextBundle

    TextBundle 文件格式旨在应用程序之间交换 Markdown 或 Fountain 之类的纯文本文件时,提供更无缝的用户体验。

    1 引用 • 2 回帖 • 81 关注
  • OkHttp

    OkHttp 是一款 HTTP & HTTP/2 客户端库,专为 Android 和 Java 应用打造。

    16 引用 • 6 回帖 • 88 关注
  • JavaScript

    JavaScript 一种动态类型、弱类型、基于原型的直译式脚本语言,内置支持类型。它的解释器被称为 JavaScript 引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在 HTML 网页上使用,用来给 HTML 网页增加动态功能。

    730 引用 • 1283 回帖
  • 书籍

    宋真宗赵恒曾经说过:“书中自有黄金屋,书中自有颜如玉。”

    84 引用 • 414 回帖