Skip to content

Commit

Permalink
feat: 新增自定义处理函数配置
Browse files Browse the repository at this point in the history
  • Loading branch information
terwer committed Jun 1, 2023
1 parent ef435aa commit f4a28a7
Show file tree
Hide file tree
Showing 6 changed files with 206 additions and 7 deletions.
14 changes: 12 additions & 2 deletions src/i18n/en_US.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"importer": "Importer",
"selectFile": "Select file",
"cancel": "Cancel",
"startImport": "Single import",
"importerLoaded": "Importer loaded",
"importerUnloaded": "Importer unloaded",
Expand Down Expand Up @@ -35,5 +34,16 @@
"tempCountExists": "Please clean up the temporary files before batch import",
"reportBug1": "Encounter problems? , to the developer terwer ",
"reportBug2": "feedback",
"reportBug3": " bar~"
"reportBug3": " bar~",
"setting": "setting",
"cancel": "Cancel",
"save": "Save",
"customFnHandler": "Custom handler",
"customFnSwitch": "Custom handler switch",
"customFnSwitchTips": "Enable or disable custom handlers",
"customFnHandlerTips": "You can customize the processing function here, and it will be called automatically during the import process. Please note: modifying this may cause the import to not work. If there is a problem, you can disable the custom processing function",
"customFnHandlerPlaceholder": "Custom handler",
"enableCustomFn": "Enable custom functions",
"enableCustomFnTips": "Are you sure you want to enable custom functions? This action may cause imports to be unavailable. Please confirm that you have understood how custom functions work?",
"importConfigSaveSuccess": "Configuration saved successfully"
}
16 changes: 13 additions & 3 deletions src/i18n/zh_CN.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"importer": "导入插件",
"selectFile": "选择文件",
"cancel": "取消",
"startImport": "单个导入",
"importerLoaded": "导入工具已加载",
"importerUnloaded": "导入工具已卸载",
Expand All @@ -28,7 +27,7 @@
"importFolder": "批量导入",
"importFolderTip": "支持混合.epub,.docx,.opml",
"importNotRecursive1": "1、不递归",
"importNotRecursive2": "2、不支持MD,批量导入MD请使用笔记本自带功能",
"importNotRecursive2": "2、不支持MD,批量导入MD请使用笔记本自带功能",
"importNotRecursive3": "3、不支持html,因为安全限制,浏览器现在无法获取绝对路径,可通过单个导入(支持资源文件)",
"importTipNotAllowed": "不允许的文件类型:",
"importError": "导入出错:",
Expand All @@ -39,5 +38,16 @@
"tempCountExists": "请先清理临时文件在进行批量导入",
"reportBug1": "遇到问题? 发邮件到 [email protected] 或者 给开发者 terwer ",
"reportBug2": "反馈一下",
"reportBug3": " 吧~"
"reportBug3": " 吧~",
"setting": "设置",
"cancel": "取消",
"save": "保存",
"customFnHandler": "自定义处理函数",
"customFnSwitch": "自定义处理函数开关",
"customFnSwitchTips": "启用或者禁用自定义处理函数",
"customFnHandlerTips": "可以在这里自定义处理函数,导入过程中会自动调用,请注意:修改此处可能会导致导入不工作,若出现问题可禁用自定义处理函数。正则表达式在线测试可参考:",
"customFnHandlerPlaceholder": "自定义处理函数",
"enableCustomFn": "启用自定义函数",
"enableCustomFnTips": "确认要启用自定义函数吗,此操作可能导致导入不可用,请确认您已经了解自定义函数的工作原理?",
"importConfigSaveSuccess": "配置保存成功"
}
5 changes: 4 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
* questions.
*/

