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

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

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

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

    22926 引用 • 92175 回帖 • 1 关注
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

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

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

  • Floria233

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

  • EmptyLight

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

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

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

    1 回复
  • 查看全部回帖
Achuan-2
给时间以生命而不是给生命以时间,如果你喜欢我的分享,欢迎给我买杯咖啡 https://www.yuque.com/achuan-2 上海

推荐标签 标签

  • Laravel

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

    20 引用 • 23 回帖 • 726 关注
  • GraphQL

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

    4 引用 • 3 回帖 • 7 关注
  • 机器学习

    机器学习(Machine Learning)是一门多领域交叉学科,涉及概率论、统计学、逼近论、凸分析、算法复杂度理论等多门学科。专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能。

    83 引用 • 37 回帖
  • SOHO

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

    7 引用 • 55 回帖 • 5 关注
  • Latke

    Latke 是一款以 JSON 为主的 Java Web 框架。

    71 引用 • 535 回帖 • 789 关注
  • Dubbo

    Dubbo 是一个分布式服务框架,致力于提供高性能和透明化的 RPC 远程服务调用方案,是 [阿里巴巴] SOA 服务化治理方案的核心框架,每天为 2,000+ 个服务提供 3,000,000,000+ 次访问量支持,并被广泛应用于阿里巴巴集团的各成员站点。

    60 引用 • 82 回帖 • 604 关注
  • 负能量

    上帝为你关上了一扇门,然后就去睡觉了....努力不一定能成功,但不努力一定很轻松 (° ー °〃)

    88 引用 • 1235 回帖 • 412 关注
  • 单点登录

    单点登录(Single Sign On)是目前比较流行的企业业务整合的解决方案之一。SSO 的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。

    9 引用 • 25 回帖 • 1 关注
  • 钉钉

    钉钉,专为中国企业打造的免费沟通协同多端平台, 阿里巴巴出品。

    15 引用 • 67 回帖 • 335 关注
  • Hadoop

    Hadoop 是由 Apache 基金会所开发的一个分布式系统基础架构。用户可以在不了解分布式底层细节的情况下,开发分布式程序。充分利用集群的威力进行高速运算和存储。

    86 引用 • 122 回帖 • 626 关注
  • Shell

    Shell 脚本与 Windows/Dos 下的批处理相似,也就是用各类命令预先放入到一个文件中,方便一次性执行的一个程序文件,主要是方便管理员进行设置或者管理用的。但是它比 Windows 下的批处理更强大,比用其他编程程序编辑的程序效率更高,因为它使用了 Linux/Unix 下的命令。

    123 引用 • 74 回帖
  • WordPress

    WordPress 是一个使用 PHP 语言开发的博客平台,用户可以在支持 PHP 和 MySQL 数据库的服务器上架设自己的博客。也可以把 WordPress 当作一个内容管理系统(CMS)来使用。WordPress 是一个免费的开源项目,在 GNU 通用公共许可证(GPLv2)下授权发布。

    66 引用 • 114 回帖 • 225 关注
  • Swift

    Swift 是苹果于 2014 年 WWDC(苹果开发者大会)发布的开发语言,可与 Objective-C 共同运行于 Mac OS 和 iOS 平台,用于搭建基于苹果平台的应用程序。

    36 引用 • 37 回帖 • 534 关注
  • 工具

    子曰:“工欲善其事,必先利其器。”

    288 引用 • 734 回帖 • 1 关注
  • ZooKeeper

    ZooKeeper 是一个分布式的,开放源码的分布式应用程序协调服务,是 Google 的 Chubby 一个开源的实现,是 Hadoop 和 HBase 的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。

    59 引用 • 29 回帖 • 13 关注
  • 职场

    找到自己的位置,萌新烦恼少。

    127 引用 • 1706 回帖
  • 智能合约

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

    1 引用 • 11 回帖 • 2 关注
  • 支付宝

    支付宝是全球领先的独立第三方支付平台,致力于为广大用户提供安全快速的电子支付/网上支付/安全支付/手机支付体验,及转账收款/水电煤缴费/信用卡还款/AA 收款等生活服务应用。

    29 引用 • 347 回帖 • 2 关注
  • 分享

    有什么新发现就分享给大家吧!

    248 引用 • 1795 回帖
  • 微服务

    微服务架构是一种架构模式,它提倡将单一应用划分成一组小的服务。服务之间互相协调,互相配合,为用户提供最终价值。每个服务运行在独立的进程中。服务于服务之间才用轻量级的通信机制互相沟通。每个服务都围绕着具体业务构建,能够被独立的部署。

    96 引用 • 155 回帖
  • jQuery

    jQuery 是一套跨浏览器的 JavaScript 库,强化 HTML 与 JavaScript 之间的操作。由 John Resig 在 2006 年 1 月的 BarCamp NYC 上释出第一个版本。全球约有 28% 的网站使用 jQuery,是非常受欢迎的 JavaScript 库。

    63 引用 • 134 回帖 • 724 关注
  • PWL

    组织简介

    用爱发电 (Programming With Love) 是一个以开源精神为核心的民间开源爱好者技术组织,“用爱发电”象征开源与贡献精神,加入组织,代表你将遵守组织的“个人开源爱好者”的各项条款。申请加入:用爱发电组织邀请帖
    用爱发电组织官网:https://programmingwithlove.stackoverflow.wiki/

    用爱发电组织的核心驱动力:

    • 遵守开源守则,体现开源&贡献精神:以分享为目的,拒绝非法牟利。
    • 自我保护:使用适当的 License 保护自己的原创作品。
    • 尊重他人:不以各种理由、各种漏洞进行未经允许的抄袭、散播、洩露;以礼相待,尊重所有对社区做出贡献的开发者;通过他人的分享习得知识,要留下足迹,表示感谢。
    • 热爱编程、热爱学习:加入组织,热爱编程是首当其要的。我们欢迎热爱讨论、分享、提问的朋友,也同样欢迎默默成就的朋友。
    • 倾听:正确并恳切对待、处理问题与建议,及时修复开源项目的 Bug ,及时与反馈者沟通。不抬杠、不无视、不辱骂。
    • 平视:不诋毁、轻视、嘲讽其他开发者,主动提出建议、施以帮助,以和谐为本。只要他人肯努力,你也可能会被昔日小看的人所超越,所以请保持谦虚。
    • 乐观且活跃:你的努力决定了你的高度。不要放弃,多年后回头俯瞰,才会发现自己已经成就往日所仰望的水平。积极地将项目开源,帮助他人学习、改进,自己也会获得相应的提升、成就与成就感。
    1 引用 • 487 回帖 • 4 关注
  • Sublime

    Sublime Text 是一款可以用来写代码、写文章的文本编辑器。支持代码高亮、自动完成,还支持通过插件进行扩展。

    10 引用 • 5 回帖 • 3 关注
  • CloudFoundry

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

    5 引用 • 18 回帖 • 173 关注
  • LaTeX

    LaTeX(音译“拉泰赫”)是一种基于 ΤΕΧ 的排版系统,由美国计算机学家莱斯利·兰伯特(Leslie Lamport)在 20 世纪 80 年代初期开发,利用这种格式,即使使用者没有排版和程序设计的知识也可以充分发挥由 TeX 所提供的强大功能,能在几天,甚至几小时内生成很多具有书籍质量的印刷品。对于生成复杂表格和数学公式,这一点表现得尤为突出。因此它非常适用于生成高印刷质量的科技和数学类文档。

    12 引用 • 54 回帖 • 48 关注
  • 房星科技

    房星网,我们不和没有钱的程序员谈理想,我们要让程序员又有理想又有钱。我们有雄厚的房地产行业线下资源,遍布昆明全城的 100 家门店、四千地产经纪人是我们坚实的后盾。

    6 引用 • 141 回帖 • 585 关注
  • GitBook

    GitBook 使您的团队可以轻松编写和维护高质量的文档。 分享知识,提高团队的工作效率,让用户满意。

    3 引用 • 8 回帖 • 1 关注