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 f4a28a7 commit f5452e2
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 21 deletions.
5 changes: 4 additions & 1 deletion src/i18n/en_US.json
Expand Up @@ -45,5 +45,8 @@
"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"
"importConfigSaveSuccess": "Configuration saved successfully",
"testOutputPlaceholder": "Here is the output of the test",
"testInput": "Test input",
"testOutput": "Test output"
}
10 changes: 9 additions & 1 deletion src/i18n/zh_CN.json
Expand Up @@ -42,12 +42,20 @@
"setting": "设置",
"cancel": "取消",
"save": "保存",
"bundledFnHandler": "插件自带的处理函数",
"bundledFnSwitch": "插件自带的处理函数开关",
"bundledFnSwitchTips": "启用或者禁用插件自带的处理函数,目前自带的处理函数已包括删除目录中链接、去除空行、资源路径修复、去除脚注等功能",
"disableBundledFnSwitchTips": "确认禁用插件自带的处理函数吗,将不会对转换结果做任何处理,包括去除链接,脚注优化等,将按照转换结果原样导入?",
"customFnHandler": "自定义处理函数",
"customFnSwitch": "自定义处理函数开关",
"customFnSwitchTips": "启用或者禁用自定义处理函数",
"customFnHandlerTips": "可以在这里自定义处理函数,导入过程中会自动调用,请注意:修改此处可能会导致导入不工作,若出现问题可禁用自定义处理函数。正则表达式在线测试可参考:",
"customFnHandlerPlaceholder": "自定义处理函数",
"enableCustomFn": "启用自定义函数",
"enableCustomFnTips": "确认要启用自定义函数吗,此操作可能导致导入不可用,请确认您已经了解自定义函数的工作原理?",
"importConfigSaveSuccess": "配置保存成功"
"importConfigSaveSuccess": "配置保存成功",
"testOutputPlaceholder": "这里是测试的输出结果",
"testInput": "测试输入",
"testOutput": "测试输出",
"customFnHandlerError": "自定义处理函数处理失败,请检查。您也可以暂时禁用自定义处理函数完成导入"
}
90 changes: 81 additions & 9 deletions src/lib/ImportSetting.svelte
Expand Up @@ -28,17 +28,20 @@
import { onMount } from "svelte"
import { confirm, showMessage } from "siyuan"
import { loadImporterConfig, saveImporterConfig } from "../store/config"
import { getExports } from "../utils/utils"
export let pluginInstance: ImporterPlugin
export let dialog
let bundledFnSwitch = true
let customFnSwitch = false
let customFn
let importerConfig = {}
const onSaveSetting = async () => {
dialog.destroy()
importerConfig.bundledFnSwitch = bundledFnSwitch
importerConfig.customFnSwitch = customFnSwitch
importerConfig.customFn = customFn
await saveImporterConfig(pluginInstance, importerConfig)
Expand Down Expand Up @@ -68,25 +71,72 @@
}
}
const updateBundledFnSwitch = (event) => {
event.stopPropagation()
if (bundledFnSwitch) {
confirm(
`⚠️${pluginInstance.i18n.bundledFnSwitch}`,
`${pluginInstance.i18n.disableBundledFnSwitchTips}`,
() => {
const inputEl = document.querySelector("#bundledFnSwitch")
inputEl.checked = bundledFnSwitch
},
() => {
bundledFnSwitch = !bundledFnSwitch
}
)
}
}
let testInput = `我衷心期盼,子孙后代们读到这封信时,会带着一种自豪感和正当的优越感。
## 评伯特兰·罗素的知识论^([\\[16\\]](#part0019.html#footnote_16))
当编者要我就罗素写点东西时,出于对这位作者的钦佩和尊敬,我立刻答应了下来。`
let testOutput = ""
const testFn = () => {
const exportsFn = getExports(customFn)
const result = exportsFn(testInput)
testOutput = result
console.log("test exportsFn=>", result)
}
onMount(async () => {
// 加载配置
importerConfig = await loadImporterConfig(pluginInstance)
bundledFnSwitch = importerConfig.bundledFnSwitch ?? true
customFnSwitch = importerConfig.customFnSwitch ?? false
customFn =
importerConfig.customFn ??
`
// 您可以参考这个案例进行修改,注意:请勿修改方法名,只需修改实现即可
// 将字符串中形如"xxx^yyy"的部分替换成"xxx"
export function customFn(mdText) {
const regex = /\\^\\(\\[.*[0-9].*]\\(#.*#.*\\)\\)/g // 匹配格式为 ^[[数字]](#链接) 的脚注
return mdText.replace(regex, "") // 使用空字符串替换匹配到的脚注
}
`
`// 您可以参考这个案例进行修改,注意:请勿修改方法名和参数名,只需修改customFn内部实现即可
// 将字符串中形如"xxx^yyy"的部分替换成"xxx"
const customFn = (mdText) => {
const regex = /\\^\\(\\[.*[0-9].*]\\(#.*#.*\\)\\)/g // 匹配格式为 ^[[数字]](#链接) 的脚注
return mdText.replace(regex, "") // 使用空字符串替换匹配到的脚注
}
module.exports = customFn`
})
</script>

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