import { App, IObject, Plugin } from "siyuan"
import { App, getFrontend, IObject, Plugin } from "siyuan"
import { createLogger } from "./utils/simple-logger"
import KernelApi from "./api/kernel-api"
import { isDev, mediaDir } from "./Constants"
Expand All @@ -41,10 +41,13 @@ import { simpleLogger } from "zhi-lib-base"
export default class ImporterPlugin extends Plugin {
public logger
public kernelApi: KernelApi
public isMobile: boolean

constructor(options: { app: App; id: string; name: string; i18n: IObject }) {
super(options)

const frontEnd = getFrontend()
this.isMobile = frontEnd === "mobile" || frontEnd === "browser-mobile"
this.logger = simpleLogger("index", "importer", isDev)
this.kernelApi = new KernelApi()
}
Expand Down
128 changes: 128 additions & 0 deletions src/lib/ImportSetting.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
<!--
- Copyright (c) 2023, Terwer . All rights reserved.
- DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-
- This code is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License version 2 only, as
- published by the Free Software Foundation. Terwer designates this
- particular file as subject to the "Classpath" exception as provided
- by Terwer in the LICENSE file that accompanied this code.
-
- This code is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- version 2 for more details (a copy is included in the LICENSE file that
- accompanied this code).
-
- You should have received a copy of the GNU General Public License version
- 2 along with this work; if not, write to the Free Software Foundation,
- Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-
- Please contact Terwer, Shenzhen, Guangdong, China, [email protected]
- or visit www.terwer.space if you need additional information or have any
- questions.
-->

<script lang="ts">
import ImporterPlugin from "../index"
import { onMount } from "svelte"
import { confirm, showMessage } from "siyuan"
import { loadImporterConfig, saveImporterConfig } from "../store/config"
export let pluginInstance: ImporterPlugin
export let dialog
let customFnSwitch = false
let customFn
let importerConfig = {}
const onSaveSetting = async () => {
dialog.destroy()
importerConfig.customFnSwitch = customFnSwitch
importerConfig.customFn = customFn
await saveImporterConfig(pluginInstance, importerConfig)
pluginInstance.logger.info("saved important config =>", importerConfig)
showMessage(`${pluginInstance.i18n.importConfigSaveSuccess}`, 2000, "info")
}
const onCancel = async () => {
dialog.destroy()
}
const updateSwitch = (event) => {
event.stopPropagation()
if (!customFnSwitch) {
confirm(
`⚠️${pluginInstance.i18n.enableCustomFn}`,
`${pluginInstance.i18n.enableCustomFnTips}`,
() => {
const inputEl = document.querySelector("#customFnSwitch")
inputEl.checked = customFnSwitch
},
() => {
customFnSwitch = !customFnSwitch
}
)
}
}
onMount(async () => {
// 加载配置
importerConfig = await loadImporterConfig(pluginInstance)
customFnSwitch = importerConfig.customFnSwitch ?? false
customFn =
importerConfig.customFn ??
`
// 您可以参考这个案例进行修改,注意:请勿修改方法名,只需修改实现即可
// 将字符串中形如"xxx^yyy"的部分替换成"xxx"
export function customFn(mdText) {
const regex = /\\^\\(\\[.*[0-9].*]\\(#.*#.*\\)\\)/g // 匹配格式为 ^[[数字]](#链接) 的脚注
return mdText.replace(regex, "") // 使用空字符串替换匹配到的脚注
}
`
})
</script>

<div class="config__tab-container">
<label class="fn__flex b3-label">
<div class="fn__flex-1">
{pluginInstance.i18n.customFnSwitch}
<div class="b3-label__text">{pluginInstance.i18n.customFnSwitchTips}</div>
</div>
<span class="fn__space" />
<input
id="customFnSwitch"
class="b3-switch fn__flex-center"
type="checkbox"
on:click={(event) => updateSwitch(event)}
bind:checked={customFnSwitch}
/>
</label>

<label class="fn__flex b3-label">
<div class="fn__flex-1">
{pluginInstance.i18n.customFnHandler}
<div class="b3-label__text">
{pluginInstance.i18n.customFnHandlerTips}
<a href="https://www.regextester.com" target="_blank">https://www.regextester.com</a>
</div>
<div class="fn__hr" />
<textarea
class="b3-text-field fn__block"
placeholder={pluginInstance.i18n.customFnHandlerPlaceholder}
rows="10"
spellcheck="false"
bind:value={customFn}
/>
</div>
</label>

<div class="b3-dialog__action">
<button class="b3-button b3-button--cancel" on:click={onCancel}>{pluginInstance.i18n.cancel}</button>
<div class="fn__space" />
<button class="b3-button b3-button--text" on:click={onSaveSetting}>{pluginInstance.i18n.save}</button>
</div>
</div>
49 changes: 48 additions & 1 deletion src/topbar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@
*/

import ImporterPlugin from "./index"
import { Dialog, getFrontend } from "siyuan"
import { Dialog, getFrontend, Menu } from "siyuan"
import ImportForm from "./lib/ImportForm.svelte"
import { iconImporter } from "./utils/svg"
import ImportSetting from "./lib/ImportSetting.svelte"

/**
* 顶栏按钮
Expand All @@ -45,6 +46,7 @@ export async function initTopbar(pluginInstance: ImporterPlugin) {
pluginInstance.logger.info(`this.i18n.importer added toolbar`)
},
})

topBarElement.addEventListener("click", async () => {
const frontEnd = getFrontend()
const isMobile = frontEnd === "mobile" || frontEnd === "browser-mobile"
Expand All @@ -62,4 +64,49 @@ export async function initTopbar(pluginInstance: ImporterPlugin) {
},
})
})

// 添加右键菜单
topBarElement.addEventListener("contextmenu", () => {
let rect = topBarElement.getBoundingClientRect()
// 如果获取不到宽度,则使用更多按钮的宽度
if (rect.width === 0) {
rect = document.querySelector("#barMore").getBoundingClientRect()
}
initContextMenu(pluginInstance, rect)
})

const initContextMenu = async (pluginInstance: ImporterPlugin, rect: DOMRect) => {
const menu = new Menu("importerContextMenu")

// 设置
menu.addItem({
iconHTML: iconImporter.iconSetting,
label: pluginInstance.i18n.setting,
click: () => {
const settingId = "siyuan-importing-setting"
const d = new Dialog({
title: `${pluginInstance.i18n.setting} - ${pluginInstance.i18n.importer}`,
content: `<div id="${settingId}"></div>`,
width: pluginInstance.isMobile ? "92vw" : "720px",
})
new ImportSetting({
target: document.getElementById(settingId) as HTMLElement,
props: {
pluginInstance: pluginInstance,
dialog: d,
},
})
},
})

if (pluginInstance.isMobile) {
menu.fullscreen()
} else {
menu.open({
x: rect.right,
y: rect.bottom,
isLeft: true,
})
}
}
}
1 change: 1 addition & 0 deletions src/utils/svg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,5 @@

export const iconImporter = {
iconImporter: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M352 96l64 0c17.7 0 32 14.3 32 32l0 256c0 17.7-14.3 32-32 32l-64 0c-17.7 0-32 14.3-32 32s14.3 32 32 32l64 0c53 0 96-43 96-96l0-256c0-53-43-96-96-96l-64 0c-17.7 0-32 14.3-32 32s14.3 32 32 32zm-9.4 182.6c12.5-12.5 12.5-32.8 0-45.3l-128-128c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L242.7 224 32 224c-17.7 0-32 14.3-32 32s14.3 32 32 32l210.7 0-73.4 73.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l128-128z"/></svg>`,
iconSetting: `<span class="importer-menu-icon"><svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 512 512"><path d="M495.9 166.6c3.2 8.7 .5 18.4-6.4 24.6l-43.3 39.4c1.1 8.3 1.7 16.8 1.7 25.4s-.6 17.1-1.7 25.4l43.3 39.4c6.9 6.2 9.6 15.9 6.4 24.6c-4.4 11.9-9.7 23.3-15.8 34.3l-4.7 8.1c-6.6 11-14 21.4-22.1 31.2c-5.9 7.2-15.7 9.6-24.5 6.8l-55.7-17.7c-13.4 10.3-28.2 18.9-44 25.4l-12.5 57.1c-2 9.1-9 16.3-18.2 17.8c-13.8 2.3-28 3.5-42.5 3.5s-28.7-1.2-42.5-3.5c-9.2-1.5-16.2-8.7-18.2-17.8l-12.5-57.1c-15.8-6.5-30.6-15.1-44-25.4L83.1 425.9c-8.8 2.8-18.6 .3-24.5-6.8c-8.1-9.8-15.5-20.2-22.1-31.2l-4.7-8.1c-6.1-11-11.4-22.4-15.8-34.3c-3.2-8.7-.5-18.4 6.4-24.6l43.3-39.4C64.6 273.1 64 264.6 64 256s.6-17.1 1.7-25.4L22.4 191.2c-6.9-6.2-9.6-15.9-6.4-24.6c4.4-11.9 9.7-23.3 15.8-34.3l4.7-8.1c6.6-11 14-21.4 22.1-31.2c5.9-7.2 15.7-9.6 24.5-6.8l55.7 17.7c13.4-10.3 28.2-18.9 44-25.4l12.5-57.1c2-9.1 9-16.3 18.2-17.8C227.3 1.2 241.5 0 256 0s28.7 1.2 42.5 3.5c9.2 1.5 16.2 8.7 18.2 17.8l12.5 57.1c15.8 6.5 30.6 15.1 44 25.4l55.7-17.7c8.8-2.8 18.6-.3 24.5 6.8c8.1 9.8 15.5 20.2 22.1 31.2l4.7 8.1c6.1 11 11.4 22.4 15.8 34.3zM256 336a80 80 0 1 0 0-160 80 80 0 1 0 0 160z"/></svg></span>`,
}

0 comments on commit f4a28a7

Please sign in to comment.