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

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

最近看社区有格式刷需求,以及自己也有需求,因此开发了格式刷插件: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; }
  • 思源笔记

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

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

    27479 引用 • 115057 回帖
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 更新了该帖

相关帖子

欢迎来到这里!

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

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

    看着很好啊,支持楼主。

    1 回复
  • Achuan-2

    谢谢支持

  • 感谢你对社区的贡献

  • jidenanian

    感谢思源有你,思源未来会越来越好

  • EmptyLight

    给个猜想:行内数学公式的样式主要是用 $$ 包裹构成的,不需要单独设置样式,可以前后添加数学公式的标志转换成数学公式。

    既然有了这个思路,行内代码也是差不多的道理,添加代码的标志(`)包裹起来也可以达到效果。

    思路具体没有测试过,可能需要通过 api 获取当前块内容,添加标志,然后通过 api 写回块。不然可能会有一点保存问题?

    1 回复
  • Achuan-2 via Android

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

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

  • langxin

    这个给力!

  • Zenez

    顶顶

  • RH108

    太强了 👍

  • tenge via Android

    开发大佬,提个 bug,加粗后用格式刷双击给其它内容赋格式,会导致内容缩小右移,且无法选中。

    1 回复
  • winds

    感谢大佬对思源的贡献!

  • Tisamn

    感谢大佬,刚好需要!

  • Floria233 via Android

    期待后续更新,这些 css 以后可以融入到插件吗?因为目前装的 css 已经很多鸟,管理压力有点大鸟

  • Achuan-2

    谢谢反馈,已经修复了。下午就可以在集市更新
    抄了下思源的代码,粘贴过去,竟然能用,真神奇哈哈哈

    1 回复
    1 操作
    Achuan-2 在 2024-10-11 11:23:32 更新了该回帖
  • hefeng

    虽然我不太需要,但还是感谢大佬的贡献

  • SU-Arron

    支持,感谢。

  • zxkmm 1 赞同

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

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

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

  • 赞!~ 楼上的更新也很不错

  • AndyImpossible

    虽然我不太需要,但还是感谢大佬的贡献 👍

  • wenbocn

    请问格式刷启用时能否更改一下鼠标形状来区分,取消右上角的弹窗文字提示?

    1 回复
  • Achuan-2 1 赞同

    启用格式刷,鼠标形状会改变的,之前有点 bug,相关文件没有打包,导致只有我本地能用,你们下载了没有这个功能

    现在已经修复了

    弹窗文字我暂时觉得还是觉得应该启用,提示用户

  • Muu

    image.png

    与这个插件好似有点冲突

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

    image.png

    1 回复
  • Achuan-2 via Android

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

  • xnyshu via macOS

    在思源里实现嵌套表格是完全不可能的吗?

  • tenge via Android

    请问大佬格式刷油漆刷光标怎么关掉呢?您展示中显示的默认光标更简洁美观

请输入回帖内容 ...
Achuan-2
公众号:Achuan 同学 ps:如果有需要使用 GPT5、Gemini 2.5 Pro、Claude 4.0 等模型的朋友,推荐一个第三方 API 网站:https://api.gpt.ge/register?aff=fQIZ,非常好用,按量付费,各个 AI 模型都能使用,使用这个链接注册将获得 $0.3 余额奖励 上海

推荐标签 标签

  • V2Ray
    1 引用 • 15 回帖 • 3 关注
  • Sillot

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

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

    主仓库地址:Hi-Windom/Sillot

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

    注意事项:

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

    Laravel 是一套简洁、优雅的 PHP Web 开发框架。它采用 MVC 设计,是一款崇尚开发效率的全栈框架。

    19 引用 • 23 回帖 • 750 关注
  • 30Seconds

    📙 前端知识精选集,包含 HTML、CSS、JavaScript、React、Node、安全等方面,每天仅需 30 秒。

    • 精选常见面试题,帮助您准备下一次面试
    • 精选常见交互,帮助您拥有简洁酷炫的站点
    • 精选有用的 React 片段,帮助你获取最佳实践
    • 精选常见代码集,帮助您提高打码效率
    • 整理前端界的最新资讯,邀您一同探索新世界
    488 引用 • 384 回帖
  • Spring

    Spring 是一个开源框架,是于 2003 年兴起的一个轻量级的 Java 开发框架,由 Rod Johnson 在其著作《Expert One-On-One J2EE Development and Design》中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 JavaEE 应用程序开发提供集成的框架。

    948 引用 • 1460 回帖
  • 代码片段

    代码片段分为 CSS 与 JS 两种代码,添加在 [设置 - 外观 - 代码片段] 中,这些代码会在思源笔记加载时自动执行,用于改善笔记的样式或功能。

    用户在该标签下分享代码片段时需在帖子标题前添加 [css] [js] 用于区分代码片段类型。

    256 引用 • 1855 回帖
  • 印象笔记
    3 引用 • 21 回帖
  • 心情

    心是产生任何想法的源泉,心本体会陷入到对自己本体不能理解的状态中,因为心能产生任何想法,不能分出对错,不能分出自己。

    59 引用 • 369 回帖
  • 智能合约

    智能合约(Smart contract)是一种旨在以信息化方式传播、验证或执行合同的计算机协议。智能合约允许在没有第三方的情况下进行可信交易,这些交易可追踪且不可逆转。智能合约概念于 1994 年由 Nick Szabo 首次提出。

    1 引用 • 11 回帖
  • Mobi.css

    Mobi.css is a lightweight, flexible CSS framework that focus on mobile.

    1 引用 • 6 回帖 • 781 关注
  • CloudFoundry

    Cloud Foundry 是 VMware 推出的业界第一个开源 PaaS 云平台,它支持多种框架、语言、运行时环境、云平台及应用服务,使开发人员能够在几秒钟内进行应用程序的部署和扩展,无需担心任何基础架构的问题。

    4 引用 • 16 回帖 • 201 关注
  • TGIF

    Thank God It's Friday! 感谢老天,总算到星期五啦!

    293 引用 • 4496 回帖 • 665 关注
  • IPFS

    IPFS(InterPlanetary File System,星际文件系统)是永久的、去中心化保存和共享文件的方法,这是一种内容可寻址、版本化、点对点超媒体的分布式协议。请浏览 IPFS 入门笔记了解更多细节。

    20 引用 • 245 回帖 • 241 关注
  • 一些有用的避坑指南。

    69 引用 • 93 回帖
  • jsoup

    jsoup 是一款 Java 的 HTML 解析器,可直接解析某个 URL 地址、HTML 文本内容。它提供了一套非常省力的 API,可通过 DOM,CSS 以及类似于 jQuery 的操作方法来取出和操作数据。

    6 引用 • 1 回帖 • 512 关注
  • Typecho

    Typecho 是一款博客程序,它在 GPLv2 许可证下发行,基于 PHP 构建,可以运行在各种平台上,支持多种数据库(MySQL、PostgreSQL、SQLite)。

    12 引用 • 67 回帖 • 440 关注
  • Love2D

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

    14 引用 • 53 回帖 • 563 关注
  • 小薇

    小薇是一个用 Java 写的 QQ 聊天机器人 Web 服务,可以用于社群互动。

    由于 Smart QQ 从 2019 年 1 月 1 日起停止服务,所以该项目也已经停止维护了!

    35 引用 • 468 回帖 • 762 关注
  • Git

    Git 是 Linux Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。

    212 引用 • 358 回帖
  • sts
    2 引用 • 2 回帖 • 245 关注
  • Word
    13 引用 • 41 回帖
  • 反馈

    Communication channel for makers and users.

    120 引用 • 906 回帖 • 289 关注
  • SOHO

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

    7 引用 • 55 回帖 • 2 关注
  • OpenResty

    OpenResty 是一个基于 NGINX 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。

    17 引用 • 52 关注
  • IDEA

    IDEA 全称 IntelliJ IDEA,是一款 Java 语言开发的集成环境,在业界被公认为最好的 Java 开发工具之一。IDEA 是 JetBrains 公司的产品,这家公司总部位于捷克共和国的首都布拉格,开发人员以严谨著称的东欧程序员为主。

    181 引用 • 400 回帖 • 3 关注
  • 开源

    Open Source, Open Mind, Open Sight, Open Future!

    415 引用 • 3602 回帖
  • Follow
    4 引用 • 12 回帖 • 14 关注