思源笔记插件丨高亮挖空插件

插件地址:Achuan-2/siyuan-plugin-highlight-cloze

🤔 背景

在学习过程中,我们经常会遇到一些需要填空的题目、需要记忆的知识点,为了方便记忆,我们可以使用高亮挖空的方式来标记这些知识点和题目,确认是否自己真的记住了这些内容。

其实 Tsundoku 主题很早是支持高亮挖空的,但是后面由于思源笔记有了插件,就被我砍掉了,一直期待有大佬写一个高亮挖空插件,但是好像一直没看到。

PixPin_2024-11-29_02-06-26

最近要准备博士研究生的英语课程考试,需要背 stock phase,闪卡适合有规律的复习,如果我想随时复习(突击复习)就不是那么方便,于是就迅速写了这样一个高亮挖空插件来帮助我复习。

✨ 功能

  • ✨ 点击顶部的插件按钮,即可隐藏/显示高亮文字。

  • ✨ 高亮挖空模式下,鼠标悬浮挖空文字可显示高亮文字。

  • ✨ 高亮挖空模式下,导出 pdf 能保持高亮挖空样式,这样就能打印挖空的文档来制作题目用于复习和测试。

  • ✨ 支持设置快捷键,默认为空

🎨 自定义 css

插件支持自定义高亮挖空的样式

举例:如果你想要高亮挖空的样式是黑色下划线,可以把设置里的 css 改为下面的内容

/* 高亮挖空的样式 */ .b3-typography mark, .b3-typography span[data-type~=mark], .protyle-wysiwyg mark, .protyle-wysiwyg span[data-type~='mark'] { color: transparent !important; transition: color 0.5s ease-in-out; background: none !important; border-bottom: 2px solid var(--b3-theme-on-background) !important; } /* 悬浮高亮挖空显示文字的样式 */ .b3-typography mark:hover, .b3-typography span[data-type~=mark]:hover, .protyle-wysiwyg mark:hover, .protyle-wysiwyg span[data-type~='mark']:hover { color: var(--b3-protyle-inline-mark-color) !important; transition: color 0.5s ease-in-out; }

如果你只是希望导出 pdf 的挖空样式是黑色下划线,在思源里还是原来的高亮样式,可以单独对 #preview .protyle-wysiwyg span[data-type~='mark']​设置样式

/* 高亮挖空的样式 */ .b3-typography mark, .b3-typography span[data-type~=mark], .protyle-wysiwyg mark, .protyle-wysiwyg span[data-type~='mark'] { color: transparent !important; transition: color 0.5s ease-in-out; } /* 悬浮高亮挖空显示文字的样式 */ .b3-typography mark:hover, .b3-typography span[data-type~=mark]:hover, .protyle-wysiwyg mark:hover, .protyle-wysiwyg span[data-type~='mark']:hover { color: var(--b3-protyle-inline-mark-color) !important; transition: color 0.5s ease-in-out; } /* 导出pdf时高亮挖空的样式 */ #preview .protyle-wysiwyg span[data-type~='mark'] { color: transparent !important; border-bottom: 2px solid var(--b3-theme-on-background); }

❤ 用爱发电

穷苦研究生在读ing,如果喜欢我的插件,欢迎给 GitHub 仓库点 star 和捐赠,这会激励我继续完善此插件和开发新插件。

🔗 参考

📒 开发笔记

添加 icon

icon

// 添加icon this.addIcons(`<symbol id="iconMarkHide" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 160 160"> <path d="M134,100v34H26v-34h-12v46h132v-46h-12Z" style="fill: #212121;"/> <path d="M62,89h36l8,21h14L87,30h-14l-33,80h14s8-21,8-21ZM80,43l14,36h-28l14-36Z" style="fill: #212121;"/> </symbol>`);

添加顶部按钮

学习

  • 发现 this.addTopBar 可以返回一个 topBarElement​,然后 click​函数里是可以直接对 topBarElement​进行样式修改的!
  • 为了点击按钮,就隐藏高亮文字,直接给 body 添加一个属性 custom-highlight-hidden​,css 只对有 custom-highlight-hidden​的 body 进行作用,这样就不用 js 来 querySelectorAll​了!
// 添加顶部栏按钮 const topBarElement = this.addTopBar({ icon: "iconMarkHide", title: this.i18n.hide, position: "right", callback: () => { if (topBarElement.style.backgroundColor === 'transparent' || !topBarElement.style.backgroundColor) { topBarElement.style.backgroundColor = "var(--b3-toolbar-hover)"; document.body.classList.add('custom-highlight-hidden'); topBarElement.setAttribute('aria-label', this.i18n.show); } else { topBarElement.style.backgroundColor = 'transparent'; document.body.classList.remove('custom-highlight-hidden'); topBarElement.setAttribute('aria-label', this.i18n.hide); } } });

