思源笔记格式刷插件开发笔记

本贴最后更新于 233 天前,其中的信息可能已经物是人非

最近看社区有格式刷需求,以及自己也有需求,因此开发了格式刷插件:Achuan-2/siyuan-plugin-formatPainter: Use the format painter to batch apply styles (github.com)

觉得好用的欢迎点个 star

思源笔记格式刷插件.gif

自己没正经学过 js,很大部分靠 GPT 实现的代码

下面整理下自己的开发笔记,欢迎大家互相交流学习

开发笔记

  • ❓ 如何设置选中内容的样式 protyle.toolbar.setInlineMark

    • 设置行内块样式
      // datatype:"kbd", "text", "strong", "em", "u", "s", "mark", "sup", "sub", "code" this.protyle.toolbar.setInlineMark(this.protyle, datatype, "range");
    • 设置背景颜色
      this.protyle.toolbar.setInlineMark(this.protyle, "text", "range", { "type": "backgroundColor", "color": backgroundColor });
    • 设置字体颜色
      this.protyle.toolbar.setInlineMark(this.protyle, "text", "range", { "type": "color", "color": color });
    • 设置字体大小
      this.protyle.toolbar.setInlineMark(this.protyle, "text", "range", { "type": "fontSize", "color": fontSize });
    • 输入 style,如何自动设置背景色、字体色、字体大小
      const { backgroundColor, color, fontSize } = parseStyle(this.formatData.style); // console.log(backgroundColor, color, fontSize); if (backgroundColor) { this.protyle.toolbar.setInlineMark(this.protyle, "text", "range", { "type": "backgroundColor", "color": backgroundColor }); } if (color) { this.protyle.toolbar.setInlineMark(this.protyle, "text", "range", { "type": "color", "color": color }); } if (fontSize) { this.protyle.toolbar.setInlineMark(this.protyle, "text", "range", { "type": "fontSize", "color": fontSize }); } } function parseStyle(styleString) { const styles = styleString.split(';').filter(s => s.trim() !== ''); const styleObject = {}; styles.forEach(style => { const [property, value] = style.split(':').map(s => s.trim()); styleObject[property] = value; }); return { backgroundColor: styleObject['background-color'], color: styleObject['color'], fontSize: styleObject['font-size'] }; }
  • ❓ 如何获取选中文本的样式,并且如果返回的节点是 span,则提取出其 data-type 和 style 内容

    对数学公式块做了特别处理,因为数学公式块的的 range.startContainer 是它前面的节点而不是它自己,会导致获取节点错误。

    function getSelectedParentHtml() { const selection = window.getSelection(); if (selection.rangeCount > 0) { const range = selection.getRangeAt(0); let selectedNode = range.startContainer; const endNode = range.endContainer; // 检查 endNode 的 previousSibling if (endNode.previousSibling && endNode.previousSibling.nodeType === Node.ELEMENT_NODE) { const previousSibling = endNode.previousSibling; if (previousSibling.tagName.toLowerCase() === "span" && previousSibling.classList.contains("render-node")) { selectedNode = previousSibling; } } let parentElement = selectedNode.nodeType === Node.TEXT_NODE ? selectedNode.parentNode : selectedNode; while (parentElement && !parentElement.hasAttribute("data-type")) { parentElement = parentElement.parentElement; } if (parentElement && parentElement.tagName.toLowerCase() === "span") { const result = { html: parentElement.outerHTML, datatype: parentElement.getAttribute("data-type"), style: parentElement.getAttribute("style") }; // 清空选区 selection.removeAllRanges(); return result; } } // 清空选区 selection.removeAllRanges(); return null; }
  • ❓ 设置格式刷模式

    • 设置格式刷模式变量:搞一个变量 FormatPainterEnable,默认为 false,点击时如果为 false,则获取选中文本的其 data-subtype 和 style 内容,FormatPainterEnable=true。
    • 之后选中文本并抬起鼠标后进行格式刷操作:监听 mouseup 和 window.getSelection();
    • 按 esc 键,退出格式刷模式,设置 FormatPainterEnable=false:监听 esc 键按下,如果 FormatPainterEnable=true 则设置为 false;
  • ❓ 如何进入格式刷和退出格式刷模式推送信息

    import { fetchPost, } from "siyuan"; // 进入格式刷模式 fetchPost("/api/notification/pushErrMsg", { "msg": this.i18n.enable, "timeout": 7000 }); // 退出格式刷模式 fetchPost("/api/notification/pushMsg", { "msg": this.i18n.disable, "timeout": 7000 });
  • ❓ 点击格式刷,如何关闭工具栏?

    // 关闭toolbar // 选择所有具有 .protyle-toolbar 类的元素 const toolbarElements = document.querySelectorAll('.protyle-toolbar'); // 遍历选中的元素 toolbarElements.forEach(element => { // 检查元素是否没有 .fn__none 类 if (!element.classList.contains('fn__none')) { // 如果没有 .fn__none 类,则添加它 element.classList.add('fn__none'); } });
  • ❓ 如何修改光标
    用 css 修改,因为 js 修改如果新打开窗口,就不方便再修改了

    • 启动格式刷时,给 body 添加自定义属性 formatPainterEnable=true, 通过 css 更改光标
    • 禁用格式刷,给 body 添加自定义属性 formatPainterEnable=false,通过 css 改回光标
    body[data-format-painter-enable="true"] .protyle-wysiwyg { cursor: url("plugins/siyuan-plugin-formatPainter/assets/formatPainter_mouse2.png"), auto; } body[data-format-painter-enable="false"] .protyle-wysiwyg { cursor: auto; }
  • 思源笔记

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

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

    25753 引用 • 106573 回帖
3 操作
Achuan-2 在 2024-10-11 13:40:40 更新了该帖
Achuan-2 在 2024-10-11 11:26:05 更新了该帖
Achuan-2 在 2024-10-11 11:17:39 更新了该帖

相关帖子

欢迎来到这里!

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

注册 关于
请输入回帖内容 ...
  • Achuan-2 via Android

    目前是可以设置数学公式样式,但问题是我不知道当前选中的内容是不是数学公式

    我目前的方式获取当前选中文字的父块,但对于行内数学公式,得到的块却是前面的行内块,而不是它的父块

  • 其他回帖
  • Achuan-2 via Android

    自己写的加脚注插件,用块引实现,把生成的脚注统一放在一个文档里,没上集市,和集市的备注增强插件差不多,根据我需要自定义样式和存放位置

  • zxkmm 1 赞同

    感谢 Achuan 佬。已点星星。写了一个 PR, 求合并:

    • 添加一个指示图案,当格式刷启动时候,dock 栏的指示图案渐变闪烁
    • 点击指示图案关闭格式刷
    • gitignore 添加 pnpm lock 文件

    Pull Request #1 · Achuan-2/siyuan-plugin-formatPainter

  • 大佬,这个评论按钮是什么插件?

    image.png

    1 回复
  • 查看全部回帖

推荐标签 标签

  • 链书

    链书(Chainbook)是 B3log 开源社区提供的区块链纸质书交易平台,通过 B3T 实现共享激励与价值链。可将你的闲置书籍上架到链书,我们共同构建这个全新的交易平台,让闲置书籍继续发挥它的价值。

    链书社

    链书目前已经下线,也许以后还有计划重制上线。

    14 引用 • 257 回帖 • 3 关注
  • 一些有用的避坑指南。

    69 引用 • 93 回帖
  • Hexo

    Hexo 是一款快速、简洁且高效的博客框架,使用 Node.js 编写。

    22 引用 • 148 回帖 • 9 关注
  • 快应用

    快应用 是基于手机硬件平台的新型应用形态;标准是由主流手机厂商组成的快应用联盟联合制定;快应用标准的诞生将在研发接口、能力接入、开发者服务等层面建设标准平台;以平台化的生态模式对个人开发者和企业开发者全品类开放。

    15 引用 • 127 回帖 • 1 关注
  • Q&A

    提问之前请先看《提问的智慧》,好的问题比好的答案更有价值。

    9869 引用 • 44854 回帖 • 77 关注
  • 正则表达式

    正则表达式(Regular Expression)使用单个字符串来描述、匹配一系列遵循某个句法规则的字符串。

    31 引用 • 94 回帖 • 1 关注
  • Log4j

    Log4j 是 Apache 开源的一款使用广泛的 Java 日志组件。

    20 引用 • 18 回帖 • 34 关注
  • Flutter

    Flutter 是谷歌的移动 UI 框架,可以快速在 iOS 和 Android 上构建高质量的原生用户界面。 Flutter 可以与现有的代码一起工作,它正在被越来越多的开发者和组织使用,并且 Flutter 是完全免费、开源的。

    39 引用 • 92 回帖 • 4 关注
  • 架构

    我们平时所说的“架构”主要是指软件架构,这是有关软件整体结构与组件的抽象描述,用于指导软件系统各个方面的设计。另外还有“业务架构”、“网络架构”、“硬件架构”等细分领域。

    142 引用 • 442 回帖
  • Love2D

    Love2D 是一个开源的, 跨平台的 2D 游戏引擎。使用纯 Lua 脚本来进行游戏开发。目前支持的平台有 Windows, Mac OS X, Linux, Android 和 iOS。

    14 引用 • 53 回帖 • 555 关注
  • 音乐

    你听到信仰的声音了么?

    62 引用 • 512 回帖 • 2 关注
  • Jenkins

    Jenkins 是一套开源的持续集成工具。它提供了非常丰富的插件,让构建、部署、自动化集成项目变得简单易用。

    54 引用 • 37 回帖 • 1 关注
  • 资讯

    资讯是用户因为及时地获得它并利用它而能够在相对短的时间内给自己带来价值的信息,资讯有时效性和地域性。

    56 引用 • 85 回帖 • 1 关注
  • Caddy

    Caddy 是一款默认自动启用 HTTPS 的 HTTP/2 Web 服务器。

    10 引用 • 54 回帖 • 176 关注
  • Lute

    Lute 是一款结构化的 Markdown 引擎,支持 Go 和 JavaScript。

    29 引用 • 202 回帖 • 27 关注
  • CentOS

    CentOS(Community Enterprise Operating System)是 Linux 发行版之一,它是来自于 Red Hat Enterprise Linux 依照开放源代码规定释出的源代码所编译而成。由于出自同样的源代码,因此有些要求高度稳定的服务器以 CentOS 替代商业版的 Red Hat Enterprise Linux 使用。两者的不同在于 CentOS 并不包含封闭源代码软件。

    240 引用 • 224 回帖
  • Bug

    Bug 本意是指臭虫、缺陷、损坏、犯贫、窃听器、小虫等。现在人们把在程序中一些缺陷或问题统称为 bug(漏洞)。

    76 引用 • 1742 回帖 • 6 关注
  • Vditor

    Vditor 是一款浏览器端的 Markdown 编辑器,支持所见即所得、即时渲染(类似 Typora)和分屏预览模式。它使用 TypeScript 实现,支持原生 JavaScript、Vue、React 和 Angular。

    371 引用 • 1854 回帖 • 2 关注
  • 前端

    前端技术一般分为前端设计和前端开发,前端设计可以理解为网站的视觉设计,前端开发则是网站的前台代码实现,包括 HTML、CSS 以及 JavaScript 等。

    246 引用 • 1338 回帖
  • GraphQL

    GraphQL 是一个用于 API 的查询语言,是一个使用基于类型系统来执行查询的服务端运行时(类型系统由你的数据定义)。GraphQL 并没有和任何特定数据库或者存储引擎绑定,而是依靠你现有的代码和数据支撑。

    4 引用 • 3 回帖 • 13 关注
  • SOHO

    为成为自由职业者在家办公而努力吧!

    7 引用 • 55 回帖
  • JavaScript

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

    730 引用 • 1281 回帖 • 1 关注
  • PostgreSQL

    PostgreSQL 是一款功能强大的企业级数据库系统,在 BSD 开源许可证下发布。

    22 引用 • 22 回帖 • 1 关注
  • V2Ray
    1 引用 • 15 回帖 • 2 关注
  • 笔记

    好记性不如烂笔头。

    310 引用 • 794 回帖 • 2 关注
  • Telegram

    Telegram 是一个非盈利性、基于云端的即时消息服务。它提供了支持各大操作系统平台的开源的客户端,也提供了很多强大的 APIs 给开发者创建自己的客户端和机器人。

    5 引用 • 35 回帖 • 1 关注
  • 浅吟主题

    Jeffrey Chen 制作的思源笔记主题,项目仓库:https://github.com/TCOTC/Whisper

    1 引用 • 28 回帖 • 1 关注