-
Notifications
You must be signed in to change notification settings - Fork 72
Add plugin 繁简转换 v1.0.0 #203
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| # 繁简转换(ZTools 插件) | ||
|
|
||
| 基于 [OpenCC](https://github.com/BYVoid/OpenCC)(`opencc-js`)的繁体字与简体字互转,支持台湾地区 / 香港地区与大陆简体之间的用词差异。 | ||
|
|
||
| ## 功能 | ||
|
|
||
| - 界面**左侧为原文**,**右侧为转换结果**,可对照查看。 | ||
| - 在 ZTools 中复制文本后呼出启动器:剪贴板有内容时会出现 **「繁简转换(剪贴板)」**,进入插件后自动填入**原文**侧;在右侧点击 **繁 → 简** 或 **简 → 繁** 生成结果。 | ||
| - 剪贴板为空时,可搜索 **「繁简转换」** 或 **「繁简」** 手动打开。 | ||
| - **繁体标准**可在界面选择 **台湾(tw)** 或 **香港(hk)**,会影响词语级转换。 | ||
|
|
||
| ## 安装依赖 | ||
|
|
||
| 在插件根目录执行: | ||
|
|
||
| ```bash | ||
| npm install | ||
| ``` | ||
|
|
||
| 需存在 `node_modules/opencc-js`(ZTools 通过 `preload.js` 以 CommonJS 加载)。 | ||
|
|
||
| ## 在 ZTools 中加载 | ||
|
|
||
| 1. 将本目录准备完整(含 `logo.png`、`plugin.json`、`preload.js`、`index.html` 等)。 | ||
| 2. ZTools → **设置** → **开发者** → **加载本地插件**,选择本插件目录。 | ||
| 3. 修改 `preload.js` 后若未生效,请对该插件 **卸载再重新加载**(preload 通常不热重载)。 | ||
|
|
||
| ## 文件说明 | ||
|
|
||
| | 文件 | 说明 | | ||
| |------|------| | ||
| | `plugin.json` | 插件元数据、主搜索框推送(剪贴板入口)与手动打开关键字 | | ||
| | `preload.js` | 读取剪贴板、`opencc-js` 转换逻辑、`onMainPush` / `onPluginEnter` | | ||
| | `index.html` / `index.js` | 双栏界面与交互 | | ||
| | `package.json` | 声明 `opencc-js` 依赖 | |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,143 @@ | ||
| <!DOCTYPE html> | ||
| <html lang="zh-CN"> | ||
| <head> | ||
| <meta charset="UTF-8" /> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1" /> | ||
| <title>繁简转换</title> | ||
| <style> | ||
| * { box-sizing: border-box; } | ||
| body { | ||
| margin: 0; | ||
| padding: 16px 18px 24px; | ||
| font-family: -apple-system, "Segoe UI", "Microsoft YaHei", "PingFang SC", sans-serif; | ||
| font-size: 14px; | ||
| line-height: 1.45; | ||
| background: #f5f5f7; | ||
| color: #1d1d1f; | ||
| } | ||
| body.dark { | ||
| background: #1c1c1e; | ||
| color: #f5f5f7; | ||
| } | ||
| h1 { | ||
| margin: 0 0 12px; | ||
| font-size: 18px; | ||
| font-weight: 600; | ||
| } | ||
| .toolbar { | ||
| display: flex; | ||
| flex-wrap: wrap; | ||
| gap: 8px; | ||
| align-items: center; | ||
| margin-bottom: 12px; | ||
| } | ||
| .toolbar label { font-size: 13px; opacity: 0.85; } | ||
| select { | ||
| padding: 6px 10px; | ||
| border-radius: 6px; | ||
| border: 1px solid #c7c7cc; | ||
| background: #fff; | ||
| color: inherit; | ||
| font-size: 13px; | ||
| } | ||
| body.dark select { | ||
| background: #2c2c2e; | ||
| border-color: #48484a; | ||
| } | ||
| .panels { | ||
| display: grid; | ||
| grid-template-columns: 1fr 1fr; | ||
| gap: 12px; | ||
| align-items: stretch; | ||
| } | ||
| @media (max-width: 520px) { | ||
| .panels { grid-template-columns: 1fr; } | ||
| } | ||
| .panel { | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 6px; | ||
| min-width: 0; | ||
| } | ||
| .panel label { | ||
| font-size: 13px; | ||
| font-weight: 500; | ||
| opacity: 0.88; | ||
| } | ||
| textarea { | ||
| width: 100%; | ||
| min-height: 160px; | ||
| flex: 1; | ||
| padding: 10px 12px; | ||
| border-radius: 8px; | ||
| border: 1px solid #c7c7cc; | ||
| background: #fff; | ||
| color: inherit; | ||
| font-size: 14px; | ||
| resize: vertical; | ||
| font-family: inherit; | ||
| } | ||
| body.dark textarea { | ||
| background: #2c2c2e; | ||
| border-color: #48484a; | ||
| } | ||
| textarea.result { | ||
| background: #fafafa; | ||
| } | ||
| body.dark textarea.result { | ||
| background: #252528; | ||
| } | ||
| .actions { | ||
| display: flex; | ||
| flex-wrap: wrap; | ||
| gap: 8px; | ||
| margin-top: 12px; | ||
| } | ||
| button { | ||
| padding: 8px 14px; | ||
| border: none; | ||
| border-radius: 6px; | ||
| background: #007aff; | ||
| color: #fff; | ||
| cursor: pointer; | ||
| font-size: 13px; | ||
| } | ||
| button:hover { background: #0066d6; } | ||
| button.secondary { | ||
| background: #e5e5ea; | ||
| color: #1d1d1f; | ||
| } | ||
| body.dark button.secondary { | ||
| background: #3a3a3c; | ||
| color: #f5f5f7; | ||
| } | ||
| button.secondary:hover { opacity: 0.92; } | ||
| </style> | ||
| </head> | ||
| <body> | ||
| <h1>繁简转换</h1> | ||
| <div class="toolbar"> | ||
| <label for="variant">繁体标准</label> | ||
| <select id="variant" aria-label="繁体标准"> | ||
| <option value="tw" selected>台湾(OpenCC tw)</option> | ||
| <option value="hk">香港(OpenCC hk)</option> | ||
| </select> | ||
| </div> | ||
| <div class="panels"> | ||
| <div class="panel"> | ||
| <label for="inputOriginal">原文</label> | ||
| <textarea id="inputOriginal" placeholder="在此粘贴或输入中文…" spellcheck="false"></textarea> | ||
| </div> | ||
| <div class="panel"> | ||
| <label for="inputResult">转换结果</label> | ||
| <textarea id="inputResult" class="result" placeholder="点击上方按钮,从原文生成…" spellcheck="false"></textarea> | ||
| </div> | ||
| </div> | ||
| <div class="actions"> | ||
| <button type="button" id="btnToSimp">繁 → 简</button> | ||
| <button type="button" id="btnToTrad">简 → 繁</button> | ||
| <button type="button" class="secondary" id="btnCopy">复制转换结果</button> | ||
| </div> | ||
| <script src="index.js"></script> | ||
| </body> | ||
| </html> |
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,77 @@ | ||||||||
| ;(function () { | ||||||||
| var originalEl = document.getElementById('inputOriginal') | ||||||||
| var resultEl = document.getElementById('inputResult') | ||||||||
| var variantEl = document.getElementById('variant') | ||||||||
|
|
||||||||
| if (window.ztools && window.ztools.isDarkColors && window.ztools.isDarkColors()) { | ||||||||
| document.body.classList.add('dark') | ||||||||
| } | ||||||||
|
|
||||||||
| function resizeHeight() { | ||||||||
| setTimeout(function () { | ||||||||
| var h = document.body.scrollHeight | ||||||||
| if (window.ztools && window.ztools.setExpendHeight) { | ||||||||
| window.ztools.setExpendHeight(h + 48) | ||||||||
| } | ||||||||
| }, 80) | ||||||||
|
Comment on lines
+11
to
+16
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||||
| } | ||||||||
|
|
||||||||
| function applyVariant() { | ||||||||
| if (window.nodeAPI && window.nodeAPI.setVariant) { | ||||||||
| window.nodeAPI.setVariant(variantEl.value) | ||||||||
| } | ||||||||
| } | ||||||||
|
|
||||||||
| variantEl.addEventListener('change', function () { | ||||||||
| applyVariant() | ||||||||
| resizeHeight() | ||||||||
| }) | ||||||||
| applyVariant() | ||||||||
|
|
||||||||
| function onTextChange() { | ||||||||
| resizeHeight() | ||||||||
| } | ||||||||
| originalEl.addEventListener('input', onTextChange) | ||||||||
| resultEl.addEventListener('input', onTextChange) | ||||||||
|
|
||||||||
| document.getElementById('btnToSimp').addEventListener('click', function () { | ||||||||
| if (!window.nodeAPI) return | ||||||||
| applyVariant() | ||||||||
| resultEl.value = window.nodeAPI.toSimplified(originalEl.value) | ||||||||
|
Comment on lines
+39
to
+40
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 此处调用
Suggested change
|
||||||||
| resizeHeight() | ||||||||
| }) | ||||||||
|
|
||||||||
| document.getElementById('btnToTrad').addEventListener('click', function () { | ||||||||
| if (!window.nodeAPI) return | ||||||||
| applyVariant() | ||||||||
| resultEl.value = window.nodeAPI.toTraditional(originalEl.value) | ||||||||
|
Comment on lines
+46
to
+47
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||||
| resizeHeight() | ||||||||
| }) | ||||||||
|
|
||||||||
| document.getElementById('btnCopy').addEventListener('click', function () { | ||||||||
| var t = resultEl.value | ||||||||
| if (!t) { | ||||||||
| if (window.ztools && window.ztools.showNotification) { | ||||||||
| window.ztools.showNotification('没有可复制的内容') | ||||||||
| } | ||||||||
| return | ||||||||
| } | ||||||||
| if (window.ztools && window.ztools.copyText) { | ||||||||
| window.ztools.copyText(t) | ||||||||
| window.ztools.showNotification('已复制转换结果') | ||||||||
| } | ||||||||
| }) | ||||||||
|
|
||||||||
| window.addEventListener('plugin-enter', function (e) { | ||||||||
| var action = e.detail || {} | ||||||||
| var payload = action.payload | ||||||||
| if (action.code === 'convert-clipboard' && typeof payload === 'string') { | ||||||||
| applyVariant() | ||||||||
| originalEl.value = payload | ||||||||
| resultEl.value = '' | ||||||||
| } | ||||||||
| resizeHeight() | ||||||||
| }) | ||||||||
|
|
||||||||
| resizeHeight() | ||||||||
| })() | ||||||||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| { | ||
| "name": "ztools-traditional-simplified", | ||
| "version": "1.0.0", | ||
| "private": true, | ||
| "type": "commonjs", | ||
| "description": "ZTools 插件:繁体字与简体字互转(基于 opencc-js)", | ||
| "dependencies": { | ||
| "opencc-js": "^1.0.5" | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| { | ||
| "name": "traditional-simplified-cn", | ||
| "title": "繁简转换", | ||
| "description": "剪贴板有文本时在启动器中推送入口;亦可手动打开(OpenCC)", | ||
| "version": "1.0.0", | ||
| "author": "lecoix", | ||
| "preload": "preload.js", | ||
| "main": "index.html", | ||
| "logo": "logo.png", | ||
| "features": [ | ||
| { | ||
| "code": "convert-clipboard", | ||
| "explain": "剪贴板有文本时推送", | ||
| "cmds": [ | ||
| { | ||
| "type": "over", | ||
| "label": "繁简转换(剪贴板)", | ||
| "minLength": 0, | ||
| "maxLength": 50000 | ||
| } | ||
| ] | ||
| }, | ||
| { | ||
| "code": "convert-ui", | ||
| "explain": "手动打开(剪贴板为空时)", | ||
| "cmds": ["繁简转换", "繁简"] | ||
| } | ||
| ] | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
建议使用
const代替var来声明这些 DOM 元素的引用。在现代 JavaScript 开发中,const是声明不打算重新赋值的变量的首选方式,有助于提高代码的可读性和可维护性。