如何让导出 pdf 也能用高亮挖空样式

弃用外部 css 方案,直接在 head 添加 style,id 设置为'snippetCSS-Markhide',这样启用高亮挖空模式,导出 pdf 也能用(发现必须要 snippetCSS 开头才行,来模拟代码片段样式)

参考插件开发快速指南 | 思源社区文档

this.styleElement = document.createElement('style'); this.styleElement.id = 'snippetCSS-Markhide'; document.head.appendChild(this.styleElement); ... // Modify top bar callback const topBarElement = this.addTopBar({ icon: "iconMarkHide", title: this.i18n.hide, position: "right", callback: async () => { if (!this.isActive) { topBarElement.style.backgroundColor = "var(--b3-toolbar-hover)"; this.isActive = true; this.styleElement.textContent = this.HIDE_STYLES; topBarElement.setAttribute('aria-label', this.i18n.show); } else { topBarElement.style.backgroundColor = 'transparent'; this.isActive = false; this.styleElement.textContent = ''; topBarElement.setAttribute('aria-label', this.i18n.hide); } } }); }

css 样式

private readonly HIDE_STYLES = `/* 高亮挖空的样式 */ .b3-typography mark, .b3-typography span[data-type~=mark], .protyle-wysiwyg mark, .protyle-wysiwyg span[data-type~='mark'] { color: transparent !important; transition: color 0.5s ease-in-out; } /* 悬浮高亮挖空显示文字的样式 */ .b3-typography mark:hover, .b3-typography span[data-type~=mark]:hover, .protyle-wysiwyg mark:hover, .protyle-wysiwyg span[data-type~='mark']:hover { color: var(--b3-protyle-inline-mark-color) !important; transition: color 0.5s ease-in-out; } `;

如何添加自定义 css 的设置,并在设置保存时就刷新 css

方案:

  • 添加设置:用 SettingUtils 添加 textarea,考虑到 css 很多行,修改默认的 rows=20,这样能完全显示 css 内容
  • 设置保存时就刷新 css:添加 callback,保存时,调用 this.updateCSS
updateCSS(css: string) { if (this.isActive) { this.styleElement.textContent = css; } } ··· async onload() { this.settingUtils = new SettingUtils({ plugin: this, name: STORAGE_NAME, }); this.settingUtils.addItem({ key: "css", value: this.HIDE_STYLES, type: "textarea", title: this.i18n.settings.css.title, description: this.i18n.settings.css.description, action: { callback: () => { const newCSS = this.settingUtils.take('css'); if (newCSS) { this.updateCSS(newCSS); } } } }); }

设置添加一个重置按钮,可以重置修改的 css

创建默认设置变量

export default class MarkHide extends Plugin { private readonly HIDE_STYLES = `/* 高亮挖空的样式 */ .b3-typography mark, .b3-typography span[data-type~=mark], .protyle-wysiwyg mark, .protyle-wysiwyg span[data-type~='mark'] { color: transparent !important; transition: color 0.5s ease-in-out; } /* 悬浮高亮挖空显示文字的样式 */ .b3-typography mark:hover, .b3-typography span[data-type~=mark]:hover, .protyle-wysiwyg mark:hover, .protyle-wysiwyg span[data-type~='mark']:hover { color: var(--b3-protyle-inline-mark-color) !important; transition: color 0.5s ease-in-out; } `; private getDefaultSettings() { return { css: this.HIDE_STYLES, }; } }

添加一个重置按钮

async onload() { // Reset Settings Button this.settingUtils.addItem({ key: "resetConfig", value: "", type: "button", title: this.i18n.settings.reset?.title || "Reset Settings", description: this.i18n.settings.reset?.description || "Reset all settings to default values", button: { label: this.i18n.settings.reset?.label || "Reset", callback: async () => { const defaultSettings = this.getDefaultSettings(); // Update each setting item's value and UI element 只是UI改了,json的值没有改,所以不点击保存可以反悔 for (const [key, value] of Object.entries(defaultSettings)) { await this.settingUtils.set(key, ''); // 等0.2秒,有一个刷新效果 await new Promise((resolve) => setTimeout(resolve, 200)); await this.settingUtils.set(key, value); } } } }); }

  • 思源笔记

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

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

    25295 引用 • 104414 回帖
4 操作
Achuan-2 在 2024-11-29 21:42:45 更新了该帖
Achuan-2 在 2024-11-29 16:54:33 更新了该帖
Achuan-2 在 2024-11-29 16:39:27 更新了该帖
Achuan-2 在 2024-11-29 16:39:10 更新了该帖

相关帖子

欢迎来到这里!

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

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