From 456b79e3c62c7ce03b0e4bb3bb8cb592d3e683d7 Mon Sep 17 00:00:00 2001 From: purocean Date: Tue, 19 Jul 2022 17:33:10 +0800 Subject: [PATCH 1/9] fix: fix selection info update --- src/renderer/startup.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/renderer/startup.ts b/src/renderer/startup.ts index 35de8001d..9416ef909 100644 --- a/src/renderer/startup.ts +++ b/src/renderer/startup.ts @@ -63,6 +63,10 @@ function changeLanguage ({ settings }: { settings: BuildInSettings }) { } } +function updateSelectionInfo () { + store.commit('setSelectionInfo', getSelectionInfo()) +} + registerHook('I18N_CHANGE_LANGUAGE', view.refresh) registerHook('SETTING_FETCHED', changeLanguage) registerHook('SETTING_BEFORE_WRITE', changeLanguage) @@ -97,9 +101,8 @@ registerHook('EXTENSION_READY', () => { }) whenEditorReady().then(({ editor }) => { - editor.onDidChangeCursorSelection(() => { - store.commit('setSelectionInfo', getSelectionInfo()) - }) + editor.onDidChangeCursorSelection(updateSelectionInfo) + editor.onDidChangeModel(updateSelectionInfo) const { currentFile } = store.state From e966f24671e01bc066243063bcbb2e2fb992cb5b Mon Sep 17 00:00:00 2001 From: purocean Date: Tue, 19 Jul 2022 18:10:46 +0800 Subject: [PATCH 2/9] fix: fix markdown-it options --- src/renderer/plugins/markdown-front-matter.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/renderer/plugins/markdown-front-matter.ts b/src/renderer/plugins/markdown-front-matter.ts index 086363268..c7a2c2581 100644 --- a/src/renderer/plugins/markdown-front-matter.ts +++ b/src/renderer/plugins/markdown-front-matter.ts @@ -1,4 +1,5 @@ import frontMatter from 'front-matter' +import type { Options } from 'markdown-it' import type { Plugin } from '@fe/context' export default { @@ -37,6 +38,11 @@ export default { originOptions = { ...md.options } } + // clear md.options + Object.keys(md.options).forEach(key => { + delete md.options[key as keyof Options] + }) + Object.assign(md.options, originOptions) if (attributes.mdOptions && typeof attributes.mdOptions === 'object') { Object.assign(md.options, attributes.mdOptions) From e055daff3da9ef653b6de0f30b3c72e0454c31f8 Mon Sep 17 00:00:00 2001 From: purocean Date: Sun, 24 Jul 2022 22:06:05 +0800 Subject: [PATCH 3/9] feat: export HTML keeping data attributes --- src/renderer/services/view.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/renderer/services/view.ts b/src/renderer/services/view.ts index 9bdddc6f8..9cc4ebcdd 100644 --- a/src/renderer/services/view.ts +++ b/src/renderer/services/view.ts @@ -139,12 +139,6 @@ export async function getContentHtml (options: BuildInHookTypes['VIEW_ON_GET_HTM node.removeAttribute('title') } - if (node.dataset) { - Object.keys(node.dataset).forEach(key => { - delete node.dataset[key] - }) - } - const len = node.children.length for (let i = len - 1; i >= 0; i--) { const ele = node.children[i] From 8d147d8984ffea33bacd33f5fefc15426777a23c Mon Sep 17 00:00:00 2001 From: purocean Date: Mon, 25 Jul 2022 11:25:42 +0800 Subject: [PATCH 4/9] feat: update style of section container --- src/renderer/plugins/markdown-container.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/renderer/plugins/markdown-container.ts b/src/renderer/plugins/markdown-container.ts index 504b4e006..62eda3565 100644 --- a/src/renderer/plugins/markdown-container.ts +++ b/src/renderer/plugins/markdown-container.ts @@ -16,6 +16,10 @@ export default { position: relative; } + .markdown-view .markdown-body .custom-container.section > :first-child { + margin-top: 0; + } + .markdown-view .markdown-body .custom-container.row { display: flex; justify-content: space-between; From f8a8c0ff88b19f02314af2b8f066d25edc0c0b14 Mon Sep 17 00:00:00 2001 From: purocean Date: Wed, 27 Jul 2022 22:21:14 +0800 Subject: [PATCH 5/9] feat: support custom previewer --- src/renderer/components/Previewer.vue | 19 +++++++++ src/renderer/plugins.ts | 2 + src/renderer/plugins/status-bar-previewer.ts | 33 +++++++++++++++ src/renderer/services/view.ts | 43 +++++++++++++++++++- src/renderer/support/store.ts | 4 ++ src/renderer/types.ts | 8 ++++ src/renderer/views/Main.vue | 6 +-- src/share/i18n/languages/en.ts | 2 + src/share/i18n/languages/zh-CN.ts | 2 + 9 files changed, 115 insertions(+), 4 deletions(-) create mode 100644 src/renderer/components/Previewer.vue create mode 100644 src/renderer/plugins/status-bar-previewer.ts diff --git a/src/renderer/components/Previewer.vue b/src/renderer/components/Previewer.vue new file mode 100644 index 000000000..a28a3d727 --- /dev/null +++ b/src/renderer/components/Previewer.vue @@ -0,0 +1,19 @@ + + + diff --git a/src/renderer/plugins.ts b/src/renderer/plugins.ts index 956321888..43573c363 100644 --- a/src/renderer/plugins.ts +++ b/src/renderer/plugins.ts @@ -9,6 +9,7 @@ import statusBarNavigation from '@fe/plugins/status-bar-navigation' import statusBarInsert from '@fe/plugins/status-bar-insert' import statusBarTool from '@fe/plugins/status-bar-tool' import statusBarHelp from '@fe/plugins/status-bar-help' +import statusBarPreviewer from '@fe/plugins/status-bar-previewer' import statusBarHistory from './plugins/status-bar-history' import statusBarPresentation from '@fe/plugins/status-bar-presentation' import statusBarControlCenter from '@fe/plugins/status-bar-control-center' @@ -67,6 +68,7 @@ export default [ statusBarInsert, statusBarTool, statusBarHelp, + statusBarPreviewer, statusBarHistory, statusBarTerminal, statusBarControlCenter, diff --git a/src/renderer/plugins/status-bar-previewer.ts b/src/renderer/plugins/status-bar-previewer.ts new file mode 100644 index 000000000..70a3573ae --- /dev/null +++ b/src/renderer/plugins/status-bar-previewer.ts @@ -0,0 +1,33 @@ +import type { Plugin } from '@fe/context' + +export default { + name: 'status-bar-previewer', + register: ctx => { + ctx.statusBar.tapMenus(menus => { + const previewers = ctx.ioc.get('VIEW_PREVIEWER') + menus['status-bar-previewer'] = { + id: 'status-bar-previewer', + position: 'right', + title: ctx.i18n.t('previewer'), + hidden: previewers.length < 1, + list: previewers.map(item => ({ + id: item.name, + type: 'normal' as any, + title: item.name, + checked: item.name === ctx.store.state.previewer, + onClick: () => ctx.view.switchPreviewer(item.name), + })).concat([{ + id: 'default-previewer', + type: 'normal' as any, + title: ctx.i18n.t('default'), + checked: ctx.store.state.previewer === 'default', + onClick: () => ctx.view.switchPreviewer('default'), + }]), + } + }) + + ctx.registerHook('VIEW_PREVIEWER_CHANGE', () => { + ctx.statusBar.refreshMenu() + }) + } +} as Plugin diff --git a/src/renderer/services/view.ts b/src/renderer/services/view.ts index 9cc4ebcdd..86da39d14 100644 --- a/src/renderer/services/view.ts +++ b/src/renderer/services/view.ts @@ -2,10 +2,11 @@ import juice from 'juice' import { CtrlCmd, Escape, registerCommand } from '@fe/core/command' import { getActionHandler, registerAction } from '@fe/core/action' import { triggerHook } from '@fe/core/hook' +import * as ioc from '@fe/core/ioc' import { DOM_CLASS_NAME } from '@fe/support/args' import { useToast } from '@fe/support/ui/toast' import store from '@fe/support/store' -import type { BuildInHookTypes, Components } from '@fe/types' +import type { BuildInHookTypes, Components, Previewer } from '@fe/types' import { t } from './i18n' import { emitResize } from './layout' import { switchDoc } from './document' @@ -279,6 +280,46 @@ export function tapContextMenus (fun: BuildContextMenu) { contextMenuFunList.push(fun) } +/** + * Switch current previewer + * @param name Previewer name + */ +export function switchPreviewer (name: string) { + if (ioc.get('VIEW_PREVIEWER').some((item) => item.name === name)) { + store.commit('setPreviewer', name) + } else { + store.commit('setPreviewer', 'default') + } + + triggerHook('VIEW_PREVIEWER_CHANGE') +} + +/** + * Register a previewer. + * @param previewer Previewer + */ +export function registerPreviewer (previewer: Previewer) { + ioc.register('VIEW_PREVIEWER', previewer) + triggerHook('VIEW_PREVIEWER_CHANGE') +} + +/** + * Remove a previewer. + * @param name Previewer name + */ +export function removePreviewer (name: string) { + ioc.removeWhen('VIEW_PREVIEWER', item => item.name === name) + switchPreviewer('default') +} + +/** + * Get all previewers. + * @returns Previewers + */ +export function getAllPreviewers () { + return ioc.get('VIEW_PREVIEWER') +} + /** * Get context menus * @param e diff --git a/src/renderer/support/store.ts b/src/renderer/support/store.ts index d4af0c4d0..26166886d 100644 --- a/src/renderer/support/store.ts +++ b/src/renderer/support/store.ts @@ -32,6 +32,7 @@ export const initState = { line: 0, column: 0 }, + previewer: 'default', } export type AppState = typeof initState @@ -89,6 +90,9 @@ export default createStore({ setShowXterm (state, data) { state.showXterm = data }, + setPreviewer (state, data: string) { + state.previewer = data + }, setShowOutline (state, data) { state.showOutline = data }, diff --git a/src/renderer/types.ts b/src/renderer/types.ts index a68ec6f3f..5ed681dd6 100644 --- a/src/renderer/types.ts +++ b/src/renderer/types.ts @@ -244,6 +244,7 @@ export type BuildInHookTypes = { VIEW_FILE_CHANGE: never, VIEW_BEFORE_REFRESH: never, VIEW_AFTER_REFRESH: never, + VIEW_PREVIEWER_CHANGE: never, VIEW_ON_GET_HTML_FILTER_NODE: { node: HTMLElement, options: { @@ -278,10 +279,16 @@ export type BuildInHookTypes = { EXTENSION_READY: { extensions: Extension[] }, } +export type Previewer = { + name: string, + component: any, +} + export type BuildInIOCTypes = { [key in keyof BuildInHookTypes]: any; } & { STATUS_BAR_MENU_TAPPERS: any; CONTROL_CENTER_SCHEMA_TAPPERS: any; THEME_STYLES: any; + VIEW_PREVIEWER: Previewer; } export type FrontMatterAttrs = { @@ -290,4 +297,5 @@ export type FrontMatterAttrs = { enableMacro?: boolean, define?: Record, mdOptions?: Record, + defaultPreviewer?: string, } diff --git a/src/renderer/views/Main.vue b/src/renderer/views/Main.vue index 0650c52d9..1851815d3 100644 --- a/src/renderer/views/Main.vue +++ b/src/renderer/views/Main.vue @@ -19,7 +19,7 @@ @@ -45,7 +45,7 @@ import Tree from '@fe/components/Tree.vue' import Xterm from '@fe/components/Xterm.vue' import FileTabs from '@fe/components/FileTabs.vue' import Editor from '@fe/components/Editor.vue' -import Preview from '@fe/components/Preview.vue' +import Previewer from '@fe/components/Previewer.vue' import SettingPanel from '@fe/components/SettingPanel.vue' import ExportPanel from '@fe/components/ExportPanel.vue' @@ -67,7 +67,7 @@ export default defineComponent({ Xterm, FileTabs, Editor, - Preview, + Previewer, XFilter, Premium, SettingPanel, diff --git a/src/share/i18n/languages/en.ts b/src/share/i18n/languages/en.ts index 096311044..48c0807af 100644 --- a/src/share/i18n/languages/en.ts +++ b/src/share/i18n/languages/en.ts @@ -31,6 +31,8 @@ const data = { 'install-extension-tips': 'Please install and enable the "%s" extension first', 'not-support-mas': 'Yank Note downloaded from the Mac Apple Store does not support this extension.', 'learn-more': 'Learn More', + 'previewer': 'Previewer', + 'default': 'Default', 'premium': { 'need-purchase': '[%s] Premium is required', 'buy-license': 'Buy License', diff --git a/src/share/i18n/languages/zh-CN.ts b/src/share/i18n/languages/zh-CN.ts index 33ef5a96a..0f752e856 100644 --- a/src/share/i18n/languages/zh-CN.ts +++ b/src/share/i18n/languages/zh-CN.ts @@ -32,6 +32,8 @@ const data: BaseLanguage = { 'install-extension-tips': '请先安装并启用 “%s” 扩展', 'not-support-mas': '从 Mac Apple Store 中下载的应用不支持此拓展。', 'learn-more': '了解更多', + 'previewer': '预览器', + 'default': '默认', 'premium': { 'need-purchase': '[%s] 需要高级版', 'buy-license': '立即购买', From dd8a6701ac0c23cc7ebd131443106a3d725f3224 Mon Sep 17 00:00:00 2001 From: purocean Date: Wed, 27 Jul 2022 23:11:20 +0800 Subject: [PATCH 6/9] feat: support set default previewer --- src/renderer/services/view.ts | 8 ++++++-- src/renderer/startup.ts | 23 ++++++++++++++++++++++- src/renderer/types.ts | 2 +- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/renderer/services/view.ts b/src/renderer/services/view.ts index 86da39d14..8c30c3a53 100644 --- a/src/renderer/services/view.ts +++ b/src/renderer/services/view.ts @@ -285,13 +285,16 @@ export function tapContextMenus (fun: BuildContextMenu) { * @param name Previewer name */ export function switchPreviewer (name: string) { + const oldPreviewer = store.state.previewer if (ioc.get('VIEW_PREVIEWER').some((item) => item.name === name)) { store.commit('setPreviewer', name) } else { store.commit('setPreviewer', 'default') } - triggerHook('VIEW_PREVIEWER_CHANGE') + if (oldPreviewer !== store.state.previewer) { + triggerHook('VIEW_PREVIEWER_CHANGE', { type: 'switch' }) + } } /** @@ -300,7 +303,7 @@ export function switchPreviewer (name: string) { */ export function registerPreviewer (previewer: Previewer) { ioc.register('VIEW_PREVIEWER', previewer) - triggerHook('VIEW_PREVIEWER_CHANGE') + triggerHook('VIEW_PREVIEWER_CHANGE', { type: 'register' }) } /** @@ -309,6 +312,7 @@ export function registerPreviewer (previewer: Previewer) { */ export function removePreviewer (name: string) { ioc.removeWhen('VIEW_PREVIEWER', item => item.name === name) + triggerHook('VIEW_PREVIEWER_CHANGE', { type: 'remove' }) switchPreviewer('default') } diff --git a/src/renderer/startup.ts b/src/renderer/startup.ts index 9416ef909..197f1d6a7 100644 --- a/src/renderer/startup.ts +++ b/src/renderer/startup.ts @@ -3,7 +3,7 @@ import { registerHook, triggerHook } from '@fe/core/hook' import store from '@fe/support/store' import * as storage from '@fe/utils/storage' import { basename } from '@fe/utils/path' -import type { BuildInSettings, Doc, Repo } from '@fe/types' +import type { BuildInSettings, Doc, FrontMatterAttrs, Repo } from '@fe/types' import { isMarked, markDoc, showHelp, switchDoc, unmarkDoc } from '@fe/services/document' import { refreshTree } from '@fe/services/tree' import { getSelectionInfo, whenEditorReady } from '@fe/services/editor' @@ -67,6 +67,15 @@ function updateSelectionInfo () { store.commit('setSelectionInfo', getSelectionInfo()) } +function switchDefaultPreviewer () { + const attributes: FrontMatterAttrs | undefined = view.getRenderEnv()?.attributes + if (attributes?.defaultPreviewer && typeof attributes.defaultPreviewer === 'string') { + view.switchPreviewer(attributes.defaultPreviewer) + } else { + view.switchPreviewer('default') + } +} + registerHook('I18N_CHANGE_LANGUAGE', view.refresh) registerHook('SETTING_FETCHED', changeLanguage) registerHook('SETTING_BEFORE_WRITE', changeLanguage) @@ -100,6 +109,18 @@ registerHook('EXTENSION_READY', () => { view.render() }) +registerHook('VIEW_PREVIEWER_CHANGE', ({ type }) => { + if (type !== 'switch') { + setTimeout(() => { + switchDefaultPreviewer() + }, 500) + } +}) + +registerHook('VIEW_FILE_CHANGE', () => { + registerHook('VIEW_RENDER', switchDefaultPreviewer, true) +}) + whenEditorReady().then(({ editor }) => { editor.onDidChangeCursorSelection(updateSelectionInfo) editor.onDidChangeModel(updateSelectionInfo) diff --git a/src/renderer/types.ts b/src/renderer/types.ts index 5ed681dd6..a82ecc85f 100644 --- a/src/renderer/types.ts +++ b/src/renderer/types.ts @@ -244,7 +244,7 @@ export type BuildInHookTypes = { VIEW_FILE_CHANGE: never, VIEW_BEFORE_REFRESH: never, VIEW_AFTER_REFRESH: never, - VIEW_PREVIEWER_CHANGE: never, + VIEW_PREVIEWER_CHANGE: { type: 'register' | 'remove' | 'switch' }, VIEW_ON_GET_HTML_FILTER_NODE: { node: HTMLElement, options: { From 192653dd7b0bd4084a11104592f296b029c8b852 Mon Sep 17 00:00:00 2001 From: purocean Date: Thu, 28 Jul 2022 14:51:30 +0800 Subject: [PATCH 7/9] feat: add translation --- src/share/i18n/languages/en.ts | 1 + src/share/i18n/languages/zh-CN.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/src/share/i18n/languages/en.ts b/src/share/i18n/languages/en.ts index 48c0807af..fd9ac4b6e 100644 --- a/src/share/i18n/languages/en.ts +++ b/src/share/i18n/languages/en.ts @@ -33,6 +33,7 @@ const data = { 'learn-more': 'Learn More', 'previewer': 'Previewer', 'default': 'Default', + 'print': 'Print', 'premium': { 'need-purchase': '[%s] Premium is required', 'buy-license': 'Buy License', diff --git a/src/share/i18n/languages/zh-CN.ts b/src/share/i18n/languages/zh-CN.ts index 0f752e856..d0e9bd7be 100644 --- a/src/share/i18n/languages/zh-CN.ts +++ b/src/share/i18n/languages/zh-CN.ts @@ -34,6 +34,7 @@ const data: BaseLanguage = { 'learn-more': '了解更多', 'previewer': '预览器', 'default': '默认', + 'print': '打印', 'premium': { 'need-purchase': '[%s] 需要高级版', 'buy-license': '立即购买', From 2307089f7159516dda9521b879bc9e6fae09457f Mon Sep 17 00:00:00 2001 From: purocean Date: Thu, 28 Jul 2022 15:06:59 +0800 Subject: [PATCH 8/9] docs: update FEATURES --- help/FEATURES.md | 1 + help/FEATURES_ZH-CN.md | 1 + 2 files changed, 2 insertions(+) diff --git a/help/FEATURES.md b/help/FEATURES.md index ee142c121..ae833499c 100644 --- a/help/FEATURES.md +++ b/help/FEATURES.md @@ -547,6 +547,7 @@ variable name | type | description `wrapCode` | `boolean` | whether to enable code wrapping `enableMacro` | `boolean` | whether to enable macro replacement `define` | `Record` | Macro definition, string replacing +`defaultPreviewer` | `string` | The default previewer for the document, some extensions may provide a special preview interface. Such as *Reveal.js extension* `mdOptions` | `Record` | Markdown-it parse options `mdOptions.html` | `boolean` | Enable HTML tags in source `mdOptions.breaks` | `boolean` | Convert `\n` in paragraphs into `
` diff --git a/help/FEATURES_ZH-CN.md b/help/FEATURES_ZH-CN.md index f5552ad76..4aecf735d 100644 --- a/help/FEATURES_ZH-CN.md +++ b/help/FEATURES_ZH-CN.md @@ -546,6 +546,7 @@ Yank Note 接入了 [OpenAI](https://openai.com),可以按下 `[= $ctx.command `wrapCode` | `boolean` | 是否开启代码换行 `enableMacro` | `boolean` | 是否开启宏替换 `define` | `Record` | 宏定义,定义文本替换 +`defaultPreviewer` | `string` | 文档默认的预览器,某些扩展可能提供特殊的预览界面。如 *Reveal.js 扩展* `mdOptions` | `Record` | Markdown-it 解析参数 `mdOptions.html` | `boolean` | 开启 HTML 解析 `mdOptions.breaks` | `boolean` | 转换 `\n` 成 `
` From f1808cace9c05e83d3cb219aa106414caa8f64ec Mon Sep 17 00:00:00 2001 From: purocean Date: Thu, 28 Jul 2022 15:20:51 +0800 Subject: [PATCH 9/9] chore: bump version --- README.md | 11 ++++++----- README_ZH-CN.md | 11 ++++++----- package.json | 2 +- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 6019cd9d2..8cb98845a 100644 --- a/README.md +++ b/README.md @@ -76,12 +76,13 @@ For more information on how to use the following functions, please see [characte ## Changelogs -### [v3.32.0](https://github.com/purocean/yn/releases/tag/v3.32.0) 2022-07-14 +### [v3.33.0](https://github.com/purocean/yn/releases/tag/v3.33.0) 2022-07-28 -1. feat: added "Export" and "Print" menu items to the status bar menu -2. feat: open the terminal and switch to the current warehouse directory by default -3. feat: add "section" container block -4. upd: the "Keep running in background" setting is disabled by default on macOS +1. fix: fix the problem that the word count statistics of open documents are not updated +2. fix: fix the problem that front matter is not refreshed when switching files +3. upd: export HTML preserves `data-*` attributes +4. upd: optimize `section` container style +5. feat(plugin): Added previewer registration, plugins can customize the document preview interface. Related APIs: `ctx.view.switchPreviewer` `ctx.view.registerPreviewer` `ctx.view.removePreviewer` `ctx.view.getAllPreviewers` [More release notes](https://github.com/purocean/yn/releases) diff --git a/README_ZH-CN.md b/README_ZH-CN.md index 38e84e4dd..6ecea19ff 100644 --- a/README_ZH-CN.md +++ b/README_ZH-CN.md @@ -76,12 +76,13 @@ ## 更新日志 -### [v3.32.0](https://github.com/purocean/yn/releases/tag/v3.32.0) 2022-07-14 +### [v3.33.0](https://github.com/purocean/yn/releases/tag/v3.33.0) 2022-07-28 -1. feat: 状态栏菜单增加“导出”、“打印”菜单项 -2. feat: 打开终端默认切换到当前仓库目录 -3. feat: 增加“section”容器块 -4. upd: macOS 上默认禁用“保持后台运行”设置 +1. fix: 修复打开文档字数统计信息不更新问题 +2. fix: 修复切换文件时候 front matter 没刷新问题 +3. upd: 导出 HTML 保留 `data-*` 属性 +4. upd: 优化 `section` 容器样式 +5. feat(plugin): 增加预览器注册,插件可以自定义文档预览界面。相关 Api: `ctx.view.switchPreviewer` `ctx.view.registerPreviewer` `ctx.view.removePreviewer` `ctx.view.getAllPreviewers` [更多发布说明](https://github.com/purocean/yn/releases) diff --git a/package.json b/package.json index 9f600ea19..61178a3a9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "yank.note", - "version": "3.32.0", + "version": "3.33.0", "description": "Yank Note: A hackable markdown note application for programmers", "main": "dist/main/app.js", "license": "AGPL-3.0",