From a041d4dcd5c73f6b90e71e17fcde3073aaa520e3 Mon Sep 17 00:00:00 2001 From: obgnail Date: Fri, 3 Jan 2025 17:54:18 +0800 Subject: [PATCH] feat: markmap: add config AUTO_UPDATE --- README.md | 71 ++++----------- plugin/global/settings/settings.default.toml | 5 ++ plugin/markmap/index.js | 92 ++++++++++---------- 3 files changed, 71 insertions(+), 97 deletions(-) diff --git a/README.md b/README.md index 55cba6df..a74572ee 100644 --- a/README.md +++ b/README.md @@ -76,29 +76,29 @@ **尊重用户的一切选择**。本项目的任何插件、任何功能皆可永久启用 / 禁用。 -> 如果有其他需求或发现 BUG,欢迎 [提 issue](https://github.com/obgnail/typora_plugin/issues/new),也欢迎 PR。如果能给我颗 star ⭐ 就更好了 :) +> 如果有其他需求或发现 BUG,欢迎 [提 issue](https://github.com/obgnail/typora_plugin/issues/new),也欢迎 PR。如果觉得本项目对你有帮助,请给我一个 star ⭐ ## 如何使用:Windows/Linux 平台 -前往 [视频版安装教程](https://github.com/obgnail/typora_plugin/issues/847) +前往 [视频安装教程](https://github.com/obgnail/typora_plugin/issues/847) 1. [下载](https://github.com/obgnail/typora_plugin/releases/latest) 插件源码的压缩包,并解压 2. 进入 Typora 安装路径,找到包含 `window.html` 的文件夹 A - - 如果是正式版 Typora,路径为 `./resources/window.html` + - 正式版 Typora,路径为 `./resources/window.html` - - 如果是免费版 Typora,路径为 `./resources/app/window.html` + - 免费版 Typora,路径为 `./resources/app/window.html` 3. 将解压得到的 plugin 文件夹粘贴进文件夹 A 下 4. 进入文件夹 `A/plugin/bin/` - - 如果是 Windows 系统,双击运行 `install_windows_amd_x64.exe`,如果看到下图,说明安装成功 + - Windows 系统:双击运行 `install_windows_amd_x64.exe`,如果看到下图,说明安装成功 - - 如果是 Linux 系统,以管理员运行 `install_linux.sh`,如果看到下图,说明安装成功 + - Linux 系统:以管理员运行 `install_linux.sh`,如果看到下图,说明安装成功 5. 验证:重启 Typora,在正文区域点击鼠标右键,弹出右键菜单栏,如果能看到 `常用插件` 栏目,说明一切顺利 @@ -113,7 +113,7 @@ 附加说明: - Windows 系统也可以通过执行 `install_windows.ps1` 安装插件;同理,Linux 系统也可以执行 `install_linux_amd_x64` 文件 -- 每个插件皆有配置选项。开发者鼓励您修改配置,以符合自身需求。配置文件夹位于 [A/plugin/global/settings/](https://github.com/obgnail/typora_plugin/tree/master/plugin/global/settings) +- 每个插件都有配置选项,建议根据个人需求进行配置。配置文件夹位于 [A/plugin/global/settings/](https://github.com/obgnail/typora_plugin/tree/master/plugin/global/settings) @@ -131,7 +131,7 @@ yay -S typora-plugin ### 我的 Typora 版本能用吗? -所有插件都在 0.9.98 版本(最后一个免费版本)和最新版本测试过。本项目理论上支持所有 Typora 版本,但是 Typora 在 0.9.98 版本以后功能才稳定下来。**0.9.98 版本以下,可能会因为缺少某些功能导致部分插件失效**。 +所有插件都在 0.9.98 版本(最后一个免费版本)和最新版本测试过。本项目理论上支持所有 Typora 版本,但 Typora 在 0.9.98 版本后功能才稳定下来。**0.9.98 之前的版本不推荐使用。** @@ -149,9 +149,9 @@ yay -S typora-plugin ### 如何修改插件配置? -目前整个项目包含 600+ 配置选项,可以比较完整的定义各个插件的行为。 +项目包含 600+ 配置选项,可以比较完整定义各个插件的行为。 -这些配置全部位于 [./plugin/global/settings/](https://github.com/obgnail/typora_plugin/tree/master/plugin/global/settings) 目录中。修改配置的方法请阅读该目录下的 [说明文件](https://github.com/obgnail/typora_plugin/blob/master/plugin/global/settings/%E8%AF%B7%E8%AF%BB%E6%88%91.md)。 +所有配置位于 [settings](https://github.com/obgnail/typora_plugin/tree/master/plugin/global/settings) 目录中。修改配置方法请阅读该目录下的 [说明文件](https://github.com/obgnail/typora_plugin/blob/master/plugin/global/settings/%E8%AF%B7%E8%AF%BB%E6%88%91.md)。 @@ -169,7 +169,7 @@ yay -S typora-plugin ### 支持 Typora for Mac 吗? -没有 Mac,故没做测试。 +没有 Mac 设备,故没做测试。 @@ -178,17 +178,17 @@ yay -S typora-plugin 所有的插件都提供了四种使用方法: - 键盘党: - - 键入 `ctrl+j`,在输入框键入 `plu` 加空格加插件名称调出插件列表(详见 `toolbar` 插件) + - `Ctrl+J` 调出插件列表(详见 `toolbar` 插件) - 快捷键(详见 `hotkeys` 插件) - 鼠标党: - - 在正文区域右键,在弹出的右键菜单中直接调用(详见 `right_click_menu` 插件) + - 在正文区域右键调用(详见 `right_click_menu` 插件) - 快捷按钮(详见 `quickButton` 插件) ### window_tab:标签页管理 -- `切换标签`:标签页处 Ctrl+滚轮滚动、ctrl+shift+tab、ctrl+tab、ctrl+PgUp、ctrl+PgDn +- `切换标签`:Ctrl+滚轮滚动、ctrl+shift+tab、ctrl+tab、ctrl+PgUp、ctrl+PgDn - `关闭标签`:ctrl+w、鼠标中键 - `新窗口打开`:ctrl+单击标签 - `排序标签`:拖拽 @@ -318,8 +318,8 @@ COMMANDS = [ - `cmd/bash`:windows 或 Mac 的默认终端 - `powershell`:微软的傻儿子 :D -- `git bash`:使用此终端前请保证安装了 git bash 并且加入环境变量 -- `wsl`:使用此终端前请保证安装了 wsl2,并且加入环境变量 +- `git bash`:需确保安装并添加到环境变量 +- `wsl`:需确保安装 WSL2 并添加到环境变量 内置环境变量: @@ -331,11 +331,6 @@ COMMANDS = [ ```toml # 默认的内建命令 -# 目前支持4个参数: -# 1. name: 展示的名称(不可重复) -# 2. shell: cmd/bash、powershell、gitbash、wsl -# 3. hotkey: 快捷键(可选) -# 4. cmd: 执行的命令 BUILTIN = [ { name = "", shell = "cmd/bash", cmd = "" }, { name = "Explorer", shell = "powershell", hotkey = "ctrl+alt+e", cmd = "explorer $d" }, @@ -412,44 +407,14 @@ NAME = "少用插件" LIST = [ "window_tab", "fence_enhance", - "auto_number", - "datatables", - "resize_image", - "resize_table", - "collapse_list", - "collapse_table", - "truncate_text", - "export_enhance", - "cipher", - "right_click_menu", - "help", - "---", - "pie_menu", - "go_top", - "text_stylize", - "slash_commands", - "ripgrep", - "article_uploader", - "preferences", - "---", - "file_counter", - "json_rpc", - "test", + ... ] [[right_click_menu.MENUS]] NAME = "常用插件" LIST = [ "commander", "markmap", - "collapse_paragraph", - "easy_modify", - "custom", - "---", - "toolbar", - "search_multi", - "md_padding", - "read_only", - "blur", + ... ] ``` diff --git a/plugin/global/settings/settings.default.toml b/plugin/global/settings/settings.default.toml index c0d544d6..dacfa212 100644 --- a/plugin/global/settings/settings.default.toml +++ b/plugin/global/settings/settings.default.toml @@ -733,6 +733,11 @@ ENABLE_TOC_MARKMAP = true # 留空 "" 表示不设置快捷键 TOC_HOTKEY = "" +# 当大纲发生变化,是否自动更新图形 +# true: 每当大纲发生变化,会自动更新图形 +# false: 当大纲发生变化,不会自动更新图形,图形会一直保持不变 +AUTO_UPDATE = true + # 点击思维导图节点是否跳转到文档对应章节 # true: 点击节点后,页面会滚动到文档中对应的标题位置 # false: 点击节点不会跳转到文档 diff --git a/plugin/markmap/index.js b/plugin/markmap/index.js index b7f4ed9a..f999eaf9 100644 --- a/plugin/markmap/index.js +++ b/plugin/markmap/index.js @@ -481,16 +481,16 @@ class tocMarkmap { const INFO = { color: "如需自定义配色方案,请手动修改 CANDIDATE_COLOR_SCHEMES 选项", maxWidth: "0 表示无长度限制", - FIX_ERROR_LEVEL_HEADER: "修复 MD001 规范。若取消勾选,则会过滤跳级标题", - CLICK_TO_LOCALE: "若取消勾选,则选项「定位的视口高度」失效", + CLICK_TO_LOCALE: "如果取消勾选,则选项「定位的视口高度」失效", LOCALE_HEIGHT_RATIO: "定位的目标章节滚动到当前视口的高度位置(百分比)", + FIX_ERROR_LEVEL_HEADER: "如果取消勾选,则会过滤跳级标题,只显示层级连续的标题", AUTO_COLLAPSE_PARAGRAPH_WHEN_FOLD: "实验性特性,不建议开启。仅当插件「章节折叠」开启时可用", - FOLDER: "若为空或不存在,则使用 TEMP 目录", + FOLDER: "如果为空或不存在,则使用 TEMP 目录", FILENAME: `支持变量:filename、timestamp、random、uuid\n支持后缀:${Downloader.getFormats()[0].extensions.join("、")}`, IMAGE_QUALITY: "仅适用于 jpg、webp 格式", BACKGROUND_COLOR: "仅适用于像素图片格式", KEEP_ALPHA_CHANNEL: "仅适用于携带透明通道的像素图片格式", - REMOVE_FOREIGN_OBJECT: "牺牲样式,提高兼容性。若导出的图片异常,请勾选此选项", + REMOVE_FOREIGN_OBJECT: "牺牲样式,提高兼容性。如果导出的图片异常,请勾选此选项", } const { DEFAULT_TOC_OPTIONS: _tocOps, DOWNLOAD_OPTIONS: _downOps } = this.config const needUpdateKey = ["DEFAULT_TOC_OPTIONS", "DOWNLOAD_OPTIONS"] @@ -503,13 +503,14 @@ class tocMarkmap { needUpdateKey.push(key) } } - const cpn = (label, key) => ({ + const inlineWidget = (label, key) => ({ label, info: INFO[key], + inline: true, value: _getConfig(key), callback: value => _setConfig(key, value), }) - const checkboxCpn = components => ({ + const checkboxWidget = components => ({ type: "checkbox", list: components.map(({ label, key, disabled }) => ({ label, info: INFO[key], value: key, checked: Boolean(_getConfig(key)), disabled })), callback: submit => components.forEach(({ key }) => _setConfig(key, submit.includes(key))), @@ -537,38 +538,39 @@ class tocMarkmap { } const chart = (fieldset = "图形") => [ - { fieldset, type: "range", inline: true, min: 1, max: 6, step: 1, ...cpn("固定配色的分支等级", "colorFreezeLevel") }, - { fieldset, type: "range", inline: true, min: 1, max: 6, step: 1, ...cpn("分支展开等级", "initialExpandLevel") }, - { fieldset, type: "range", inline: true, min: 0, max: 100, step: 1, ...cpn("节点内边距", "paddingX") }, - { fieldset, type: "range", inline: true, min: 0, max: 200, step: 1, ...cpn("节点水平间距", "spacingHorizontal") }, - { fieldset, type: "range", inline: true, min: 0, max: 100, step: 1, ...cpn("节点垂直间距", "spacingVertical") }, - { fieldset, type: "range", inline: true, min: 0, max: 1000, step: 10, ...cpn("节点最大长度", "maxWidth") }, - { fieldset, type: "range", inline: true, min: 0, max: 1000, step: 10, ...cpn("动画持续时间", "duration") }, + { fieldset, type: "range", min: 1, max: 6, step: 1, ...inlineWidget("固定配色的分支等级", "colorFreezeLevel") }, + { fieldset, type: "range", min: 1, max: 6, step: 1, ...inlineWidget("分支展开等级", "initialExpandLevel") }, + { fieldset, type: "range", min: 0, max: 100, step: 1, ...inlineWidget("节点内边距", "paddingX") }, + { fieldset, type: "range", min: 0, max: 200, step: 1, ...inlineWidget("节点水平间距", "spacingHorizontal") }, + { fieldset, type: "range", min: 0, max: 100, step: 1, ...inlineWidget("节点垂直间距", "spacingVertical") }, + { fieldset, type: "range", min: 0, max: 1000, step: 10, ...inlineWidget("节点最大长度", "maxWidth") }, + { fieldset, type: "range", min: 0, max: 1000, step: 10, ...inlineWidget("动画持续时间", "duration") }, ] const window = (fieldset = "窗口") => [ - { fieldset, type: "range", inline: true, min: 0.5, max: 1, step: 0.01, ...cpn("窗口填充率", "fitRatio") }, - { fieldset, type: "range", inline: true, min: 20, max: 95, step: 1, ...cpn("初始的窗口宽度", "WIDTH_PERCENT_WHEN_INIT") }, - { fieldset, type: "range", inline: true, min: 20, max: 95, step: 1, ...cpn("初始的窗口高度", "HEIGHT_PERCENT_WHEN_INIT") }, - { fieldset, type: "range", inline: true, min: 20, max: 95, step: 1, ...cpn("固定顶部的窗口高度", "HEIGHT_PERCENT_WHEN_PIN_UP") }, - { fieldset, type: "range", inline: true, min: 20, max: 95, step: 1, ...cpn("固定右侧的窗口宽度", "WIDTH_PERCENT_WHEN_PIN_RIGHT") }, - { fieldset, type: "range", inline: true, min: 0.1, max: 0.95, step: 0.01, ...cpn("定位的视口高度", "LOCALE_HEIGHT_RATIO") }, + { fieldset, type: "range", min: 0.5, max: 1, step: 0.01, ...inlineWidget("窗口填充率", "fitRatio") }, + { fieldset, type: "range", min: 20, max: 95, step: 1, ...inlineWidget("初始的窗口宽度", "WIDTH_PERCENT_WHEN_INIT") }, + { fieldset, type: "range", min: 20, max: 95, step: 1, ...inlineWidget("初始的窗口高度", "HEIGHT_PERCENT_WHEN_INIT") }, + { fieldset, type: "range", min: 20, max: 95, step: 1, ...inlineWidget("固定顶部的窗口高度", "HEIGHT_PERCENT_WHEN_PIN_UP") }, + { fieldset, type: "range", min: 20, max: 95, step: 1, ...inlineWidget("固定右侧的窗口宽度", "WIDTH_PERCENT_WHEN_PIN_RIGHT") }, + { fieldset, type: "range", min: 0.1, max: 0.95, step: 0.01, ...inlineWidget("定位的视口高度", "LOCALE_HEIGHT_RATIO") }, ] - const ability = (legend = "能力") => { + const behavior = (legend = "行为") => { const hasPlugin = this.utils.getPlugin("collapse_paragraph") const components = [ { label: "兼容跳级标题", key: "FIX_ERROR_LEVEL_HEADER" }, - { label: "鼠标滚轮进行缩放", key: "zoom" }, - { label: "鼠标滚轮进行平移", key: "pan" }, - { label: "鼠标点击节点进行定位", key: "CLICK_TO_LOCALE" }, - { label: "折叠节点后自动适配窗口", key: "autoFit" }, - { label: "更新内容后自动适配窗口", key: "AUTO_FIT_WHEN_UPDATE" }, - { label: "调整窗口后自动适配窗口", key: "AUTO_FIT_WHEN_RESIZE" }, - { label: "更新时不展开已折叠节点", key: "REMEMBER_FOLD_WHEN_UPDATE" }, - { label: "折叠节点时自动折叠章节", disabled: !hasPlugin, key: "AUTO_COLLAPSE_PARAGRAPH_WHEN_FOLD" }, + { label: "允许缩放图形", key: "zoom" }, + { label: "允许平移图形", key: "pan" }, + { label: "大纲变化后,自动更新图形", key: "AUTO_UPDATE" }, + { label: "点击节点后,跳转到文档对应章节", key: "CLICK_TO_LOCALE" }, + { label: "折叠节点后,自动调整图形大小以适配窗口", key: "autoFit" }, + { label: "更新图形后,自动调整图形大小以适配窗口", key: "AUTO_FIT_WHEN_UPDATE" }, + { label: "调整窗口后,自动调整图形大小以适配窗口", key: "AUTO_FIT_WHEN_RESIZE" }, + { label: "更新图形后,已折叠的节点保持折叠状态", key: "REMEMBER_FOLD_WHEN_UPDATE" }, + { label: "折叠节点后,自动折叠对应的章节内容", key: "AUTO_COLLAPSE_PARAGRAPH_WHEN_FOLD", disabled: !hasPlugin }, ] - return { label: "", legend, ...checkboxCpn(components) } + return { label: "", legend, ...checkboxWidget(components) } } const download = (fieldset = "导出") => { @@ -580,19 +582,19 @@ class tocMarkmap { { label: "导出后打开文件所在目录", key: "SHOW_IN_FINDER" }, ] return [ - { fieldset, type: "number", inline: true, min: 1, max: 1000, step: 1, ...cpn("水平内边距", "PADDING_HORIZONTAL") }, - { fieldset, type: "number", inline: true, min: 1, max: 1000, step: 1, ...cpn("垂直内边距", "PADDING_VERTICAL") }, - { fieldset, type: "number", inline: true, min: 0.01, max: 1, step: 0.01, ...cpn("图片质量", "IMAGE_QUALITY") }, - { fieldset, type: "color", inline: true, ...cpn("文字颜色", "TEXT_COLOR") }, - { fieldset, type: "color", inline: true, ...cpn("圆圈颜色", "OPEN_CIRCLE_COLOR") }, - { fieldset, type: "color", inline: true, ...cpn("背景颜色", "BACKGROUND_COLOR") }, - { fieldset, type: "input", inline: true, placeholder: this.utils.tempFolder, ...cpn("默认文件夹", "FOLDER") }, - { fieldset, type: "input", inline: true, ...cpn("默认文件名", "FILENAME") }, - { fieldset, label: "", ...checkboxCpn(components) }, + { fieldset, type: "number", min: 1, max: 1000, step: 1, ...inlineWidget("水平内边距", "PADDING_HORIZONTAL") }, + { fieldset, type: "number", min: 1, max: 1000, step: 1, ...inlineWidget("垂直内边距", "PADDING_VERTICAL") }, + { fieldset, type: "number", min: 0.01, max: 1, step: 0.01, ...inlineWidget("图片质量", "IMAGE_QUALITY") }, + { fieldset, type: "color", ...inlineWidget("文字颜色", "TEXT_COLOR") }, + { fieldset, type: "color", ...inlineWidget("圆圈颜色", "OPEN_CIRCLE_COLOR") }, + { fieldset, type: "color", ...inlineWidget("背景颜色", "BACKGROUND_COLOR") }, + { fieldset, type: "input", placeholder: this.utils.tempFolder, ...inlineWidget("默认文件夹", "FOLDER") }, + { fieldset, type: "input", ...inlineWidget("默认文件名", "FILENAME") }, + { fieldset, label: "", ...checkboxWidget(components) }, ] } - const components = [color(), ...chart(), ...window(), ability(), ...download()]; + const components = [color(), ...chart(), ...window(), behavior(), ...download()]; const { response } = await this.utils.dialog.modalAsync({ title: "设置", width: "520px", components }); if (response === 1) { components.forEach(c => c.callback(c.submit)); @@ -760,13 +762,15 @@ class tocMarkmap { isShow = () => this.utils.isShow(this.entities.modal) _draw = async (md, fit = true, options) => { - this.utils.show(this.entities.modal); + this.utils.show(this.entities.modal) if (this.markmap) { - await this._update(md, fit); + if (this.config.AUTO_UPDATE) { + await this._update(md, fit) + } } else { - this._initModalRect(); - await this.controller.lazyLoad(); - await this._create(md, options); + this._initModalRect() + await this.controller.lazyLoad() + await this._create(md, options) } }