<label class="fn__flex b3-label">
<div class="fn__flex-1">
{pluginInstance.i18n.customFnSwitch}
Expand All @@ -113,16 +163,38 @@
<textarea
class="b3-text-field fn__block"
placeholder={pluginInstance.i18n.customFnHandlerPlaceholder}
rows="10"
rows="8"
spellcheck="false"
bind:value={customFn}
/>
</div>
</label>

<label class="fn__flex b3-label">
<div class="fn__flex-1">
<button class="b3-button b3-button--outline fn__flex-right fn__size200" on:click={testFn}> 测试 </button>
<div class="fn__hr" />
{pluginInstance.i18n.testInput}
<textarea class="b3-text-field fn__block test-data-item" rows="6" spellcheck="false" bind:value={testInput} />
{pluginInstance.i18n.testOutput}
<textarea
class="b3-text-field fn__block test-data-item"
placeholder={pluginInstance.i18n.testOutputPlaceholder}
rows="6"
spellcheck="false"
bind:value={testOutput}
/>
</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>

<style lang="stylus">
.test-data-item
margin 4px 0
</style>
45 changes: 36 additions & 9 deletions src/service/importService.ts
Expand Up @@ -26,8 +26,17 @@
import { mediaDir, workspaceDir } from "../Constants"
import { getBackend, getFrontend, showMessage } from "siyuan"
import ImporterPlugin from "../index"
import { copyDir, isPC, removeEmptyLines, removeFootnotes, removeLinks, replaceImagePath } from "../utils/utils"
import {
copyDir,
getExports,
isPC,
removeEmptyLines,
removeFootnotes,
removeLinks,
replaceImagePath,
} from "../utils/utils"
import shortHash from "shorthash2"
import { loadImporterConfig } from "../store/config"

export class ImportService {
/**
Expand Down Expand Up @@ -104,14 +113,32 @@ export class ImportService {
}

// 文本处理
// 删除目录中链接
mdText = removeLinks(mdText)
// 去除空行
mdText = removeEmptyLines(mdText)
// 资源路径
mdText = replaceImagePath(mdText)
// 去除脚注
mdText = removeFootnotes(mdText)
const importConfig = await loadImporterConfig(pluginInstance)
if (importConfig.bundledFnSwitch) {
pluginInstance.logger.info("Using bundled handler process text")
// 删除目录中链接
mdText = removeLinks(mdText)
// 去除空行
mdText = removeEmptyLines(mdText)
// 资源路径
mdText = replaceImagePath(mdText)
// 去除脚注
mdText = removeFootnotes(mdText)
}

// 自定义文本处理
if (importConfig.customFnSwitch) {
pluginInstance.logger.warn("Using custom handler process text")
try {
const customFn = importConfig.customFn
const exportsFn = getExports(customFn)
mdText = exportsFn(mdText)
} catch (e) {
showMessage(`${pluginInstance.i18n.customFnHandlerError} ${e.toString()}`, 5000, "error")
}
}

// 保存处理的最终文本
await pluginInstance.kernelApi.saveTextData(`${toFilename}`, mdText)

return {
Expand Down
6 changes: 5 additions & 1 deletion src/utils/utils.ts
Expand Up @@ -146,7 +146,7 @@ export const copyDir = async (src, dest) => {
const fs = window.require("fs")
const path = window.require("path")

if(!fs.existsSync(src)){
if (!fs.existsSync(src)) {
console.warn("Can not get path")
return
}
Expand All @@ -171,3 +171,7 @@ export const copyDir = async (src, dest) => {
}
}
}

export const getExports = (jsText) => {
return eval(jsText)
}

0 comments on commit f5452e2

Please sign in to comment.